Revision: 4303
          http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4303&view=rev
Author:   dcommander
Date:     2011-02-21 13:43:44 +0000 (Mon, 21 Feb 2011)

Log Message:
-----------
Using a fixed port range with -via can cause a race condition between multiple 
vncviewer instances, whereby one instance calls bind() and finds the port to be 
free, then another instance calls bind() and finds the same port to be free, 
because the first instance hasn't started the SSH tunnel on it yet.  This patch 
works around the issue by using ephemeral ports.  All known modern O/S's 
increment the ephemeral port number by 1 after bind(), so the port is 
effectively "reserved" after bind(), and this prevents another vncviewer 
instance from trying to reserve the same port.

Modified Paths:
--------------
    trunk/common/network/TcpSocket.cxx

Modified: trunk/common/network/TcpSocket.cxx
===================================================================
--- trunk/common/network/TcpSocket.cxx  2011-02-21 13:40:33 UTC (rev 4302)
+++ trunk/common/network/TcpSocket.cxx  2011-02-21 13:43:44 UTC (rev 4303)
@@ -71,7 +71,7 @@
 /* Tunnelling support. */
 int network::findFreeTcpPort (void)
 {
-  int sock, port;
+  int sock;
   struct sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
@@ -80,15 +80,16 @@
   if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     throw SocketException ("unable to create socket", errorNumber);
 
-  for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
-    addr.sin_port = htons ((unsigned short) port);
-    if (bind (sock, (struct sockaddr *)&addr, sizeof (addr)) == 0) {
-      closesocket (sock);
-      return port;
-    }
-  }
-  throw SocketException ("no free port in range", 0);
-  return 0;
+  addr.sin_port = 0;
+  if (bind (sock, (struct sockaddr *)&addr, sizeof (addr)) < 0)
+    throw SocketException ("unable to find free port", errorNumber);
+
+  socklen_t n = sizeof(addr);
+  if (getsockname (sock, (struct sockaddr *)&addr, &n) < 0)
+    throw SocketException ("unable to get port number", errorNumber);
+
+  closesocket (sock);
+  return ntohs(addr.sin_port);
 }
 
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Tigervnc-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tigervnc-commits

Reply via email to