Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:49

0001 //===-- Socket.h ------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_HOST_SOCKET_H
0010 #define LLDB_HOST_SOCKET_H
0011 
0012 #include <memory>
0013 #include <string>
0014 #include <vector>
0015 
0016 #include "lldb/Host/MainLoopBase.h"
0017 #include "lldb/Utility/Timeout.h"
0018 #include "lldb/lldb-private.h"
0019 
0020 #include "lldb/Host/SocketAddress.h"
0021 #include "lldb/Utility/IOObject.h"
0022 #include "lldb/Utility/Status.h"
0023 
0024 #ifdef _WIN32
0025 #include "lldb/Host/Pipe.h"
0026 #include "lldb/Host/windows/windows.h"
0027 #include <winsock2.h>
0028 #include <ws2tcpip.h>
0029 #endif
0030 
0031 namespace llvm {
0032 class StringRef;
0033 }
0034 
0035 namespace lldb_private {
0036 
0037 #if defined(_WIN32)
0038 typedef SOCKET NativeSocket;
0039 typedef lldb::pipe_t shared_fd_t;
0040 #else
0041 typedef int NativeSocket;
0042 typedef NativeSocket shared_fd_t;
0043 #endif
0044 class Socket;
0045 class TCPSocket;
0046 class UDPSocket;
0047 
0048 class SharedSocket {
0049 public:
0050   static const shared_fd_t kInvalidFD;
0051 
0052   SharedSocket(const Socket *socket, Status &error);
0053 
0054   shared_fd_t GetSendableFD() { return m_fd; }
0055 
0056   Status CompleteSending(lldb::pid_t child_pid);
0057 
0058   static Status GetNativeSocket(shared_fd_t fd, NativeSocket &socket);
0059 
0060 private:
0061 #ifdef _WIN32
0062   Pipe m_socket_pipe;
0063   NativeSocket m_socket;
0064 #endif
0065   shared_fd_t m_fd;
0066 };
0067 
0068 class Socket : public IOObject {
0069 public:
0070   enum SocketProtocol {
0071     ProtocolTcp,
0072     ProtocolUdp,
0073     ProtocolUnixDomain,
0074     ProtocolUnixAbstract
0075   };
0076 
0077   struct HostAndPort {
0078     std::string hostname;
0079     uint16_t port;
0080 
0081     bool operator==(const HostAndPort &R) const {
0082       return port == R.port && hostname == R.hostname;
0083     }
0084   };
0085 
0086   static const NativeSocket kInvalidSocketValue;
0087 
0088   ~Socket() override;
0089 
0090   static const char *FindSchemeByProtocol(const SocketProtocol protocol);
0091   static bool FindProtocolByScheme(const char *scheme,
0092                                    SocketProtocol &protocol);
0093 
0094   static llvm::Error Initialize();
0095   static void Terminate();
0096 
0097   static std::unique_ptr<Socket> Create(const SocketProtocol protocol,
0098                                         Status &error);
0099 
0100   virtual Status Connect(llvm::StringRef name) = 0;
0101   virtual Status Listen(llvm::StringRef name, int backlog) = 0;
0102 
0103   // Use the provided main loop instance to accept new connections. The callback
0104   // will be called (from MainLoop::Run) for each new connection. This function
0105   // does not block.
0106   virtual llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
0107   Accept(MainLoopBase &loop,
0108          std::function<void(std::unique_ptr<Socket> socket)> sock_cb) = 0;
0109 
0110   // Accept a single connection and "return" it in the pointer argument. This
0111   // function blocks until the connection arrives.
0112   virtual Status Accept(const Timeout<std::micro> &timeout, Socket *&socket);
0113 
0114   // Initialize a Tcp Socket object in listening mode.  listen and accept are
0115   // implemented separately because the caller may wish to manipulate or query
0116   // the socket after it is initialized, but before entering a blocking accept.
0117   static llvm::Expected<std::unique_ptr<TCPSocket>>
0118   TcpListen(llvm::StringRef host_and_port, int backlog = 5);
0119 
0120   static llvm::Expected<std::unique_ptr<Socket>>
0121   TcpConnect(llvm::StringRef host_and_port);
0122 
0123   static llvm::Expected<std::unique_ptr<UDPSocket>>
0124   UdpConnect(llvm::StringRef host_and_port);
0125 
0126   static int GetOption(NativeSocket sockfd, int level, int option_name,
0127                        int &option_value);
0128   int GetOption(int level, int option_name, int &option_value) {
0129     return GetOption(m_socket, level, option_name, option_value);
0130   };
0131 
0132   static int SetOption(NativeSocket sockfd, int level, int option_name,
0133                        int option_value);
0134   int SetOption(int level, int option_name, int option_value) {
0135     return SetOption(m_socket, level, option_name, option_value);
0136   };
0137 
0138   NativeSocket GetNativeSocket() const { return m_socket; }
0139   SocketProtocol GetSocketProtocol() const { return m_protocol; }
0140 
0141   Status Read(void *buf, size_t &num_bytes) override;
0142   Status Write(const void *buf, size_t &num_bytes) override;
0143 
0144   Status Close() override;
0145 
0146   bool IsValid() const override { return m_socket != kInvalidSocketValue; }
0147   WaitableHandle GetWaitableHandle() override;
0148 
0149   static llvm::Expected<HostAndPort>
0150   DecodeHostAndPort(llvm::StringRef host_and_port);
0151 
0152   // If this Socket is connected then return the URI used to connect.
0153   virtual std::string GetRemoteConnectionURI() const { return ""; };
0154 
0155   // If the Socket is listening then return the URI for clients to connect.
0156   virtual std::vector<std::string> GetListeningConnectionURI() const {
0157     return {};
0158   }
0159 
0160 protected:
0161   Socket(SocketProtocol protocol, bool should_close);
0162 
0163   virtual size_t Send(const void *buf, const size_t num_bytes);
0164 
0165   static int CloseSocket(NativeSocket sockfd);
0166   static Status GetLastError();
0167   static void SetLastError(Status &error);
0168   static NativeSocket CreateSocket(const int domain, const int type,
0169                                    const int protocol, Status &error);
0170   static NativeSocket AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
0171                                    socklen_t *addrlen, Status &error);
0172 
0173   SocketProtocol m_protocol;
0174   NativeSocket m_socket;
0175   bool m_should_close_fd;
0176 };
0177 
0178 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
0179                               const Socket::HostAndPort &HP);
0180 
0181 } // namespace lldb_private
0182 
0183 #endif // LLDB_HOST_SOCKET_H