summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2015-03-17 13:39:39 +0100
committerPierre Ossman <ossman@cendio.se>2015-03-17 17:18:50 +0100
commit57cab51d83629ee7e0ede8eaa869453cc9231434 (patch)
treea829392a6cf8003778fce30ecfca2570954d91ca /common
parent9d78440b8354ae81f3fc094569f710c27f3ad0e6 (diff)
downloadtigervnc-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.cxx58
-rw-r--r--common/network/TcpSocket.h1
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();
};