blob: ff1ca7d10a2f17c9d5ca94d287e8756131bce65e [file] [log] [blame]
Zachary Turner98688922014-08-06 18:16:26 +00001//===-- Socket.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Host/Socket.h"
11
12#include "lldb/Core/Log.h"
13#include "lldb/Core/RegularExpression.h"
14#include "lldb/Host/Config.h"
Zachary Turnerc00cf4a2014-08-15 22:04:21 +000015#include "lldb/Host/FileSystem.h"
Zachary Turner98688922014-08-06 18:16:26 +000016#include "lldb/Host/Host.h"
17#include "lldb/Host/SocketAddress.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000018#include "lldb/Host/StringConvert.h"
Zachary Turner98688922014-08-06 18:16:26 +000019#include "lldb/Host/TimeValue.h"
Zachary Turner98688922014-08-06 18:16:26 +000020
Shawn Best8da0bf32014-11-08 01:41:49 +000021#ifdef __ANDROID_NDK__
22#include <linux/tcp.h>
23#include <bits/error_constants.h>
24#include <asm-generic/errno-base.h>
25#include <errno.h>
26#include <arpa/inet.h>
27#endif
28
Zachary Turner98688922014-08-06 18:16:26 +000029#ifndef LLDB_DISABLE_POSIX
30#include <arpa/inet.h>
31#include <netdb.h>
32#include <netinet/in.h>
33#include <netinet/tcp.h>
34#include <sys/socket.h>
35#include <sys/un.h>
36#endif
37
38using namespace lldb;
39using namespace lldb_private;
40
41#if defined(_WIN32)
42typedef const char * set_socket_option_arg_type;
43typedef char * get_socket_option_arg_type;
44const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
45#else // #if defined(_WIN32)
46typedef const void * set_socket_option_arg_type;
47typedef void * get_socket_option_arg_type;
48const NativeSocket Socket::kInvalidSocketValue = -1;
49#endif // #if defined(_WIN32)
50
Todd Fialacacde7d2014-09-27 16:54:22 +000051#ifdef __ANDROID__
52// Android does not have SUN_LEN
53#ifndef SUN_LEN
54#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
55#endif
56#endif // #ifdef __ANDROID__
57
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +000058namespace {
59
60NativeSocket CreateSocket(const int domain, const int type, const int protocol, bool child_processes_inherit)
61{
62 auto socketType = type;
63#ifdef SOCK_CLOEXEC
64 if (!child_processes_inherit) {
65 socketType |= SOCK_CLOEXEC;
66 }
67#endif
68 return ::socket (domain, socketType, protocol);
69}
70
71NativeSocket Accept(NativeSocket sockfd, struct sockaddr *addr, socklen_t *addrlen, bool child_processes_inherit)
72{
73#ifdef SOCK_CLOEXEC
74 int flags = 0;
75 if (!child_processes_inherit) {
76 flags |= SOCK_CLOEXEC;
77 }
78 return ::accept4 (sockfd, addr, addrlen, flags);
79#else
80 return ::accept (sockfd, addr, addrlen);
81#endif
82}
83}
84
Zachary Turner98688922014-08-06 18:16:26 +000085Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
86 : IOObject(eFDTypeSocket, should_close)
87 , m_protocol(protocol)
88 , m_socket(socket)
89{
90
91}
92
93Socket::~Socket()
94{
95 Close();
96}
97
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +000098Error Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
Zachary Turner98688922014-08-06 18:16:26 +000099{
100 // Store the result in a unique_ptr in case we error out, the memory will get correctly freed.
101 std::unique_ptr<Socket> final_socket;
102 NativeSocket sock = kInvalidSocketValue;
103 Error error;
104
105 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
106 if (log)
107 log->Printf ("Socket::TcpConnect (host/port = %s)", host_and_port.data());
108
109 std::string host_str;
110 std::string port_str;
111 int32_t port = INT32_MIN;
112 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
113 return error;
114
115 // Create the socket
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000116 sock = CreateSocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000117 if (sock == kInvalidSocketValue)
118 {
119 // TODO: On Windows, use WSAGetLastError().
120 error.SetErrorToErrno();
121 return error;
122 }
123
124 // Since they both refer to the same socket descriptor, arbitrarily choose the send socket to
125 // be the owner.
126 final_socket.reset(new Socket(sock, ProtocolTcp, true));
127
128 // Enable local address reuse
129 final_socket->SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
130
131 struct sockaddr_in sa;
132 ::memset (&sa, 0, sizeof (sa));
133 sa.sin_family = AF_INET;
134 sa.sin_port = htons (port);
135
136 int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
137
138 if (inet_pton_result <= 0)
139 {
140 struct hostent *host_entry = gethostbyname (host_str.c_str());
141 if (host_entry)
142 host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
143 inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
144 if (inet_pton_result <= 0)
145 {
146 // TODO: On Windows, use WSAGetLastError()
147 if (inet_pton_result == -1)
148 error.SetErrorToErrno();
149 else
150 error.SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
151
152 return error;
153 }
154 }
155
156 if (-1 == ::connect (sock, (const struct sockaddr *)&sa, sizeof(sa)))
157 {
158 // TODO: On Windows, use WSAGetLastError()
159 error.SetErrorToErrno();
160 return error;
161 }
162
163 // Keep our TCP packets coming without any delays.
164 final_socket->SetOption(IPPROTO_TCP, TCP_NODELAY, 1);
165 error.Clear();
166 socket = final_socket.release();
167 return error;
168}
169
Vince Harron33aea902015-03-31 00:27:10 +0000170Error Socket::TcpListen(
171 llvm::StringRef host_and_port,
172 bool child_processes_inherit,
173 Socket *&socket,
174 Predicate<uint16_t>* predicate,
175 int backlog)
Zachary Turner98688922014-08-06 18:16:26 +0000176{
177 std::unique_ptr<Socket> listen_socket;
178 NativeSocket listen_sock = kInvalidSocketValue;
179 Error error;
180
181 const sa_family_t family = AF_INET;
182 const int socktype = SOCK_STREAM;
183 const int protocol = IPPROTO_TCP;
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000184 listen_sock = ::CreateSocket (family, socktype, protocol, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000185 if (listen_sock == kInvalidSocketValue)
186 {
187 error.SetErrorToErrno();
188 return error;
189 }
190
191 listen_socket.reset(new Socket(listen_sock, ProtocolTcp, true));
192
193 // enable local address reuse
194 listen_socket->SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
195
196 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
197 if (log)
Vince Harroneb303ee2015-01-17 02:20:29 +0000198 log->Printf ("Socket::TcpListen (%s)", host_and_port.data());
Zachary Turner98688922014-08-06 18:16:26 +0000199
200 std::string host_str;
201 std::string port_str;
202 int32_t port = INT32_MIN;
203 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
204 return error;
205
206 SocketAddress anyaddr;
207 if (anyaddr.SetToAnyAddress (family, port))
208 {
209 int err = ::bind (listen_sock, anyaddr, anyaddr.GetLength());
210 if (err == -1)
211 {
212 // TODO: On Windows, use WSAGetLastError()
213 error.SetErrorToErrno();
214 return error;
215 }
216
Vince Harron33aea902015-03-31 00:27:10 +0000217 err = ::listen (listen_sock, backlog);
Zachary Turner98688922014-08-06 18:16:26 +0000218 if (err == -1)
219 {
220 // TODO: On Windows, use WSAGetLastError()
221 error.SetErrorToErrno();
222 return error;
223 }
224
225 // We were asked to listen on port zero which means we
226 // must now read the actual port that was given to us
227 // as port zero is a special code for "find an open port
228 // for me".
229 if (port == 0)
Vince Harron014bb7d2015-01-16 00:47:08 +0000230 port = listen_socket->GetLocalPortNumber();
Zachary Turner98688922014-08-06 18:16:26 +0000231
232 // Set the port predicate since when doing a listen://<host>:<port>
233 // it often needs to accept the incoming connection which is a blocking
234 // system call. Allowing access to the bound port using a predicate allows
235 // us to wait for the port predicate to be set to a non-zero value from
236 // another thread in an efficient manor.
237 if (predicate)
Vince Harron014bb7d2015-01-16 00:47:08 +0000238 predicate->SetValue (port, eBroadcastAlways);
Zachary Turner98688922014-08-06 18:16:26 +0000239
240 socket = listen_socket.release();
241 }
242
243 return error;
244}
245
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000246Error Socket::BlockingAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
Zachary Turner98688922014-08-06 18:16:26 +0000247{
248 Error error;
249 std::string host_str;
250 std::string port_str;
251 int32_t port;
252 if (!DecodeHostAndPort(host_and_port, host_str, port_str, port, &error))
253 return error;
254
255 const sa_family_t family = AF_INET;
256 const int socktype = SOCK_STREAM;
257 const int protocol = IPPROTO_TCP;
258 SocketAddress listen_addr;
259 if (host_str.empty())
260 listen_addr.SetToLocalhost(family, port);
261 else if (host_str.compare("*") == 0)
262 listen_addr.SetToAnyAddress(family, port);
263 else
264 {
265 if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol))
266 {
267 error.SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str());
268 return error;
269 }
270 }
271
272 bool accept_connection = false;
273 std::unique_ptr<Socket> accepted_socket;
274
275 // Loop until we are happy with our connection
276 while (!accept_connection)
277 {
278 struct sockaddr_in accept_addr;
279 ::memset (&accept_addr, 0, sizeof accept_addr);
280#if !(defined (__linux__) || defined(_WIN32))
281 accept_addr.sin_len = sizeof accept_addr;
282#endif
283 socklen_t accept_addr_len = sizeof accept_addr;
284
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000285 int sock = Accept (this->GetNativeSocket(),
286 (struct sockaddr *)&accept_addr,
287 &accept_addr_len,
288 child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000289
290 if (sock == kInvalidSocketValue)
291 {
292 // TODO: On Windows, use WSAGetLastError()
293 error.SetErrorToErrno();
294 break;
295 }
296
297 bool is_same_addr = true;
298#if !(defined(__linux__) || (defined(_WIN32)))
299 is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len);
300#endif
301 if (is_same_addr)
302 is_same_addr = (accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr);
303
304 if (is_same_addr || (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY))
305 {
306 accept_connection = true;
307 // Since both sockets have the same descriptor, arbitrarily choose the send
308 // socket to be the owner.
309 accepted_socket.reset(new Socket(sock, ProtocolTcp, true));
310 }
311 else
312 {
313 const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
314 const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
315 ::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
316 accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
317 listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
318 accepted_socket.reset();
319 }
320 }
321
322 if (!accepted_socket)
323 return error;
324
325 // Keep our TCP packets coming without any delays.
326 accepted_socket->SetOption (IPPROTO_TCP, TCP_NODELAY, 1);
327 error.Clear();
328 socket = accepted_socket.release();
329 return error;
330
331}
332
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000333Error Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
Zachary Turner98688922014-08-06 18:16:26 +0000334{
335 std::unique_ptr<Socket> final_send_socket;
336 std::unique_ptr<Socket> final_recv_socket;
337 NativeSocket final_send_fd = kInvalidSocketValue;
338 NativeSocket final_recv_fd = kInvalidSocketValue;
339
340 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
341 if (log)
342 log->Printf ("Socket::UdpConnect (host/port = %s)", host_and_port.data());
343
344 Error error;
345 std::string host_str;
346 std::string port_str;
347 int32_t port = INT32_MIN;
348 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
349 return error;
350
351 // Setup the receiving end of the UDP connection on this localhost
352 // on port zero. After we bind to port zero we can read the port.
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000353 final_recv_fd = ::CreateSocket (AF_INET, SOCK_DGRAM, 0, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000354 if (final_recv_fd == kInvalidSocketValue)
355 {
356 // Socket creation failed...
357 // TODO: On Windows, use WSAGetLastError().
358 error.SetErrorToErrno();
359 }
360 else
361 {
362 final_recv_socket.reset(new Socket(final_recv_fd, ProtocolUdp, true));
363
364 // Socket was created, now lets bind to the requested port
365 SocketAddress addr;
366 addr.SetToAnyAddress (AF_INET, 0);
367
368 if (::bind (final_recv_fd, addr, addr.GetLength()) == -1)
369 {
370 // Bind failed...
371 // TODO: On Windows use WSAGetLastError()
372 error.SetErrorToErrno();
373 }
374 }
375
376 assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
377 if (error.Fail())
378 return error;
379
380 // At this point we have setup the receive port, now we need to
381 // setup the UDP send socket
382
383 struct addrinfo hints;
384 struct addrinfo *service_info_list = NULL;
385
386 ::memset (&hints, 0, sizeof(hints));
387 hints.ai_family = AF_INET;
388 hints.ai_socktype = SOCK_DGRAM;
389 int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
390 if (err != 0)
391 {
392 error.SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
393 host_str.c_str(),
394 port_str.c_str(),
395 err,
396 gai_strerror(err));
397 return error;
398 }
399
400 for (struct addrinfo *service_info_ptr = service_info_list;
401 service_info_ptr != NULL;
402 service_info_ptr = service_info_ptr->ai_next)
403 {
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000404 final_send_fd = ::CreateSocket (service_info_ptr->ai_family,
405 service_info_ptr->ai_socktype,
406 service_info_ptr->ai_protocol,
407 child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000408
409 if (final_send_fd != kInvalidSocketValue)
410 {
411 final_send_socket.reset(new Socket(final_send_fd, ProtocolUdp, true));
412 final_send_socket->m_udp_send_sockaddr = service_info_ptr;
413 break;
414 }
415 else
416 continue;
417 }
418
419 :: freeaddrinfo (service_info_list);
420
421 if (final_send_fd == kInvalidSocketValue)
422 {
423 // TODO: On Windows, use WSAGetLastError().
424 error.SetErrorToErrno();
425 return error;
426 }
427
428 send_socket = final_send_socket.release();
429 recv_socket = final_recv_socket.release();
430 error.Clear();
431 return error;
432}
433
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000434Error Socket::UnixDomainConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
Zachary Turner98688922014-08-06 18:16:26 +0000435{
436 Error error;
437#ifndef LLDB_DISABLE_POSIX
438 std::unique_ptr<Socket> final_socket;
439
440 // Open the socket that was passed in as an option
441 struct sockaddr_un saddr_un;
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000442 int fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000443 if (fd == kInvalidSocketValue)
444 {
445 error.SetErrorToErrno();
446 return error;
447 }
448
449 final_socket.reset(new Socket(fd, ProtocolUnixDomain, true));
450
451 saddr_un.sun_family = AF_UNIX;
452 ::strncpy(saddr_un.sun_path, name.data(), sizeof(saddr_un.sun_path) - 1);
453 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
454#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
455 saddr_un.sun_len = SUN_LEN (&saddr_un);
456#endif
457
458 if (::connect (fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
459 {
460 error.SetErrorToErrno();
461 return error;
462 }
463
464 socket = final_socket.release();
465#else
466 error.SetErrorString("Unix domain sockets are not supported on this platform.");
467#endif
468 return error;
469}
470
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000471Error Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
Zachary Turner98688922014-08-06 18:16:26 +0000472{
473 Error error;
474#ifndef LLDB_DISABLE_POSIX
475 struct sockaddr_un saddr_un;
476 std::unique_ptr<Socket> listen_socket;
477 std::unique_ptr<Socket> final_socket;
478 NativeSocket listen_fd = kInvalidSocketValue;
479 NativeSocket socket_fd = kInvalidSocketValue;
480
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000481 listen_fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000482 if (listen_fd == kInvalidSocketValue)
483 {
484 error.SetErrorToErrno();
485 return error;
486 }
487
488 listen_socket.reset(new Socket(listen_fd, ProtocolUnixDomain, true));
489
490 saddr_un.sun_family = AF_UNIX;
491 ::strncpy(saddr_un.sun_path, name.data(), sizeof(saddr_un.sun_path) - 1);
492 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
493#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
494 saddr_un.sun_len = SUN_LEN (&saddr_un);
495#endif
496
Zachary Turnerc00cf4a2014-08-15 22:04:21 +0000497 FileSystem::Unlink(name.data());
Zachary Turner98688922014-08-06 18:16:26 +0000498 bool success = false;
499 if (::bind (listen_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
500 {
501 if (::listen (listen_fd, 5) == 0)
502 {
Oleksiy Vyalov477e42a2014-11-14 16:25:18 +0000503 socket_fd = Accept (listen_fd, NULL, 0, child_processes_inherit);
Zachary Turner98688922014-08-06 18:16:26 +0000504 if (socket_fd > 0)
505 {
506 final_socket.reset(new Socket(socket_fd, ProtocolUnixDomain, true));
507 success = true;
508 }
509 }
510 }
511
512 if (!success)
513 {
514 error.SetErrorToErrno();
515 return error;
516 }
517 // We are done with the listen port
518 listen_socket.reset();
519
520 socket = final_socket.release();
521#else
522 error.SetErrorString("Unix domain sockets are not supported on this platform.");
523#endif
524 return error;
525}
526
527bool
528Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
529 std::string &host_str,
530 std::string &port_str,
531 int32_t& port,
532 Error *error_ptr)
533{
534 static RegularExpression g_regex ("([^:]+):([0-9]+)");
535 RegularExpression::Match regex_match(2);
536 if (g_regex.Execute (host_and_port.data(), &regex_match))
537 {
538 if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
539 regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
540 {
Vince Harron014bb7d2015-01-16 00:47:08 +0000541 bool ok = false;
542 port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
543 if (ok && port < UINT16_MAX)
Zachary Turner98688922014-08-06 18:16:26 +0000544 {
545 if (error_ptr)
546 error_ptr->Clear();
547 return true;
548 }
Vince Harron014bb7d2015-01-16 00:47:08 +0000549 // port is too large
550 if (error_ptr)
551 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
552 return false;
Zachary Turner98688922014-08-06 18:16:26 +0000553 }
554 }
555
556 // If this was unsuccessful, then check if it's simply a signed 32-bit integer, representing
557 // a port with an empty host.
558 host_str.clear();
559 port_str.clear();
Vince Harron014bb7d2015-01-16 00:47:08 +0000560 bool ok = false;
561 port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
562 if (ok && port < UINT16_MAX)
Zachary Turner98688922014-08-06 18:16:26 +0000563 {
564 port_str = host_and_port;
Vince Harron014bb7d2015-01-16 00:47:08 +0000565 if (error_ptr)
566 error_ptr->Clear();
Zachary Turner98688922014-08-06 18:16:26 +0000567 return true;
568 }
569
570 if (error_ptr)
571 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
572 return false;
573}
574
575IOObject::WaitableHandle Socket::GetWaitableHandle()
576{
577 // TODO: On Windows, use WSAEventSelect
578 return m_socket;
579}
580
581Error Socket::Read (void *buf, size_t &num_bytes)
582{
583 Error error;
584 int bytes_received = 0;
585 do
586 {
587 bytes_received = ::recv (m_socket, static_cast<char *>(buf), num_bytes, 0);
588 // TODO: Use WSAGetLastError on windows.
589 } while (bytes_received < 0 && errno == EINTR);
590
591 if (bytes_received < 0)
592 {
593 error.SetErrorToErrno();
594 num_bytes = 0;
595 }
596 else
597 num_bytes = bytes_received;
598
599 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_COMMUNICATION));
600 if (log)
601 {
602 log->Printf ("%p Socket::Read() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
603 static_cast<void*>(this),
604 static_cast<uint64_t>(m_socket),
605 buf,
606 static_cast<uint64_t>(num_bytes),
607 static_cast<int64_t>(bytes_received),
608 error.AsCString());
609 }
610
611 return error;
612}
613
614Error Socket::Write (const void *buf, size_t &num_bytes)
615{
616 Error error;
617 int bytes_sent = 0;
618 do
619 {
620 if (m_protocol == ProtocolUdp)
621 {
622 bytes_sent = ::sendto (m_socket,
623 static_cast<const char*>(buf),
624 num_bytes,
625 0,
626 m_udp_send_sockaddr,
627 m_udp_send_sockaddr.GetLength());
628 }
629 else
630 bytes_sent = ::send (m_socket, static_cast<const char *>(buf), num_bytes, 0);
631 // TODO: Use WSAGetLastError on windows.
632 } while (bytes_sent < 0 && errno == EINTR);
633
634 if (bytes_sent < 0)
635 {
636 // TODO: On Windows, use WSAGEtLastError.
637 error.SetErrorToErrno();
638 num_bytes = 0;
639 }
640 else
641 num_bytes = bytes_sent;
642
643 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
644 if (log)
645 {
646 log->Printf ("%p Socket::Write() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
647 static_cast<void*>(this),
648 static_cast<uint64_t>(m_socket),
649 buf,
650 static_cast<uint64_t>(num_bytes),
651 static_cast<int64_t>(bytes_sent),
652 error.AsCString());
653 }
654
655 return error;
656}
657
658Error Socket::PreDisconnect()
659{
660 Error error;
661 return error;
662}
663
664Error Socket::Close()
665{
666 Error error;
667 if (!IsValid() || !m_should_close_fd)
668 return error;
669
670 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
671 if (log)
672 log->Printf ("%p Socket::Close (fd = %i)", static_cast<void*>(this), m_socket);
673
674#if defined(_WIN32)
675 bool success = !!closesocket(m_socket);
676#else
677 bool success = !!::close (m_socket);
678#endif
679 // A reference to a FD was passed in, set it to an invalid value
680 m_socket = kInvalidSocketValue;
681 if (!success)
682 {
683 // TODO: On Windows, use WSAGetLastError().
684 error.SetErrorToErrno();
685 }
686
687 return error;
688}
689
690
691int Socket::GetOption(int level, int option_name, int &option_value)
692{
693 get_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
694 socklen_t option_value_size = sizeof(int);
695 return ::getsockopt(m_socket, level, option_name, option_value_p, &option_value_size);
696}
697
698int Socket::SetOption(int level, int option_name, int option_value)
699{
700 set_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
701 return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
702}
703
Vince Harron014bb7d2015-01-16 00:47:08 +0000704uint16_t Socket::GetLocalPortNumber(const NativeSocket& socket)
Zachary Turner98688922014-08-06 18:16:26 +0000705{
706 // We bound to port zero, so we need to figure out which port we actually bound to
Zachary Turner48b475c2015-04-02 20:57:38 +0000707 if (socket != kInvalidSocketValue)
Zachary Turner98688922014-08-06 18:16:26 +0000708 {
709 SocketAddress sock_addr;
710 socklen_t sock_addr_len = sock_addr.GetMaxLength ();
711 if (::getsockname (socket, sock_addr, &sock_addr_len) == 0)
712 return sock_addr.GetPort ();
713 }
714 return 0;
715}
716
717// Return the port number that is being used by the socket.
Vince Harron014bb7d2015-01-16 00:47:08 +0000718uint16_t Socket::GetLocalPortNumber() const
Zachary Turner98688922014-08-06 18:16:26 +0000719{
Vince Harron014bb7d2015-01-16 00:47:08 +0000720 return GetLocalPortNumber (m_socket);
Zachary Turner98688922014-08-06 18:16:26 +0000721}
Vince Harron014bb7d2015-01-16 00:47:08 +0000722
723std::string Socket::GetLocalIPAddress () const
724{
725 // We bound to port zero, so we need to figure out which port we actually bound to
Zachary Turner48b475c2015-04-02 20:57:38 +0000726 if (m_socket != kInvalidSocketValue)
Vince Harron014bb7d2015-01-16 00:47:08 +0000727 {
728 SocketAddress sock_addr;
729 socklen_t sock_addr_len = sock_addr.GetMaxLength ();
730 if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
731 return sock_addr.GetIPAddress ();
732 }
733 return "";
734}
735
736uint16_t Socket::GetRemotePortNumber () const
737{
Zachary Turner48b475c2015-04-02 20:57:38 +0000738 if (m_socket != kInvalidSocketValue)
Vince Harron014bb7d2015-01-16 00:47:08 +0000739 {
740 SocketAddress sock_addr;
741 socklen_t sock_addr_len = sock_addr.GetMaxLength ();
742 if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
743 return sock_addr.GetPort ();
744 }
745 return 0;
746}
747
748std::string Socket::GetRemoteIPAddress () const
749{
750 // We bound to port zero, so we need to figure out which port we actually bound to
Zachary Turner48b475c2015-04-02 20:57:38 +0000751 if (m_socket != kInvalidSocketValue)
Vince Harron014bb7d2015-01-16 00:47:08 +0000752 {
753 SocketAddress sock_addr;
754 socklen_t sock_addr_len = sock_addr.GetMaxLength ();
755 if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
756 return sock_addr.GetIPAddress ();
757 }
758 return "";
759}
760
761