1 //===-- TCPSocket.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 #if defined(_MSC_VER) 11 #define _WINSOCK_DEPRECATED_NO_WARNINGS 12 #endif 13 14 #include "lldb/Host/common/TCPSocket.h" 15 16 #include "lldb/Host/Config.h" 17 #include "lldb/Host/MainLoop.h" 18 #include "lldb/Utility/Log.h" 19 20 #include "llvm/Config/config.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 #ifndef LLDB_DISABLE_POSIX 24 #include <arpa/inet.h> 25 #include <netinet/tcp.h> 26 #include <sys/socket.h> 27 #endif 28 29 #if defined(LLVM_ON_WIN32) 30 #include <winsock2.h> 31 #endif 32 33 #ifdef LLVM_ON_WIN32 34 #define CLOSE_SOCKET closesocket 35 #else 36 #define CLOSE_SOCKET ::close 37 #endif 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 namespace { 43 const int kType = SOCK_STREAM; 44 } 45 46 TCPSocket::TCPSocket(bool should_close, bool child_processes_inherit) 47 : Socket(ProtocolTcp, should_close, child_processes_inherit) {} 48 49 TCPSocket::TCPSocket(NativeSocket socket, const TCPSocket &listen_socket) 50 : Socket(ProtocolTcp, listen_socket.m_should_close_fd, 51 listen_socket.m_child_processes_inherit) { 52 m_socket = socket; 53 } 54 55 TCPSocket::TCPSocket(NativeSocket socket, bool should_close, 56 bool child_processes_inherit) 57 : Socket(ProtocolTcp, should_close, child_processes_inherit) { 58 m_socket = socket; 59 } 60 61 TCPSocket::~TCPSocket() { CloseListenSockets(); } 62 63 bool TCPSocket::IsValid() const { 64 return m_socket != kInvalidSocketValue || m_listen_sockets.size() != 0; 65 } 66 67 // Return the port number that is being used by the socket. 68 uint16_t TCPSocket::GetLocalPortNumber() const { 69 if (m_socket != kInvalidSocketValue) { 70 SocketAddress sock_addr; 71 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 72 if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0) 73 return sock_addr.GetPort(); 74 } else if (!m_listen_sockets.empty()) { 75 SocketAddress sock_addr; 76 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 77 if (::getsockname(m_listen_sockets.begin()->first, sock_addr, 78 &sock_addr_len) == 0) 79 return sock_addr.GetPort(); 80 } 81 return 0; 82 } 83 84 std::string TCPSocket::GetLocalIPAddress() const { 85 // We bound to port zero, so we need to figure out which port we actually 86 // bound to 87 if (m_socket != kInvalidSocketValue) { 88 SocketAddress sock_addr; 89 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 90 if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0) 91 return sock_addr.GetIPAddress(); 92 } 93 return ""; 94 } 95 96 uint16_t TCPSocket::GetRemotePortNumber() const { 97 if (m_socket != kInvalidSocketValue) { 98 SocketAddress sock_addr; 99 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 100 if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0) 101 return sock_addr.GetPort(); 102 } 103 return 0; 104 } 105 106 std::string TCPSocket::GetRemoteIPAddress() const { 107 // We bound to port zero, so we need to figure out which port we actually 108 // bound to 109 if (m_socket != kInvalidSocketValue) { 110 SocketAddress sock_addr; 111 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 112 if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0) 113 return sock_addr.GetIPAddress(); 114 } 115 return ""; 116 } 117 118 Error TCPSocket::CreateSocket(int domain) { 119 Error error; 120 if (IsValid()) 121 error = Close(); 122 if (error.Fail()) 123 return error; 124 m_socket = Socket::CreateSocket(domain, kType, IPPROTO_TCP, 125 m_child_processes_inherit, error); 126 return error; 127 } 128 129 Error TCPSocket::Connect(llvm::StringRef name) { 130 131 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); 132 if (log) 133 log->Printf("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); 134 135 Error error; 136 std::string host_str; 137 std::string port_str; 138 int32_t port = INT32_MIN; 139 if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) 140 return error; 141 142 auto addresses = 143 lldb_private::SocketAddress::GetAddressInfo(host_str.c_str(), NULL); 144 for (auto address : addresses) { 145 error = CreateSocket(address.GetFamily()); 146 if (error.Fail()) 147 continue; 148 149 address.SetPort(port); 150 151 if (-1 == ::connect(GetNativeSocket(), &address.sockaddr(), 152 address.GetLength())) { 153 continue; 154 } 155 156 SetOptionNoDelay(); 157 158 error.Clear(); 159 return error; 160 } 161 162 error.SetErrorString("Failed to connect port"); 163 return error; 164 } 165 166 Error TCPSocket::Listen(llvm::StringRef name, int backlog) { 167 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 168 if (log) 169 log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data()); 170 171 Error error; 172 std::string host_str; 173 std::string port_str; 174 int32_t port = INT32_MIN; 175 if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) 176 return error; 177 178 auto addresses = 179 lldb_private::SocketAddress::GetAddressInfo(host_str.c_str(), NULL); 180 for (auto address : addresses) { 181 int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP, 182 m_child_processes_inherit, error); 183 if (error.Fail()) { 184 error.Clear(); 185 continue; 186 } 187 188 // enable local address reuse 189 SetOptionReuseAddress(); 190 191 address.SetPort(port); 192 193 int err = ::bind(fd, &address.sockaddr(), address.GetLength()); 194 if (-1 != err) 195 err = ::listen(fd, backlog); 196 197 if (-1 == err) { 198 CLOSE_SOCKET(fd); 199 continue; 200 } 201 202 if (port == 0) { 203 socklen_t sa_len = address.GetLength(); 204 if (getsockname(fd, &address.sockaddr(), &sa_len) == 0) 205 port = address.GetPort(); 206 } 207 m_listen_sockets[fd] = address; 208 } 209 210 if (m_listen_sockets.size() == 0) 211 error.SetErrorString("Failed to connect port"); 212 return error; 213 } 214 215 void TCPSocket::CloseListenSockets() { 216 for (auto socket : m_listen_sockets) 217 CLOSE_SOCKET(socket.first); 218 m_listen_sockets.clear(); 219 } 220 221 Error TCPSocket::Accept(Socket *&conn_socket) { 222 Error error; 223 if (m_listen_sockets.size() == 0) { 224 error.SetErrorString("No open listening sockets!"); 225 return error; 226 } 227 228 int sock = -1; 229 int listen_sock = -1; 230 lldb_private::SocketAddress AcceptAddr; 231 MainLoop accept_loop; 232 std::vector<MainLoopBase::ReadHandleUP> handles; 233 for (auto socket : m_listen_sockets) { 234 auto fd = socket.first; 235 auto inherit = this->m_child_processes_inherit; 236 auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit)); 237 handles.emplace_back(accept_loop.RegisterReadObject( 238 io_sp, [fd, inherit, &sock, &AcceptAddr, &error, 239 &listen_sock](MainLoopBase &loop) { 240 socklen_t sa_len = AcceptAddr.GetMaxLength(); 241 sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit, 242 error); 243 listen_sock = fd; 244 loop.RequestTermination(); 245 }, error)); 246 if (error.Fail()) 247 return error; 248 } 249 250 bool accept_connection = false; 251 std::unique_ptr<TCPSocket> accepted_socket; 252 // Loop until we are happy with our connection 253 while (!accept_connection) { 254 accept_loop.Run(); 255 256 if (error.Fail()) 257 return error; 258 259 lldb_private::SocketAddress &AddrIn = m_listen_sockets[listen_sock]; 260 if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) { 261 CLOSE_SOCKET(sock); 262 llvm::errs() << llvm::formatv( 263 "error: rejecting incoming connection from {0} (expecting {1})", 264 AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress()); 265 continue; 266 } 267 accept_connection = true; 268 accepted_socket.reset(new TCPSocket(sock, *this)); 269 } 270 271 if (!accepted_socket) 272 return error; 273 274 // Keep our TCP packets coming without any delays. 275 accepted_socket->SetOptionNoDelay(); 276 error.Clear(); 277 conn_socket = accepted_socket.release(); 278 CloseListenSockets(); 279 return error; 280 } 281 282 int TCPSocket::SetOptionNoDelay() { 283 return SetOption(IPPROTO_TCP, TCP_NODELAY, 1); 284 } 285 286 int TCPSocket::SetOptionReuseAddress() { 287 return SetOption(SOL_SOCKET, SO_REUSEADDR, 1); 288 } 289