changeset 11595:3256656698f2 draft

(svn r15968) -Codechange: do not allocate a buffer for NetworkAddresses so passing it around is easier.
author rubidium <rubidium@openttd.org>
date Tue, 07 Apr 2009 19:04:37 +0000
parents cfcc6ab7830b
children 6904b4e22518
files src/network/core/address.cpp src/network/core/address.h
diffstat 2 files changed, 36 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
 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 @@
 	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)));
--- 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 @@
 	 * @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 @@
 	 * @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 @@
 	 * @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 @@
 	 * @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 @@
 	 * 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,6 +177,7 @@
 	/**
 	 * 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)
 	{
@@ -192,6 +187,16 @@
 	/**
 	 * 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<NetworkAddress*>(this)->CompareTo(address) == 0;
+	}
+
+	/**
+	 * Compare the address of this class with the address of another.
+	 * @param address the other address.
 	 */
 	bool operator < (NetworkAddress address)
 	{
@@ -199,21 +204,6 @@
 	}
 
 	/**
-	 * 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.
 	 */