3
<title>EndpointAddress Class</title>
6
<h1>Table of Contents</h1>
8
<li><a href="#1.">1. Network Addressing</a>
9
<li><a href="#2.">2. EndpointAddrlist class</a>
11
<li><a href="#2.1.">2.1. Constructors</a>
13
<li><a href="#3.">3. EndpointAddress</a>
15
<li><a href="#3.1.">3.1. Constructor</a>
17
<li><a href="#4.">4. File Locations</a>
18
<li><a href="#5.">5. Errors from <tt>getaddrinfo</tt></a>
20
<li><a href="#5.1.">5.1. Resolution Errors</a>
21
<li><a href="#5.2.">5.2. Usage Errors</a>
25
<a name="1."><h1>1. Network Addressing</h1></a>
26
<p>Addressing a socket is not a trivial topic. A port number, transport layer
27
protocol, and possibly more than one IPv4 or IPv6 or DNS address must be
28
given. The DNS has to be resolved, addresses have to be chosen, port numbers
29
must be resolved, and so on.
31
<p>Fortunately, nearly everything needed to represent an Internet address
32
can be encapsulated into a regular ordinary <tt>string</tt>, which can be
33
entered by the user. All thats needed is this string to create an
34
<tt>EndpointAddrlist</tt> object, although other information may be supplied
35
(in particular, the transport layer protocol -- UDP or TCP -- must be passed
36
outside of the string, for security reasons). EndpointAddrlist attempts to
37
take care of everything regarding addresses, including things which many
38
applications would otherwise ignore (such as multiple addresses per name).
40
<p><tt>Endpoint</tt> accepts EndpointAddrlist as remote and local addresses,
41
in which case all the addresses shall be tried. EndpointAddress encapsulates
44
<a name="2."><h1>2. EndpointAddrlist Class</h1></a>
45
<p>EndpointAddrlist encapsulates an array of <tt>addrinfo</tt>s obtained
46
through the protocol-independent <tt>getaddrinfo</tt>. Although the class
47
name is singular, it is possible for multiple addresses to be listed within.
48
Your application can choose to ignore all but one, but its recommended to
49
try to connect to alternative addresses if the first one doesn't work,
52
<a name="2.1."><h2>2.1. Constructors</h2></a>
53
<p>The following arguments are accepted, in order:
55
<h3>string hostname</h3>
56
<p>A hostname. This is passed to <tt>getnameinfo</tt> which either resolves
57
the DNS name or uses <tt>inet_pton</tt> to convert from presentation form
58
to numeric form. Note that <tt>inet_pton</tt> only supports dotted-decimal
59
IPv4 or hex-string IPv6 addresss, and <b>not</b> the following alternative
60
IPv4 address formats (which <tt>inet_aton</tt> and therefore ping support):
62
<li><b>Implied octets</b>: 127.1 = 127.0.0.1, 127.1.2 = 127.1.0.2
63
<li><b>Hexadecimal octets</b>: 0x7f.0.0.0 = 127.0.0.1
64
<li><b>Octal octets</b>: 0377.0377.0377.0377 = 255.255.255.255
65
<li><b>Binary octets?</b>
66
<li><b>Dotless addresses</b>: 2130706433 = 127.0.0.1,
67
0x7f000001 = 127.0.0.1, 017700000001 = 127.0.0.1
69
<p>Regular dotted-decimal strings such as "127.0.0.1" (IPv4) and hex string
70
"::1" (IPv6) are allowed. DNS names may resolve to either IPv4 or
71
IPv6 addresses, depending on if A or AAAA resource records exist.
72
If your host doesn't support both IPv4 and IPv6, either one can be disabled
73
by setting the default address family later on.
75
<p>The hostname can also contain a service port, in URL-style. That is,
76
a hostname followed by a colon and then a port, rather than a period. Netstat
77
represents port 139 of 10.0.0.2 as "10.0.0.2.139", but this is not acceptable.
78
"10.0.0.2:139" is supported by this class, and has the advantage of being
79
aesthetically pleasing and easy to parse. With one exception.
81
<p>IPv6 addresses contain embedded colons. However, they always contain
82
more than one colon. "::1" is interpreted as an IPv6 address with no port,
83
while "127.0.0.1:1" is interpreted as port 1 on 127.0.0.1. So how can port
84
names be specified with IPv6 addresses? Several purposals have been made, but
85
the best by far (and the one which this class understands) is to enclose
86
the IPv6 address in brackets, like so: [::1]:80 = port 80 of ::1. IPv6-enabled
87
web browsers understand this. The parser is loose about what is accepted:
88
[::1]80, ::1]:80 and even ::1]80 will be interpreted identically, but you
89
shouldn't rely on this. For orthogonality (the [] notation has roots in
90
email systems), an IPv4 address is acceptable in brackets:
91
[127.0.0.1]:80 works as expected. Brackets also turn on AI_NUMERICHOST, which
92
prevents DNS resolving -- [example.com]:80 won't work, but example.com:80 will.
93
<i>Brackets enclose literals, they are optional with IPv4 but required with
96
<p>If a port is given, it replaces the <tt>service</tt> variable, described
97
below. This is to allow users to override default port numbers in case of an
98
emergency. It should not be viewed as a security concern.
100
<h3>string service = ""</h3>
101
<p>The service name resolves to a port number through <tt>services</tt>.
102
This means you can specify human-readable service names such as
103
"http" for port 80 TCP. Numeric strings are also allowed, such as "80";
104
this is passed to <tt>getaddrinfo</tt> and handled there.
106
<p><tt>getaddrinfo</tt> handles this input, but before it gets to it, this
107
class interprets port numbers with commas in them. The port number is 16-bits,
108
and both octets can be specified as two 0-255 integers, separated by a
109
common; for example, "1,2" is 0x0102. This is most useful for raw ICMP sockets;
110
they understand the first octet as the type code and the second as the code
111
code (this is specific to the Endpoint library). Other bases besides decimal
114
<p>This argument can often be omitted if you know for sure <tt>hostname</tt>
116
contain a port number, but specifying it is most useful for allowing a
117
default port if none is specified in <tt>hostname</tt>.
119
<h3>int type = 0</h3>
120
<p>A bitmask of the following:
122
<li><b>TCP</b> - Transport Control Protocol
123
<li><b>UDP</b> - User Datagram Protocol
124
<li><b>RAW_<i>xxx</i></b> - Raw socket with transport-layer protocol <i>xxx</i>
128
<li><b>CLIENT (0)</b> - Actively connects to another host
129
<li><b>SERVER (1)</b> - Passively waits for another host to connect
132
<p>The default is TCP | CLIENT, which seems to be the most common.
134
<p>To use IPv4 raw sockets on Unix, you need root access. You also need to give
135
the transport-layer protocol; these are derived from IPPROTO_, see protocols.h.
136
For example, to send raw ICMP packets, use RAW_ICMP, to send raw UDP, RAW_UDP.
137
Endpoint will make the IP header for you unless you choose RAW_RAW, in which
138
case you can do it yourself. The idea is that you RAW_xxx makes the raw IP as
139
well as xxx header for you, although this is only implemented with RAW_UDP
143
<h3>int family = EndpointAddrlist::g_default_family</h3>
144
<p>Specifies the address as well as protocol family. Allowed values are:
146
<li><b>AF_UNSPEC</b>: "unspecified", host is dual-stack and supports both
147
IPv4 and IPv6 (either is acceptable)
148
<li><b>AF_INET</b>: Only want IPv4 addresses
149
<li><b>AF_INET6</b>: Only want IPv6 addresses
151
<p>EndpointAddrlist::g_default_family can be set on a global (or at least
152
program-wide) scale, to reflect which protocol families the host supports.
153
An IPv4-only host would set this to AF_INET, an IPv6-only host AF_INET6,
154
a dual-stack IPv4 and IPv6 host would use AF_UNSPEC.
156
<h3>EndpointAddress GetAddress()</h3>
157
<p>Returns the current address. Unless GetAddressNext() is called, this is the
158
first address. See GetAddressNext(), which is preferred for most applications.
159
However, GetAddress() has its uses; sometimes there is no reason to try
160
multiple names, for example if there is no DNS name.
162
<h3>EndpointAddress GetAddressNext()</h3>
163
<p>Return the current address, and move to the next one (post-increment).
164
This should be done instead of just trying to use the first address. The
165
proper protocol is to try each address, until one succeeds.
167
<a name="3."><h1>3. EndpointAddress</h1></a>
168
<p>Encapsulates a single address. This is a subclass of the <tt>addrinfo</tt>
169
structure, whose declaration is reproduced below:
172
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
173
int ai_family; /* PF_xxx */
174
int ai_socktype; /* SOCK_xxx */
175
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
176
size_t ai_addrlen; /* length of ai_addr */
177
char *ai_canonname; /* canonical name for hostname */
178
struct sockaddr *ai_addr; /* binary address */
179
struct addrinfo *ai_next; /* next structure in linked list */
182
<p>There is also an m_bool boolean value, which is true if the fields above
185
<a name="3.1."><h2>3.1. Constructor</h2></a>
186
<p>EndpointAddrlist(addrinfo*) is the only constructor. If the pointer is
187
non-null, each field is copied shallowly and m_bool is true. If null,
190
<h2>operator string()</h2>
191
<p>Stringifies the address by returning IP() + ":" + Port(). The reason why
193
returned rather than its DNS name is threefold: not all hosts have DNS
194
names, DNS names may have more than one host, and forward/reverse DNS may
195
not match. If IP() contains a colon, it is put in square brackets as is
199
<p>Returns a human-readable form of the address. operator string() calls
200
this. The IP address will be returned, as either a dotted-decimal or
203
<p>This function internally calls <tt>inet_ntop</tt> (numeric to
204
presentation) with the proper flags and passing the proper structures,
205
depending on if the address is IPv4 or IPv6. Manually, this is tedious.
206
WinSock does not provide <tt>inet_ntop</tt> so a implementation copied
207
from BIND is provided.
209
<h2>string DNS()</h2>
210
<p>Returns the canonical DNS name in ai_cannonname, or an empty string
213
<h2>string Name()</h2>
214
<p>Returns DNS() if not empty, else IP().
216
<h2>string Port()</h2>
217
<p>Returns the port number.
219
<h2>operator bool()</h2>
220
<p>Returns m_bool, which is false if there is no address.
222
<a name="4."><h1>4. File Locations</h1></a>
223
<p><tt>services</tt> and <tt>hosts</tt> are used during service
224
and name resolution (name resolution additionally uses DNS). Both these
225
files can be by default found in the following locations:
227
<li><b>Unix:</b> /etc
228
<li><b>Windows NT, 2000, XP:</b> C:\windows\system32\drivers\etc, C:\winnt\system32\drivers\etc
229
<li><b>Windows 95, 98, Me:</b> C:\windows
232
<a name="5."><h1>5. Errors From <tt>getaddrinfo()</tt></h1></a>
233
<p>A non-zero return value from <tt>getaddrinfo</tt> is one of the following,
234
organized in order of likelihood, from greatest to least. The Posix 1g and
235
Win32 constants as well as BSD and Win32 <tt>gai_strerror</tt> results are
238
<a name="5.1."><h2>5.1. Resolution Errors</h2></a>
239
<p>If an error occurs, <tt>m_bool</tt> is set to false,
240
<tt>m_error_code</tt> is set to <tt>EP_ERROR_GETADDRINFO</tt>, and
241
<tt>m_error_str</tt> is set to a description of the problem.
243
<p>Unless literals are given, the hostname and service name need to be
244
resolved. Errors can happen in this process.
247
<h3>EAI_AGAIN = WSATRY_AGAIN</h3>
249
<li><b>BSD:</b> "Temporary failure in name resolution."
251
<p>There was a temporary DNS failure and you should try again.
253
<h3>EAI_FAIL = WSANO_RECOVERY</h3>
255
<li><b>BSD:</b> "Non-recoverable failure in name resolution."
259
<h3>EAI_NODATA = WSANO_DATA / EAI_NONAME</h3>
261
<li><b>BSD:</b> "No address associated with <i>hostname</i>."
263
<p>This was removed from RFC, its equivalence or lack thereof to
264
EAI_NONAME is unknown. The latest version of Windows defines EAI_NODATA
267
<h3>EAI_NONAME = WSAHOST_NOT_FOUND</h3>
269
<li><b>BSD:</b> "<i>hostname</i> or <i>service</i> not provided, or not known."
270
<li><b>Win32:</b> "No such host is known."
272
<p>Not provided or no address associated with hostname.
274
<h3>EAI_SERVICE = WSATYPE_NOT_FOUND</h3>
276
<li><b>BSD:</b> "<i>service</i> not supported for ai_socktype."
277
<li><b>Win32:</b> "The specified class was not found."
279
<p>The symbolic service name could not be resolved, the entry in
280
<tt>services</tt> is missing. The reference to "ai_socktype" means
281
that if you try to connect to the "domain" service with TCP, and
282
the <tt>services</tt> file only has an entry for TCP, you'll also get this
283
error (although most systems now define both TCP and UDP for all services).
284
This error never happens with numeric port numbers, so if
285
you're concerned about portability, use them. Win32's <tt>services</tt>
286
is quite small and doesn't cover all the esoteric service names, although
287
it has its uses with custom servers (if you use a symbolic service name
288
in your server and the user wants to change the port, all he has to do is
289
change the definition in <tt>services</tt> -- however, your install
290
program must add a line to the file.).
292
<a name="5.2."><h2>5.2. Usage Errors</h2></a>
293
<p>These errors are mostly the fault of the programmer; either you (the class
294
user) or me (the class programmer). Errors that "should not happen" should
295
not happen under class design, even if invalid parameters are passed to the class.
298
<h3>EAI_FAMILY = WSAEAFNOSUPPORT</h3>
300
<li><b>BSD:</b> "<i>ai_family</i> not supported."
301
<li><b>Win32:</b> "An address incompatible with the requested protocol was used."
303
<p>hints.ai_family is invalid. The address family is specified as the last
304
argument, and can be either AF_UNSPEC (IPv4 and/or) IPv6, AF_INET (IPv4),
305
or AF_INET6 (IPv4). If the parameter is not given,
306
EndpointAddress::g_default_family is used. Either the default family
307
(which defaults to AF_UNSPEC) or the passed family is invalid.
310
<h3>EAI_BADFLAGS = WSAEINVAL</h3>
312
<li><b>BSD:</b> "Invalid value for <i>ai_flags</i>."
313
<li><b>Win32:</b> never generated?
315
<p>Valid values are AI_PASSIVE, AI_CANONNAME, and AI_NUMERICHOST.
316
EndpointAddress only sets AI_PASSIVE (for servers) and AI_NUMERICHOST
317
(for bracketed literals) so this should never happen.
319
<h3>EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY</h3>
321
<li>BSD: "Memory allocation failure."
325
<h3>EAI_ADDRFAMILY</h3>
327
<li><b>BSD:</b> "Address family for <i>hostname</i> not supported."
328
<li><b>Win32:</b> N/A
330
<p>Presumably this means an address family other than AF_UNSPEC was
331
given, and no address of that type is associated with the hostname.
332
Does not exist on Win32.</p>
335
<h3>EAI_SOCKTYPE = WSAESOCKNOSUPPORT</h3>
337
<li><b>BSD:</b> "<i>ai_socktype</i> not supported."
338
<li><b>Win32:</b> "The support for the specified socket type does not exist in this address family."
340
<p>hints.ai_socktype is invalid. EndpointAddrlist sets this field to
341
either SOCK_DGRAM for UDP or SOCK_STREAM for TCP so this should never happen.
345
<li><b>BSD:</b> "System error returned in <i>errno</i>."
346
<li><b>Win32:</b> N/A
348
<p>This error code code is rarely used, but it means the errno variable
349
will contain additional error information. Does not exist on Win32 (and most Unixes).