From 460fbc7c921b4d960ca76a938f4221038c3c286d Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 10 Apr 2009 09:23:35 +0000 Subject: (svn r16007) -Fix (r16004): when we want to bind to both IPv4 and IPv6, make the master socket do that too; too bad getaddrinfo can't handle binding to any address on any port at the same time :( --- src/network/core/address.cpp | 24 +++++++++++++++++++++--- src/network/core/address.h | 3 +-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 541b4673b..d869ceecb 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -178,14 +178,21 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList * char port_name[6]; seprintf(port_name, lastof(port_name), "%u", this->GetPort()); + bool reset_hostname = false; /* Setting both hostname to NULL and port to 0 is not allowed. * As port 0 means bind to any port, the other must mean that * we want to bind to 'all' IPs. */ if (StrEmpty(this->hostname) && this->address_length == 0 && this->GetPort() == 0) { - strecpy(this->hostname, this->address.ss_family == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname)); + reset_hostname = true; + int fam = this->address.ss_family; + if (fam == AF_UNSPEC) fam = family; + strecpy(this->hostname, fam == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname)); } int e = getaddrinfo(StrEmpty(this->hostname) ? NULL : this->hostname, port_name, &hints, &ai); + + if (reset_hostname) strecpy(this->hostname, "", lastof(this->hostname)); + if (e != 0) { if (func != ResolveLoopProc) { DEBUG(net, 0, "getaddrinfo(%s, %s) failed: %s", this->hostname, port_name, FS2OTTD(gai_strerror(e))); @@ -305,9 +312,20 @@ static SOCKET ListenLoopProc(addrinfo *runp) return sock; } -SOCKET NetworkAddress::Listen(int socktype, SocketList *sockets) +void NetworkAddress::Listen(int socktype, SocketList *sockets) { - return this->Resolve(AF_UNSPEC, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); + assert(sockets != NULL); + + /* Setting both hostname to NULL and port to 0 is not allowed. + * As port 0 means bind to any port, the other must mean that + * we want to bind to 'all' IPs. */ + if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC && + StrEmpty(this->hostname) && this->GetPort() == 0) { + this->Resolve(AF_INET, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); + this->Resolve(AF_INET6, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); + } else { + this->Resolve(AF_UNSPEC, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); + } } #endif /* ENABLE_NETWORK */ diff --git a/src/network/core/address.h b/src/network/core/address.h index 2c37860c4..564d23625 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.h @@ -227,9 +227,8 @@ public: * Make the given socket listen. * @param socktype the type of socket (TCP, UDP, etc) * @param sockets the list of sockets to add the sockets to - * @return the socket (if sockets != NULL) */ - SOCKET Listen(int socktype, SocketList *sockets = NULL); + void Listen(int socktype, SocketList *sockets); }; #endif /* ENABLE_NETWORK */ -- cgit v1.2.3-70-g09d2