summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ConnectionFileDescriptor.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-07-15 16:31:38 +0000
committerGreg Clayton <gclayton@apple.com>2011-07-15 16:31:38 +0000
commit57508026c276d9ffca1d84dfb74ea60c9b18b76a (patch)
tree1b7c2f0628ceac3e836ce9f3f0a33fc123c5d37f /lldb/source/Core/ConnectionFileDescriptor.cpp
parente9d62935d3c42cb73c39fc4d0dc46bc35dc213ec (diff)
downloadbcm5719-llvm-57508026c276d9ffca1d84dfb74ea60c9b18b76a.tar.gz
bcm5719-llvm-57508026c276d9ffca1d84dfb74ea60c9b18b76a.zip
Added the ability to connect using "tcp://<host>:<port>" which is the
same as the old "connect://<host>:<port>". Also added the ability to connect using "udp://<host>:<port>" which will open a connected datagram socket. I need to find a way to specify a non connected datagram socket as well. We might need to start setting some settings in the URL itself, maybe something like: udp://<host>:<port>?connected=yes udp://<host>:<port>?connected=no I am open to suggestions for URL settings. Also did more work on the KDP darwin kernel plug-in. llvm-svn: 135277
Diffstat (limited to 'lldb/source/Core/ConnectionFileDescriptor.cpp')
-rw-r--r--lldb/source/Core/ConnectionFileDescriptor.cpp104
1 files changed, 101 insertions, 3 deletions
diff --git a/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp
index d7adc8b8bb9..f5375ca6cdf 100644
--- a/lldb/source/Core/ConnectionFileDescriptor.cpp
+++ b/lldb/source/Core/ConnectionFileDescriptor.cpp
@@ -97,7 +97,15 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
}
else if (strstr(s, "connect://"))
{
- return SocketConnect (s + strlen("connect://"), error_ptr);
+ return ConnectTCP (s + strlen("connect://"), error_ptr);
+ }
+ else if (strstr(s, "tcp://"))
+ {
+ return ConnectTCP (s + strlen("tcp://"), error_ptr);
+ }
+ else if (strstr(s, "udp://"))
+ {
+ return ConnectUDP (s + strlen("udp://"), error_ptr);
}
else if (strstr(s, "fd://"))
{
@@ -626,10 +634,10 @@ ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_p
}
ConnectionStatus
-ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error_ptr)
+ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::SocketConnect (host/port = %s)",
+ "%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
m_is_socket = true;
@@ -715,6 +723,96 @@ ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error
return eConnectionStatusSuccess;
}
+ConnectionStatus
+ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
+{
+ lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
+ "%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
+ this, host_and_port);
+ Close (m_fd, NULL);
+ m_is_socket = true;
+
+ RegularExpression regex ("([^:]+):([0-9]+)");
+ if (regex.Execute (host_and_port, 2) == false)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
+ return eConnectionStatusError;
+ }
+ std::string host_str;
+ std::string port_str;
+ if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
+ regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
+ return eConnectionStatusError;
+ }
+
+ int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
+ if (port == INT32_MIN)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
+ return eConnectionStatusError;
+ }
+ // Create the socket
+ m_fd = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (m_fd == -1)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorToErrno();
+ return eConnectionStatusError;
+ }
+
+ m_should_close_fd = true;
+
+ // Enable local address reuse
+ SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
+
+ struct sockaddr_in sa;
+ ::memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons (port);
+
+ int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
+
+ if (inet_pton_result <= 0)
+ {
+ struct hostent *host_entry = gethostbyname (host_str.c_str());
+ if (host_entry)
+ 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)
+ {
+
+ if (error_ptr)
+ {
+ if (inet_pton_result == -1)
+ error_ptr->SetErrorToErrno();
+ else
+ error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
+ }
+ Close (m_fd, NULL);
+ return eConnectionStatusError;
+ }
+ }
+
+ if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+ {
+ if (error_ptr)
+ error_ptr->SetErrorToErrno();
+ Close (m_fd, NULL);
+ return eConnectionStatusError;
+ }
+
+ // Keep our TCP packets coming without any delays.
+ SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+ if (error_ptr)
+ error_ptr->Clear();
+ return eConnectionStatusSuccess;
+}
+
#if defined(__MINGW32__) || defined(__MINGW64__)
typedef const char * set_socket_option_arg_type;
typedef char * get_socket_option_arg_type;
OpenPOWER on IntegriCloud