[Lldb-commits] [lldb] r183457 - Remove the debugserver "--open-connection" option and obey the hostname that is passed into debugserver.

Greg Clayton gclayton at apple.com
Thu Jun 6 15:44:19 PDT 2013


Author: gclayton
Date: Thu Jun  6 17:44:19 2013
New Revision: 183457

URL: http://llvm.org/viewvc/llvm-project?rev=183457&view=rev
Log:
Remove the debugserver "--open-connection" option and obey the hostname that is passed into debugserver.

you can now specify:

debugserver host:port
debugserver port
debugserver /path/to/file

When "host" is specified, we will only accept connections from that host. If host is not specified, we default to "localhost".


Modified:
    lldb/trunk/tools/debugserver/source/RNBSocket.cpp
    lldb/trunk/tools/debugserver/source/RNBSocket.h
    lldb/trunk/tools/debugserver/source/debugserver.cpp

Modified: lldb/trunk/tools/debugserver/source/RNBSocket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBSocket.cpp?rev=183457&r1=183456&r2=183457&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBSocket.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBSocket.cpp Thu Jun  6 17:44:19 2013
@@ -30,13 +30,63 @@
    this function is called to wait for an incoming connection.
    This function blocks while waiting for that connection.  */
 
+bool
+ResolveIPV4HostName (const char *hostname, in_addr_t &addr)
+{
+    if (hostname == NULL ||
+        hostname[0] == '\0' ||
+        strcmp(hostname, "localhost") == 0 ||
+        strcmp(hostname, "127.0.0.1") == 0)
+    {
+        addr = htonl (INADDR_LOOPBACK);
+        return true;
+    }
+    else if (strcmp(hostname, "*") == 0)
+    {
+        addr = htonl (INADDR_ANY);
+        return true;
+    }
+    else
+    {
+        // See if an IP address was specified as numbers
+        int inet_pton_result = ::inet_pton (AF_INET, hostname, &addr);
+
+        if (inet_pton_result == 1)
+            return true;
+        
+        struct hostent *host_entry = gethostbyname (hostname);
+        if (host_entry)
+        {
+            std::string ip_str (::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
+            inet_pton_result = ::inet_pton (AF_INET, ip_str.c_str(), &addr);
+            if (inet_pton_result == 1)
+                return true;
+        }
+    }
+    return false;
+}
+
 rnb_err_t
-RNBSocket::Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton, bool localhost_only)
+RNBSocket::Listen (const char *listen_host, in_port_t port, PortBoundCallback callback, const void *callback_baton)
 {
     //DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
     // Disconnect without saving errno
     Disconnect (false);
 
+    // Now figure out the hostname that will be attaching and palce it into
+    struct sockaddr_in listen_addr;
+    ::memset (&listen_addr, 0, sizeof listen_addr);
+    listen_addr.sin_len = sizeof listen_addr;
+    listen_addr.sin_family = AF_INET;
+    listen_addr.sin_port = htons (port);
+    listen_addr.sin_addr.s_addr = INADDR_ANY;
+    
+    if (!ResolveIPV4HostName(listen_host, listen_addr.sin_addr.s_addr))
+    {
+        DNBLogThreaded("error: failed to resolve connecting host '%s'", listen_host);
+        return rnb_err;
+    }
+    
     DNBError err;
     int listen_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (listen_fd == -1)
@@ -56,15 +106,7 @@ RNBSocket::Listen (in_port_t port, PortB
     sa.sin_len = sizeof sa;
     sa.sin_family = AF_INET;
     sa.sin_port = htons (port);
-    if (localhost_only)
-    {
-        sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-    }
-    else
-    {
-        sa.sin_addr.s_addr = htonl (INADDR_ANY);
-    }
-
+    sa.sin_addr.s_addr = INADDR_ANY; // Let incoming connections bind to any host network interface (this is NOT who can connect to us)
     int error = ::bind (listen_fd, (struct sockaddr *) &sa, sizeof(sa));
     if (error == -1)
         err.SetError(errno, DNBError::POSIX);
@@ -92,7 +134,7 @@ RNBSocket::Listen (in_port_t port, PortB
         }
     }
 
-    error = ::listen (listen_fd, 1);
+    error = ::listen (listen_fd, 5);
     if (error == -1)
         err.SetError(errno, DNBError::POSIX);
 
@@ -105,12 +147,52 @@ RNBSocket::Listen (in_port_t port, PortB
         return rnb_err;
     }
 
-    m_fd = ::accept (listen_fd, NULL, 0);
-    if (m_fd == -1)
-        err.SetError(errno, DNBError::POSIX);
-
-    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
-        err.LogThreaded("::accept ( socket = %i, address = NULL, address_len = 0 )", listen_fd);
+    struct sockaddr_in accept_addr;
+    ::memset (&accept_addr, 0, sizeof accept_addr);
+    accept_addr.sin_len = sizeof accept_addr;
+
+    bool accept_connection = false;
+
+    // Loop until we are happy with our connection
+    while (!accept_connection)
+    {
+        socklen_t accept_addr_len = sizeof accept_addr;
+        m_fd = ::accept (listen_fd, (struct sockaddr *)&accept_addr, &accept_addr_len);
+
+        if (m_fd == -1)
+            err.SetError(errno, DNBError::POSIX);
+        
+        if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
+            err.LogThreaded("::accept ( socket = %i, address = %p, address_len = %u )", listen_fd, &accept_addr, accept_addr_len);
+
+        if (err.Fail())
+            break;
+
+        if (listen_addr.sin_addr.s_addr == INADDR_ANY)
+            accept_connection = true;
+        else
+        {
+            if (accept_addr_len == listen_addr.sin_len &&
+                accept_addr.sin_addr.s_addr == listen_addr.sin_addr.s_addr)
+            {
+                accept_connection = true;
+            }
+            else
+            {
+                ::close (m_fd);
+                m_fd = -1;
+                const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
+                const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sin_addr.s_addr;
+                ::fprintf (stderr,
+                           "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
+                           accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
+                           listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
+                DNBLogThreaded ("error: rejecting connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)",
+                                accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
+                                listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
+            }
+        }
+    }
 
     ClosePort (listen_fd, false);
 
@@ -145,24 +227,11 @@ RNBSocket::Connect (const char *host, ui
     sa.sin_family = AF_INET;
     sa.sin_port = htons (port);
     
-    if (host == NULL)
-        host = "localhost";
-
-    int inet_pton_result = ::inet_pton (AF_INET, host, &sa.sin_addr);
-    
-    if (inet_pton_result <= 0)
+    if (!ResolveIPV4HostName(host, sa.sin_addr.s_addr))
     {
-        struct hostent *host_entry = gethostbyname (host);
-        if (host_entry)
-        {
-            std::string host_str (::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
-            inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
-            if (inet_pton_result <= 0)
-            {
-                Disconnect (false);
-                return rnb_err;
-            }
-        }
+        DNBLogThreaded("error: failed to resolve host '%s'", host);
+        Disconnect (false);
+        return rnb_err;
     }
     
     if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))

Modified: lldb/trunk/tools/debugserver/source/RNBSocket.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBSocket.h?rev=183457&r1=183456&r2=183457&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBSocket.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBSocket.h Thu Jun  6 17:44:19 2013
@@ -43,7 +43,10 @@ public:
         Disconnect (false);
     }
 
-    rnb_err_t Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton, bool localhost_only);
+    rnb_err_t Listen (const char *listen_host,
+                      in_port_t port,
+                      PortBoundCallback callback,
+                      const void *callback_baton);
     rnb_err_t Connect (const char *host, uint16_t port);
 
     rnb_err_t useFD(int fd);

Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=183457&r1=183456&r2=183457&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/trunk/tools/debugserver/source/debugserver.cpp Thu Jun  6 17:44:19 2013
@@ -685,13 +685,13 @@ PortWasBoundCallback (const void *baton,
 }
 
 static int
-StartListening (RNBRemote *remote, int listen_port, const char *unix_socket_name, bool localhost_only)
+StartListening (RNBRemote *remote, const char *listen_host, int listen_port, const char *unix_socket_name)
 {
     if (!remote->Comm().IsConnected())
     {
         if (listen_port != 0)
-            RNBLogSTDOUT ("Listening to port %i...\n", listen_port);
-        if (remote->Comm().Listen(listen_port, PortWasBoundCallback, unix_socket_name, localhost_only) != rnb_success)
+            RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", listen_port, listen_host ? listen_host : "localhost");
+        if (remote->Comm().Listen(listen_host, listen_port, PortWasBoundCallback, unix_socket_name) != rnb_success)
         {
             RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
             return 0;
@@ -787,7 +787,6 @@ static struct option g_long_options[] =
     { "working-dir",        required_argument,  NULL,               'W' },  // The working directory that the inferior process should have (only if debugserver launches the process)
     { "platform",           required_argument,  NULL,               'p' },  // Put this executable into a remote platform mode
     { "unix-socket",        required_argument,  NULL,               'u' },  // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
-    { "open-connection",    no_argument,        NULL,               'H' },  // If debugserver is listening to a TCP port, allow connections from any host (as opposed to just "localhost" connections)
     { NULL,                 0,                  NULL,               0   }
 };
 
@@ -843,7 +842,6 @@ main (int argc, char *argv[])
     useconds_t waitfor_interval = 1000;     // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
     useconds_t waitfor_duration = 0;        // Time in seconds to wait for a process by name, 0 means wait forever.
     bool no_stdio = false;
-    bool localhost_only = true;
 
 #if !defined (DNBLOG_ENABLED)
     compile_options += "(no-logging) ";
@@ -1083,10 +1081,6 @@ main (int argc, char *argv[])
             case 'u':
                 unix_socket_name.assign (optarg);
                 break;
-
-            case 'H':
-                localhost_only = false;
-                break;
         }
     }
     
@@ -1156,6 +1150,7 @@ main (int argc, char *argv[])
                   compile_options.c_str(),
                   RNB_ARCH);
 
