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/Support/Errno.h" 21 #include "llvm/Support/Error.h" 22 #include "llvm/Support/Regex.h" 23 #include "llvm/Support/WindowsError.h" 24 25 #if LLDB_ENABLE_POSIX 26 #include "lldb/Host/posix/DomainSocket.h" 27 28 #include <arpa/inet.h> 29 #include <netdb.h> 30 #include <netinet/in.h> 31 #include <netinet/tcp.h> 32 #include <sys/socket.h> 33 #include <sys/un.h> 34 #include <unistd.h> 35 #endif 36 37 #ifdef __linux__ 38 #include "lldb/Host/linux/AbstractSocket.h" 39 #endif 40 41 #ifdef __ANDROID__ 42 #include <arpa/inet.h> 43 #include <asm-generic/errno-base.h> 44 #include <cerrno> 45 #include <fcntl.h> 46 #include <linux/tcp.h> 47 #include <sys/syscall.h> 48 #include <unistd.h> 49 #endif // __ANDROID__ 50 51 using namespace lldb; 52 using namespace lldb_private; 53 54 #if defined(_WIN32) 55 typedef const char *set_socket_option_arg_type; 56 typedef char *get_socket_option_arg_type; 57 const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET; 58 #else // #if defined(_WIN32) 59 typedef const void *set_socket_option_arg_type; 60 typedef void *get_socket_option_arg_type; 61 const NativeSocket Socket::kInvalidSocketValue = -1; 62 #endif // #if defined(_WIN32) 63 64 static bool IsInterrupted() { 65 #if defined(_WIN32) 66 return ::WSAGetLastError() == WSAEINTR; 67 #else 68 return errno == EINTR; 69 #endif 70 } 71 72 Socket::Socket(SocketProtocol protocol, bool should_close, 73 bool child_processes_inherit) 74 : IOObject(eFDTypeSocket), m_protocol(protocol), 75 m_socket(kInvalidSocketValue), 76 m_child_processes_inherit(child_processes_inherit), 77 m_should_close_fd(should_close) {} 78 79 Socket::~Socket() { Close(); } 80 81 llvm::Error Socket::Initialize() { 82 #if defined(_WIN32) 83 auto wVersion = WINSOCK_VERSION; 84 WSADATA wsaData; 85 int err = ::WSAStartup(wVersion, &wsaData); 86 if (err == 0) { 87 if (wsaData.wVersion < wVersion) { 88 WSACleanup(); 89 return llvm::make_error<llvm::StringError>( 90 "WSASock version is not expected.", llvm::inconvertibleErrorCode()); 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::PreDisconnect() { 272 Status error; 273 return error; 274 } 275 276 Status Socket::Close() { 277 Status error; 278 if (!IsValid() || !m_should_close_fd) 279 return error; 280 281 Log *log = GetLog(LLDBLog::Connection); 282 LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", 283 static_cast<void *>(this), static_cast<uint64_t>(m_socket)); 284 285 #if defined(_WIN32) 286 bool success = closesocket(m_socket) == 0; 287 #else 288 bool success = ::close(m_socket) == 0; 289 #endif 290 // A reference to a FD was passed in, set it to an invalid value 291 m_socket = kInvalidSocketValue; 292 if (!success) { 293 SetLastError(error); 294 } 295 296 return error; 297 } 298 299 int Socket::GetOption(int level, int option_name, int &option_value) { 300 get_socket_option_arg_type option_value_p = 301 reinterpret_cast<get_socket_option_arg_type>(&option_value); 302 socklen_t option_value_size = sizeof(int); 303 return ::getsockopt(m_socket, level, option_name, option_value_p, 304 &option_value_size); 305 } 306 307 int Socket::SetOption(int level, int option_name, int option_value) { 308 set_socket_option_arg_type option_value_p = 309 reinterpret_cast<get_socket_option_arg_type>(&option_value); 310 return ::setsockopt(m_socket, level, option_name, option_value_p, 311 sizeof(option_value)); 312 } 313 314 size_t Socket::Send(const void *buf, const size_t num_bytes) { 315 return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0); 316 } 317 318 void Socket::SetLastError(Status &error) { 319 #if defined(_WIN32) 320 error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32); 321 #else 322 error.SetErrorToErrno(); 323 #endif 324 } 325 326 NativeSocket Socket::CreateSocket(const int domain, const int type, 327 const int protocol, 328 bool child_processes_inherit, Status &error) { 329 error.Clear(); 330 auto socket_type = type; 331 #ifdef SOCK_CLOEXEC 332 if (!child_processes_inherit) 333 socket_type |= SOCK_CLOEXEC; 334 #endif 335 auto sock = ::socket(domain, socket_type, protocol); 336 if (sock == kInvalidSocketValue) 337 SetLastError(error); 338 339 return sock; 340 } 341 342 NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, 343 socklen_t *addrlen, 344 bool child_processes_inherit, Status &error) { 345 error.Clear(); 346 #if defined(ANDROID_USE_ACCEPT_WORKAROUND) 347 // Hack: 348 // This enables static linking lldb-server to an API 21 libc, but still 349 // having it run on older devices. It is necessary because API 21 libc's 350 // implementation of accept() uses the accept4 syscall(), which is not 351 // available in older kernels. Using an older libc would fix this issue, but 352 // introduce other ones, as the old libraries were quite buggy. 353 int fd = syscall(__NR_accept, sockfd, addr, addrlen); 354 if (fd >= 0 && !child_processes_inherit) { 355 int flags = ::fcntl(fd, F_GETFD); 356 if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1) 357 return fd; 358 SetLastError(error); 359 close(fd); 360 } 361 return fd; 362 #elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) 363 int flags = 0; 364 if (!child_processes_inherit) { 365 flags |= SOCK_CLOEXEC; 366 } 367 NativeSocket fd = llvm::sys::RetryAfterSignal( 368 static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags); 369 #else 370 NativeSocket fd = llvm::sys::RetryAfterSignal( 371 static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen); 372 #endif 373 if (fd == kInvalidSocketValue) 374 SetLastError(error); 375 return fd; 376 } 377 378 llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, 379 const Socket::HostAndPort &HP) { 380 return OS << '[' << HP.hostname << ']' << ':' << HP.port; 381 } 382