1//===-- Socket.h ------------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_Host_Socket_h_
11#define liblldb_Host_Socket_h_
12
13#include <memory>
14#include <string>
15
16#include "lldb/lldb-private.h"
17
18#include "lldb/Core/Error.h"
19#include "lldb/Host/IOObject.h"
20#include "lldb/Host/Predicate.h"
21#include "lldb/Host/SocketAddress.h"
22
23#ifdef _WIN32
24#include "lldb/Host/windows/windows.h"
25#include <winsock2.h>
26#include <ws2tcpip.h>
27#endif
28
29namespace llvm
30{
31    class StringRef;
32}
33
34namespace lldb_private {
35
36#if defined(_MSC_VER)
37    typedef SOCKET NativeSocket;
38#else
39    typedef int NativeSocket;
40#endif
41
42class Socket : public IOObject
43{
44public:
45    typedef enum
46    {
47        ProtocolTcp,
48        ProtocolUdp,
49        ProtocolUnixDomain,
50        ProtocolUnixAbstract
51    } SocketProtocol;
52
53    static const NativeSocket kInvalidSocketValue;
54
55    ~Socket() override;
56
57    static std::unique_ptr<Socket> Create(const SocketProtocol protocol, bool child_processes_inherit, Error &error);
58
59    virtual Error Connect(llvm::StringRef name) = 0;
60    virtual Error Listen(llvm::StringRef name, int backlog) = 0;
61    virtual Error Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket) = 0;
62
63    // Initialize a Tcp Socket object in listening mode.  listen and accept are implemented
64    // separately because the caller may wish to manipulate or query the socket after it is
65    // initialized, but before entering a blocking accept.
66    static Error TcpListen(
67        llvm::StringRef host_and_port,
68        bool child_processes_inherit,
69        Socket *&socket,
70        Predicate<uint16_t>* predicate,
71        int backlog = 5);
72    static Error TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
73    static Error UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket);
74    static Error UnixDomainConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
75    static Error UnixDomainAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
76    static Error UnixAbstractConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
77    static Error UnixAbstractAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
78
79    int GetOption (int level, int option_name, int &option_value);
80    int SetOption (int level, int option_name, int option_value);
81
82    NativeSocket GetNativeSocket () const { return m_socket; }
83    SocketProtocol GetSocketProtocol () const { return m_protocol; }
84
85    Error Read (void *buf, size_t &num_bytes) override;
86    Error Write (const void *buf, size_t &num_bytes) override;
87
88    virtual Error PreDisconnect ();
89    Error Close() override;
90
91    bool IsValid () const override { return m_socket != kInvalidSocketValue; }
92    WaitableHandle GetWaitableHandle () override;
93
94    static bool
95    DecodeHostAndPort (llvm::StringRef host_and_port,
96                       std::string &host_str,
97                       std::string &port_str,
98                       int32_t& port,
99                       Error *error_ptr);
100
101protected:
102    Socket(NativeSocket socket, SocketProtocol protocol, bool should_close);
103
104    virtual size_t Send(const void *buf, const size_t num_bytes);
105
106    static void SetLastError(Error &error);
107    static NativeSocket CreateSocket(
108        const int domain, const int type, const int protocol, bool child_processes_inherit, Error& error);
109    static NativeSocket AcceptSocket(
110        NativeSocket sockfd, struct sockaddr *addr, socklen_t *addrlen, bool child_processes_inherit, Error& error);
111
112    SocketProtocol m_protocol;
113    NativeSocket m_socket;
114};
115
116} // namespace lldb_private
117
118#endif // liblldb_Host_Socket_h_
119