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