1275072Semaste//===-- Socket.h ------------------------------------------------*- C++ -*-===//
2275072Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6275072Semaste//
7275072Semaste//===----------------------------------------------------------------------===//
8275072Semaste
9275072Semaste#ifndef liblldb_Host_Socket_h_
10275072Semaste#define liblldb_Host_Socket_h_
11275072Semaste
12296417Sdim#include <memory>
13275072Semaste#include <string>
14275072Semaste
15275072Semaste#include "lldb/lldb-private.h"
16275072Semaste
17275072Semaste#include "lldb/Host/SocketAddress.h"
18321369Sdim#include "lldb/Utility/IOObject.h"
19344779Sdim#include "lldb/Utility/Predicate.h"
20321369Sdim#include "lldb/Utility/Status.h"
21275072Semaste
22275072Semaste#ifdef _WIN32
23275072Semaste#include "lldb/Host/windows/windows.h"
24275072Semaste#include <winsock2.h>
25275072Semaste#include <ws2tcpip.h>
26275072Semaste#endif
27275072Semaste
28314564Sdimnamespace llvm {
29314564Sdimclass StringRef;
30275072Semaste}
31275072Semaste
32275072Semastenamespace lldb_private {
33275072Semaste
34360784Sdim#if defined(_WIN32)
35314564Sdimtypedef SOCKET NativeSocket;
36275072Semaste#else
37314564Sdimtypedef int NativeSocket;
38275072Semaste#endif
39275072Semaste
40314564Sdimclass Socket : public IOObject {
41275072Semastepublic:
42353358Sdim  enum SocketProtocol {
43314564Sdim    ProtocolTcp,
44314564Sdim    ProtocolUdp,
45314564Sdim    ProtocolUnixDomain,
46314564Sdim    ProtocolUnixAbstract
47353358Sdim  };
48275072Semaste
49314564Sdim  static const NativeSocket kInvalidSocketValue;
50275072Semaste
51314564Sdim  ~Socket() override;
52275072Semaste
53353358Sdim  static llvm::Error Initialize();
54353358Sdim  static void Terminate();
55353358Sdim
56314564Sdim  static std::unique_ptr<Socket> Create(const SocketProtocol protocol,
57314564Sdim                                        bool child_processes_inherit,
58321369Sdim                                        Status &error);
59296417Sdim
60321369Sdim  virtual Status Connect(llvm::StringRef name) = 0;
61321369Sdim  virtual Status Listen(llvm::StringRef name, int backlog) = 0;
62321369Sdim  virtual Status Accept(Socket *&socket) = 0;
63296417Sdim
64314564Sdim  // Initialize a Tcp Socket object in listening mode.  listen and accept are
65341825Sdim  // implemented separately because the caller may wish to manipulate or query
66341825Sdim  // the socket after it is initialized, but before entering a blocking accept.
67321369Sdim  static Status TcpListen(llvm::StringRef host_and_port,
68321369Sdim                          bool child_processes_inherit, Socket *&socket,
69321369Sdim                          Predicate<uint16_t> *predicate, int backlog = 5);
70321369Sdim  static Status TcpConnect(llvm::StringRef host_and_port,
71321369Sdim                           bool child_processes_inherit, Socket *&socket);
72321369Sdim  static Status UdpConnect(llvm::StringRef host_and_port,
73321369Sdim                           bool child_processes_inherit, Socket *&socket);
74321369Sdim  static Status UnixDomainConnect(llvm::StringRef host_and_port,
75321369Sdim                                  bool child_processes_inherit,
76321369Sdim                                  Socket *&socket);
77321369Sdim  static Status UnixDomainAccept(llvm::StringRef host_and_port,
78314564Sdim                                 bool child_processes_inherit, Socket *&socket);
79321369Sdim  static Status UnixAbstractConnect(llvm::StringRef host_and_port,
80321369Sdim                                    bool child_processes_inherit,
81321369Sdim                                    Socket *&socket);
82321369Sdim  static Status UnixAbstractAccept(llvm::StringRef host_and_port,
83314564Sdim                                   bool child_processes_inherit,
84314564Sdim                                   Socket *&socket);
85275072Semaste
86314564Sdim  int GetOption(int level, int option_name, int &option_value);
87314564Sdim  int SetOption(int level, int option_name, int option_value);
88275072Semaste
89314564Sdim  NativeSocket GetNativeSocket() const { return m_socket; }
90314564Sdim  SocketProtocol GetSocketProtocol() const { return m_protocol; }
91275072Semaste
92321369Sdim  Status Read(void *buf, size_t &num_bytes) override;
93321369Sdim  Status Write(const void *buf, size_t &num_bytes) override;
94275072Semaste
95321369Sdim  virtual Status PreDisconnect();
96321369Sdim  Status Close() override;
97275072Semaste
98314564Sdim  bool IsValid() const override { return m_socket != kInvalidSocketValue; }
99314564Sdim  WaitableHandle GetWaitableHandle() override;
100275072Semaste
101314564Sdim  static bool DecodeHostAndPort(llvm::StringRef host_and_port,
102314564Sdim                                std::string &host_str, std::string &port_str,
103321369Sdim                                int32_t &port, Status *error_ptr);
104275072Semaste
105353358Sdim  // If this Socket is connected then return the URI used to connect.
106353358Sdim  virtual std::string GetRemoteConnectionURI() const { return ""; };
107353358Sdim
108288943Sdimprotected:
109321369Sdim  Socket(SocketProtocol protocol, bool should_close,
110321369Sdim         bool m_child_process_inherit);
111296417Sdim
112314564Sdim  virtual size_t Send(const void *buf, const size_t num_bytes);
113296417Sdim
114321369Sdim  static void SetLastError(Status &error);
115314564Sdim  static NativeSocket CreateSocket(const int domain, const int type,
116314564Sdim                                   const int protocol,
117321369Sdim                                   bool child_processes_inherit, Status &error);
118314564Sdim  static NativeSocket AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
119314564Sdim                                   socklen_t *addrlen,
120321369Sdim                                   bool child_processes_inherit, Status &error);
121296417Sdim
122314564Sdim  SocketProtocol m_protocol;
123314564Sdim  NativeSocket m_socket;
124321369Sdim  bool m_child_processes_inherit;
125360784Sdim  bool m_should_close_fd;
126275072Semaste};
127275072Semaste
128296417Sdim} // namespace lldb_private
129296417Sdim
130296417Sdim#endif // liblldb_Host_Socket_h_
131