reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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_