[vino/gnome-2-32] Bind both an IPv4 and an IPv6 socket



commit 633cac196ddb41485bf3428d5ca00c7860d48831
Author: Thorsten Glaser <tg mirbsd de>
Date:   Mon Apr 11 18:49:37 2011 +0200

    Bind both an IPv4 and an IPv6 socket
    
    Under some configurations on Linux, and an BSD, the dfault behaviour is
    to bind only an IPv6 socket when IPv6 support is enabled. The default
    Linux kernel configuration is to bind both an IPv4 and an IPv6 socket.
    Using two listening sockets fixes the problem, bug 604809.

 server/libvncserver/sockets.c |   34 ++++++++++++++++++++++++++--------
 1 files changed, 26 insertions(+), 8 deletions(-)
---
diff --git a/server/libvncserver/sockets.c b/server/libvncserver/sockets.c
index c4275b0..b3f3714 100644
--- a/server/libvncserver/sockets.c
+++ b/server/libvncserver/sockets.c
@@ -583,6 +583,7 @@ ListenOnTCPPort(rfbScreenInfoPtr rfbScreen, int port, const char *netIface)
   if(netIface == NULL || strlen(netIface) == 0)
   {
 #ifdef ENABLE_IPV6
+    int sock6 = -1;
     struct sockaddr_in6 s6;
 
     memset(&s6, 0, sizeof(s6));
@@ -590,10 +591,10 @@ ListenOnTCPPort(rfbScreenInfoPtr rfbScreen, int port, const char *netIface)
     s6.sin6_port   = htons(port);
     s6.sin6_addr   = in6addr_any;
 
-    sock = NewSocketListenTCP ((struct sockaddr*)&s6, sizeof(s6));
-    rfbLog("Listening IPv{4,6}://*:%d\n", port);
+    sock6 = NewSocketListenTCP ((struct sockaddr*)&s6, sizeof(s6));
+    rfbLog("Listening IPv6://[::]:%d\n", port);
 #endif
-    if(sock < 0) {
+
       struct sockaddr_in s4;
 
       memset(&s4, 0, sizeof(s4));
@@ -603,15 +604,23 @@ ListenOnTCPPort(rfbScreenInfoPtr rfbScreen, int port, const char *netIface)
 
       sock = NewSocketListenTCP ((struct sockaddr*)&s4, sizeof(s4));
       rfbLog("Listening IPv4://0.0.0.0:%d\n", port);
-    }
 
+#ifdef ENABLE_IPV6
+    if(sock6 > 0) {
+       psock[*ptot] = sock6;
+      *ptot        += 1;
+    }
+#endif
     if(sock > 0) {
-      psock[0] = sock;
-     *ptot     = 1;
-      return TRUE;
+       psock[*ptot] = sock;
+      *ptot        += 1;
     }
 
-    rfbLog("Problems in NewSocketListenTCP(), sock=%d\n", sock);
+    if (*ptot)
+      return TRUE;
+
+    /* no need to log sock/sock6, both are -1 here */
+    rfbLog("Problems in NewSocketListenTCP()\n");
     return FALSE;
   }
 
@@ -681,6 +690,15 @@ NewSocketListenTCP(struct sockaddr *addr, socklen_t len)
       return -1;
     }
 
+#ifdef ENABLE_IPV6
+    if (addr->sa_family == AF_INET6) {
+#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
+      setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one));
+      /* we cannot really check for errors here */
+#endif
+    }
+#endif
+
     if (bind(sock, addr, len) < 0) {
       close(sock);
       return -1;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]