forked from mas-bandwidth/yojimbo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
yojimbo_address.h
356 lines (232 loc) · 12.2 KB
/
yojimbo_address.h
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
Yojimbo Client/Server Network Protocol Library.
Copyright © 2016, The Network Protocol Company, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef YOJIMBO_ADDRESS_H
#define YOJIMBO_ADDRESS_H
#include "yojimbo_config.h"
#include <stdint.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct addrinfo;
struct sockaddr_in6;
struct sockaddr_storage;
namespace yojimbo
{
/**
The maximum length of an address when converted to a string (includes terminating NULL).
@see Address::ToString
*/
const int MaxAddressLength = 256;
/**
Address type.
@see Address::GetType.
*/
enum AddressType
{
ADDRESS_NONE, ///< Not an address. Set by the default constructor.
ADDRESS_IPV4, ///< An IPv4 address, eg: "146.95.129.237"
ADDRESS_IPV6 ///< An IPv6 address, eg: "48d9:4a08:b543:ae31:89d8:3226:b92c:cbba"
};
/**
An IP address and port number.
Supports both IPv4 and IPv6 addresses.
Identifies where a packet came from, and where a packet should be sent.
*/
class Address
{
AddressType m_type; ///< The address type: IPv4 or IPv6.
union
{
uint32_t ipv4; ///< IPv4 address data. Valid if type is ADDRESS_IPV4.
uint16_t ipv6[8]; ///< IPv6 address data. Valid if type is ADDRESS_IPV6.
} m_address;
uint16_t m_port; ///< The IP port. Valid for IPv4 and IPv6 address types.
public:
/**
Address default constructor.
Designed for convenience so you can have address members of classes and initialize them via assignment.
An address created by the default constructor will have address type set to ADDRESS_NONE. Address::IsValid will return false.
@see IsValid
*/
Address();
/**
Create an IPv4 address.
IMPORTANT: Pass in port in local byte order. The address class handles the conversion to network order for you.
@param a The first field of the IPv4 address.
@param b The second field of the IPv4 address.
@param c The third field of the IPv4 address.
@param d The fourth field of the IPv4 address.
@param port The IPv4 port (local byte order).
*/
Address( uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port = 0 );
/**
Create an IPv4 address.
IMPORTANT: Pass in address and port in local byte order. The address class handles the conversion to network order for you.
@param address The IPv4 address (local byte order).
@param port The IPv4 port (local byte order).
*/
explicit Address( uint32_t address, int16_t port = 0 );
/**
Create an IPv6 address.
IMPORTANT: Pass in address fields and the port in local byte order. The address class handles the conversion to network order for you.
@param a First field of the IPv6 address (local byte order).
@param b Second field of the IPv6 address (local byte order).
@param c Third field of the IPv6 address (local byte order).
@param d Fourth field of the IPv6 address (local byte order).
@param e Fifth field of the IPv6 address (local byte order).
@param f Sixth field of the IPv6 address (local byte order).
@param g Seventh field of the IPv6 address (local byte order).
@param h Eigth field of the IPv6 address (local byte order).
@param port The IPv6 port (local byte order).
*/
explicit Address( uint16_t a, uint16_t b, uint16_t c, uint16_t d,
uint16_t e, uint16_t f, uint16_t g, uint16_t h,
uint16_t port = 0 );
/**
Create an IPv6 address.
IMPORTANT: Pass in address fields and the port in local byte order. The address class handles the conversion to network order for you.
@param address Array containing 8 16bit address fields for the IPv6 address (local byte order).
@param port The IPv6 port (local byte order).
*/
explicit Address( const uint16_t address[], uint16_t port = 0 );
/**
Create an address from a sockaddr_storage.
This is a convenience function for working with BSD socket APIs.
Depending on the information in sockaddr_storage ss_family, the address will become ADDRESS_TYPE_IPV4 or ADDRESS_TYPE_IPV6.
If something goes wrong in the conversion the address type is set to ADDRESS_TYPE_NONE and Address::IsValid returns false.
@param addr The sockaddr_storage data to convert to an address.
@see Address::IsValid
@see Address::GetType
*/
explicit Address( const sockaddr_storage * addr );
/**
Parse a string to an address.
This versions supports parsing a port included in the address string. For example, "127.0.0.1:4000" and "[::1]:40000".
Parsing is performed via inet_pton once the port # has been extracted from the string, so you may specify any IPv4 or IPv6 address formatted in any valid way, and it should work as you expect.
Depending on the type of data in the string the address will become ADDRESS_TYPE_IPV4 or ADDRESS_TYPE_IPV6.
If the string is not recognized as a valid address, the address type is set to ADDRESS_TYPE_NONE, causing Address::IsValid to return false. Please check that after creating an address from a string.
@param address The string to parse to create the address.
@see Address::IsValid
@see Address::GetType
*/
explicit Address( const char * address );
/**
Parse a string to an address.
This versions overrides any port read in the address with the port parameter. This lets you parse "127.0.0.1" and "[::1]" and pass in the port you want programatically.
Parsing is performed via inet_pton once the port # has been extracted from the string, so you may specify any IPv4 or IPv6 address formatted in any valid way, and it should work as you expect.
Depending on the type of data in the string the address will become ADDRESS_TYPE_IPV4 or ADDRESS_TYPE_IPV6.
If the string is not recognized as a valid address, the address type is set to ADDRESS_TYPE_NONE, causing Address::IsValid to return false. Please check that after creating an address from a string.
@param address The string to parse to create the address.
@param port Overrides the port number read from the string (if any).
@see Address::IsValid
@see Address::GetType
*/
explicit Address( const char * address, uint16_t port );
/**
Clear the address.
The address type is set to ADDRESS_TYPE_NONE.
After this function is called Address::IsValid will return false.
*/
void Clear();
/**
Get the IPv4 address data.
@returns The IPv4 address (local byte order).
*/
uint32_t GetAddress4() const;
/**
Get the IPv6 address data.
@returns the IPv6 address data (local byte order).
*/
const uint16_t * GetAddress6() const;
/**
Set the port.
This is useful when you want to programatically set a server port, eg. try to open a server on ports 40000, 40001, etc...
@param port The port number (local byte order). Works for both IPv4 and IPv6 addresses.
*/
void SetPort( uint16_t port );
/**
Get the port number.
@returns The port number (local byte order).
*/
uint16_t GetPort() const;
/**
Get the address type.
@returns The address type: ADDRESS_NONE, ADDRESS_IPV4 or ADDRESS_IPV6.
*/
AddressType GetType() const;
/**
Convert the address to a string.
@param buffer The buffer the address will be written to.
@param bufferSize The size of the buffer in bytes. Must be at least MaxAddressLength.
*/
const char * ToString( char buffer[], int bufferSize ) const;
/**
True if the address is valid.
A valid address is any address with a type other than ADDRESS_TYPE_NONE.
@returns True if the address is valid, false otherwise.
*/
bool IsValid() const;
/**
Is this a loopback address?
Corresponds to an IPv4 address of "127.0.0.1", or an IPv6 address of "::1".
@returns True if this is the loopback address.
*/
bool IsLoopback() const;
/**
Is this an IPv6 link local address?
Corresponds to the first field of the address being 0xfe80
@returns True if this address is a link local IPv6 address.
*/
bool IsLinkLocal() const;
/**
Is this an IPv6 site local address?
Corresponds to the first field of the address being 0xfec0
@returns True if this address is a site local IPv6 address.
*/
bool IsSiteLocal() const;
/**
Is this an IPv6 multicast address?
Corresponds to the first field of the IPv6 address being 0xff00
@returns True if this address is a multicast IPv6 address.
*/
bool IsMulticast() const;
/**
Is this in IPv6 global unicast address?
Corresponds to any IPv6 address that is not any of the following:
1. Link Local
2. Site Local
3. Multicast
4. Loopback
@returns True if this is a global unicast IPv6 address.
*/
bool IsGlobalUnicast() const;
// -----------------------------------
bool operator ==( const Address & other ) const;
bool operator !=( const Address & other ) const;
protected:
/**
Helper function to parse an address string.
Used by the constructors that take a string parameter.
@param address The string to parse.
*/
void Parse( const char * address );
};
}
#endif // #ifndef YOJIMBO_ADDRESS_H