1 //===-- SocketAddress.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_HOST_SOCKETADDRESS_H
10 #define LLDB_HOST_SOCKETADDRESS_H
11 
12 #include <cstdint>
13 
14 #ifdef _WIN32
15 #include "lldb/Host/windows/windows.h"
16 #include <winsock2.h>
17 #include <ws2tcpip.h>
18 typedef ADDRESS_FAMILY sa_family_t;
19 #else
20 #include <netdb.h>
21 #include <netinet/in.h>
22 #include <sys/socket.h>
23 #endif
24 
25 #if defined(__FreeBSD__)
26 #include <sys/types.h>
27 #endif
28 
29 #include <string>
30 #include <vector>
31 
32 namespace lldb_private {
33 
34 class SocketAddress {
35 public:
36   // Static method to get all address information for a host and/or service
37   static std::vector<SocketAddress>
38   GetAddressInfo(const char *hostname, const char *servname, int ai_family,
39                  int ai_socktype, int ai_protocol, int ai_flags = 0);
40 
41   // Constructors and Destructors
42   SocketAddress();
43   SocketAddress(const struct addrinfo *addr_info);
44   SocketAddress(const struct sockaddr &s);
45   SocketAddress(const struct sockaddr_in &s);
46   SocketAddress(const struct sockaddr_in6 &s);
47   SocketAddress(const struct sockaddr_storage &s);
48   ~SocketAddress();
49 
50   // Operators
51   const SocketAddress &operator=(const struct addrinfo *addr_info);
52 
53   const SocketAddress &operator=(const struct sockaddr &s);
54 
55   const SocketAddress &operator=(const struct sockaddr_in &s);
56 
57   const SocketAddress &operator=(const struct sockaddr_in6 &s);
58 
59   const SocketAddress &operator=(const struct sockaddr_storage &s);
60 
61   bool operator==(const SocketAddress &rhs) const;
62   bool operator!=(const SocketAddress &rhs) const;
63 
64   // Clear the contents of this socket address
65   void Clear();
66 
67   // Get the length for the current socket address family
68   socklen_t GetLength() const;
69 
70   // Get the max length for the largest socket address supported.
71   static socklen_t GetMaxLength();
72 
73   // Get the socket address family
74   sa_family_t GetFamily() const;
75 
76   // Set the socket address family
77   void SetFamily(sa_family_t family);
78 
79   // Get the address
80   std::string GetIPAddress() const;
81 
82   // Get the port if the socket address for the family has a port
83   uint16_t GetPort() const;
84 
85   // Set the port if the socket address for the family has a port. The family
86   // must be set correctly prior to calling this function.
87   bool SetPort(uint16_t port);
88 
89   // Set the socket address according to the first match from a call to
90   // getaddrinfo() (or equivalent functions for systems that don't have
91   // getaddrinfo(). If "addr_info_ptr" is not NULL, it will get filled in with
92   // the match that was used to populate this socket address.
93   bool
94   getaddrinfo(const char *host,    // Hostname ("foo.bar.com" or "foo" or IP
95                                    // address string ("123.234.12.1" or
96                                    // "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
97               const char *service, // Protocol name ("tcp", "http", etc) or a
98                                    // raw port number string ("81")
99               int ai_family = PF_UNSPEC, int ai_socktype = 0,
100               int ai_protocol = 0, int ai_flags = 0);
101 
102   // Quick way to set the SocketAddress to localhost given the family. Returns
103   // true if successful, false if "family" doesn't support localhost or if
104   // "family" is not supported by this class.
105   bool SetToLocalhost(sa_family_t family, uint16_t port);
106 
107   bool SetToAnyAddress(sa_family_t family, uint16_t port);
108 
109   // Returns true if there is a valid socket address in this object.
110   bool IsValid() const;
111 
112   // Returns true if the socket is INADDR_ANY
113   bool IsAnyAddr() const;
114 
115   // Returns true if the socket is INADDR_LOOPBACK
116   bool IsLocalhost() const;
117 
118   // Direct access to all of the sockaddr structures
119   struct sockaddr &sockaddr() {
120     return m_socket_addr.sa;
121   }
122 
123   const struct sockaddr &sockaddr() const { return m_socket_addr.sa; }
124 
125   struct sockaddr_in &sockaddr_in() {
126     return m_socket_addr.sa_ipv4;
127   }
128 
129   const struct sockaddr_in &sockaddr_in() const {
130     return m_socket_addr.sa_ipv4;
131   }
132 
133   struct sockaddr_in6 &sockaddr_in6() {
134     return m_socket_addr.sa_ipv6;
135   }
136 
137   const struct sockaddr_in6 &sockaddr_in6() const {
138     return m_socket_addr.sa_ipv6;
139   }
140 
141   struct sockaddr_storage &sockaddr_storage() {
142     return m_socket_addr.sa_storage;
143   }
144 
145   const struct sockaddr_storage &sockaddr_storage() const {
146     return m_socket_addr.sa_storage;
147   }
148 
149   // Conversion operators to allow getting the contents of this class as a
150   // pointer to the appropriate structure. This allows an instance of this
151   // class to be used in calls that take one of the sockaddr structure variants
152   // without having to manually use the correct accessor function.
153 
154   operator struct sockaddr *() { return &m_socket_addr.sa; }
155 
156   operator const struct sockaddr *() const { return &m_socket_addr.sa; }
157 
158   operator struct sockaddr_in *() { return &m_socket_addr.sa_ipv4; }
159 
160   operator const struct sockaddr_in *() const { return &m_socket_addr.sa_ipv4; }
161 
162   operator struct sockaddr_in6 *() { return &m_socket_addr.sa_ipv6; }
163 
164   operator const struct sockaddr_in6 *() const {
165     return &m_socket_addr.sa_ipv6;
166   }
167 
168   operator const struct sockaddr_storage *() const {
169     return &m_socket_addr.sa_storage;
170   }
171 
172   operator struct sockaddr_storage *() { return &m_socket_addr.sa_storage; }
173 
174 protected:
175   typedef union sockaddr_tag {
176     struct sockaddr sa;
177     struct sockaddr_in sa_ipv4;
178     struct sockaddr_in6 sa_ipv6;
179     struct sockaddr_storage sa_storage;
180   } sockaddr_t;
181 
182   // Classes that inherit from SocketAddress can see and modify these
183   sockaddr_t m_socket_addr;
184 };
185 
186 } // namespace lldb_private
187 
188 #endif // LLDB_HOST_SOCKETADDRESS_H
189