Add Socket::Get[Remote/Local]IpAddress and unit tests

Differential Revision: http://reviews.llvm.org/D6917

llvm-svn: 226234
diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index c12fa07..f93ad7e 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -222,7 +222,7 @@
         // as port zero is a special code for "find an open port
         // for me".
         if (port == 0)
-            port = listen_socket->GetPortNumber();
+            port = listen_socket->GetLocalPortNumber();
 
         // Set the port predicate since when doing a listen://<host>:<port>
         // it often needs to accept the incoming connection which is a blocking
@@ -230,7 +230,7 @@
         // us to wait for the port predicate to be set to a non-zero value from
         // another thread in an efficient manor.
         if (predicate)
-            predicate->SetValue(port, eBroadcastAlways);
+            predicate->SetValue (port, eBroadcastAlways);
 
         socket = listen_socket.release();
     }
@@ -533,13 +533,18 @@
         if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
             regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
         {
-            port = StringConvert::ToSInt32 (port_str.c_str(), INT32_MIN);
-            if (port != INT32_MIN)
+            bool ok = false;
+            port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
+            if (ok && port < UINT16_MAX)
             {
                 if (error_ptr)
                     error_ptr->Clear();
                 return true;
             }
+            // port is too large
+            if (error_ptr)
+                error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
+            return false;
         }
     }
 
@@ -547,10 +552,13 @@
     // a port with an empty host.
     host_str.clear();
     port_str.clear();
-    port = StringConvert::ToSInt32(host_and_port.data(), INT32_MIN);
-    if (port != INT32_MIN)
+    bool ok = false;
+    port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
+    if (ok && port < UINT16_MAX)
     {
         port_str = host_and_port;
+        if (error_ptr)
+            error_ptr->Clear();
         return true;
     }
 
@@ -688,7 +696,7 @@
 	return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
 }
 
-uint16_t Socket::GetPortNumber(const NativeSocket& socket)
+uint16_t Socket::GetLocalPortNumber(const NativeSocket& socket)
 {
     // We bound to port zero, so we need to figure out which port we actually bound to
     if (socket >= 0)
@@ -702,7 +710,47 @@
 }
 
 // Return the port number that is being used by the socket.
-uint16_t Socket::GetPortNumber() const
+uint16_t Socket::GetLocalPortNumber() const
 {
-    return GetPortNumber(m_socket);
+    return GetLocalPortNumber (m_socket);
 }
+
+std::string  Socket::GetLocalIPAddress () const
+{
+    // We bound to port zero, so we need to figure out which port we actually bound to
+    if (m_socket >= 0)
+    {
+        SocketAddress sock_addr;
+        socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+        if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
+            return sock_addr.GetIPAddress ();
+    }
+    return "";
+}
+
+uint16_t Socket::GetRemotePortNumber () const
+{
+    if (m_socket >= 0)
+    {
+        SocketAddress sock_addr;
+        socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+        if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+            return sock_addr.GetPort ();
+    }
+    return 0;
+}
+
+std::string Socket::GetRemoteIPAddress () const
+{
+    // We bound to port zero, so we need to figure out which port we actually bound to
+    if (m_socket >= 0)
+    {
+        SocketAddress sock_addr;
+        socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+        if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+            return sock_addr.GetIPAddress ();
+    }
+    return "";
+}
+
+