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