From e4dc793c42ab7bbd1ca896d1c10d9f63244011b6 Mon Sep 17 00:00:00 2001 From: Jessica James Date: Tue, 30 Nov 2021 17:28:14 -0600 Subject: [PATCH] Fix & cleanup sockets; update jessilib --- src/common/IRC_Client.cpp | 23 +- src/common/SecureSocket.cpp | 216 +++++++----------- src/common/Socket.cpp | 351 +++++++++++++++++------------ src/include/Jupiter/SecureSocket.h | 29 +-- src/include/Jupiter/Socket.h | 48 ++-- src/jessilib | 2 +- 6 files changed, 314 insertions(+), 355 deletions(-) diff --git a/src/common/IRC_Client.cpp b/src/common/IRC_Client.cpp index bc7e7a0..225a2c8 100644 --- a/src/common/IRC_Client.cpp +++ b/src/common/IRC_Client.cpp @@ -377,14 +377,12 @@ size_t Jupiter::IRC::Client::messageChannels(std::string_view message) return m_channels.size(); } -int Jupiter::IRC::Client::process_line(std::string_view in_line) { - Jupiter::ReferenceString line{in_line}; // TODO: remove this - if (!line.empty()) - { +int Jupiter::IRC::Client::process_line(std::string_view line) { + if (!line.empty()) { Jupiter::IRC::Client::writeToLogs(line); if (m_output != nullptr) { // TODO: use ostream instead - fwrite(in_line.data(), sizeof(char), in_line.size(), m_output); + fwrite(line.data(), sizeof(char), line.size(), m_output); fputs("\r\n", m_output); } @@ -1116,8 +1114,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { return 0; } -bool Jupiter::IRC::Client::connect() -{ +bool Jupiter::IRC::Client::connect() { std::string_view clientAddress = Jupiter::IRC::Client::readConfigValue("ClientAddress"_jrs); if (m_socket->connect(m_server_hostname.c_str(), m_server_port, clientAddress.empty() ? nullptr : static_cast(clientAddress).c_str(), (unsigned short)Jupiter::IRC::Client::readConfigLong("ClientPort"_jrs)) == false) return false; @@ -1181,15 +1178,12 @@ void Jupiter::IRC::Client::reconnect() } } -int Jupiter::IRC::Client::think() -{ - auto handle_error = [this](int error_code) - { +int Jupiter::IRC::Client::think() { + auto handle_error = [this](int error_code) { if (this->m_dead == true) return error_code; - if (this->m_max_reconnect_attempts < 0 || this->m_reconnect_attempts < this->m_max_reconnect_attempts) - { + if (this->m_max_reconnect_attempts < 0 || this->m_reconnect_attempts < this->m_max_reconnect_attempts) { if (!this->m_reconnect_delay || this->m_reconnect_time < time(0)) this->reconnect(); @@ -1203,8 +1197,7 @@ int Jupiter::IRC::Client::think() return handle_error(-1); int tmp = m_socket->recv(); - if (tmp > 0) - { + if (tmp > 0) { // Process incoming data using namespace std::literals; auto tokens = jessilib::split_view(m_socket->getBuffer(), "\r\n"sv); diff --git a/src/common/SecureSocket.cpp b/src/common/SecureSocket.cpp index 3bfc021..0693218 100644 --- a/src/common/SecureSocket.cpp +++ b/src/common/SecureSocket.cpp @@ -21,66 +21,61 @@ #include // OpenSSL SSL errors #include "SecureSocket.h" -struct Jupiter::SecureSocket::SSLData -{ - SSL *handle = nullptr; - SSL_CTX *context = nullptr; - const SSL_METHOD *method = nullptr; - Jupiter::SecureSocket::EncryptionMethod eMethod = ANY; +struct Jupiter::SecureSocket::SSLData { + SSL* handle = nullptr; + SSL_CTX* context = nullptr; + const SSL_METHOD* method = nullptr; std::string cert; std::string key; ~SSLData(); }; -Jupiter::SecureSocket::SSLData::~SSLData() -{ - if (Jupiter::SecureSocket::SSLData::handle != nullptr) - { - if (SSL_shutdown(Jupiter::SecureSocket::SSLData::handle) == 0) SSL_shutdown(Jupiter::SecureSocket::SSLData::handle); +Jupiter::SecureSocket::SSLData::~SSLData() { + if (Jupiter::SecureSocket::SSLData::handle != nullptr) { + if (SSL_shutdown(Jupiter::SecureSocket::SSLData::handle) == 0) { + SSL_shutdown(Jupiter::SecureSocket::SSLData::handle); + } SSL_free(Jupiter::SecureSocket::SSLData::handle); } if (Jupiter::SecureSocket::SSLData::context != nullptr) SSL_CTX_free(Jupiter::SecureSocket::SSLData::context); } -Jupiter::SecureSocket &Jupiter::SecureSocket::operator=(Jupiter::SecureSocket &&source) -{ +Jupiter::SecureSocket &Jupiter::SecureSocket::operator=(Jupiter::SecureSocket &&source) { Jupiter::Socket::operator=(std::move(source)); - Jupiter::SecureSocket::SSLdata_ = source.SSLdata_; - source.SSLdata_ = nullptr; + m_ssl_data = source.m_ssl_data; + source.m_ssl_data = nullptr; return *this; } -Jupiter::SecureSocket::SecureSocket() : Jupiter::Socket() -{ - Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData(); +Jupiter::SecureSocket::SecureSocket() : Jupiter::Socket() { + m_ssl_data = new Jupiter::SecureSocket::SSLData(); } -Jupiter::SecureSocket::SecureSocket(size_t bufferSize) : Jupiter::Socket(bufferSize) -{ - Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData(); +Jupiter::SecureSocket::SecureSocket(size_t bufferSize) + : Jupiter::Socket(bufferSize) { + m_ssl_data = new Jupiter::SecureSocket::SSLData(); } -Jupiter::SecureSocket::SecureSocket(Jupiter::Socket &&source) : Jupiter::Socket(std::move(source)) -{ - Jupiter::SecureSocket::SSLdata_ = new Jupiter::SecureSocket::SSLData(); +Jupiter::SecureSocket::SecureSocket(Jupiter::Socket &&source) + : Jupiter::Socket(std::move(source)) { + m_ssl_data = new Jupiter::SecureSocket::SSLData(); } -Jupiter::SecureSocket::SecureSocket(Jupiter::SecureSocket &&source) : Jupiter::Socket(std::move(source)) -{ - Jupiter::SecureSocket::SSLdata_ = source.SSLdata_; - source.SSLdata_ = nullptr; +Jupiter::SecureSocket::SecureSocket(Jupiter::SecureSocket &&source) + : Jupiter::Socket(std::move(source)) { + m_ssl_data = source.m_ssl_data; + source.m_ssl_data = nullptr; } -Jupiter::SecureSocket::~SecureSocket() -{ - if (Jupiter::SecureSocket::SSLdata_ != nullptr) delete Jupiter::SecureSocket::SSLdata_; +Jupiter::SecureSocket::~SecureSocket() { + if (m_ssl_data != nullptr) { + delete m_ssl_data; + } } -Jupiter::SecureSocket *Jupiter::SecureSocket::accept() -{ - SocketType tSock = SSL_accept(Jupiter::SecureSocket::SSLdata_->handle); - if (tSock > 0) - { +Jupiter::SecureSocket *Jupiter::SecureSocket::accept() { + SocketType tSock = SSL_accept(m_ssl_data->handle); + if (tSock > 0) { SecureSocket *r = new SecureSocket(Jupiter::SecureSocket::getBufferSize()); r->setDescriptor(tSock); r->setType(this->getType()); @@ -90,86 +85,46 @@ Jupiter::SecureSocket *Jupiter::SecureSocket::accept() return nullptr; } -bool Jupiter::SecureSocket::bind(const char *hostname, unsigned short iPort, bool andListen) -{ +bool Jupiter::SecureSocket::bind(const char *hostname, unsigned short iPort, bool andListen) { return Jupiter::Socket::bind(hostname, iPort, andListen); } -void Jupiter::SecureSocket::shutdown() -{ +void Jupiter::SecureSocket::shutdown() { Jupiter::Socket::shutdown(); - if (Jupiter::SecureSocket::SSLdata_ != nullptr && Jupiter::SecureSocket::SSLdata_->handle != nullptr) + if (m_ssl_data != nullptr && m_ssl_data->handle != nullptr) { - if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) - SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle); + if (SSL_shutdown(m_ssl_data->handle) == 0) { + SSL_shutdown(m_ssl_data->handle); + } } } -void Jupiter::SecureSocket::close() -{ +void Jupiter::SecureSocket::close() { Jupiter::Socket::close(); - if (Jupiter::SecureSocket::SSLdata_ != nullptr && Jupiter::SecureSocket::SSLdata_->handle != nullptr) - { - if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) - SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle); - SSL_free(Jupiter::SecureSocket::SSLdata_->handle); - Jupiter::SecureSocket::SSLdata_->handle = nullptr; - } -} - -const SSL_METHOD *translateEncryptionMethod(Jupiter::SecureSocket::EncryptionMethod method) { - // These are disabled due to deprecations, but also there's not that much reason to actually maintain this method - // since we realistically never use anything except EncryptionMethod::ANY. It was an interesting idea, but there - // just isn't a real use case for these methods. Regardless, better way to implement setMethod/getMethod() would be - // to not provide any abstract implementation at all, and to instead include such option setting as part of some - // OpenSSL provider plugin - switch (method) { - //case Jupiter::SecureSocket::EncryptionMethod::SSL3: - // return SSLv3_method(); - case Jupiter::SecureSocket::EncryptionMethod::TLS1: - //return TLSv1_method(); - case Jupiter::SecureSocket::EncryptionMethod::TLS1_1: - //return TLSv1_1_method(); - case Jupiter::SecureSocket::EncryptionMethod::TLS1_2: - //return TLSv1_2_method(); - case Jupiter::SecureSocket::EncryptionMethod::DTLS1: - //return DTLSv1_method(); - case Jupiter::SecureSocket::EncryptionMethod::ANY: - return SSLv23_method(); - default: - return nullptr; + if (m_ssl_data != nullptr && m_ssl_data->handle != nullptr) { + if (SSL_shutdown(m_ssl_data->handle) == 0) { + SSL_shutdown(m_ssl_data->handle); + } + SSL_free(m_ssl_data->handle); + m_ssl_data->handle = nullptr; } } -const char *Jupiter::SecureSocket::getCipherName() const -{ - return SSL_CIPHER_get_name(SSL_get_current_cipher(Jupiter::SecureSocket::SSLdata_->handle)); +const char *Jupiter::SecureSocket::getCipherName() const { + return SSL_CIPHER_get_name(SSL_get_current_cipher(m_ssl_data->handle)); } -Jupiter::SecureSocket::EncryptionMethod Jupiter::SecureSocket::getMethod() const -{ - return Jupiter::SecureSocket::SSLdata_->eMethod; -} - -void Jupiter::SecureSocket::setMethod(Jupiter::SecureSocket::EncryptionMethod method) -{ - Jupiter::SecureSocket::SSLdata_->eMethod = method; -} - -bool loadCertificate(SSL_CTX *context, const char *cert, const char *key) -{ +bool loadCertificate(SSL_CTX *context, const char *cert, const char *key) { if (SSL_CTX_load_verify_locations(context, cert, key) != 1) ERR_print_errors_fp(stderr); if (SSL_CTX_set_default_verify_paths(context) != 1) ERR_print_errors_fp(stderr); - if (SSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM) <= 0) - { + if (SSL_CTX_use_certificate_file(context, cert, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); return false; } - if (SSL_CTX_use_PrivateKey_file(context, key, SSL_FILETYPE_PEM) <= 0) - { + if (SSL_CTX_use_PrivateKey_file(context, key, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); return false; } @@ -178,95 +133,84 @@ bool loadCertificate(SSL_CTX *context, const char *cert, const char *key) return true; } -void Jupiter::SecureSocket::setCertificate(std::string cert, std::string key) -{ - Jupiter::SecureSocket::SSLdata_->cert = std::move(cert); - Jupiter::SecureSocket::SSLdata_->key = std::move(key); +void Jupiter::SecureSocket::setCertificate(std::string cert, std::string key) { + m_ssl_data->cert = std::move(cert); + m_ssl_data->key = std::move(key); } -void Jupiter::SecureSocket::setCertificate(std::string_view pem) -{ +void Jupiter::SecureSocket::setCertificate(std::string_view pem) { Jupiter::SecureSocket::setCertificate(static_cast(pem), static_cast(pem)); } -bool Jupiter::SecureSocket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) -{ +bool Jupiter::SecureSocket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) { return Jupiter::Socket::connect(hostname, iPort, clientAddress, clientPort) && this->initSSL(); } -int Jupiter::SecureSocket::peek() -{ - if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) +int Jupiter::SecureSocket::peek() { + if (m_ssl_data->handle == nullptr) return -1; Jupiter::Socket::Buffer &buffer = this->getInternalBuffer(); - buffer.erase(); - int r = SSL_peek(Jupiter::SecureSocket::SSLdata_->handle, buffer.get_str(), static_cast(this->getBufferSize())); + buffer.clear(); + int r = SSL_peek(m_ssl_data->handle, buffer.data(), static_cast(this->getBufferSize())); if (r > 0) buffer.set_length(r); return r; } -int Jupiter::SecureSocket::recv() -{ - if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) +int Jupiter::SecureSocket::recv() { + if (m_ssl_data->handle == nullptr) return -1; Jupiter::Socket::Buffer &buffer = this->getInternalBuffer(); - buffer.erase(); - int r = SSL_read(Jupiter::SecureSocket::SSLdata_->handle, buffer.get_str(), static_cast(this->getBufferSize())); + buffer.clear(); + int r = SSL_read(m_ssl_data->handle, buffer.data(), static_cast(this->getBufferSize())); if (r > 0) buffer.set_length(r); return r; } -int Jupiter::SecureSocket::send(const char *data, size_t datalen) -{ - return SSL_write(Jupiter::SecureSocket::SSLdata_->handle, data, static_cast(datalen)); +int Jupiter::SecureSocket::send(const char *data, size_t datalen) { + return SSL_write(m_ssl_data->handle, data, static_cast(datalen)); } -bool Jupiter::SecureSocket::initSSL() -{ +bool Jupiter::SecureSocket::initSSL() { SSL_load_error_strings(); SSL_library_init(); - if (Jupiter::SecureSocket::SSLdata_->context == nullptr) - { - if (Jupiter::SecureSocket::SSLdata_->method == nullptr) - { - Jupiter::SecureSocket::SSLdata_->method = translateEncryptionMethod(Jupiter::SecureSocket::SSLdata_->eMethod); - if (Jupiter::SecureSocket::SSLdata_->method == nullptr) + if (m_ssl_data->context == nullptr) { + if (m_ssl_data->method == nullptr) { + m_ssl_data->method = TLS_method(); + if (m_ssl_data->method == nullptr) return false; } - Jupiter::SecureSocket::SSLdata_->context = SSL_CTX_new(Jupiter::SecureSocket::SSLdata_->method); - if (Jupiter::SecureSocket::SSLdata_->context == nullptr) - { + m_ssl_data->context = SSL_CTX_new(m_ssl_data->method); + if (m_ssl_data->context == nullptr) { ERR_print_errors_fp(stderr); return false; } - if (!Jupiter::SecureSocket::SSLdata_->cert.empty()) - loadCertificate(Jupiter::SecureSocket::SSLdata_->context, Jupiter::SecureSocket::SSLdata_->cert.c_str(), Jupiter::SecureSocket::SSLdata_->key.c_str()); + if (!m_ssl_data->cert.empty()) { + loadCertificate(m_ssl_data->context, m_ssl_data->cert.c_str(), m_ssl_data->key.c_str()); + } } - Jupiter::SecureSocket::SSLdata_->handle = SSL_new(Jupiter::SecureSocket::SSLdata_->context); - if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) - { + m_ssl_data->handle = SSL_new(m_ssl_data->context); + if (m_ssl_data->handle == nullptr) { ERR_print_errors_fp(stderr); return false; } // Not suppressing this warning; descriptor ideally shouldn't be getting shortened here, even if it's "safe" // TODO: Can't resolve this without removing OpenSSL usage on Windows; we should ideally use Windows APIs - if (SSL_set_fd(Jupiter::SecureSocket::SSLdata_->handle, this->getDescriptor()) == 0) - { + if (SSL_set_fd(m_ssl_data->handle, this->getDescriptor()) == 0) { ERR_print_errors_fp(stderr); return false; } - if (SSL_set_tlsext_host_name(Jupiter::SecureSocket::SSLdata_->handle, this->getRemoteHostnameC()) != 1) // This error check is potentially redundant, but no documentation has been found. - { + if (SSL_set_tlsext_host_name(m_ssl_data->handle, this->getRemoteHostnameC()) != 1) { + // This error check is potentially redundant, but no documentation has been found. ERR_print_errors_fp(stderr); return false; } - int t = SSL_connect(Jupiter::SecureSocket::SSLdata_->handle); + int t = SSL_connect(m_ssl_data->handle); if (t != 1) { ERR_print_errors_fp(stderr); diff --git a/src/common/Socket.cpp b/src/common/Socket.cpp index 6f9f0e2..c85696d 100644 --- a/src/common/Socket.cpp +++ b/src/common/Socket.cpp @@ -45,12 +45,68 @@ bool socketInit = false; #pragma warning(disable: 4267) #endif +constexpr size_t s_initial_buffer_size = 512; + +Jupiter::Socket::Buffer::Buffer() + : m_buffer{ ::operator new(s_initial_buffer_size) }, + m_buffer_capacity{ s_initial_buffer_size }, + m_buffer_size{0} { +} + +Jupiter::Socket::Buffer::~Buffer() { + ::operator delete(m_buffer); +} + void Jupiter::Socket::Buffer::set_length(size_t in_length) { - this->length = in_length; + m_buffer_size = in_length; } -char *Jupiter::Socket::Buffer::get_str() const { - return this->str; +size_t Jupiter::Socket::Buffer::capacity() const { + return m_buffer_capacity; +} + +void Jupiter::Socket::Buffer::reserve(size_t new_capacity) { + if (capacity() == new_capacity // Skip when already this size + || new_capacity == 0 // Don't allow empty buffers, results in 0 from recv + || new_capacity < m_buffer_size) { // Don't shrink smaller than what we require + return; + } + + // We're gonna change the buffer one way or another; update our capacity + m_buffer_capacity = new_capacity; + + if (m_buffer_size == 0) { + // Nothing to copy; easy mode + ::operator delete(m_buffer); + m_buffer = ::operator new(new_capacity); + return; + } + + // Backup current buffer data + void* old_buffer = m_buffer; + + // Create new buffer + m_buffer = ::operator new(new_capacity); + std::memcpy(m_buffer, old_buffer, m_buffer_size); + + // Nuke the old buffer + ::operator delete(m_buffer); +} + +void Jupiter::Socket::Buffer::clear() { + m_buffer_size = 0; +} + +std::string_view Jupiter::Socket::Buffer::view() const { + return { static_cast(m_buffer), m_buffer_size }; +} + +void* Jupiter::Socket::Buffer::data() const { + return m_buffer; +} + +char* Jupiter::Socket::Buffer::chr_data() const { + return static_cast(m_buffer); } struct Jupiter::Socket::Data { @@ -71,7 +127,7 @@ struct Jupiter::Socket::Data { }; Jupiter::Socket::Data::Data(size_t buffer_size) { - Jupiter::Socket::Data::buffer.setBufferSizeNoCopy(buffer_size); + Jupiter::Socket::Data::buffer.reserve(buffer_size); } Jupiter::Socket::Data::Data(const Data &source) { @@ -89,8 +145,8 @@ Jupiter::Socket::Data::Data(const Data &source) { } Jupiter::Socket &Jupiter::Socket::operator=(Jupiter::Socket &&source) { - Jupiter::Socket::data_ = source.data_; - source.data_ = nullptr; + m_data = source.m_data; + source.m_data = nullptr; return *this; } @@ -98,62 +154,62 @@ Jupiter::Socket::Socket() : Jupiter::Socket::Socket(512) { } Jupiter::Socket::Socket(size_t bufferSize) { - Jupiter::Socket::data_ = new Jupiter::Socket::Data(bufferSize); + m_data = new Jupiter::Socket::Data(bufferSize); } Jupiter::Socket::Socket(Jupiter::Socket &&source) { - Jupiter::Socket::data_ = source.data_; - source.data_ = nullptr; + m_data = source.m_data; + source.m_data = nullptr; } Jupiter::Socket::~Socket() { - if (Jupiter::Socket::data_ != nullptr) { - if (Jupiter::Socket::data_->rawSock > 0) + if (m_data != nullptr) { + if (m_data->rawSock > 0) Jupiter::Socket::close(); - delete Jupiter::Socket::data_; + delete m_data; } } void Jupiter::Socket::setType(int type) { - Jupiter::Socket::data_->sockType = type; + m_data->sockType = type; } void Jupiter::Socket::setProtocol(int proto) { - Jupiter::Socket::data_->sockProto = proto; + m_data->sockProto = proto; } int Jupiter::Socket::getType() const { - return Jupiter::Socket::data_->sockType; + return m_data->sockType; } int Jupiter::Socket::getProtocol() const { - return Jupiter::Socket::data_->sockProto; + return m_data->sockProto; } bool Jupiter::Socket::connect(addrinfo *info) { #if defined _WIN32 - if (!socketInit && !Jupiter::Socket::init()) + if (!socketInit && !Jupiter::Socket::init()) { return false; + } #endif // _WIN32 - Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); + m_data->rawSock = socket(info->ai_family, m_data->sockType, m_data->sockProto); - if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET - || (Jupiter::Socket::data_->sockType != SOCK_RAW && Jupiter::Socket::data_->sockProto != IPPROTO_RAW && ::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)) + if (m_data->rawSock == INVALID_SOCKET + || (m_data->sockType != SOCK_RAW && m_data->sockProto != IPPROTO_RAW && ::connect(m_data->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)) return false; return true; } -bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) -{ +bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) { #if defined _WIN32 if (!socketInit && !Jupiter::Socket::init()) return false; #endif // _WIN32 - Jupiter::Socket::data_->remote_host = hostname; - Jupiter::Socket::data_->remote_port = iPort; - addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->remote_host.c_str(), std::to_string(Jupiter::Socket::data_->remote_port).c_str()); + m_data->remote_host = hostname; + m_data->remote_port = iPort; + addrinfo *info_head = Jupiter::Socket::getAddrInfo(m_data->remote_host.c_str(), std::to_string(m_data->remote_port).c_str()); if (info_head != nullptr) { addrinfo *info = info_head; do { @@ -163,21 +219,20 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const break; } else { - Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); - if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) { + m_data->rawSock = socket(info->ai_family, m_data->sockType, m_data->sockProto); + if (m_data->rawSock == INVALID_SOCKET) { info = info->ai_next; continue; } } - if (::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) - { + if (::connect(m_data->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { #if defined _WIN32 - ::closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(m_data->rawSock); #else // _WIN32 - ::close(Jupiter::Socket::data_->rawSock); + ::close(m_data->rawSock); #endif // WIN32 - Jupiter::Socket::data_->rawSock = INVALID_SOCKET; + m_data->rawSock = INVALID_SOCKET; info = info->ai_next; continue; } @@ -190,38 +245,40 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const return false; } -bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andListen) -{ +bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andListen) { #if defined _WIN32 - if (!socketInit && !Jupiter::Socket::init()) + if (!socketInit && !Jupiter::Socket::init()) { return false; + } #endif // _WIN32 - Jupiter::Socket::data_->bound_host = hostname; - Jupiter::Socket::data_->bound_port = iPort; - addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->bound_host.c_str(), std::to_string(Jupiter::Socket::data_->bound_port).c_str()); + m_data->bound_host = hostname; + m_data->bound_port = iPort; + addrinfo *info_head = Jupiter::Socket::getAddrInfo(m_data->bound_host.c_str(), std::to_string(m_data->bound_port).c_str()); if (info_head != nullptr) { addrinfo *info = info_head; do { - Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); - if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) { + m_data->rawSock = socket(info->ai_family, m_data->sockType, m_data->sockProto); + if (m_data->rawSock == INVALID_SOCKET) { info = info->ai_next; continue; } - if (::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { + if (::bind(m_data->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { #if defined _WIN32 - ::closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(m_data->rawSock); #else // _WIN32 - ::close(Jupiter::Socket::data_->rawSock); + ::close(m_data->rawSock); #endif // WIN32 - Jupiter::Socket::data_->rawSock = INVALID_SOCKET; + m_data->rawSock = INVALID_SOCKET; info = info->ai_next; continue; } Jupiter::Socket::freeAddrInfo(info_head); - if (andListen && Jupiter::Socket::data_->sockType == SOCK_STREAM && ::listen(Jupiter::Socket::data_->rawSock, SOMAXCONN) == SOCKET_ERROR) + if (andListen && m_data->sockType == SOCK_STREAM && ::listen(m_data->rawSock, SOMAXCONN) == SOCKET_ERROR) { return false; + } + return true; } while (info != nullptr); Jupiter::Socket::freeAddrInfo(info_head); @@ -230,39 +287,32 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL } void Jupiter::Socket::shutdown() { - if (Jupiter::Socket::data_ != nullptr) { - ::shutdown(Jupiter::Socket::data_->rawSock, 2); - Jupiter::Socket::data_->is_shutdown = true; + if (m_data != nullptr) { + ::shutdown(m_data->rawSock, 2); + m_data->is_shutdown = true; } } void Jupiter::Socket::close() { - if (Jupiter::Socket::data_ != nullptr) { - if (Jupiter::Socket::data_->is_shutdown == false) + if (m_data != nullptr) { + if (m_data->is_shutdown == false) this->shutdown(); #if defined _WIN32 - ::closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(m_data->rawSock); #else // _WIN32 - ::close(Jupiter::Socket::data_->rawSock); + ::close(m_data->rawSock); #endif // _WIN32 - Jupiter::Socket::data_->rawSock = 0; + m_data->rawSock = 0; } } bool Jupiter::Socket::isShutdown() const { - return Jupiter::Socket::data_->is_shutdown; -} - -addrinfo *Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) { // static - addrinfo *ptr; - if (getaddrinfo(hostname, port, nullptr, &ptr)) return nullptr; - return ptr; + return m_data->is_shutdown; } -addrinfo *Jupiter::Socket::getStaticAddrInfo(const char *hostname, const char *port) { // static - static addrinfo *ptr = nullptr; - if (ptr != nullptr) freeaddrinfo(ptr); - ptr = Jupiter::Socket::getAddrInfo(hostname, port); +addrinfo* Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) { // static + addrinfo *ptr{}; + getaddrinfo(hostname, port, nullptr, &ptr); return ptr; } @@ -271,63 +321,61 @@ void Jupiter::Socket::freeAddrInfo(addrinfo *info) { // static } addrinfo *Jupiter::Socket::getAddrInfo(addrinfo *addr, unsigned int result) { // static - addrinfo *ptr = addr; - for (unsigned int i = 0; i != result && ptr != nullptr; i++) ptr = ptr->ai_next; + addrinfo* ptr = addr; + while (ptr != nullptr && result != 0) { + ptr = ptr->ai_next; + --result; + } + return ptr; } -char *Jupiter::Socket::resolveAddress(const addrinfo *addr) { // static - static char resolved[NI_MAXHOST]; +std::string Jupiter::Socket::resolveAddress(const addrinfo *addr) { // static + char resolved[NI_MAXHOST]; getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, NI_NUMERICHOST); return resolved; } -char *Jupiter::Socket::resolveAddress(addrinfo *addr, unsigned int result) { // static +std::string Jupiter::Socket::resolveAddress(addrinfo *addr, unsigned int result) { // static addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result); - if (ptr == nullptr) return nullptr; + if (ptr == nullptr) { + return {}; + } + return Jupiter::Socket::resolveAddress(ptr); } -char *Jupiter::Socket::resolveAddress(const char *hostname, unsigned int result) { // static +std::string Jupiter::Socket::resolveAddress(const char *hostname, unsigned int result) { // static addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0); - if (info == nullptr) return nullptr; + if (info == nullptr) { + return {}; + }; + return Jupiter::Socket::resolveAddress(info, result); } -char *Jupiter::Socket::resolveHostname(addrinfo *addr) { // static - static char resolved[NI_MAXHOST]; +std::string Jupiter::Socket::resolveHostname(addrinfo *addr) { // static + char resolved[NI_MAXHOST]; getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, sizeof(resolved), 0, 0, 0); return resolved; } -char *Jupiter::Socket::resolveHostname_alloc(addrinfo *addr) { // static - char *resolved = new char[NI_MAXHOST]; - getnameinfo(addr->ai_addr, addr->ai_addrlen, resolved, NI_MAXHOST, 0, 0, 0); - return resolved; -} - -char *Jupiter::Socket::resolveHostname(addrinfo *addr, unsigned int result) { // static +std::string Jupiter::Socket::resolveHostname(addrinfo *addr, unsigned int result) { // static addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result); - if (ptr == nullptr) return nullptr; - return Jupiter::Socket::resolveHostname(ptr); -} + if (ptr == nullptr) { + return {}; + } -char *Jupiter::Socket::resolveHostname_alloc(addrinfo *addr, unsigned int result) { // static - addrinfo *ptr = Jupiter::Socket::getAddrInfo(addr, result); - if (ptr == nullptr) return nullptr; - return Jupiter::Socket::resolveHostname_alloc(ptr); + return Jupiter::Socket::resolveHostname(ptr); } -char *Jupiter::Socket::resolveHostname(const char *hostname, unsigned int result) { // static +std::string Jupiter::Socket::resolveHostname(const char *hostname, unsigned int result) { // static addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0); - if (info == nullptr) return nullptr; - return Jupiter::Socket::resolveHostname(info, result); -} + if (info == nullptr) { + return {}; + } -char *Jupiter::Socket::resolveHostname_alloc(const char *hostname, unsigned int result) { // static - addrinfo *info = Jupiter::Socket::getAddrInfo(hostname, 0); - if (info == nullptr) return nullptr; - return Jupiter::Socket::resolveHostname_alloc(info, result); + return Jupiter::Socket::resolveHostname(info, result); } uint32_t Jupiter::Socket::pton4(const char *str) { @@ -371,44 +419,44 @@ Jupiter::StringS Jupiter::Socket::ntop(void *ip, size_t size) { } } -Jupiter::Socket *Jupiter::Socket::accept() { +Jupiter::Socket* Jupiter::Socket::accept() { sockaddr addr; socklen_t size = sizeof(addr); - SocketType tSock = ::accept(Socket::data_->rawSock, &addr, &size); + SocketType tSock = ::accept(m_data->rawSock, &addr, &size); if (tSock != INVALID_SOCKET) { char resolved[NI_MAXHOST]; char resolved_port[NI_MAXSERV]; getnameinfo(&addr, size, resolved, sizeof(resolved), resolved_port, sizeof(resolved_port), NI_NUMERICHOST | NI_NUMERICSERV); - Socket *r = new Socket(Jupiter::Socket::data_->buffer.capacity()); - r->data_->rawSock = tSock; - r->data_->sockType = Jupiter::Socket::data_->sockType; - r->data_->sockProto = Jupiter::Socket::data_->sockProto; - r->data_->remote_host = resolved; - r->data_->remote_port = static_cast(Jupiter_strtoi(resolved_port, 10)); - return r; + Socket *result = new Socket(m_data->buffer.capacity()); + result->m_data->rawSock = tSock; + result->m_data->sockType = m_data->sockType; + result->m_data->sockProto = m_data->sockProto; + result->m_data->remote_host = resolved; + result->m_data->remote_port = static_cast(Jupiter_strtoi(resolved_port, 10)); + return result; } return nullptr; } bool Jupiter::Socket::setReadTimeout(unsigned long milliseconds) { #if defined _WIN32 - return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&milliseconds), sizeof(milliseconds)) == 0; + return setsockopt(m_data->rawSock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&milliseconds), sizeof(milliseconds)) == 0; #else // _WIN32 timeval time; time.tv_sec = milliseconds / 1000; time.tv_usec = (milliseconds % 1000) * 1000; - return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const void *) &time, sizeof(time)) == 0; + return setsockopt(m_data->rawSock, SOL_SOCKET, SO_RCVTIMEO, (const void *) &time, sizeof(time)) == 0; #endif // _WIN32 } bool Jupiter::Socket::setSendTimeout(unsigned long milliseconds) { #if defined _WIN32 - return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast(&milliseconds), sizeof(milliseconds)) == 0; + return setsockopt(m_data->rawSock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast(&milliseconds), sizeof(milliseconds)) == 0; #else // _WIN32 timeval time; time.tv_sec = milliseconds / 1000; time.tv_usec = (milliseconds % 1000) * 1000; - return setsockopt(Jupiter::Socket::data_->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const void *) &time, sizeof(time)) == 0; + return setsockopt(m_data->rawSock, SOL_SOCKET, SO_SNDTIMEO, (const void *) &time, sizeof(time)) == 0; #endif // _WIN32 } @@ -419,10 +467,10 @@ bool Jupiter::Socket::setTimeout(unsigned long milliseconds) { bool Jupiter::Socket::setBlocking(bool mode) { #if defined _WIN32 - Jupiter::Socket::data_->blockMode = !mode; - return ioctlsocket(Jupiter::Socket::data_->rawSock, FIONBIO, &Jupiter::Socket::data_->blockMode) == 0; + m_data->blockMode = !mode; + return ioctlsocket(m_data->rawSock, FIONBIO, &m_data->blockMode) == 0; #else // _WIN32 - int flags = fcntl(Jupiter::Socket::data_->rawSock, F_GETFL, 0); + int flags = fcntl(m_data->rawSock, F_GETFL, 0); if (flags < 0) return 0; if (mode) { flags &= ~O_NONBLOCK; @@ -430,61 +478,62 @@ bool Jupiter::Socket::setBlocking(bool mode) { else { flags |= O_NONBLOCK; } - return fcntl(Jupiter::Socket::data_->rawSock, F_SETFL, flags) == 0; + return fcntl(m_data->rawSock, F_SETFL, flags) == 0; #endif // _WIN32 } bool Jupiter::Socket::getBlockingMode() const { #if defined _WIN32 - return !Jupiter::Socket::data_->blockMode; + return !m_data->blockMode; #else // _WIN32 - int flags = fcntl(data_->rawSock, F_GETFL, 0); + int flags = fcntl(m_data->rawSock, F_GETFL, 0); if (flags == -1) return false; return !(flags & O_NONBLOCK); #endif } const std::string &Jupiter::Socket::getRemoteHostname() const { - return Jupiter::Socket::data_->remote_host; + return m_data->remote_host; } const char *Jupiter::Socket::getRemoteHostnameC() const { - return Jupiter::Socket::data_->remote_host.c_str(); + return m_data->remote_host.c_str(); } const std::string &Jupiter::Socket::getBoundHostname() const { - return Jupiter::Socket::data_->bound_host; + return m_data->bound_host; } const char *Jupiter::Socket::getBoundHostnameC() const { - return Jupiter::Socket::data_->bound_host.c_str(); + return m_data->bound_host.c_str(); } unsigned short Jupiter::Socket::getRemotePort() const { - return Jupiter::Socket::data_->remote_port; + return m_data->remote_port; } unsigned short Jupiter::Socket::getBoundPort() const { - return Jupiter::Socket::data_->bound_port; + return m_data->bound_port; } std::string_view Jupiter::Socket::getBuffer() const { - return Jupiter::Socket::data_->buffer; + return m_data->buffer.view(); } size_t Jupiter::Socket::getBufferSize() const { - return Jupiter::Socket::data_->buffer.capacity(); + return m_data->buffer.capacity(); } std::string_view Jupiter::Socket::setBufferSize(size_t size) { - Jupiter::Socket::data_->buffer.setBufferSize(size); - return Jupiter::Socket::data_->buffer; + m_data->buffer.reserve(size); + return m_data->buffer.view(); } std::string_view Jupiter::Socket::getData() { - if (this->recv() <= 0) - Jupiter::Socket::data_->buffer.erase(); - return Jupiter::Socket::data_->buffer; + if (this->recv() <= 0) { + m_data->buffer.clear(); + } + return m_data->buffer.view(); } const char *Jupiter::Socket::getLocalHostname() { // static @@ -494,11 +543,11 @@ const char *Jupiter::Socket::getLocalHostname() { // static } void Jupiter::Socket::clearBuffer() { - Jupiter::Socket::data_->buffer.erase(); + m_data->buffer.clear(); } int Jupiter::Socket::send(const char *data, size_t datalen) { - return ::send(Jupiter::Socket::data_->rawSock, data, datalen, 0); + return ::send(m_data->rawSock, data, datalen, 0); } int Jupiter::Socket::send(std::string_view str) { @@ -510,32 +559,32 @@ int Jupiter::Socket::send(const char *msg) { } int Jupiter::Socket::sendTo(const addrinfo *info, const char *data, size_t datalen) { - return sendto(Jupiter::Socket::data_->rawSock, data, datalen, 0, info->ai_addr, info->ai_addrlen); + return sendto(m_data->rawSock, data, datalen, 0, info->ai_addr, info->ai_addrlen); } int Jupiter::Socket::sendTo(const addrinfo *info, const char *msg) { - return sendto(Jupiter::Socket::data_->rawSock, msg, strlen(msg), 0, info->ai_addr, info->ai_addrlen); + return sendto(m_data->rawSock, msg, strlen(msg), 0, info->ai_addr, info->ai_addrlen); } int Jupiter::Socket::peek() { - Jupiter::Socket::data_->buffer.erase(); - int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK); + m_data->buffer.clear(); + int r = ::recv(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), MSG_PEEK); if (r > 0) - Jupiter::Socket::data_->buffer.set_length(r); + m_data->buffer.set_length(r); return r; } int Jupiter::Socket::peekFrom(addrinfo *info) { - Jupiter::Socket::data_->buffer.erase(); + m_data->buffer.clear(); if (info == nullptr) - return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK, nullptr, nullptr); + return recvfrom(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), MSG_PEEK, nullptr, nullptr); socklen_t len = info->ai_addrlen; if (len <= 0) { info->ai_addr = new sockaddr(); len = sizeof(sockaddr); } - int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK, info->ai_addr, &len); + int r = recvfrom(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), MSG_PEEK, info->ai_addr, &len); if (r >= 0) { info->ai_addrlen = len; info->ai_family = info->ai_addr->sa_family; @@ -546,24 +595,26 @@ int Jupiter::Socket::peekFrom(addrinfo *info) { } int Jupiter::Socket::recv() { - Jupiter::Socket::data_->buffer.erase(); - int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0); - if (r > 0) - Jupiter::Socket::data_->buffer.set_length(r); + m_data->buffer.clear(); + int r = ::recv(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), 0); + if (r > 0) { + m_data->buffer.set_length(r); + } return r; } -int Jupiter::Socket::recvFrom(addrinfo *info) { - Jupiter::Socket::data_->buffer.erase(); - if (info == nullptr) - return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0, nullptr, nullptr); +int Jupiter::Socket::recvFrom(addrinfo* info) { + m_data->buffer.clear(); + if (info == nullptr) { + return recvfrom(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), 0, nullptr, nullptr); + } socklen_t len = info->ai_addrlen; if (len <= 0) { info->ai_addr = new sockaddr(); len = sizeof(sockaddr); } - int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0, info->ai_addr, &len); + int r = recvfrom(m_data->rawSock, m_data->buffer.chr_data(), m_data->buffer.capacity(), 0, info->ai_addr, &len); if (r >= 0) { info->ai_addrlen = len; info->ai_family = info->ai_addr->sa_family; @@ -608,15 +659,15 @@ bool Jupiter::Socket::cleanup() { // static } Jupiter::Socket::SocketType Jupiter::Socket::getDescriptor() const { - return Jupiter::Socket::data_->rawSock; + return m_data->rawSock; } void Jupiter::Socket::setDescriptor(SocketType descriptor) { - Jupiter::Socket::data_->rawSock = descriptor; + m_data->rawSock = descriptor; } Jupiter::Socket::Buffer &Jupiter::Socket::getInternalBuffer() const { - return Jupiter::Socket::data_->buffer; + return m_data->buffer; } /** Re-enable warnings */ diff --git a/src/include/Jupiter/SecureSocket.h b/src/include/Jupiter/SecureSocket.h index d4e8194..f3fc3f8 100644 --- a/src/include/Jupiter/SecureSocket.h +++ b/src/include/Jupiter/SecureSocket.h @@ -39,39 +39,12 @@ namespace Jupiter { public: - /** - * @brief Enumerator translating to various SSL/TLS protocols. - * Used in getMethod() and setMethod(). - */ - enum EncryptionMethod - { - //SSL3 = 1, /** SSL 3.0 - Unrecommended */ - TLS1 = 2, /** TLS 1.0 - Unrecommended */ - TLS1_1 = 3, /** TLS 1.1 */ - TLS1_2 = 4, /** TLS 1.2 */ - DTLS1 = 5, /** DTLS 1.0 */ - ANY = 126, /** Attempt to use any of the above encryption methods (generally the most secure available between both client and server) */ - END = 127 /** END OF ENUM */ - }; - /** * @brief Returns the name of the cipher currently in use. * @return Name of cipher currently in use, or "NONE" if none is in use. */ const char *getCipherName() const; - /** - * @brief Returns the encryption method that the socket attempts to use. - * This is ANY by default. - * @return Encrpytion method that the socket attempts to use. - */ - EncryptionMethod getMethod() const; - - /** - * @brief Sets the encryption method to be used when connecting. - */ - void setMethod(EncryptionMethod method); - /** * @brief Loads a certificate and key for use. * @@ -207,7 +180,7 @@ namespace Jupiter /** Private members */ private: struct SSLData; - SSLData *SSLdata_; + SSLData *m_ssl_data; }; } diff --git a/src/include/Jupiter/Socket.h b/src/include/Jupiter/Socket.h index 404a501..98204cf 100644 --- a/src/include/Jupiter/Socket.h +++ b/src/include/Jupiter/Socket.h @@ -76,18 +76,7 @@ namespace Jupiter * @param port String containing the target port. * @return Pointer to a NULL-terminated linked list of addrinfo on success, nullptr otherwise. */ - static addrinfo *getAddrInfo(const char *hostname, const char *port); - - /** - * @brief Resolves and stores address information in an addrinfo struct. - * Unlike the function getAddrInfo, this function stores the returned addrinfo - * as static, meaning that any subsequent calls will overwrite the previous call. - * - * @param host String containing the hostname of the target. - * @param port String containing the target port. - * @return Pointer to a NULL-terminated linked list of addrinfo on success, nullptr otherwise. - */ - static addrinfo *getStaticAddrInfo(const char *hostname, const char *port); + static addrinfo* getAddrInfo(const char *hostname, const char *port); /** * @brief Frees the resources associated with an addrinfo struct. @@ -112,7 +101,7 @@ namespace Jupiter * @param addr Address info containing IP address. * @return String containing the text representation of the stored address on success, nullptr otherwise. */ - static char *resolveAddress(const addrinfo *addr); + static std::string resolveAddress(const addrinfo *addr); /** * @brief Returns the text representation of an addrinfo's stored address. @@ -121,7 +110,7 @@ namespace Jupiter * @param result Which result to return. * @return String containing the text representation of the stored address on success, nullptr otherwise. */ - static char *resolveAddress(addrinfo *addr, unsigned int result); + static std::string resolveAddress(addrinfo *addr, unsigned int result); /** * @brief Resolves a hostname to an IP address. @@ -130,7 +119,7 @@ namespace Jupiter * @param result Which resolution result to return. * @return String containing the text representation of the resolved address on success, nullptr otherwise. */ - static char *resolveAddress(const char *hostname, unsigned int result); + static std::string resolveAddress(const char *hostname, unsigned int result); /** * @brief Resolves an address to a hostname. (Reverse DNS) @@ -139,8 +128,7 @@ namespace Jupiter * @param addr Address info containing IP address. * @return String containing the hostname of the stored address on success, nullptr otherwise. */ - static char *resolveHostname(addrinfo *addr); - static char *resolveHostname_alloc(addrinfo *addr); + static std::string resolveHostname(addrinfo *addr); /** * @brief Resolves an address to a hostname. (Reverse DNS) @@ -149,8 +137,7 @@ namespace Jupiter * @param result Which result to return. * @return String containing the hostname of the stored address on success, nullptr otherwise. */ - static char *resolveHostname(addrinfo *addr, unsigned int result); - static char *resolveHostname_alloc(addrinfo *addr, unsigned int result); + static std::string resolveHostname(addrinfo *addr, unsigned int result); /** * @brief Resolves an address to a hostname. (Reverse DNS) @@ -159,8 +146,7 @@ namespace Jupiter * @param result Which resolution result to return. * @return String containing the hostname of the resolved address on success, nullptr otherwise. */ - static char *resolveHostname(const char *hostname, unsigned int result); - static char *resolveHostname_alloc(const char *hostname, unsigned int result); + static std::string resolveHostname(const char *hostname, unsigned int result); /** * @brief Reinterprets an IPv4 address as a 32-bit integer in network byte order. @@ -415,7 +401,7 @@ namespace Jupiter * @return Number of bytes written to buffer on success, SOCKET_ERROR (-1) otherwise. * Note: Any returned value less than or equal to 0 should be treated as an error. */ - virtual int recvFrom(addrinfo *info); + virtual int recvFrom(addrinfo* info); int receive(); /** @see recv() */ @@ -544,11 +530,23 @@ namespace Jupiter /** * @brief An extended verison of the string class, which allows for low-level length and string modification. */ - class Buffer : public Jupiter::StringL + class Buffer { public: + Buffer(); + ~Buffer(); void set_length(size_t in_length); - char *get_str() const; + size_t capacity() const; + void reserve(size_t new_capacity); + void clear(); + std::string_view view() const; + void* data() const; + char* chr_data() const; + + private: + void* m_buffer; + size_t m_buffer_capacity; + size_t m_buffer_size; }; /** @@ -575,7 +573,7 @@ namespace Jupiter /** Private members */ private: struct Data; - Data *data_; + Data *m_data; }; } diff --git a/src/jessilib b/src/jessilib index f714a1d..25198a3 160000 --- a/src/jessilib +++ b/src/jessilib @@ -1 +1 @@ -Subproject commit f714a1da00dfd9f1f6ef9a8350099318ddd4734e +Subproject commit 25198a3c77c45c1713b3e6befd3b945ee981d5a9