diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index e61024111e..0db0705d9d 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -14,12 +14,9 @@ const char *NetworkAddress::GetHostname() { - if (this->hostname == NULL) { + if (StrEmpty(this->hostname)) { assert(this->address_length != 0); - - char buf[NETWORK_HOSTNAME_LENGTH] = { '\0' }; - getnameinfo((struct sockaddr *)&this->address, this->address_length, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); - this->hostname = strdup(buf); + getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), NULL, 0, NI_NUMERICHOST); } return this->hostname; } @@ -59,9 +56,15 @@ void NetworkAddress::SetPort(uint16 port) const char *NetworkAddress::GetAddressAsString() { /* 6 = for the : and 5 for the decimal port number */ - static char buf[NETWORK_HOSTNAME_LENGTH + 6]; + static char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7]; - seprintf(buf, lastof(buf), "%s:%d", this->GetHostname(), this->GetPort()); + char family; + switch (this->address.ss_family) { + case AF_INET: family = '4'; break; + case AF_INET6: family = '6'; break; + default: family = '?'; break; + } + seprintf(buf, lastof(buf), "%s:%d (IPv%c)", this->GetHostname(), this->GetPort(), family); return buf; } @@ -156,6 +159,10 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, LoopProc fun char port_name[6]; seprintf(port_name, lastof(port_name), "%u", this->GetPort()); + if (this->address_length == 0 && StrEmpty(this->hostname)) { + strecpy(this->hostname, this->address.ss_family == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname)); + } + int e = getaddrinfo(this->GetHostname(), port_name, &hints, &ai); if (e != 0) { DEBUG(net, 0, "getaddrinfo(%s, %s) failed: %s", this->GetHostname(), port_name, FS2OTTD(gai_strerror(e))); diff --git a/src/network/core/address.h b/src/network/core/address.h index ecb3a8f22f..f2bc00f74d 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.h @@ -8,6 +8,8 @@ #ifdef ENABLE_NETWORK #include "os_abstraction.h" +#include "config.h" +#include "../../string_func.h" /** * Wrapper for (un)resolved network addresses; there's no reason to transform @@ -16,9 +18,9 @@ */ class NetworkAddress { private: - 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 + char hostname[NETWORK_HOSTNAME_LENGTH]; ///< The hostname + size_t address_length; ///< The length of the resolved address + sockaddr_storage address; ///< The resolved address /** * Helper function to resolve something to a socket. @@ -43,9 +45,9 @@ public: * @param port the port */ NetworkAddress(in_addr_t ip, uint16 port) : - hostname(NULL), address_length(sizeof(sockaddr)) { + *this->hostname = '\0'; memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = AF_INET; ((struct sockaddr_in*)&this->address)->sin_addr.s_addr = ip; @@ -57,10 +59,10 @@ public: * @param address the IP address with port */ NetworkAddress(struct sockaddr_storage &address, size_t address_length) : - hostname(NULL), address_length(address_length), address(address) { + *this->hostname = '\0'; } /** @@ -68,9 +70,9 @@ public: * @param address the IP address with port */ NetworkAddress(sockaddr *address, size_t address_length) : - hostname(NULL), address_length(address_length) { + *this->hostname = '\0'; memset(&this->address, 0, sizeof(this->address)); memcpy(&this->address, address, address_length); } @@ -82,9 +84,9 @@ public: * @param family the address family */ NetworkAddress(const char *hostname = "0.0.0.0", uint16 port = 0, int family = AF_INET) : - hostname(strdup(hostname)), address_length(0) { + strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname)); memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = family; this->SetPort(port); @@ -94,17 +96,9 @@ public: * Make a clone of another address * @param address the address to clone */ - NetworkAddress(const NetworkAddress &address) : - hostname(address.hostname == NULL ? NULL : strdup(address.hostname)), - address_length(address.address_length), - address(address.address) + NetworkAddress(const NetworkAddress &address) { - } - - /** Clean up our mess */ - ~NetworkAddress() - { - free(hostname); + memcpy(this, &address, sizeof(*this)); } /** @@ -183,12 +177,23 @@ public: /** * Compare the address of this class with the address of another. * @param address the other address. + * @return true if both match. */ bool operator == (NetworkAddress address) { return this->CompareTo(address) == 0; } + /** + * Compare the address of this class with the address of another. + * @param address the other address. + * @return true if both match. + */ + bool operator == (NetworkAddress address) const + { + return const_cast(this)->CompareTo(address) == 0; + } + /** * Compare the address of this class with the address of another. * @param address the other address. @@ -198,21 +203,6 @@ public: return this->CompareTo(address) < 0; } - /** - * Assign another address to ourself - * @param other obviously the address to assign to us - * @return 'this' - */ - NetworkAddress& operator = (const NetworkAddress &other) - { - if (this != &other) { // protect against invalid self-assignment - free(this->hostname); - memcpy(this, &other, sizeof(*this)); - if (other.hostname != NULL) this->hostname = strdup(other.hostname); - } - return *this; - } - /** * Connect to the given address. * @return the connected socket or INVALID_SOCKET.