[Lldb-commits] [lldb] r226234 - Add Socket::Get[Remote/Local]IpAddress and unit tests

Vince Harron vharron at google.com
Thu Jan 15 16:47:08 PST 2015


Author: vharron
Date: Thu Jan 15 18:47:08 2015
New Revision: 226234

URL: http://llvm.org/viewvc/llvm-project?rev=226234&view=rev
Log:
Add Socket::Get[Remote/Local]IpAddress and unit tests

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


Added:
    lldb/trunk/gtest/unittest/Host/
    lldb/trunk/gtest/unittest/Host/Makefile
    lldb/trunk/gtest/unittest/Host/SocketAddressTest.cpp
    lldb/trunk/gtest/unittest/Host/SocketTest.cpp
    lldb/trunk/gtest/unittest/Host/SocketTestMock.cpp
Modified:
    lldb/trunk/gtest/gtest.xcodeproj/project.pbxproj
    lldb/trunk/include/lldb/Host/Socket.h
    lldb/trunk/include/lldb/Host/SocketAddress.h
    lldb/trunk/source/Host/common/Socket.cpp
    lldb/trunk/source/Host/common/SocketAddress.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp

Modified: lldb/trunk/gtest/gtest.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/gtest.xcodeproj/project.pbxproj?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/gtest/gtest.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/gtest/gtest.xcodeproj/project.pbxproj Thu Jan 15 18:47:08 2015
@@ -12,6 +12,10 @@
 		236ED33619D490B0008CA7D7 /* Makefile.rules */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.rules; sourceTree = "<group>"; };
 		33064C981A5C7A1A0033D415 /* UriParserTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UriParserTest.cpp; path = Utility/UriParserTest.cpp; sourceTree = "<group>"; };
 		33064C9D1A5C7AC90033D415 /* do-gtest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "do-gtest.py"; sourceTree = "<group>"; };
+		330E475C1A609CF600FD2884 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Host/Makefile; sourceTree = "<group>"; };
+		330E475D1A609CF600FD2884 /* SocketTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocketTest.cpp; path = Host/SocketTest.cpp; sourceTree = "<group>"; };
+		330E475E1A60B31F00FD2884 /* SocketTestMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocketTestMock.cpp; path = Host/SocketTestMock.cpp; sourceTree = "<group>"; };
+		330E47621A62451800FD2884 /* SocketAddressTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddressTest.cpp; path = Host/SocketAddressTest.cpp; sourceTree = "<group>"; };
 		338C47F41A1E67B900B46077 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Utility/Makefile; sourceTree = "<group>"; };
 		338C47F51A1E67B900B46077 /* StringExtractorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorTest.cpp; path = Utility/StringExtractorTest.cpp; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -20,6 +24,7 @@
 		236ED32F19D4901D008CA7D7 /* unittest */ = {
 			isa = PBXGroup;
 			children = (
+				330E475B1A609CDF00FD2884 /* Host */,
 				338C47F31A1E677900B46077 /* Utility */,
 				236ED33019D4903E008CA7D7 /* Plugins */,
 			);
@@ -68,6 +73,17 @@
 			);
 			sourceTree = "<group>";
 		};
