From 8cc73c997a35d8abedd64dcd45b1016c57330000 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Mon, 5 Oct 2015 22:24:07 -0400 Subject: [PATCH] Jupiter::Socket: * Replaced 'host' with 'remote_host' and 'bound_host' * Replace 'port' with 'remote_port' and 'bound_port' * Fixed a bug involving sockets not getting closed. --- Jupiter/SecureSocket.cpp | 2 +- Jupiter/Socket.cpp | 106 +++++++++++++++++++++++++++------------ Jupiter/Socket.h | 21 +++++--- Release/Jupiter.lib | Bin 292870 -> 294078 bytes 4 files changed, 90 insertions(+), 39 deletions(-) diff --git a/Jupiter/SecureSocket.cpp b/Jupiter/SecureSocket.cpp index a8d5bf3..199b2cf 100644 --- a/Jupiter/SecureSocket.cpp +++ b/Jupiter/SecureSocket.cpp @@ -249,7 +249,7 @@ bool Jupiter::SecureSocket::initSSL() ERR_print_errors_fp(stderr); return false; } - if (SSL_set_tlsext_host_name(Jupiter::SecureSocket::SSLdata_->handle, this->getHost()) != 1) // This error check is potentially redundant, but no documentation has been found. + 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. { ERR_print_errors_fp(stderr); return false; diff --git a/Jupiter/Socket.cpp b/Jupiter/Socket.cpp index c5c964b..dfb5ad3 100644 --- a/Jupiter/Socket.cpp +++ b/Jupiter/Socket.cpp @@ -54,11 +54,13 @@ char *Jupiter::Socket::Buffer::get_str() const struct Jupiter::Socket::Data { Jupiter::Socket::Buffer buffer; - SOCKET rawSock; - unsigned short port; - Jupiter::CStringS host; - int sockType; - int sockProto; + SOCKET rawSock = INVALID_SOCKET; + unsigned short remote_port = 0; + unsigned short bound_port = 0; + Jupiter::CStringS remote_host; + Jupiter::CStringS bound_host; + int sockType = SOCK_RAW; + int sockProto = IPPROTO_RAW; #if defined _WIN32 unsigned long blockMode = 0; #endif @@ -69,20 +71,18 @@ struct Jupiter::Socket::Data Jupiter::Socket::Data::Data(size_t buffer_size) { Jupiter::Socket::Data::buffer.setBufferSizeNoCopy(buffer_size); - Jupiter::Socket::Data::port = 0; - Jupiter::Socket::Data::rawSock = 0; - Jupiter::Socket::Data::sockType = SOCK_RAW; - Jupiter::Socket::Data::sockProto = IPPROTO_RAW; } Jupiter::Socket::Data::Data(const Data &source) { Jupiter::Socket::Data::buffer = source.buffer; - Jupiter::Socket::Data::port = source.port; + Jupiter::Socket::Data::remote_port = source.remote_port; + Jupiter::Socket::Data::bound_port = source.bound_port; Jupiter::Socket::Data::rawSock = source.rawSock; Jupiter::Socket::Data::sockType = source.sockType; Jupiter::Socket::Data::sockProto = source.sockProto; - Jupiter::Socket::Data::host = source.host; + Jupiter::Socket::Data::remote_host = source.remote_host; + Jupiter::Socket::Data::bound_host = source.bound_host; #if defined _WIN32 Jupiter::Socket::Data::blockMode = source.blockMode; #endif @@ -158,28 +158,42 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const if (!socketInit && !Jupiter::Socket::init()) return false; #endif // _WIN32 - Jupiter::Socket::data_->host.set(hostname); - Jupiter::Socket::data_->port = iPort; - addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->port).c_str()); + Jupiter::Socket::data_->remote_host.set(hostname); + Jupiter::Socket::data_->remote_port = iPort; + addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->remote_host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->remote_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) + if (clientAddress != nullptr) { - info = info->ai_next; - continue; + // bind will initialize our socket + if (Jupiter::Socket::bind(clientAddress, clientPort, false) == false) + 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) + { + info = info->ai_next; + continue; + } } - if (clientAddress != nullptr) - this->bind(clientAddress, clientPort, false); if (::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { +#if defined _WIN32 + closesocket(Jupiter::Socket::data_->rawSock); +#else // _WIN32 + close(Jupiter::Socket::data_->rawSock); +#endif // WIN32 + Jupiter::Socket::data_->rawSock = INVALID_SOCKET; info = info->ai_next; continue; } + Jupiter::Socket::freeAddrInfo(info_head); return true; } while (info != nullptr); @@ -194,20 +208,33 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL if (!socketInit && !Jupiter::Socket::init()) return false; #endif // _WIN32 - Jupiter::Socket::data_->host.set(hostname); - Jupiter::Socket::data_->port = iPort; - addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->port).c_str()); + Jupiter::Socket::data_->bound_host.set(hostname); + Jupiter::Socket::data_->bound_port = iPort; + addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->bound_host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::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 || ::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) + if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) { info = info->ai_next; continue; } + + if (::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) + { +#if defined _WIN32 + closesocket(Jupiter::Socket::data_->rawSock); +#else // _WIN32 + close(Jupiter::Socket::data_->rawSock); +#endif // WIN32 + Jupiter::Socket::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) return false; @@ -360,8 +387,8 @@ Jupiter::Socket *Jupiter::Socket::accept() r->data_->rawSock = tSock; r->data_->sockType = Jupiter::Socket::data_->sockType; r->data_->sockProto = Jupiter::Socket::data_->sockProto; - r->data_->host.set(resolved); - r->data_->port = static_cast(Jupiter_strtoi(resolved_port, 10)); + r->data_->remote_host.set(resolved); + r->data_->remote_port = static_cast(Jupiter_strtoi(resolved_port, 10)); return r; } return nullptr; @@ -421,19 +448,34 @@ bool Jupiter::Socket::getBlockingMode() const #endif } -const Jupiter::ReadableString &Jupiter::Socket::getHostname() const +const Jupiter::ReadableString &Jupiter::Socket::getRemoteHostname() const +{ + return Jupiter::Socket::data_->remote_host; +} + +const char *Jupiter::Socket::getRemoteHostnameC() const +{ + return Jupiter::Socket::data_->remote_host.c_str(); +} + +const Jupiter::ReadableString &Jupiter::Socket::getBoundHostname() const +{ + return Jupiter::Socket::data_->bound_host; +} + +const char *Jupiter::Socket::getBoundHostnameC() const { - return Jupiter::Socket::data_->host; + return Jupiter::Socket::data_->bound_host.c_str(); } -const char *Jupiter::Socket::getHost() const +unsigned short Jupiter::Socket::getRemotePort() const { - return Jupiter::Socket::data_->host.c_str(); + return Jupiter::Socket::data_->remote_port; } -unsigned short Jupiter::Socket::getPort() const +unsigned short Jupiter::Socket::getBoundPort() const { - return Jupiter::Socket::data_->port; + return Jupiter::Socket::data_->bound_port; } const Jupiter::ReadableString &Jupiter::Socket::getBuffer() const diff --git a/Jupiter/Socket.h b/Jupiter/Socket.h index bd69fdf..44f9e3d 100644 --- a/Jupiter/Socket.h +++ b/Jupiter/Socket.h @@ -278,25 +278,34 @@ namespace Jupiter virtual void closeSocket(); /** - * @brief Returns the hostname that the socket is connected to or listening to. + * @brief Returns the hostname that the socket is connected to. * * @return String containing the hostname. */ - const Jupiter::ReadableString &getHostname() const; + const Jupiter::ReadableString &getRemoteHostname() const; + const char *getRemoteHostnameC() const; /** - * @brief Returns the hostname of the server that the socket is connected to. + * @brief Returns the hostname that the socket is bound/listening to. * * @return String containing the hostname. */ - const char *getHost() const; + const Jupiter::ReadableString &getBoundHostname() const; + const char *getBoundHostnameC() const; /** - * @brief Returns the port which the Socket is connected to or listening to. + * @brief Returns the port which the Socket is connected to. * * @return Port number. */ - unsigned short getPort() const; + unsigned short getRemotePort() const; + + /** + * @brief Returns the port which the Socket is bound/listening to. + * + * @return Port number. + */ + unsigned short getBoundPort() const; /** * @brief Returns the type of the socket. diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index 68b696a88e872df5badd8eb1eb7a7f3c15e5e83f..84378916453c03c2732eb49b54ffebc0232e609f 100644 GIT binary patch delta 34925 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 delta 34063 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