diff options
author | Pierre Ossman <ossman@cendio.se> | 2015-03-17 13:39:39 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2015-03-17 17:18:50 +0100 |
commit | 57cab51d83629ee7e0ede8eaa869453cc9231434 (patch) | |
tree | a829392a6cf8003778fce30ecfca2570954d91ca /common | |
parent | 9d78440b8354ae81f3fc094569f710c27f3ad0e6 (diff) | |
download | tigervnc-57cab51d83629ee7e0ede8eaa869453cc9231434.tar.gz tigervnc-57cab51d83629ee7e0ede8eaa869453cc9231434.zip |
Resurrect TcpListener::getMyAddresses()
It is needed by WinVNC, but got removed in 892d10a70. Also fix
a couple of issues:
- Use getnameinfo() in order to be compatible with Windows XP
- Make it static since it doesn't use a specific socket
- Respect UseIPv4 and UseIPv6
- Flags for getaddrinfo() that match binding code
- Dummy service value for Windows compatibility
Diffstat (limited to 'common')
-rw-r--r-- | common/network/TcpSocket.cxx | 58 | ||||
-rw-r--r-- | common/network/TcpSocket.h | 1 |
2 files changed, 59 insertions, 0 deletions
diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx index 26ea1f5e..bd9971c1 100644 --- a/common/network/TcpSocket.cxx +++ b/common/network/TcpSocket.cxx @@ -533,6 +533,64 @@ TcpListener::accept() { return s; } +void TcpListener::getMyAddresses(std::list<char*>* result) { +#if defined(HAVE_GETADDRINFO) + struct addrinfo *ai, *current, hints; + + initSockets(); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + // Windows doesn't like NULL for service, so specify something + if ((getaddrinfo(NULL, "1", &hints, &ai)) != 0) + return; + + for (current= ai; current != NULL; current = current->ai_next) { + switch (current->ai_family) { + case AF_INET: + if (!UseIPv4) + continue; + break; + case AF_INET6: + if (!UseIPv6) + continue; + break; + default: + continue; + } + + char *addr = new char[INET6_ADDRSTRLEN]; + + getnameinfo(current->ai_addr, current->ai_addrlen, addr, INET6_ADDRSTRLEN, + NULL, 0, NI_NUMERICHOST); + + result->push_back(addr); + } + + freeaddrinfo(ai); +#else + const hostent* addrs = gethostbyname(0); + if (!UseIPv4) + return; + if (addrs == 0) + throw rdr::SystemException("gethostbyname", errorNumber); + if (addrs->h_addrtype != AF_INET) + throw rdr::Exception("getMyAddresses: bad family"); + for (int i=0; addrs->h_addr_list[i] != 0; i++) { + const char* addrC = inet_ntoa(*((struct in_addr*)addrs->h_addr_list[i])); + char* addr = new char[strlen(addrC)+1]; + strcpy(addr, addrC); + result->push_back(addr); + } +#endif /* defined(HAVE_GETADDRINFO) */ +} + int TcpListener::getMyPort() { return TcpSocket::getSockPort(getFd()); } diff --git a/common/network/TcpSocket.h b/common/network/TcpSocket.h index 29c09c69..bb55e7d2 100644 --- a/common/network/TcpSocket.h +++ b/common/network/TcpSocket.h @@ -81,6 +81,7 @@ namespace network { virtual void shutdown(); virtual Socket* accept(); + static void getMyAddresses(std::list<char*>* result); int getMyPort(); }; |