1 //===-- Socket.cpp --------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Host/Socket.h" 10 11 #include "lldb/Host/Config.h" 12 #include "lldb/Host/Host.h" 13 #include "lldb/Host/SocketAddress.h" 14 #include "lldb/Host/common/TCPSocket.h" 15 #include "lldb/Host/common/UDPSocket.h" 16 #include "lldb/Utility/LLDBLog.h" 17 #include "lldb/Utility/Log.h" 18 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/Support/Errno.h" 22 #include "llvm/Support/Error.h" 23 #include "llvm/Support/Regex.h" 24 #include "llvm/Support/WindowsError.h" 25 26 #if LLDB_ENABLE_POSIX 27 #include "lldb/Host/posix/DomainSocket.h" 28 29 #include <arpa/inet.h> 30 #include <netdb.h> 31 #include <netinet/in.h> 32 #include <netinet/tcp.h> 33 #include <sys/socket.h> 34 #include <sys/un.h> 35 #include <unistd.h> 36 #endif 37 38 #ifdef __linux__ 39 #include "lldb/Host/linux/AbstractSocket.h" 40 #endif 41 42 #ifdef __ANDROID__ 43 #include <arpa/inet.h> 44 #include <asm-generic/errno-base.h> 45 #include <cerrno> 46 #include <fcntl.h> 47 #include <linux/tcp.h> 48 #include <sys/syscall.h> 49 #include <unistd.h> 50 #endif // __ANDROID__ 51 52 using namespace lldb; 53 using namespace lldb_private; 54 55 #if defined(_WIN32) 56 typedef const char *set_socket_option_arg_type; 57 typedef char *get_socket_option_arg_type; 58 const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET; 59 #else // #if defined(_WIN32) 60 typedef const void *set_socket_option_arg_type; 61 typedef void *get_socket_option_arg_type; 62 const NativeSocket Socket::kInvalidSocketValue = -1; 63 #endif // #if defined(_WIN32) 64 65 static bool IsInterrupted() { 66 #if defined(_WIN32) 67 return ::WSAGetLastError() == WSAEINTR; 68 #else 69 return errno == EINTR; 70 #endif 71 } 72 73 Socket::Socket(SocketProtocol protocol, bool should_close, 74 bool child_processes_inherit) 75 : IOObject(eFDTypeSocket), m_protocol(protocol), 76 m_socket(kInvalidSocketValue), 77 m_child_processes_inherit(child_processes_inherit), 78 m_should_close_fd(should_close) {} 79 80 Socket::~Socket() { Close(); } 81 82 llvm::Error Socket::Initialize() { 83 #if defined(_WIN32) 84 auto wVersion = WINSOCK_VERSION; 85 WSADATA wsaData; 86 int err = ::WSAStartup(wVersion, &wsaData); 87 if (err == 0) { 88 if (wsaData.wVersion < wVersion) { 89 WSACleanup(); 90 return llvm::createStringError("WSASock version is not expected."); 91 } 92 } else { 93 return llvm::errorCodeToError(llvm::mapWindowsError(::WSAGetLastError())); 94 } 95 #endif 96 97 return llvm::Error::success(); 98 } 99 100 void Socket::Terminate() { 101 #if defined(_WIN32) 102 ::WSACleanup(); 103 #endif 104 } 105 106 std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, 107 bool child_processes_inherit, 108 Status &error) { 109 error.Clear(); 110 111 std::unique_ptr<Socket> socket_up; 112 switch (protocol) { 113 case ProtocolTcp: 114 socket_up = 115 std::make_unique<TCPSocket>(true, child_processes_inherit); 116 break; 117 case ProtocolUdp: 118 socket_up = 119 std::make_unique<UDPSocket>(true, child_processes_inherit); 120 break; 121 case ProtocolUnixDomain: 122 #if LLDB_ENABLE_POSIX 123 socket_up = 124 std::make_unique<DomainSocket>(true, child_processes_inherit); 125 #else 126 error.SetErrorString( 127 "Unix domain sockets are not supported on this platform."); 128 #endif 129 break; 130 case ProtocolUnixAbstract: 131 #ifdef __linux__ 132 socket_up = 133 std::make_unique<AbstractSocket>(child_processes_inherit); 134 #else 135 error.SetErrorString( 136 "Abstract domain sockets are not supported on this platform."); 137 #endif 138 break; 139 } 140 141 if (error.Fail()) 142 socket_up.reset(); 143 144 return socket_up; 145 } 146 147 llvm::Expected<std::unique_ptr<Socket>> 148 Socket::TcpConnect(llvm::StringRef host_and_port, 149 bool child_processes_inherit) { 150 Log *log = GetLog(LLDBLog::Connection); 151 LLDB_LOG(log, "host_and_port = {0}", host_and_port); 152 153 Status error; 154 std::unique_ptr<Socket> connect_socket( 155 Create(ProtocolTcp, child_processes_inherit, error)); 156 if (error.Fail()) 157 return error.ToError(); 158 159 error = connect_socket->Connect(host_and_port); 160 if (error.Success()) 161 return std::move(connect_socket); 162 163 return error.ToError(); 164 } 165 166 llvm::Expected<std::unique_ptr<TCPSocket>> 167 Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, 168 int backlog) { 169 Log *log = GetLog(LLDBLog::Connection); 170 LLDB_LOG(log, "host_and_port = {0}", host_and_port); 171 172 std::unique_ptr<TCPSocket> listen_socket( 173 new TCPSocket(true, child_processes_inherit)); 174 175 Status error = listen_socket->Listen(host_and_port, backlog); 176 if (error.Fail()) 177 return error.ToError(); 178 179 return std::move(listen_socket); 180 } 181 182 llvm::Expected<std::unique_ptr<UDPSocket>> 183 Socket::UdpConnect(llvm::StringRef host_and_port, 184 bool child_processes_inherit) { 185 return UDPSocket::Connect(host_and_port, child_processes_inherit); 186 } 187 188 llvm::Expected<Socket::HostAndPort> Socket::DecodeHostAndPort(llvm::StringRef host_and_port) { 189 static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)"); 190 HostAndPort ret; 191 llvm::SmallVector<llvm::StringRef, 3> matches; 192 if (g_regex.match(host_and_port, &matches)) { 193 ret.hostname = matches[1].str(); 194 // IPv6 addresses are wrapped in [] when specified with ports 195 if (ret.hostname.front() == '[' && ret.hostname.back() == ']') 196 ret.hostname = ret.hostname.substr(1, ret.hostname.size() - 2); 197 if (to_integer(matches[2], ret.port, 10)) 198 return ret; 199 } else { 200 // If this was unsuccessful, then check if it's simply an unsigned 16-bit 201 // integer, representing a port with an empty host. 202 if (to_integer(host_and_port, ret.port, 10)) 203 return ret; 204 } 205 206 return llvm::createStringError(llvm::inconvertibleErrorCode(), 207 "invalid host:port specification: '%s'", 208 host_and_port.str().c_str()); 209 } 210 211 IOObject::WaitableHandle Socket::GetWaitableHandle() { 212 // TODO: On Windows, use WSAEventSelect 213 return m_socket; 214 } 215 216 Status Socket::Read(void *buf, size_t &num_bytes) { 217 Status error; 218 int bytes_received = 0; 219 do { 220 bytes_received = ::recv(m_socket, static_cast<char *>(buf), num_bytes, 0); 221 } while (bytes_received < 0 && IsInterrupted()); 222 223 if (bytes_received < 0) { 224 SetLastError(error); 225 num_bytes = 0; 226 } else 227 num_bytes = bytes_received; 228 229 Log *log = GetLog(LLDBLog::Communication); 230 if (log) { 231 LLDB_LOGF(log, 232 "%p Socket::Read() (socket = %" PRIu64 233 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 234 " (error = %s)", 235 static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, 236 static_cast<uint64_t>(num_bytes), 237 static_cast<int64_t>(bytes_received), error.AsCString()); 238 } 239 240 return error; 241 } 242 243 Status Socket::Write(const void *buf, size_t &num_bytes) { 244 const size_t src_len = num_bytes; 245 Status error; 246 int bytes_sent = 0; 247 do { 248 bytes_sent = Send(buf, num_bytes); 249 } while (bytes_sent < 0 && IsInterrupted()); 250 251 if (bytes_sent < 0) { 252 SetLastError(error); 253 num_bytes = 0; 254 } else 255 num_bytes = bytes_sent; 256 257 Log *log = GetLog(LLDBLog::Communication); 258 if (log) { 259 LLDB_LOGF(log, 260 "%p Socket::Write() (socket = %" PRIu64 261 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 262 " (error = %s)", 263 static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, 264 static_cast<uint64_t>(src_len), 265 static_cast<int64_t>(bytes_sent), error.AsCString()); 266 } 267 268 return error; 269 } 270 271 Status Socket::Close() { 272 Status error; 273 if (!IsValid() || !m_should_close_fd) 274 return error; 275 276 Log *log = GetLog(LLDBLog::Connection); 277 LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", 278 static_cast<void *>(this), static_cast<uint64_t>(m_socket)); 279 280 #if defined(_WIN32) 281 bool success = closesocket(m_socket) == 0; 282 #else 283 bool success = ::close(m_socket) == 0; 284 #endif 285 // A reference to a FD was passed in, set it to an invalid value 286 m_socket = kInvalidSocketValue; 287 if (!success) { 288 SetLastError(error); 289 } 290 291 return error; 292 } 293 294 int Socket::GetOption(int level, int option_name, int &option_value) { 295 get_socket_option_arg_type option_value_p = 296 reinterpret_cast<get_socket_option_arg_type>(&option_value); 297 socklen_t option_value_size = sizeof(int); 298 return ::getsockopt(m_socket, level, option_name, option_value_p, 299 &option_value_size); 300 } 301 302 int Socket::SetOption(int level, int option_name, int option_value) { 303 set_socket_option_arg_type option_value_p = 304 reinterpret_cast<get_socket_option_arg_type>(&option_value); 305 return ::setsockopt(m_socket, level, option_name, option_value_p, 306 sizeof(option_value)); 307 } 308 309 size_t Socket::Send(const void *buf, const size_t num_bytes) { 310 return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0); 311 } 312 313 void Socket::SetLastError(Status &error) { 314 #if defined(_WIN32) 315 error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32); 316 #else 317 error.SetErrorToErrno(); 318 #endif 319 } 320 321 NativeSocket Socket::CreateSocket(const int domain, const int type, 322 const int protocol, 323 bool child_processes_inherit, Status &error) { 324 error.Clear(); 325 auto socket_type = type; 326 #ifdef SOCK_CLOEXEC 327 if (!child_processes_inherit) 328 socket_type |= SOCK_CLOEXEC; 329 #endif 330 auto sock = ::socket(domain, socket_type, protocol); 331 if (sock == kInvalidSocketValue) 332 SetLastError(error); 333 334 return sock; 335 } 336 337 NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, 338 socklen_t *addrlen, 339 bool child_processes_inherit, Status &error) { 340 error.Clear(); 341 #if defined(ANDROID_USE_ACCEPT_WORKAROUND) 342 // Hack: 343 // This enables static linking lldb-server to an API 21 libc, but still 344 // having it run on older devices. It is necessary because API 21 libc's 345 // implementation of accept() uses the accept4 syscall(), which is not 346 // available in older kernels. Using an older libc would fix this issue, but 347 // introduce other ones, as the old libraries were quite buggy. 348 int fd = syscall(__NR_accept, sockfd, addr, addrlen); 349 if (fd >= 0 && !child_processes_inherit) { 350 int flags = ::fcntl(fd, F_GETFD); 351 if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1) 352 return fd; 353 SetLastError(error); 354 close(fd); 355 } 356 return fd; 357 #elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) 358 int flags = 0; 359 if (!child_processes_inherit) { 360 flags |= SOCK_CLOEXEC; 361 } 362 NativeSocket fd = llvm::sys::RetryAfterSignal( 363 static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags); 364 #else 365 NativeSocket fd = llvm::sys::RetryAfterSignal( 366 static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen); 367 #endif 368 if (fd == kInvalidSocketValue) 369 SetLastError(error); 370 return fd; 371 } 372 373 llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, 374 const Socket::HostAndPort &HP) { 375 return OS << '[' << HP.hostname << ']' << ':' << HP.port; 376 } 377