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