Index: gtest/gtest.xcodeproj/project.pbxproj =================================================================== --- gtest/gtest.xcodeproj/project.pbxproj +++ gtest/gtest.xcodeproj/project.pbxproj @@ -12,6 +12,10 @@ 236ED33619D490B0008CA7D7 /* Makefile.rules */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.rules; sourceTree = ""; }; 33064C981A5C7A1A0033D415 /* UriParserTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UriParserTest.cpp; path = Utility/UriParserTest.cpp; sourceTree = ""; }; 33064C9D1A5C7AC90033D415 /* do-gtest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "do-gtest.py"; sourceTree = ""; }; + 330E475C1A609CF600FD2884 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Host/Makefile; sourceTree = ""; }; + 330E475D1A609CF600FD2884 /* SocketTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocketTest.cpp; path = Host/SocketTest.cpp; sourceTree = ""; }; + 330E475E1A60B31F00FD2884 /* SocketTestGlue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocketTestGlue.cpp; path = Host/SocketTestGlue.cpp; sourceTree = ""; }; + 330E47621A62451800FD2884 /* SocketAddressTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddressTest.cpp; path = Host/SocketAddressTest.cpp; sourceTree = ""; }; 338C47F41A1E67B900B46077 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Utility/Makefile; sourceTree = ""; }; 338C47F51A1E67B900B46077 /* StringExtractorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorTest.cpp; path = Utility/StringExtractorTest.cpp; sourceTree = ""; }; /* End PBXFileReference section */ @@ -20,6 +24,7 @@ 236ED32F19D4901D008CA7D7 /* unittest */ = { isa = PBXGroup; children = ( + 330E475B1A609CDF00FD2884 /* Host */, 338C47F31A1E677900B46077 /* Utility */, 236ED33019D4903E008CA7D7 /* Plugins */, ); @@ -68,6 +73,17 @@ ); sourceTree = ""; }; + 330E475B1A609CDF00FD2884 /* Host */ = { + isa = PBXGroup; + children = ( + 330E475E1A60B31F00FD2884 /* SocketTestGlue.cpp */, + 330E475C1A609CF600FD2884 /* Makefile */, + 330E475D1A609CF600FD2884 /* SocketTest.cpp */, + 330E47621A62451800FD2884 /* SocketAddressTest.cpp */, + ); + name = Host; + sourceTree = ""; + }; 338C47F31A1E677900B46077 /* Utility */ = { isa = PBXGroup; children = ( Index: include/lldb/Host/Socket.h =================================================================== --- include/lldb/Host/Socket.h +++ include/lldb/Host/Socket.h @@ -70,22 +70,35 @@ 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 @@ int32_t& port, Error *error_ptr); - +protected: SocketProtocol m_protocol; NativeSocket m_socket; SocketAddress m_udp_send_sockaddr; // Send address used for UDP connections. Index: include/lldb/Host/SocketAddress.h =================================================================== --- include/lldb/Host/SocketAddress.h +++ include/lldb/Host/SocketAddress.h @@ -31,6 +31,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include namespace lldb_private { @@ -100,6 +101,12 @@ 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 Index: lldb.xcodeproj/project.pbxproj =================================================================== --- lldb.xcodeproj/project.pbxproj +++ lldb.xcodeproj/project.pbxproj @@ -583,6 +583,8 @@ 26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */ = {isa = PBXBuildFile; fileRef = 26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */; }; 33064C9A1A5C7A330033D415 /* UriParser.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33064C991A5C7A330033D415 /* UriParser.cpp */; }; 33064C9C1A5C7A490033D415 /* UriParser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33064C9B1A5C7A490033D415 /* UriParser.h */; }; + 330E475F1A60B84400FD2884 /* ConnectionFileDescriptorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */; }; + 330E47611A60B91000FD2884 /* ConnectionFileDescriptorPosix.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 330E47601A60B91000FD2884 /* ConnectionFileDescriptorPosix.h */; }; 3FDFDDBD199C3A06009756A7 /* FileAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */; }; 3FDFDDBF199D345E009756A7 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBE199D345E009756A7 /* FileCache.cpp */; }; 3FDFDDC6199D37ED009756A7 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */; }; @@ -937,6 +939,7 @@ AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */, 33064C9C1A5C7A490033D415 /* UriParser.h in CopyFiles */, 33064C9A1A5C7A330033D415 /* UriParser.cpp in CopyFiles */, + 330E47611A60B91000FD2884 /* ConnectionFileDescriptorPosix.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; @@ -1801,6 +1804,7 @@ 26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderPOSIXDYLD.h; sourceTree = ""; }; 33064C991A5C7A330033D415 /* UriParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UriParser.cpp; path = source/Utility/UriParser.cpp; sourceTree = ""; }; 33064C9B1A5C7A490033D415 /* UriParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UriParser.h; path = source/Utility/UriParser.h; sourceTree = ""; }; + 330E47601A60B91000FD2884 /* ConnectionFileDescriptorPosix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionFileDescriptorPosix.h; path = include/lldb/Host/posix/ConnectionFileDescriptorPosix.h; sourceTree = SOURCE_ROOT; }; 3F5E8AF31A40D4A500A73232 /* PipeBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PipeBase.h; path = include/lldb/Host/PipeBase.h; sourceTree = ""; }; 3FDFD6C3199C396E009756A7 /* FileAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileAction.h; path = include/lldb/Target/FileAction.h; sourceTree = ""; }; 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileAction.cpp; path = source/Target/FileAction.cpp; sourceTree = ""; }; @@ -4172,6 +4176,7 @@ 3FDFDDC4199D37BE009756A7 /* posix */ = { isa = PBXGroup; children = ( + 330E47601A60B91000FD2884 /* ConnectionFileDescriptorPosix.h */, AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */, 3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */, 3FDFE53019A292F0009756A7 /* HostInfoPosix.cpp */, @@ -5027,6 +5032,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 330E475F1A60B84400FD2884 /* ConnectionFileDescriptorPosix.cpp in Sources */, 26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; Index: source/Host/common/Socket.cpp =================================================================== --- source/Host/common/Socket.cpp +++ source/Host/common/Socket.cpp @@ -16,7 +16,6 @@ #include "lldb/Host/Host.h" #include "lldb/Host/SocketAddress.h" #include "lldb/Host/TimeValue.h" -#include "lldb/Interpreter/Args.h" #ifdef __ANDROID_NDK__ #include @@ -222,7 +221,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://: // it often needs to accept the incoming connection which is a blocking @@ -230,9 +229,9 @@ // 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(); + socket = listen_socket.release (); } return error; @@ -533,27 +532,33 @@ if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) && regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str)) { - port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN); - if (port != INT32_MIN) + port = ::strtoul (port_str.c_str(), nullptr, 10); + if (port < 65536) { 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; } } - + // If this was unsuccessful, then check if it's simply a signed 32-bit integer, representing // a port with an empty host. host_str.clear(); port_str.clear(); - port = Args::StringToSInt32(host_and_port.data(), INT32_MIN); - if (port != INT32_MIN) + port = ::strtoul (host_and_port.data(), nullptr, 10); + if (port < 65536) { port_str = host_and_port; + if (error_ptr) + error_ptr->Clear(); return true; } - + if (error_ptr) error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data()); return false; @@ -688,7 +693,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 +707,46 @@ } // Return the port number that is being used by the socket. -uint16_t Socket::GetPortNumber() const +uint16_t Socket::GetLocalPortNumber() const +{ + 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 { - return GetPortNumber(m_socket); + 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 ""; +} + Index: source/Host/common/SocketAddress.cpp =================================================================== --- source/Host/common/SocketAddress.cpp +++ source/Host/common/SocketAddress.cpp @@ -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(src)); + if (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(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 @@ #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 { Index: source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp =================================================================== --- source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -274,7 +274,7 @@ if (conn_ap->IsConnected()) { const Socket& socket = static_cast(*conn_ap->GetReadObject()); - const uint16_t reply_port = socket.GetPortNumber(); + const uint16_t reply_port = socket.GetLocalPortNumber(); if (reply_port != 0) {