]> source.dussan.org Git - tigervnc.git/commitdiff
Resurrect TcpListener::getMyAddresses()
authorPierre Ossman <ossman@cendio.se>
Tue, 17 Mar 2015 12:39:39 +0000 (13:39 +0100)
committerPierre Ossman <ossman@cendio.se>
Tue, 17 Mar 2015 16:18:50 +0000 (17:18 +0100)
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

common/network/TcpSocket.cxx
common/network/TcpSocket.h
win/winvnc/VNCServerWin32.cxx

index 26ea1f5ea22fe9bf193addfea3d7ab6cd160b25d..bd9971c138186732b4d4751c5517e51dfa5a8733 100644 (file)
@@ -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());
 }
index 29c09c69ba99754097fc67bcf9ab9ec248c84052..bb55e7d2ab97a2aac36b1008a6f3069d635d8729 100644 (file)
@@ -81,6 +81,7 @@ namespace network {
     virtual void shutdown();
     virtual Socket* accept();
 
+    static void getMyAddresses(std::list<char*>* result);
     int getMyPort();
   };
 
index 36dbcee11f3a79c691245c07a6c7515441e3e6a8..038998563844648e9150a053ac76ddbe78b96cd2 100644 (file)
@@ -101,8 +101,8 @@ void VNCServerWin32::processAddressChange(network::SocketListener* sock_) {
 
   // Fetch the list of addresses
   std::list<char*> addrs;
-  if (rfbSock.sock)
-    rfbSock.sock->getMyAddresses(&addrs);
+  if (rfbSock.isListening())
+    TcpListener::getMyAddresses(&addrs);
   else
     addrs.push_front(strDup("Not accepting connections"));