1//===-- Socket.h ------------------------------------------------*- C++ -*-===// 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#ifndef LLDB_HOST_SOCKET_H 10#define LLDB_HOST_SOCKET_H 11 12#include <memory> 13#include <string> 14 15#include "lldb/lldb-private.h" 16 17#include "lldb/Host/SocketAddress.h" 18#include "lldb/Utility/IOObject.h" 19#include "lldb/Utility/Status.h" 20 21#ifdef _WIN32 22#include "lldb/Host/windows/windows.h" 23#include <winsock2.h> 24#include <ws2tcpip.h> 25#endif 26 27namespace llvm { 28class StringRef; 29} 30 31namespace lldb_private { 32 33#if defined(_WIN32) 34typedef SOCKET NativeSocket; 35#else 36typedef int NativeSocket; 37#endif 38class TCPSocket; 39class UDPSocket; 40 41class Socket : public IOObject { 42public: 43 enum SocketProtocol { 44 ProtocolTcp, 45 ProtocolUdp, 46 ProtocolUnixDomain, 47 ProtocolUnixAbstract 48 }; 49 50 struct HostAndPort { 51 std::string hostname; 52 uint16_t port; 53 54 bool operator==(const HostAndPort &R) const { 55 return port == R.port && hostname == R.hostname; 56 } 57 }; 58 59 static const NativeSocket kInvalidSocketValue; 60 61 ~Socket() override; 62 63 static llvm::Error Initialize(); 64 static void Terminate(); 65 66 static std::unique_ptr<Socket> Create(const SocketProtocol protocol, 67 bool child_processes_inherit, 68 Status &error); 69 70 virtual Status Connect(llvm::StringRef name) = 0; 71 virtual Status Listen(llvm::StringRef name, int backlog) = 0; 72 virtual Status Accept(Socket *&socket) = 0; 73 74 // Initialize a Tcp Socket object in listening mode. listen and accept are 75 // implemented separately because the caller may wish to manipulate or query 76 // the socket after it is initialized, but before entering a blocking accept. 77 static llvm::Expected<std::unique_ptr<TCPSocket>> 78 TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, 79 int backlog = 5); 80 81 static llvm::Expected<std::unique_ptr<Socket>> 82 TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); 83 84 static llvm::Expected<std::unique_ptr<UDPSocket>> 85 UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); 86 87 int GetOption(int level, int option_name, int &option_value); 88 int SetOption(int level, int option_name, int option_value); 89 90 NativeSocket GetNativeSocket() const { return m_socket; } 91 SocketProtocol GetSocketProtocol() const { return m_protocol; } 92 93 Status Read(void *buf, size_t &num_bytes) override; 94 Status Write(const void *buf, size_t &num_bytes) override; 95 96 Status Close() override; 97 98 bool IsValid() const override { return m_socket != kInvalidSocketValue; } 99 WaitableHandle GetWaitableHandle() override; 100 101 static llvm::Expected<HostAndPort> 102 DecodeHostAndPort(llvm::StringRef host_and_port); 103 104 // If this Socket is connected then return the URI used to connect. 105 virtual std::string GetRemoteConnectionURI() const { return ""; }; 106 107protected: 108 Socket(SocketProtocol protocol, bool should_close, 109 bool m_child_process_inherit); 110 111 virtual size_t Send(const void *buf, const size_t num_bytes); 112 113 static void SetLastError(Status &error); 114 static NativeSocket CreateSocket(const int domain, const int type, 115 const int protocol, 116 bool child_processes_inherit, Status &error); 117 static NativeSocket AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, 118 socklen_t *addrlen, 119 bool child_processes_inherit, Status &error); 120 121 SocketProtocol m_protocol; 122 NativeSocket m_socket; 123 bool m_child_processes_inherit; 124 bool m_should_close_fd; 125}; 126 127llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 128 const Socket::HostAndPort &HP); 129 130} // namespace lldb_private 131 132#endif // LLDB_HOST_SOCKET_H 133