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 #include "lldb/Host/common/TCPSocket.h" 11 12 #include "lldb/Core/Log.h" 13 #include "lldb/Host/Config.h" 14 15 #ifndef LLDB_DISABLE_POSIX 16 #include <arpa/inet.h> 17 #include <netinet/tcp.h> 18 #include <sys/socket.h> 19 #endif 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 namespace { 25 26 const int kDomain = AF_INET; 27 const int kType = SOCK_STREAM; 28 } 29 30 TCPSocket::TCPSocket(NativeSocket socket, bool should_close) 31 : Socket(socket, ProtocolTcp, should_close) {} 32 33 TCPSocket::TCPSocket(bool child_processes_inherit, Error &error) 34 : TCPSocket(CreateSocket(kDomain, kType, IPPROTO_TCP, 35 child_processes_inherit, error), 36 true) {} 37 38 // Return the port number that is being used by the socket. 39 uint16_t TCPSocket::GetLocalPortNumber() const { 40 if (m_socket != kInvalidSocketValue) { 41 SocketAddress sock_addr; 42 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 43 if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0) 44 return sock_addr.GetPort(); 45 } 46 return 0; 47 } 48 49 std::string TCPSocket::GetLocalIPAddress() const { 50 // We bound to port zero, so we need to figure out which port we actually 51 // bound to 52 if (m_socket != kInvalidSocketValue) { 53 SocketAddress sock_addr; 54 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 55 if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0) 56 return sock_addr.GetIPAddress(); 57 } 58 return ""; 59 } 60 61 uint16_t TCPSocket::GetRemotePortNumber() const { 62 if (m_socket != kInvalidSocketValue) { 63 SocketAddress sock_addr; 64 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 65 if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0) 66 return sock_addr.GetPort(); 67 } 68 return 0; 69 } 70 71 std::string TCPSocket::GetRemoteIPAddress() const { 72 // We bound to port zero, so we need to figure out which port we actually 73 // bound to 74 if (m_socket != kInvalidSocketValue) { 75 SocketAddress sock_addr; 76 socklen_t sock_addr_len = sock_addr.GetMaxLength(); 77 if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0) 78 return sock_addr.GetIPAddress(); 79 } 80 return ""; 81 } 82 83 Error TCPSocket::Connect(llvm::StringRef name) { 84 if (m_socket == kInvalidSocketValue) 85 return Error("Invalid socket"); 86 87 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); 88 if (log) 89 log->Printf("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); 90 91 Error error; 92 std::string host_str; 93 std::string port_str; 94 int32_t port = INT32_MIN; 95 if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) 96 return error; 97 98 struct sockaddr_in sa; 99 ::memset(&sa, 0, sizeof(sa)); 100 sa.sin_family = kDomain; 101 sa.sin_port = htons(port); 102 103 int inet_pton_result = ::inet_pton(kDomain, host_str.c_str(), &sa.sin_addr); 104 105 if (inet_pton_result <= 0) { 106 struct hostent *host_entry = gethostbyname(host_str.c_str()); 107 if (host_entry) 108 host_str = ::inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list); 109 inet_pton_result = ::inet_pton(kDomain, host_str.c_str(), &sa.sin_addr); 110 if (inet_pton_result <= 0) { 111 if (inet_pton_result == -1) 112 SetLastError(error); 113 else 114 error.SetErrorStringWithFormat("invalid host string: '%s'", 115 host_str.c_str()); 116 117 return error; 118 } 119 } 120 121 if (-1 == 122 ::connect(GetNativeSocket(), (const struct sockaddr *)&sa, sizeof(sa))) { 123 SetLastError(error); 124 return error; 125 } 126 127 // Keep our TCP packets coming without any delays. 128 SetOptionNoDelay(); 129 error.Clear(); 130 return error; 131 } 132 133 Error TCPSocket::Listen(llvm::StringRef name, int backlog) { 134 Error error; 135 136 // enable local address reuse 137 SetOptionReuseAddress(); 138 139 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 140 if (log) 141 log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data()); 142 143 std::string host_str; 144 std::string port_str; 145 int32_t port = INT32_MIN; 146 if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) 147 return error; 148 149 SocketAddress bind_addr; 150 151 // Only bind to the loopback address if we are expecting a connection from 152 // localhost to avoid any firewall issues. 153 const bool bind_addr_success = (host_str == "127.0.0.1") 154 ? bind_addr.SetToLocalhost(kDomain, port) 155 : bind_addr.SetToAnyAddress(kDomain, port); 156 157 if (!bind_addr_success) { 158 error.SetErrorString("Failed to bind port"); 159 return error; 160 } 161 162 int err = ::bind(GetNativeSocket(), bind_addr, bind_addr.GetLength()); 163 if (err != -1) 164 err = ::listen(GetNativeSocket(), backlog); 165 166 if (err == -1) 167 SetLastError(error); 168 169 return error; 170 } 171 172 Error TCPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, 173 Socket *&conn_socket) { 174 Error error; 175 std::string host_str; 176 std::string port_str; 177 int32_t port; 178 if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) 179 return error; 180 181 const sa_family_t family = kDomain; 182 const int socktype = kType; 183 const int protocol = IPPROTO_TCP; 184 SocketAddress listen_addr; 185 if (host_str.empty()) 186 listen_addr.SetToLocalhost(family, port); 187 else if (host_str.compare("*") == 0) 188 listen_addr.SetToAnyAddress(family, port); 189 else { 190 if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, 191 socktype, protocol)) { 192 error.SetErrorStringWithFormat("unable to resolve hostname '%s'", 193 host_str.c_str()); 194 return error; 195 } 196 } 197 198 bool accept_connection = false; 199 std::unique_ptr<TCPSocket> accepted_socket; 200 201 // Loop until we are happy with our connection 202 while (!accept_connection) { 203 struct sockaddr_in accept_addr; 204 ::memset(&accept_addr, 0, sizeof accept_addr); 205 #if !(defined(__linux__) || defined(_WIN32)) 206 accept_addr.sin_len = sizeof accept_addr; 207 #endif 208 socklen_t accept_addr_len = sizeof accept_addr; 209 210 int sock = AcceptSocket(GetNativeSocket(), (struct sockaddr *)&accept_addr, 211 &accept_addr_len, child_processes_inherit, error); 212 213 if (error.Fail()) 214 break; 215 216 bool is_same_addr = true; 217 #if !(defined(__linux__) || (defined(_WIN32))) 218 is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len); 219 #endif 220 if (is_same_addr) 221 is_same_addr = (accept_addr.sin_addr.s_addr == 222 listen_addr.sockaddr_in().sin_addr.s_addr); 223 224 if (is_same_addr || 225 (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY)) { 226 accept_connection = true; 227 accepted_socket.reset(new TCPSocket(sock, true)); 228 } else { 229 const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr; 230 const uint8_t *listen_ip = 231 (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr; 232 ::fprintf(stderr, "error: rejecting incoming connection from %u.%u.%u.%u " 233 "(expecting %u.%u.%u.%u)\n", 234 accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3], 235 listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]); 236 accepted_socket.reset(); 237 } 238 } 239 240 if (!accepted_socket) 241 return error; 242 243 // Keep our TCP packets coming without any delays. 244 accepted_socket->SetOptionNoDelay(); 245 error.Clear(); 246 conn_socket = accepted_socket.release(); 247 return error; 248 } 249 250 int TCPSocket::SetOptionNoDelay() { 251 return SetOption(IPPROTO_TCP, TCP_NODELAY, 1); 252 } 253 254 int TCPSocket::SetOptionReuseAddress() { 255 return SetOption(SOL_SOCKET, SO_REUSEADDR, 1); 256 } 257