aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Host/Socket.h
blob: c6df5634e24e40d87a0147c59748e3a1edfd0c2c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//===-- Socket.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Host_Socket_h_
#define liblldb_Host_Socket_h_

#include <memory>
#include <string>

#include "lldb/lldb-private.h"

#include "lldb/Host/SocketAddress.h"
#include "lldb/Utility/IOObject.h"
#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/Status.h"

#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

namespace llvm {
class StringRef;
}

namespace lldb_private {

#if defined(_WIN32)
typedef SOCKET NativeSocket;
#else
typedef int NativeSocket;
#endif

class Socket : public IOObject {
public:
  enum SocketProtocol {
    ProtocolTcp,
    ProtocolUdp,
    ProtocolUnixDomain,
    ProtocolUnixAbstract
  };

  static const NativeSocket kInvalidSocketValue;

  ~Socket() override;

  static llvm::Error Initialize();
  static void Terminate();

  static std::unique_ptr<Socket> Create(const SocketProtocol protocol,
                                        bool child_processes_inherit,
                                        Status &error);

  virtual Status Connect(llvm::StringRef name) = 0;
  virtual Status Listen(llvm::StringRef name, int backlog) = 0;
  virtual Status Accept(Socket *&socket) = 0;

  // Initialize a Tcp Socket object in listening mode.  listen and accept are
  // implemented separately because the caller may wish to manipulate or query
  // the socket after it is initialized, but before entering a blocking accept.
  static Status TcpListen(llvm::StringRef host_and_port,
                          bool child_processes_inherit, Socket *&socket,
                          Predicate<uint16_t> *predicate, int backlog = 5);
  static Status TcpConnect(llvm::StringRef host_and_port,
                           bool child_processes_inherit, Socket *&socket);
  static Status UdpConnect(llvm::StringRef host_and_port,
                           bool child_processes_inherit, Socket *&socket);
  static Status UnixDomainConnect(llvm::StringRef host_and_port,
                                  bool child_processes_inherit,
                                  Socket *&socket);
  static Status UnixDomainAccept(llvm::StringRef host_and_port,
                                 bool child_processes_inherit, Socket *&socket);
  static Status UnixAbstractConnect(llvm::StringRef host_and_port,
                                    bool child_processes_inherit,
                                    Socket *&socket);
  static Status UnixAbstractAccept(llvm::StringRef host_and_port,
                                   bool child_processes_inherit,
                                   Socket *&socket);

  int GetOption(int level, int option_name, int &option_value);
  int SetOption(int level, int option_name, int option_value);

  NativeSocket GetNativeSocket() const { return m_socket; }
  SocketProtocol GetSocketProtocol() const { return m_protocol; }

  Status Read(void *buf, size_t &num_bytes) override;
  Status Write(const void *buf, size_t &num_bytes) override;

  virtual Status PreDisconnect();
  Status Close() override;

  bool IsValid() const override { return m_socket != kInvalidSocketValue; }
  WaitableHandle GetWaitableHandle() override;

  static bool DecodeHostAndPort(llvm::StringRef host_and_port,
                                std::string &host_str, std::string &port_str,
                                int32_t &port, Status *error_ptr);

  // If this Socket is connected then return the URI used to connect.
  virtual std::string GetRemoteConnectionURI() const { return ""; };

protected:
  Socket(SocketProtocol protocol, bool should_close,
         bool m_child_process_inherit);

  virtual size_t Send(const void *buf, const size_t num_bytes);

  static void SetLastError(Status &error);
  static NativeSocket CreateSocket(const int domain, const int type,
                                   const int protocol,
                                   bool child_processes_inherit, Status &error);
  static NativeSocket AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
                                   socklen_t *addrlen,
                                   bool child_processes_inherit, Status &error);

  SocketProtocol m_protocol;
  NativeSocket m_socket;
  bool m_child_processes_inherit;
  bool m_should_close_fd;
};

} // namespace lldb_private

#endif // liblldb_Host_Socket_h_