diff options
Diffstat (limited to 'src/network/core')
-rw-r--r-- | src/network/core/address.cpp | 17 | ||||
-rw-r--r-- | src/network/core/address.h | 29 | ||||
-rw-r--r-- | src/network/core/udp.cpp | 4 |
3 files changed, 35 insertions, 15 deletions
diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 28ab98887..c1313fe74 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -15,8 +15,10 @@ const char *NetworkAddress::GetHostname() { if (this->hostname == NULL) { + assert(this->address_length != 0); + char buf[NETWORK_HOSTNAME_LENGTH] = { '\0' }; - getnameinfo((struct sockaddr *)&this->address, sizeof(this->address), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); + getnameinfo((struct sockaddr *)&this->address, this->address_length, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); this->hostname = strdup(buf); } return this->hostname; @@ -56,9 +58,9 @@ const char *NetworkAddress::GetAddressAsString() const sockaddr_storage *NetworkAddress::GetAddress() { - if (!this->resolved) { + if (!this->IsResolved()) { ((struct sockaddr_in *)&this->address)->sin_addr.s_addr = NetworkResolveHost(this->hostname); - this->resolved = true; + this->address_length = sizeof(sockaddr); } return &this->address; } @@ -90,11 +92,18 @@ SOCKET NetworkAddress::Connect() if (!SetNoDelay(sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed"); - if (connect(sock, runp->ai_addr, runp->ai_addrlen) != 0) continue; + if (connect(sock, runp->ai_addr, runp->ai_addrlen) != 0) { + closesocket(sock); + sock = INVALID_SOCKET; + continue; + } /* Connection succeeded */ if (!SetNonBlocking(sock)) DEBUG(net, 0, "Setting non-blocking mode failed"); + this->address_length = runp->ai_addrlen; + assert(sizeof(this->address) >= runp->ai_addrlen); + memcpy(&this->address, runp->ai_addr, runp->ai_addrlen); break; } freeaddrinfo (ai); diff --git a/src/network/core/address.h b/src/network/core/address.h index 598cd305e..3e8ca0343 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.h @@ -16,8 +16,8 @@ */ class NetworkAddress { private: - bool resolved; ///< Has the IP address been resolved char *hostname; ///< The hostname, NULL if there isn't one + size_t address_length; ///< The length of the resolved address sockaddr_storage address; ///< The resolved address public: @@ -27,8 +27,8 @@ public: * @param port the port */ NetworkAddress(in_addr_t ip, uint16 port) : - resolved(true), - hostname(NULL) + hostname(NULL), + address_length(sizeof(sockaddr)) { memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = AF_INET; @@ -40,9 +40,9 @@ public: * Create a network address based on a resolved IP and port * @param address the IP address with port */ - NetworkAddress(struct sockaddr_storage &address) : - resolved(true), + NetworkAddress(struct sockaddr_storage &address, size_t address_length) : hostname(NULL), + address_length(address_length), address(address) { } @@ -53,8 +53,8 @@ public: * @param port the port */ NetworkAddress(const char *hostname = NULL, uint16 port = 0) : - resolved(false), - hostname(hostname == NULL ? NULL : strdup(hostname)) + hostname(hostname == NULL ? NULL : strdup(hostname)), + address_length(0) { memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = AF_INET; @@ -66,8 +66,8 @@ public: * @param address the address to clone */ NetworkAddress(const NetworkAddress &address) : - resolved(address.resolved), hostname(address.hostname == NULL ? NULL : strdup(address.hostname)), + address_length(address.address_length), address(address.address) { } @@ -98,6 +98,17 @@ public: const sockaddr_storage *GetAddress(); /** + * Get the (valid) length of the address. + * @return the length + */ + size_t GetAddressLength() + { + /* Resolve it if we didn't do it already */ + if (!this->IsResolved()) this->GetAddress(); + return this->address_length; + } + + /** * Get the port * @return the port */ @@ -115,7 +126,7 @@ public: */ bool IsResolved() const { - return this->resolved; + return this->address_length != 0; } /** diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 110cec2f2..4818767d9 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -89,7 +89,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv) p->PrepareToSend(); /* Send the buffer */ - res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), sizeof(*recv->GetAddress())); + res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), recv->GetAddressLength()); /* Check for any errors, but ignore it otherwise */ if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR()); @@ -119,7 +119,7 @@ void NetworkUDPSocketHandler::ReceivePackets() /* We got some bytes for the base header of the packet. */ if (nbytes > 2) { - NetworkAddress address(client_addr); + NetworkAddress address(client_addr, client_len); p.PrepareToRead(); /* If the size does not match the packet must be corrupted. |