+    std::string listen_host;
     int listen_port = INT32_MAX;
     char str[PATH_MAX];
     str[0] = '\0';
@@ -1172,16 +1167,27 @@ main (int argc, char *argv[])
         int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &listen_port);
         if (items_scanned == 2)
         {
-            DNBLogDebug("host = '%s'  port = %i", str, listen_port);
-        }
-        else if (argv[0][0] == '/')
-        {
-            listen_port = INT32_MAX;
-            strncpy(str, argv[0], sizeof(str));
+            listen_host = str;
+            DNBLogDebug("host = '%s'  port = %i", listen_host.c_str(), listen_port);
         }
         else
         {
-            show_usage_and_exit (2);
+            // No hostname means "localhost"
+            int items_scanned = ::sscanf (argv[0], "%i", &listen_port);
+            if (items_scanned == 1)
+            {
+                listen_host = "localhost";
+                DNBLogDebug("host = '%s'  port = %i", listen_host.c_str(), listen_port);
+            }
+            else if (argv[0][0] == '/')
+            {
+                listen_port = INT32_MAX;
+                strncpy(str, argv[0], sizeof(str));
+            }
+            else
+            {
+                show_usage_and_exit (2);
+            }
         }
 
         // We just used the 'host:port' or the '/path/file' arg...
@@ -1292,7 +1298,7 @@ main (int argc, char *argv[])
 #endif
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
+                    if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')
@@ -1405,7 +1411,7 @@ main (int argc, char *argv[])
                 {
                     if (listen_port != INT32_MAX)
                     {
-                        if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
+                        if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
                             mode = eRNBRunLoopModeExit;
                     }
                     else if (str[0] == '/')
@@ -1430,7 +1436,7 @@ main (int argc, char *argv[])
                     {
                         if (listen_port != INT32_MAX)
                         {
-                            if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
+                            if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
                                 mode = eRNBRunLoopModeExit;
                         }
                         else if (str[0] == '/')
@@ -1457,7 +1463,7 @@ main (int argc, char *argv[])
             case eRNBRunLoopModePlatformMode:
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
+                    if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')





More information about the lldb-commits mailing list