aboutsummaryrefslogtreecommitdiff
path: root/lldb/include/lldb/Host/SocketAddress.h
blob: 862e1104a084d44e5ae05eb685888a048f753104 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//===-- SocketAddress.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_HOST_SOCKETADDRESS_H
#define LLDB_HOST_SOCKETADDRESS_H

#include <stdint.h>

#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#include <winsock2.h>
#include <ws2tcpip.h>
typedef ADDRESS_FAMILY sa_family_t;
#else
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif

#if defined(__FreeBSD__)
#include <sys/types.h>
#endif

#include <string>
#include <vector>

namespace lldb_private {

class SocketAddress {
public:
  // Static method to get all address information for a host and/or service
  static std::vector<SocketAddress>
  GetAddressInfo(const char *hostname, const char *servname, int ai_family,
                 int ai_socktype, int ai_protocol, int ai_flags = 0);

  // Constructors and Destructors
  SocketAddress();
  SocketAddress(const struct addrinfo *addr_info);
  SocketAddress(const struct sockaddr &s);
  SocketAddress(const struct sockaddr_in &s);
  SocketAddress(const struct sockaddr_in6 &s);
  SocketAddress(const struct sockaddr_storage &s);
  ~SocketAddress();

  // Operators
  const SocketAddress &operator=(const struct addrinfo *addr_info);

  const SocketAddress &operator=(const struct sockaddr &s);

  const SocketAddress &operator=(const struct sockaddr_in &s);

  const SocketAddress &operator=(const struct sockaddr_in6 &s);

  const SocketAddress &operator=(const struct sockaddr_storage &s);

  bool operator==(const SocketAddress &rhs) const;
  bool operator!=(const SocketAddress &rhs) const;

  // Clear the contents of this socket address
  void Clear();

  // Get the length for the current socket address family
  socklen_t GetLength() const;

  // Get the max length for the largest socket address supported.
  static socklen_t GetMaxLength();

  // Get the socket address family
  sa_family_t GetFamily() const;

  // Set the socket address family
  void SetFamily(sa_family_t family);

  // Get the address
  std::string GetIPAddress() const;

  // Get the port if the socket address for the family has a port
  uint16_t GetPort() const;

  // Set the port if the socket address for the family has a port. The family
  // must be set correctly prior to calling this function.
  bool SetPort(uint16_t port);

  // Set the socket address according to the first match from a call to
  // getaddrinfo() (or equivalent functions for systems that don't have
  // getaddrinfo(). If "addr_info_ptr" is not NULL, it will get filled in with
  // the match that was used to populate this socket address.
  bool
  getaddrinfo(const char *host,    // Hostname ("foo.bar.com" or "foo" or IP
                                   // address string ("123.234.12.1" or
                                   // "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
              const char *service, // Protocol name ("tcp", "http", etc) or a
                                   // raw port number string ("81")
              int ai_family = PF_UNSPEC, int ai_socktype = 0,
              int ai_protocol = 0, int ai_flags = 0);

  // Quick way to set the SocketAddress to localhost given the family. Returns
  // true if successful, false if "family" doesn't support localhost or if
  // "family" is not supported by this class.
  bool SetToLocalhost(sa_family_t family, uint16_t port);

  bool SetToAnyAddress(sa_family_t family, uint16_t port);

  // Returns true if there is a valid socket address in this object.
  bool IsValid() const;

  // Returns true if the socket is INADDR_ANY
  bool IsAnyAddr() const;

  // Returns true if the socket is INADDR_LOOPBACK
  bool IsLocalhost() const;

  // Direct access to all of the sockaddr structures
  struct sockaddr &sockaddr() {
    return m_socket_addr.sa;
  }

  const struct sockaddr &sockaddr() const { return m_socket_addr.sa; }

  struct sockaddr_in &sockaddr_in() {
    return m_socket_addr.sa_ipv4;
  }

  const struct sockaddr_in &sockaddr_in() const {
    return m_socket_addr.sa_ipv4;
  }

  struct sockaddr_in6 &sockaddr_in6() {
    return m_socket_addr.sa_ipv6;
  }

  const struct sockaddr_in6 &sockaddr_in6() const {
    return m_socket_addr.sa_ipv6;
  }

  struct sockaddr_storage &sockaddr_storage() {
    return m_socket_addr.sa_storage;
  }

  const struct sockaddr_storage &sockaddr_storage() const {
    return m_socket_addr.sa_storage;
  }

  // Conversion operators to allow getting the contents of this class as a
  // pointer to the appropriate structure. This allows an instance of this
  // class to be used in calls that take one of the sockaddr structure variants
  // without having to manually use the correct accessor function.

  operator struct sockaddr *() { return &m_socket_addr.sa; }

  operator const struct sockaddr *() const { return &m_socket_addr.sa; }

  operator struct sockaddr_in *() { return &m_socket_addr.sa_ipv4; }

  operator const struct sockaddr_in *() const { return &m_socket_addr.sa_ipv4; }

  operator struct sockaddr_in6 *() { return &m_socket_addr.sa_ipv6; }

  operator const struct sockaddr_in6 *() const {
    return &m_socket_addr.sa_ipv6;
  }

  operator const struct sockaddr_storage *() const {
    return &m_socket_addr.sa_storage;
  }

  operator struct sockaddr_storage *() { return &m_socket_addr.sa_storage; }

protected:
  typedef union sockaddr_tag {
    struct sockaddr sa;
    struct sockaddr_in sa_ipv4;
    struct sockaddr_in6 sa_ipv6;
    struct sockaddr_storage sa_storage;
  } sockaddr_t;

  // Classes that inherit from SocketAddress can see and modify these
  sockaddr_t m_socket_addr;
};

} // namespace lldb_private

#endif // LLDB_HOST_SOCKETADDRESS_H