+		330E475B1A609CDF00FD2884 /* Host */ = {
+			isa = PBXGroup;
+			children = (
+				330E475E1A60B31F00FD2884 /* SocketTestMock.cpp */,
+				330E475C1A609CF600FD2884 /* Makefile */,
+				330E475D1A609CF600FD2884 /* SocketTest.cpp */,
+				330E47621A62451800FD2884 /* SocketAddressTest.cpp */,
+			);
+			name = Host;
+			sourceTree = "<group>";
+		};
 		338C47F31A1E677900B46077 /* Utility */ = {
 			isa = PBXGroup;
 			children = (

Added: lldb/trunk/gtest/unittest/Host/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/unittest/Host/Makefile?rev=226234&view=auto
==============================================================================
--- lldb/trunk/gtest/unittest/Host/Makefile (added)
+++ lldb/trunk/gtest/unittest/Host/Makefile Thu Jan 15 18:47:08 2015
@@ -0,0 +1,32 @@
+THIS_FILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/
+
+LEVEL := $(realpath $(THIS_FILE_DIR)../../make)
+
+CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
+ENABLE_THREADS := YES
+# the fact that we need all of these source files to compile Socket.cpp
+# is a good indication that we need some refactoring
+CXX_SOURCES := $(wildcard *.cpp) \
+    $(realpath $(LEVEL)/../../source/Core/Error.cpp) \
+    $(realpath $(LEVEL)/../../source/Core/RegularExpression.cpp) \
+    $(realpath $(LEVEL)/../../source/Core/Stream.cpp) \
+    $(realpath $(LEVEL)/../../source/Core/StreamString.cpp) \
+    $(realpath $(LEVEL)/../../source/Host/common/Socket.cpp) \
+    $(realpath $(LEVEL)/../../source/Host/common/SocketAddress.cpp) \
+    $(realpath $(LEVEL)/../../source/Host/common/StringConvert.cpp) \
+    $(realpath $(LEVEL)/../../source/Host/common/TimeValue.cpp)
+
+OS := $(shell uname -s)
+ifeq ($(OS),Windows)
+CXX_SOURCES := $(CXX_SOURCES) \
+    $(LEVEL)/../../source/Host/windows/Condition.cpp \
+    $(LEVEL)/../../source/Host/windows/Mutex.cpp
+else
+CXX_SOURCES := $(CXX_SOURCES) \
+    $(LEVEL)/../../source/Host/common/Condition.cpp \
+    $(LEVEL)/../../source/Host/common/Mutex.cpp
+endif
+
+MAKE_DSYM := NO
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/gtest/unittest/Host/SocketAddressTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/unittest/Host/SocketAddressTest.cpp?rev=226234&view=auto
==============================================================================
--- lldb/trunk/gtest/unittest/Host/SocketAddressTest.cpp (added)
+++ lldb/trunk/gtest/unittest/Host/SocketAddressTest.cpp Thu Jan 15 18:47:08 2015
@@ -0,0 +1,77 @@
+//===-- SocketAddressTest.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "gtest/gtest.h"
+
+#include "lldb/Host/SocketAddress.h"
+
+namespace
+{
+    class SocketAddressTest: public ::testing::Test
+    {
+    };
+}
+
+using namespace lldb_private;
+
+TEST_F (SocketAddressTest, Set)
+{
+    SocketAddress sa;
+    ASSERT_TRUE (sa.SetToLocalhost (AF_INET, 1138));
+    ASSERT_STREQ ("127.0.0.1", sa.GetIPAddress ().c_str ());
+    ASSERT_EQ (1138, sa.GetPort ());
+
+    ASSERT_TRUE (sa.SetToAnyAddress (AF_INET, 0));
+    ASSERT_STREQ ("0.0.0.0", sa.GetIPAddress ().c_str ());
+    ASSERT_EQ (0, sa.GetPort ());
+
+    ASSERT_TRUE (sa.SetToLocalhost (AF_INET6, 1139));
+#ifdef _WIN32
+    ASSERT_STREQ ("0:0:0:0:0:0:0:1", sa.GetIPAddress ().c_str ());
+#else
+    ASSERT_STREQ ("::1", sa.GetIPAddress ().c_str ());
+#endif
+    ASSERT_EQ (1139, sa.GetPort ());
+}
+
+#ifdef _WIN32
+
+// we need to test our inet_ntop implementation for Windows XP
+const char* inet_ntop (int af, const void * src,
+                        char * dst, socklen_t size);
+
+TEST_F (SocketAddressTest, inet_ntop)
+{
+    const uint8_t address4[4] = {255, 0, 1, 100};
+    const uint8_t address6[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 255, 0};
+   
+    char buffer[INET6_ADDRSTRLEN];
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ ("1:203:405:607:809:a0b:c0d:ff00", inet_ntop (AF_INET6, address6, buffer, sizeof (buffer)));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ ("1:203:405:607:809:a0b:c0d:ff00", inet_ntop (AF_INET6, address6, buffer, 31));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ (nullptr, inet_ntop (AF_INET6, address6, buffer, 0));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ (nullptr, inet_ntop (AF_INET6, address6, buffer, 30));
+    
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ ("255.0.1.100", inet_ntop (AF_INET, address4, buffer, sizeof (buffer)));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ ("255.0.1.100", inet_ntop (AF_INET, address4, buffer, 12));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ (nullptr, inet_ntop (AF_INET, address4, buffer, 0));
+    memset (buffer, 'x', sizeof (buffer));
+    EXPECT_STREQ (nullptr, inet_ntop (AF_INET, address4, buffer, 11));
+}
+
+#endif
+
+

Added: lldb/trunk/gtest/unittest/Host/SocketTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/unittest/Host/SocketTest.cpp?rev=226234&view=auto
==============================================================================
--- lldb/trunk/gtest/unittest/Host/SocketTest.cpp (added)
+++ lldb/trunk/gtest/unittest/Host/SocketTest.cpp Thu Jan 15 18:47:08 2015
@@ -0,0 +1,132 @@
+//===-- SocketTest.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <thread>
+
+#include "gtest/gtest.h"
+
+#include "lldb/Host/Socket.h"
+
+class SocketTest: public ::testing::Test
+{
+};
+
+using namespace lldb_private;
+
+void AcceptThread (Socket* listen_socket,
+                  const char* listen_remote_address,
+                  bool child_processes_inherit,
+                  Socket** accept_socket,
+                  Error* error)
+{
+    *error = listen_socket->BlockingAccept (listen_remote_address, child_processes_inherit, *accept_socket);
+}
+
+void CreateConnectedSockets (std::unique_ptr<Socket>* a_up, std::unique_ptr<Socket>* b_up)
+{
+    Predicate<uint16_t> port_predicate;
+    // Used when binding to port zero to wait for the thread
+    // that creates the socket, binds and listens to resolve
+    // the port number.
+    
+    port_predicate.SetValue (0, eBroadcastNever);
+    
+    bool child_processes_inherit = false;
+    Socket *socket = nullptr;
+    const char* listen_remote_address = "localhost:0";
+    Error error = Socket::TcpListen (listen_remote_address, child_processes_inherit, socket, &port_predicate);
+    std::unique_ptr<Socket> listen_socket_up (socket);
+    socket = nullptr;
+    EXPECT_FALSE (error.Fail ());
+    EXPECT_NE (nullptr, listen_socket_up.get ());
+    EXPECT_TRUE (listen_socket_up->IsValid ());
+
+    Error accept_error;
+    Socket* accept_socket;
+    std::thread accept_thread (AcceptThread,
+                               listen_socket_up.get (),
+                               listen_remote_address,
+                               child_processes_inherit,
+                               &accept_socket,
+                               &accept_error);
+    
+    char connect_remote_address[64];
+    snprintf (connect_remote_address, sizeof (connect_remote_address), "localhost:%u", port_predicate.GetValue ());
+    error = Socket::TcpConnect (connect_remote_address, child_processes_inherit, socket);
+    a_up->reset (socket);
+    socket = nullptr;
+    EXPECT_TRUE (error.Success ());
+    EXPECT_NE (nullptr, a_up->get ());
+    EXPECT_TRUE ((*a_up)->IsValid ());
+    
+    accept_thread.join ();
+    b_up->reset (accept_socket);
+    EXPECT_TRUE (accept_error.Success ());
+    EXPECT_NE (nullptr, b_up->get ());
+    EXPECT_TRUE ((*b_up)->IsValid ());
+    
+    listen_socket_up.reset ();
+}
+
+TEST_F (SocketTest, DecodeHostAndPort)
+{
+    std::string host_str;
+    std::string port_str;
+    int32_t port;
+    Error error;
+    EXPECT_TRUE (Socket::DecodeHostAndPort ("localhost:1138", host_str, port_str, port, &error));
+    EXPECT_STREQ ("localhost", host_str.c_str ());
+    EXPECT_STREQ ("1138", port_str.c_str ());
+    EXPECT_EQ (1138, port);
+    EXPECT_TRUE (error.Success ());
+    
+    EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:65536", host_str, port_str, port, &error));
+    EXPECT_TRUE (error.Fail ());
+    EXPECT_STREQ ("invalid host:port specification: 'google.com:65536'", error.AsCString ());
+    
+    EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:-1138", host_str, port_str, port, &error));
+    EXPECT_TRUE (error.Fail ());
+    EXPECT_STREQ ("invalid host:port specification: 'google.com:-1138'", error.AsCString ());
+    
+    EXPECT_TRUE (Socket::DecodeHostAndPort ("12345", host_str, port_str, port, &error));
+    EXPECT_STREQ ("", host_str.c_str ());
+    EXPECT_STREQ ("12345", port_str.c_str ());
+    EXPECT_EQ (12345, port);
+    EXPECT_TRUE (error.Success ());
+    
+    EXPECT_TRUE (Socket::DecodeHostAndPort ("*:0", host_str, port_str, port, &error));
+    EXPECT_STREQ ("*", host_str.c_str ());
+    EXPECT_STREQ ("0", port_str.c_str ());
+    EXPECT_EQ (0, port);
+    EXPECT_TRUE (error.Success ());
+    
+}
+
+TEST_F (SocketTest, Listen0ConnectAccept)
+{
+    std::unique_ptr<Socket> socket_a_up;
+    std::unique_ptr<Socket> socket_b_up;
+    CreateConnectedSockets (&socket_a_up, &socket_b_up);
+}
+
+TEST_F (SocketTest, GetAddress)
+{
+    std::unique_ptr<Socket> socket_a_up;
+    std::unique_ptr<Socket> socket_b_up;
+    CreateConnectedSockets (&socket_a_up, &socket_b_up);
+    
+    EXPECT_EQ (socket_a_up->GetLocalPortNumber (), socket_b_up->GetRemotePortNumber ());
+    EXPECT_EQ (socket_b_up->GetLocalPortNumber (), socket_a_up->GetRemotePortNumber ());
+    EXPECT_NE (socket_a_up->GetLocalPortNumber (), socket_b_up->GetLocalPortNumber ());
+    EXPECT_STREQ ("127.0.0.1", socket_a_up->GetRemoteIPAddress ().c_str ());
+    EXPECT_STREQ ("127.0.0.1", socket_b_up->GetRemoteIPAddress ().c_str ());
+}
+
+
+

Added: lldb/trunk/gtest/unittest/Host/SocketTestMock.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/gtest/unittest/Host/SocketTestMock.cpp?rev=226234&view=auto
==============================================================================
--- lldb/trunk/gtest/unittest/Host/SocketTestMock.cpp (added)
+++ lldb/trunk/gtest/unittest/Host/SocketTestMock.cpp Thu Jan 15 18:47:08 2015
@@ -0,0 +1,64 @@
+//===-- SocketTestMock.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This file provides a few necessary functions to link SocketTest.cpp
+// Bringing in the real implementations results in a cascade of dependencies
+// that pull in all of lldb.
+
+#include "lldb/Core/Log.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+using namespace lldb_private;
+
+void
+lldb_private::Log::Error (char const*, ...)
+{
+}
+
+void
+lldb_private::Log::Printf (char const*, ...)
+{
+}
+
+Log*
+lldb_private::GetLogIfAnyCategoriesSet (unsigned int)
+{
+    return nullptr;
+}
+
+#include "lldb/Host/FileSystem.h"
+
+#ifdef _WIN32
+
+Error
+FileSystem::Unlink(const char *path)
+{
+    Error error;
+    BOOL result = ::DeleteFile(path);
+    if (!result)
+        error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+    return error;
+}
+
+#else
+
+Error
+FileSystem::Unlink (const char *path)
+{
+    Error error;
+    if (::unlink (path) == -1)
+        error.SetErrorToErrno ();
+    return error;
+}
+
+#endif
+

Modified: lldb/trunk/include/lldb/Host/Socket.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Socket.h?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Socket.h (original)
+++ lldb/trunk/include/lldb/Host/Socket.h Thu Jan 15 18:47:08 2015
@@ -70,22 +70,35 @@ public:
     int GetOption (int level, int option_name, int &option_value);
     int SetOption (int level, int option_name, int option_value);
 
-    static uint16_t GetPortNumber(const NativeSocket& socket);
-    uint16_t GetPortNumber () const;
+    // returns port number or 0 if error
+    static uint16_t GetLocalPortNumber (const NativeSocket& socket);
+    
+    // returns port number or 0 if error
+    uint16_t GetLocalPortNumber () const;
+
+    // returns ip address string or empty string if error
+    std::string GetLocalIPAddress () const;
+
+    // must be connected
+    // returns port number or 0 if error
+    uint16_t GetRemotePortNumber () const;
+
+    // must be connected
+    // returns ip address string or empty string if error
+    std::string GetRemoteIPAddress () const;
 
     NativeSocket GetNativeSocket () const { return m_socket; }
-    SocketProtocol GetSocketProtocol() const { return m_protocol; }
+    SocketProtocol GetSocketProtocol () const { return m_protocol; }
 
     virtual Error Read (void *buf, size_t &num_bytes);
     virtual Error Write (const void *buf, size_t &num_bytes);
 
-    virtual Error PreDisconnect();
-    virtual Error Close();
+    virtual Error PreDisconnect ();
+    virtual Error Close ();
 
-    virtual bool IsValid() const { return m_socket != kInvalidSocketValue; }
-    virtual WaitableHandle GetWaitableHandle();
+    virtual bool IsValid () const { return m_socket != kInvalidSocketValue; }
+    virtual WaitableHandle GetWaitableHandle ();
 
-protected:
     static bool
     DecodeHostAndPort (llvm::StringRef host_and_port, 
                        std::string &host_str, 
@@ -93,7 +106,7 @@ protected:
                        int32_t& port,
                        Error *error_ptr);
 
-
+protected:
     SocketProtocol m_protocol;
     NativeSocket m_socket;
     SocketAddress m_udp_send_sockaddr;    // Send address used for UDP connections.

Modified: lldb/trunk/include/lldb/Host/SocketAddress.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/SocketAddress.h?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/SocketAddress.h (original)
+++ lldb/trunk/include/lldb/Host/SocketAddress.h Thu Jan 15 18:47:08 2015
@@ -31,6 +31,7 @@ typedef ADDRESS_FAMILY sa_family_t;
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include <string>
 
 namespace lldb_private {
 
@@ -100,6 +101,12 @@ public:
     SetFamily (sa_family_t family);
 
     //------------------------------------------------------------------
+    // Get the address
+    //------------------------------------------------------------------
+    std::string
+    GetIPAddress () const;
+
+    //------------------------------------------------------------------
     // Get the port if the socket address for the family has a port
     //------------------------------------------------------------------
     uint16_t

Modified: lldb/trunk/source/Host/common/Socket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Socket.cpp?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Socket.cpp (original)
+++ lldb/trunk/source/Host/common/Socket.cpp Thu Jan 15 18:47:08 2015
@@ -222,7 +222,7 @@ Error Socket::TcpListen(llvm::StringRef
         // 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 @@ Error Socket::TcpListen(llvm::StringRef
         // 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 @@ Socket::DecodeHostAndPort(llvm::StringRe
         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 @@ Socket::DecodeHostAndPort(llvm::StringRe
     // 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 @@ int Socket::SetOption(int level, int opt
 	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 @@ uint16_t Socket::GetPortNumber(const Nat
 }
 
 // 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 "";
+}
+
+

Modified: lldb/trunk/source/Host/common/SocketAddress.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/SocketAddress.cpp?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/SocketAddress.cpp (original)
+++ lldb/trunk/source/Host/common/SocketAddress.cpp Thu Jan 15 18:47:08 2015
@@ -21,6 +21,56 @@
 // Other libraries and framework includes
 // Project includes
 
+// WindowsXP needs an inet_ntop implementation
+#ifdef _WIN32
+
+#ifndef INET6_ADDRSTRLEN // might not be defined in older Windows SDKs
+#define INET6_ADDRSTRLEN 46
+#endif
+
+// TODO: implement shortened form "::" for runs of zeros
+const char* inet_ntop(int af, const void * src,
+                      char * dst, socklen_t size)
+{
+    if (size==0)
+    {
+        return nullptr;
+    }
+    
+    switch (af)
+    {
+        case AF_INET:
+        {
+            const char* formatted = inet_ntoa(*static_cast<const in_addr*>(src));
+            if (formatted && strlen(formatted) < size)
+            {
+                strncpy(dst, formatted, size);
+                return dst;
+            }
+            return nullptr;
+        case AF_INET6:
+            {
+                char tmp[INET6_ADDRSTRLEN] = {0};
+                const uint16_t* src16 = static_cast<const uint16_t*>(src);
+                int full_size = _snprintf(tmp, sizeof(tmp),
+                                          "%x:%x:%x:%x:%x:%x:%x:%x",
+                                          ntohs(src16[0]), ntohs(src16[1]), ntohs(src16[2]), ntohs(src16[3]),
+                                          ntohs(src16[4]), ntohs(src16[5]), ntohs(src16[6]), ntohs(src16[7])
+                                          );
+                if (full_size < size)
+                {
+                    strncpy(dst,tmp,size);
+                    return dst;
+                }
+                return nullptr;
+            }
+        }
+        return nullptr;
+    }
+    
+#endif
+    
+
 using namespace lldb_private;
 
 //----------------------------------------------------------------------
@@ -124,6 +174,26 @@ SocketAddress::SetFamily (sa_family_t fa
 #endif
 }
 
+std::string
+SocketAddress::GetIPAddress () const
+{
+    char str[INET6_ADDRSTRLEN] = {0};
+    switch (GetFamily())
+    {
+        case AF_INET:
+            if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv4.sin_addr, str, sizeof(str)))
+            {
+                return str;
+            }
+        case AF_INET6:
+            if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv6.sin6_addr, str, sizeof(str)))
+            {
+                return str;
+            }
+    }
+    return "";
+}
+
 uint16_t
 SocketAddress::GetPort () const
 {

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=226234&r1=226233&r2=226234&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Thu Jan 15 18:47:08 2015
@@ -274,7 +274,7 @@ ProcessKDP::DoConnectRemote (Stream *str
     if (conn_ap->IsConnected())
     {
         const Socket& socket = static_cast<const Socket&>(*conn_ap->GetReadObject());
-        const uint16_t reply_port = socket.GetPortNumber();
+        const uint16_t reply_port = socket.GetLocalPortNumber();
 
         if (reply_port != 0)
         {





More information about the lldb-commits mailing list