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 27 namespace llvm { 28 class StringRef; 29 } 30 31 namespace lldb_private { 32 33 #if defined(_WIN32) 34 typedef SOCKET NativeSocket; 35 #else 36 typedef int NativeSocket; 37 #endif 38 class TCPSocket; 39 class UDPSocket; 40 41 class Socket : public IOObject { 42 public: 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 107 protected: 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 127 llvm::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