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>
18typedef 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
32namespace lldb_private {
33
34class SocketAddress {
35public:
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
174protected:
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