1dda28197Spatrick //===-- TCPSocket.cpp -----------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #if defined(_MSC_VER)
10061da546Spatrick #define _WINSOCK_DEPRECATED_NO_WARNINGS
11061da546Spatrick #endif
12061da546Spatrick
13061da546Spatrick #include "lldb/Host/common/TCPSocket.h"
14061da546Spatrick
15061da546Spatrick #include "lldb/Host/Config.h"
16061da546Spatrick #include "lldb/Host/MainLoop.h"
17*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
18061da546Spatrick #include "lldb/Utility/Log.h"
19061da546Spatrick
20061da546Spatrick #include "llvm/Config/llvm-config.h"
21061da546Spatrick #include "llvm/Support/Errno.h"
22dda28197Spatrick #include "llvm/Support/WindowsError.h"
23061da546Spatrick #include "llvm/Support/raw_ostream.h"
24061da546Spatrick
25061da546Spatrick #if LLDB_ENABLE_POSIX
26061da546Spatrick #include <arpa/inet.h>
27061da546Spatrick #include <netinet/tcp.h>
28061da546Spatrick #include <sys/socket.h>
29061da546Spatrick #endif
30061da546Spatrick
31061da546Spatrick #if defined(_WIN32)
32061da546Spatrick #include <winsock2.h>
33061da546Spatrick #endif
34061da546Spatrick
35061da546Spatrick #ifdef _WIN32
36061da546Spatrick #define CLOSE_SOCKET closesocket
37061da546Spatrick typedef const char *set_socket_option_arg_type;
38061da546Spatrick #else
39061da546Spatrick #include <unistd.h>
40061da546Spatrick #define CLOSE_SOCKET ::close
41061da546Spatrick typedef const void *set_socket_option_arg_type;
42061da546Spatrick #endif
43061da546Spatrick
44061da546Spatrick using namespace lldb;
45061da546Spatrick using namespace lldb_private;
46061da546Spatrick
GetLastSocketError()47dda28197Spatrick static Status GetLastSocketError() {
48dda28197Spatrick std::error_code EC;
49dda28197Spatrick #ifdef _WIN32
50dda28197Spatrick EC = llvm::mapWindowsError(WSAGetLastError());
51dda28197Spatrick #else
52dda28197Spatrick EC = std::error_code(errno, std::generic_category());
53dda28197Spatrick #endif
54dda28197Spatrick return EC;
55dda28197Spatrick }
56dda28197Spatrick
57*f6aab3d8Srobert static const int kType = SOCK_STREAM;
58061da546Spatrick
TCPSocket(bool should_close,bool child_processes_inherit)59061da546Spatrick TCPSocket::TCPSocket(bool should_close, bool child_processes_inherit)
60061da546Spatrick : Socket(ProtocolTcp, should_close, child_processes_inherit) {}
61061da546Spatrick
TCPSocket(NativeSocket socket,const TCPSocket & listen_socket)62061da546Spatrick TCPSocket::TCPSocket(NativeSocket socket, const TCPSocket &listen_socket)
63061da546Spatrick : Socket(ProtocolTcp, listen_socket.m_should_close_fd,
64061da546Spatrick listen_socket.m_child_processes_inherit) {
65061da546Spatrick m_socket = socket;
66061da546Spatrick }
67061da546Spatrick
TCPSocket(NativeSocket socket,bool should_close,bool child_processes_inherit)68061da546Spatrick TCPSocket::TCPSocket(NativeSocket socket, bool should_close,
69061da546Spatrick bool child_processes_inherit)
70061da546Spatrick : Socket(ProtocolTcp, should_close, child_processes_inherit) {
71061da546Spatrick m_socket = socket;
72061da546Spatrick }
73061da546Spatrick
~TCPSocket()74061da546Spatrick TCPSocket::~TCPSocket() { CloseListenSockets(); }
75061da546Spatrick
IsValid() const76061da546Spatrick bool TCPSocket::IsValid() const {
77061da546Spatrick return m_socket != kInvalidSocketValue || m_listen_sockets.size() != 0;
78061da546Spatrick }
79061da546Spatrick
80061da546Spatrick // Return the port number that is being used by the socket.
GetLocalPortNumber() const81061da546Spatrick uint16_t TCPSocket::GetLocalPortNumber() const {
82061da546Spatrick if (m_socket != kInvalidSocketValue) {
83061da546Spatrick SocketAddress sock_addr;
84061da546Spatrick socklen_t sock_addr_len = sock_addr.GetMaxLength();
85061da546Spatrick if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0)
86061da546Spatrick return sock_addr.GetPort();
87061da546Spatrick } else if (!m_listen_sockets.empty()) {
88061da546Spatrick SocketAddress sock_addr;
89061da546Spatrick socklen_t sock_addr_len = sock_addr.GetMaxLength();
90061da546Spatrick if (::getsockname(m_listen_sockets.begin()->first, sock_addr,
91061da546Spatrick &sock_addr_len) == 0)
92061da546Spatrick return sock_addr.GetPort();
93061da546Spatrick }
94061da546Spatrick return 0;
95061da546Spatrick }
96061da546Spatrick
GetLocalIPAddress() const97061da546Spatrick std::string TCPSocket::GetLocalIPAddress() const {
98061da546Spatrick // We bound to port zero, so we need to figure out which port we actually
99061da546Spatrick // bound to
100061da546Spatrick if (m_socket != kInvalidSocketValue) {
101061da546Spatrick SocketAddress sock_addr;
102061da546Spatrick socklen_t sock_addr_len = sock_addr.GetMaxLength();
103061da546Spatrick if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0)
104061da546Spatrick return sock_addr.GetIPAddress();
105061da546Spatrick }
106061da546Spatrick return "";
107061da546Spatrick }
108061da546Spatrick
GetRemotePortNumber() const109061da546Spatrick uint16_t TCPSocket::GetRemotePortNumber() const {
110061da546Spatrick if (m_socket != kInvalidSocketValue) {
111061da546Spatrick SocketAddress sock_addr;
112061da546Spatrick socklen_t sock_addr_len = sock_addr.GetMaxLength();
113061da546Spatrick if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0)
114061da546Spatrick return sock_addr.GetPort();
115061da546Spatrick }
116061da546Spatrick return 0;
117061da546Spatrick }
118061da546Spatrick
GetRemoteIPAddress() const119061da546Spatrick std::string TCPSocket::GetRemoteIPAddress() const {
120061da546Spatrick // We bound to port zero, so we need to figure out which port we actually
121061da546Spatrick // bound to
122061da546Spatrick if (m_socket != kInvalidSocketValue) {
123061da546Spatrick SocketAddress sock_addr;
124061da546Spatrick socklen_t sock_addr_len = sock_addr.GetMaxLength();
125061da546Spatrick if (::getpeername(m_socket, sock_addr, &sock_addr_len) == 0)
126061da546Spatrick return sock_addr.GetIPAddress();
127061da546Spatrick }
128061da546Spatrick return "";
129061da546Spatrick }
130061da546Spatrick
GetRemoteConnectionURI() const131061da546Spatrick std::string TCPSocket::GetRemoteConnectionURI() const {
132061da546Spatrick if (m_socket != kInvalidSocketValue) {
133dda28197Spatrick return std::string(llvm::formatv(
134dda28197Spatrick "connect://[{0}]:{1}", GetRemoteIPAddress(), GetRemotePortNumber()));
135061da546Spatrick }
136061da546Spatrick return "";
137061da546Spatrick }
138061da546Spatrick
CreateSocket(int domain)139061da546Spatrick Status TCPSocket::CreateSocket(int domain) {
140061da546Spatrick Status error;
141061da546Spatrick if (IsValid())
142061da546Spatrick error = Close();
143061da546Spatrick if (error.Fail())
144061da546Spatrick return error;
145061da546Spatrick m_socket = Socket::CreateSocket(domain, kType, IPPROTO_TCP,
146061da546Spatrick m_child_processes_inherit, error);
147061da546Spatrick return error;
148061da546Spatrick }
149061da546Spatrick
Connect(llvm::StringRef name)150061da546Spatrick Status TCPSocket::Connect(llvm::StringRef name) {
151061da546Spatrick
152*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Communication);
153061da546Spatrick LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
154061da546Spatrick
155061da546Spatrick Status error;
156*f6aab3d8Srobert llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name);
157*f6aab3d8Srobert if (!host_port)
158*f6aab3d8Srobert return Status(host_port.takeError());
159061da546Spatrick
160*f6aab3d8Srobert std::vector<SocketAddress> addresses =
161*f6aab3d8Srobert SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr,
162*f6aab3d8Srobert AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
163061da546Spatrick for (SocketAddress &address : addresses) {
164061da546Spatrick error = CreateSocket(address.GetFamily());
165061da546Spatrick if (error.Fail())
166061da546Spatrick continue;
167061da546Spatrick
168*f6aab3d8Srobert address.SetPort(host_port->port);
169061da546Spatrick
170*f6aab3d8Srobert if (llvm::sys::RetryAfterSignal(-1, ::connect, GetNativeSocket(),
171*f6aab3d8Srobert &address.sockaddr(),
172*f6aab3d8Srobert address.GetLength()) == -1) {
173*f6aab3d8Srobert Close();
174061da546Spatrick continue;
175061da546Spatrick }
176061da546Spatrick
177*f6aab3d8Srobert if (SetOptionNoDelay() == -1) {
178*f6aab3d8Srobert Close();
179*f6aab3d8Srobert continue;
180*f6aab3d8Srobert }
181061da546Spatrick
182061da546Spatrick error.Clear();
183061da546Spatrick return error;
184061da546Spatrick }
185061da546Spatrick
186061da546Spatrick error.SetErrorString("Failed to connect port");
187061da546Spatrick return error;
188061da546Spatrick }
189061da546Spatrick
Listen(llvm::StringRef name,int backlog)190061da546Spatrick Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
191*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Connection);
192061da546Spatrick LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data());
193061da546Spatrick
194061da546Spatrick Status error;
195*f6aab3d8Srobert llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name);
196*f6aab3d8Srobert if (!host_port)
197*f6aab3d8Srobert return Status(host_port.takeError());
198061da546Spatrick
199*f6aab3d8Srobert if (host_port->hostname == "*")
200*f6aab3d8Srobert host_port->hostname = "0.0.0.0";
201061da546Spatrick std::vector<SocketAddress> addresses = SocketAddress::GetAddressInfo(
202*f6aab3d8Srobert host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
203061da546Spatrick for (SocketAddress &address : addresses) {
204061da546Spatrick int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP,
205061da546Spatrick m_child_processes_inherit, error);
206*f6aab3d8Srobert if (error.Fail() || fd < 0)
207061da546Spatrick continue;
208061da546Spatrick
209061da546Spatrick // enable local address reuse
210061da546Spatrick int option_value = 1;
211061da546Spatrick set_socket_option_arg_type option_value_p =
212061da546Spatrick reinterpret_cast<set_socket_option_arg_type>(&option_value);
213*f6aab3d8Srobert if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, option_value_p,
214*f6aab3d8Srobert sizeof(option_value)) == -1) {
215*f6aab3d8Srobert CLOSE_SOCKET(fd);
216*f6aab3d8Srobert continue;
217*f6aab3d8Srobert }
218061da546Spatrick
219061da546Spatrick SocketAddress listen_address = address;
220061da546Spatrick if(!listen_address.IsLocalhost())
221*f6aab3d8Srobert listen_address.SetToAnyAddress(address.GetFamily(), host_port->port);
222061da546Spatrick else
223*f6aab3d8Srobert listen_address.SetPort(host_port->port);
224061da546Spatrick
225061da546Spatrick int err =
226061da546Spatrick ::bind(fd, &listen_address.sockaddr(), listen_address.GetLength());
227*f6aab3d8Srobert if (err != -1)
228061da546Spatrick err = ::listen(fd, backlog);
229061da546Spatrick
230*f6aab3d8Srobert if (err == -1) {
231dda28197Spatrick error = GetLastSocketError();
232061da546Spatrick CLOSE_SOCKET(fd);
233061da546Spatrick continue;
234061da546Spatrick }
235061da546Spatrick
236*f6aab3d8Srobert if (host_port->port == 0) {
237061da546Spatrick socklen_t sa_len = address.GetLength();
238061da546Spatrick if (getsockname(fd, &address.sockaddr(), &sa_len) == 0)
239*f6aab3d8Srobert host_port->port = address.GetPort();
240061da546Spatrick }
241061da546Spatrick m_listen_sockets[fd] = address;
242061da546Spatrick }
243061da546Spatrick
244dda28197Spatrick if (m_listen_sockets.empty()) {
245dda28197Spatrick assert(error.Fail());
246061da546Spatrick return error;
247061da546Spatrick }
248dda28197Spatrick return Status();
249dda28197Spatrick }
250061da546Spatrick
CloseListenSockets()251061da546Spatrick void TCPSocket::CloseListenSockets() {
252061da546Spatrick for (auto socket : m_listen_sockets)
253061da546Spatrick CLOSE_SOCKET(socket.first);
254061da546Spatrick m_listen_sockets.clear();
255061da546Spatrick }
256061da546Spatrick
Accept(Socket * & conn_socket)257061da546Spatrick Status TCPSocket::Accept(Socket *&conn_socket) {
258061da546Spatrick Status error;
259061da546Spatrick if (m_listen_sockets.size() == 0) {
260061da546Spatrick error.SetErrorString("No open listening sockets!");
261061da546Spatrick return error;
262061da546Spatrick }
263061da546Spatrick
264*f6aab3d8Srobert NativeSocket sock = kInvalidSocketValue;
265*f6aab3d8Srobert NativeSocket listen_sock = kInvalidSocketValue;
266061da546Spatrick lldb_private::SocketAddress AcceptAddr;
267061da546Spatrick MainLoop accept_loop;
268061da546Spatrick std::vector<MainLoopBase::ReadHandleUP> handles;
269061da546Spatrick for (auto socket : m_listen_sockets) {
270061da546Spatrick auto fd = socket.first;
271061da546Spatrick auto inherit = this->m_child_processes_inherit;
272061da546Spatrick auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit));
273061da546Spatrick handles.emplace_back(accept_loop.RegisterReadObject(
274061da546Spatrick io_sp, [fd, inherit, &sock, &AcceptAddr, &error,
275061da546Spatrick &listen_sock](MainLoopBase &loop) {
276061da546Spatrick socklen_t sa_len = AcceptAddr.GetMaxLength();
277061da546Spatrick sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit,
278061da546Spatrick error);
279061da546Spatrick listen_sock = fd;
280061da546Spatrick loop.RequestTermination();
281061da546Spatrick }, error));
282061da546Spatrick if (error.Fail())
283061da546Spatrick return error;
284061da546Spatrick }
285061da546Spatrick
286061da546Spatrick bool accept_connection = false;
287061da546Spatrick std::unique_ptr<TCPSocket> accepted_socket;
288061da546Spatrick // Loop until we are happy with our connection
289061da546Spatrick while (!accept_connection) {
290061da546Spatrick accept_loop.Run();
291061da546Spatrick
292061da546Spatrick if (error.Fail())
293061da546Spatrick return error;
294061da546Spatrick
295061da546Spatrick lldb_private::SocketAddress &AddrIn = m_listen_sockets[listen_sock];
296061da546Spatrick if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) {
297*f6aab3d8Srobert if (sock != kInvalidSocketValue) {
298061da546Spatrick CLOSE_SOCKET(sock);
299*f6aab3d8Srobert sock = kInvalidSocketValue;
300*f6aab3d8Srobert }
301061da546Spatrick llvm::errs() << llvm::formatv(
302061da546Spatrick "error: rejecting incoming connection from {0} (expecting {1})",
303061da546Spatrick AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress());
304061da546Spatrick continue;
305061da546Spatrick }
306061da546Spatrick accept_connection = true;
307061da546Spatrick accepted_socket.reset(new TCPSocket(sock, *this));
308061da546Spatrick }
309061da546Spatrick
310061da546Spatrick if (!accepted_socket)
311061da546Spatrick return error;
312061da546Spatrick
313061da546Spatrick // Keep our TCP packets coming without any delays.
314061da546Spatrick accepted_socket->SetOptionNoDelay();
315061da546Spatrick error.Clear();
316061da546Spatrick conn_socket = accepted_socket.release();
317061da546Spatrick return error;
318061da546Spatrick }
319061da546Spatrick
SetOptionNoDelay()320061da546Spatrick int TCPSocket::SetOptionNoDelay() {
321061da546Spatrick return SetOption(IPPROTO_TCP, TCP_NODELAY, 1);
322061da546Spatrick }
323061da546Spatrick
SetOptionReuseAddress()324061da546Spatrick int TCPSocket::SetOptionReuseAddress() {
325061da546Spatrick return SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
326061da546Spatrick }
327