forked from OSchip/llvm-project
Add Socket::Get[Remote/Local]IpAddress and unit tests
Differential Revision: http://reviews.llvm.org/D6917 llvm-svn: 226234
This commit is contained in:
parent
0a3a7ccb3a
commit
014bb7da79
|
@ -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 = (
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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 ());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef ADDRESS_FAMILY sa_family_t;
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include <string>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
|
@ -99,6 +100,12 @@ public:
|
|||
void
|
||||
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
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -222,7 +222,7 @@ Error Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inhe
|
|||
// 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 host_and_port, bool child_processes_inhe
|
|||
// 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::StringRef host_and_port,
|
|||
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::StringRef host_and_port,
|
|||
// 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 option_name, int option_value)
|
|||
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 NativeSocket& socket)
|
|||
}
|
||||
|
||||
// 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 "";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 family)
|
|||
#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
|
||||
{
|
||||
|
|
|
@ -274,7 +274,7 @@ ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url)
|
|||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue