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 
GetNativeSocket()90   NativeSocket GetNativeSocket() const { return m_socket; }
GetSocketProtocol()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 
IsValid()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.
GetRemoteConnectionURI()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