1getaddrinfo(3) Library Functions Manual getaddrinfo(3)
2
3
4
6 getaddrinfo, freeaddrinfo, gai_strerror - network address and service
7 translation
8
10 Standard C library (libc, -lc)
11
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netdb.h>
16
17 int getaddrinfo(const char *restrict node,
18 const char *restrict service,
19 const struct addrinfo *restrict hints,
20 struct addrinfo **restrict res);
21
22 void freeaddrinfo(struct addrinfo *res);
23
24 const char *gai_strerror(int errcode);
25
26 Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
27
28 getaddrinfo(), freeaddrinfo(), gai_strerror():
29 Since glibc 2.22:
30 _POSIX_C_SOURCE >= 200112L
31 glibc 2.21 and earlier:
32 _POSIX_C_SOURCE
33
35 Given node and service, which identify an Internet host and a service,
36 getaddrinfo() returns one or more addrinfo structures, each of which
37 contains an Internet address that can be specified in a call to bind(2)
38 or connect(2). The getaddrinfo() function combines the functionality
39 provided by the gethostbyname(3) and getservbyname(3) functions into a
40 single interface, but unlike the latter functions, getaddrinfo() is
41 reentrant and allows programs to eliminate IPv4-versus-IPv6 dependen‐
42 cies.
43
44 The addrinfo structure used by getaddrinfo() contains the following
45 fields:
46
47 struct addrinfo {
48 int ai_flags;
49 int ai_family;
50 int ai_socktype;
51 int ai_protocol;
52 socklen_t ai_addrlen;
53 struct sockaddr *ai_addr;
54 char *ai_canonname;
55 struct addrinfo *ai_next;
56 };
57
58 The hints argument points to an addrinfo structure that specifies cri‐
59 teria for selecting the socket address structures returned in the list
60 pointed to by res. If hints is not NULL it points to an addrinfo
61 structure whose ai_family, ai_socktype, and ai_protocol specify crite‐
62 ria that limit the set of socket addresses returned by getaddrinfo(),
63 as follows:
64
65 ai_family
66 This field specifies the desired address family for the returned
67 addresses. Valid values for this field include AF_INET and
68 AF_INET6. The value AF_UNSPEC indicates that getaddrinfo()
69 should return socket addresses for any address family (either
70 IPv4 or IPv6, for example) that can be used with node and ser‐
71 vice.
72
73 ai_socktype
74 This field specifies the preferred socket type, for example
75 SOCK_STREAM or SOCK_DGRAM. Specifying 0 in this field indicates
76 that socket addresses of any type can be returned by getad‐
77 drinfo().
78
79 ai_protocol
80 This field specifies the protocol for the returned socket ad‐
81 dresses. Specifying 0 in this field indicates that socket ad‐
82 dresses with any protocol can be returned by getaddrinfo().
83
84 ai_flags
85 This field specifies additional options, described below. Mul‐
86 tiple flags are specified by bitwise OR-ing them together.
87
88 All the other fields in the structure pointed to by hints must contain
89 either 0 or a null pointer, as appropriate.
90
91 Specifying hints as NULL is equivalent to setting ai_socktype and
92 ai_protocol to 0; ai_family to AF_UNSPEC; and ai_flags to
93 (AI_V4MAPPED | AI_ADDRCONFIG). (POSIX specifies different defaults for
94 ai_flags; see NOTES.) node specifies either a numerical network ad‐
95 dress (for IPv4, numbers-and-dots notation as supported by
96 inet_aton(3); for IPv6, hexadecimal string format as supported by
97 inet_pton(3)), or a network hostname, whose network addresses are
98 looked up and resolved. If hints.ai_flags contains the AI_NUMERICHOST
99 flag, then node must be a numerical network address. The AI_NUMERI‐
100 CHOST flag suppresses any potentially lengthy network host address
101 lookups.
102
103 If the AI_PASSIVE flag is specified in hints.ai_flags, and node is
104 NULL, then the returned socket addresses will be suitable for
105 bind(2)ing a socket that will accept(2) connections. The returned
106 socket address will contain the "wildcard address" (INADDR_ANY for IPv4
107 addresses, IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is
108 used by applications (typically servers) that intend to accept connec‐
109 tions on any of the host's network addresses. If node is not NULL,
110 then the AI_PASSIVE flag is ignored.
111
112 If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned
113 socket addresses will be suitable for use with connect(2), sendto(2),
114 or sendmsg(2). If node is NULL, then the network address will be set
115 to the loopback interface address (INADDR_LOOPBACK for IPv4 addresses,
116 IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications
117 that intend to communicate with peers running on the same host.
118
119 service sets the port in each returned address structure. If this ar‐
120 gument is a service name (see services(5)), it is translated to the
121 corresponding port number. This argument can also be specified as a
122 decimal number, which is simply converted to binary. If service is
123 NULL, then the port number of the returned socket addresses will be
124 left uninitialized. If AI_NUMERICSERV is specified in hints.ai_flags
125 and service is not NULL, then service must point to a string containing
126 a numeric port number. This flag is used to inhibit the invocation of
127 a name resolution service in cases where it is known not to be re‐
128 quired.
129
130 Either node or service, but not both, may be NULL.
131
132 The getaddrinfo() function allocates and initializes a linked list of
133 addrinfo structures, one for each network address that matches node and
134 service, subject to any restrictions imposed by hints, and returns a
135 pointer to the start of the list in res. The items in the linked list
136 are linked by the ai_next field.
137
138 There are several reasons why the linked list may have more than one
139 addrinfo structure, including: the network host is multihomed, accessi‐
140 ble over multiple protocols (e.g., both AF_INET and AF_INET6); or the
141 same service is available from multiple socket types (one SOCK_STREAM
142 address and another SOCK_DGRAM address, for example). Normally, the
143 application should try using the addresses in the order in which they
144 are returned. The sorting function used within getaddrinfo() is de‐
145 fined in RFC 3484; the order can be tweaked for a particular system by
146 editing /etc/gai.conf (available since glibc 2.5).
147
148 If hints.ai_flags includes the AI_CANONNAME flag, then the ai_canonname
149 field of the first of the addrinfo structures in the returned list is
150 set to point to the official name of the host.
151
152 The remaining fields of each returned addrinfo structure are initial‐
153 ized as follows:
154
155 • The ai_family, ai_socktype, and ai_protocol fields return the socket
156 creation parameters (i.e., these fields have the same meaning as the
157 corresponding arguments of socket(2)). For example, ai_family might
158 return AF_INET or AF_INET6; ai_socktype might return SOCK_DGRAM or
159 SOCK_STREAM; and ai_protocol returns the protocol for the socket.
160
161 • A pointer to the socket address is placed in the ai_addr field, and
162 the length of the socket address, in bytes, is placed in the ai_ad‐
163 drlen field.
164
165 If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses
166 are returned in the list pointed to by res only if the local system has
167 at least one IPv4 address configured, and IPv6 addresses are returned
168 only if the local system has at least one IPv6 address configured. The
169 loopback address is not considered for this case as valid as a config‐
170 ured address. This flag is useful on, for example, IPv4-only systems,
171 to ensure that getaddrinfo() does not return IPv6 socket addresses that
172 would always fail in connect(2) or bind(2).
173
174 If hints.ai_flags specifies the AI_V4MAPPED flag, and hints.ai_family
175 was specified as AF_INET6, and no matching IPv6 addresses could be
176 found, then return IPv4-mapped IPv6 addresses in the list pointed to by
177 res. If both AI_V4MAPPED and AI_ALL are specified in hints.ai_flags,
178 then return both IPv6 and IPv4-mapped IPv6 addresses in the list
179 pointed to by res. AI_ALL is ignored if AI_V4MAPPED is not also speci‐
180 fied.
181
182 The freeaddrinfo() function frees the memory that was allocated for the
183 dynamically allocated linked list res.
184
185 Extensions to getaddrinfo() for Internationalized Domain Names
186 Starting with glibc 2.3.4, getaddrinfo() has been extended to selec‐
187 tively allow the incoming and outgoing hostnames to be transparently
188 converted to and from the Internationalized Domain Name (IDN) format
189 (see RFC 3490, Internationalizing Domain Names in Applications (IDNA)).
190 Four new flags are defined:
191
192 AI_IDN If this flag is specified, then the node name given in node is
193 converted to IDN format if necessary. The source encoding is
194 that of the current locale.
195
196 If the input name contains non-ASCII characters, then the IDN
197 encoding is used. Those parts of the node name (delimited by
198 dots) that contain non-ASCII characters are encoded using ASCII
199 Compatible Encoding (ACE) before being passed to the name reso‐
200 lution functions.
201
202 AI_CANONIDN
203 After a successful name lookup, and if the AI_CANONNAME flag was
204 specified, getaddrinfo() will return the canonical name of the
205 node corresponding to the addrinfo structure value passed back.
206 The return value is an exact copy of the value returned by the
207 name resolution function.
208
209 If the name is encoded using ACE, then it will contain the xn--
210 prefix for one or more components of the name. To convert these
211 components into a readable form the AI_CANONIDN flag can be
212 passed in addition to AI_CANONNAME. The resulting string is en‐
213 coded using the current locale's encoding.
214
215 AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES
216 Setting these flags will enable the IDNA_ALLOW_UNASSIGNED (allow
217 unassigned Unicode code points) and IDNA_USE_STD3_ASCII_RULES
218 (check output to make sure it is a STD3 conforming hostname)
219 flags respectively to be used in the IDNA handling.
220
222 getaddrinfo() returns 0 if it succeeds, or one of the following nonzero
223 error codes:
224
225 EAI_ADDRFAMILY
226 The specified network host does not have any network addresses
227 in the requested address family.
228
229 EAI_AGAIN
230 The name server returned a temporary failure indication. Try
231 again later.
232
233 EAI_BADFLAGS
234 hints.ai_flags contains invalid flags; or, hints.ai_flags in‐
235 cluded AI_CANONNAME and name was NULL.
236
237 EAI_FAIL
238 The name server returned a permanent failure indication.
239
240 EAI_FAMILY
241 The requested address family is not supported.
242
243 EAI_MEMORY
244 Out of memory.
245
246 EAI_NODATA
247 The specified network host exists, but does not have any network
248 addresses defined.
249
250 EAI_NONAME
251 The node or service is not known; or both node and service are
252 NULL; or AI_NUMERICSERV was specified in hints.ai_flags and ser‐
253 vice was not a numeric port-number string.
254
255 EAI_SERVICE
256 The requested service is not available for the requested socket
257 type. It may be available through another socket type. For ex‐
258 ample, this error could occur if service was "shell" (a service
259 available only on stream sockets), and either hints.ai_protocol
260 was IPPROTO_UDP, or hints.ai_socktype was SOCK_DGRAM; or the er‐
261 ror could occur if service was not NULL, and hints.ai_socktype
262 was SOCK_RAW (a socket type that does not support the concept of
263 services).
264
265 EAI_SOCKTYPE
266 The requested socket type is not supported. This could occur,
267 for example, if hints.ai_socktype and hints.ai_protocol are in‐
268 consistent (e.g., SOCK_DGRAM and IPPROTO_TCP, respectively).
269
270 EAI_SYSTEM
271 Other system error; errno is set to indicate the error.
272
273 The gai_strerror() function translates these error codes to a human
274 readable string, suitable for error reporting.
275
277 /etc/gai.conf
278
280 For an explanation of the terms used in this section, see at‐
281 tributes(7).
282
283 ┌─────────────────────────────────┬───────────────┬────────────────────┐
284 │Interface │ Attribute │ Value │
285 ├─────────────────────────────────┼───────────────┼────────────────────┤
286 │getaddrinfo() │ Thread safety │ MT-Safe env locale │
287 ├─────────────────────────────────┼───────────────┼────────────────────┤
288 │freeaddrinfo(), gai_strerror() │ Thread safety │ MT-Safe │
289 └─────────────────────────────────┴───────────────┴────────────────────┘
290
292 According to POSIX.1, specifying hints as NULL should cause ai_flags to
293 be assumed as 0. The GNU C library instead assumes a value of
294 (AI_V4MAPPED | AI_ADDRCONFIG) for this case, since this value is
295 considered an improvement on the specification.
296
298 POSIX.1-2008.
299
300 getaddrinfo()
301 RFC 2553.
302
304 POSIX.1-2001.
305
306 AI_ADDRCONFIG
307 AI_ALL
308 AI_V4MAPPED
309 glibc 2.3.3.
310
311 AI_NUMERICSERV
312 glibc 2.3.4.
313
315 getaddrinfo() supports the address%scope-id notation for specifying the
316 IPv6 scope-ID.
317
319 The following programs demonstrate the use of getaddrinfo(),
320 gai_strerror(), freeaddrinfo(), and getnameinfo(3). The programs are
321 an echo server and client for UDP datagrams.
322
323 Server program
324
325 #include <netdb.h>
326 #include <stdio.h>
327 #include <stdlib.h>
328 #include <string.h>
329 #include <sys/socket.h>
330 #include <sys/types.h>
331 #include <unistd.h>
332
333 #define BUF_SIZE 500
334
335 int
336 main(int argc, char *argv[])
337 {
338 int sfd, s;
339 char buf[BUF_SIZE];
340 ssize_t nread;
341 socklen_t peer_addrlen;
342 struct addrinfo hints;
343 struct addrinfo *result, *rp;
344 struct sockaddr_storage peer_addr;
345
346 if (argc != 2) {
347 fprintf(stderr, "Usage: %s port\n", argv[0]);
348 exit(EXIT_FAILURE);
349 }
350
351 memset(&hints, 0, sizeof(hints));
352 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
353 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
354 hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
355 hints.ai_protocol = 0; /* Any protocol */
356 hints.ai_canonname = NULL;
357 hints.ai_addr = NULL;
358 hints.ai_next = NULL;
359
360 s = getaddrinfo(NULL, argv[1], &hints, &result);
361 if (s != 0) {
362 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
363 exit(EXIT_FAILURE);
364 }
365
366 /* getaddrinfo() returns a list of address structures.
367 Try each address until we successfully bind(2).
368 If socket(2) (or bind(2)) fails, we (close the socket
369 and) try the next address. */
370
371 for (rp = result; rp != NULL; rp = rp->ai_next) {
372 sfd = socket(rp->ai_family, rp->ai_socktype,
373 rp->ai_protocol);
374 if (sfd == -1)
375 continue;
376
377 if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
378 break; /* Success */
379
380 close(sfd);
381 }
382
383 freeaddrinfo(result); /* No longer needed */
384
385 if (rp == NULL) { /* No address succeeded */
386 fprintf(stderr, "Could not bind\n");
387 exit(EXIT_FAILURE);
388 }
389
390 /* Read datagrams and echo them back to sender. */
391
392 for (;;) {
393 char host[NI_MAXHOST], service[NI_MAXSERV];
394
395 peer_addrlen = sizeof(peer_addr);
396 nread = recvfrom(sfd, buf, BUF_SIZE, 0,
397 (struct sockaddr *) &peer_addr, &peer_addrlen);
398 if (nread == -1)
399 continue; /* Ignore failed request */
400
401 s = getnameinfo((struct sockaddr *) &peer_addr,
402 peer_addrlen, host, NI_MAXHOST,
403 service, NI_MAXSERV, NI_NUMERICSERV);
404 if (s == 0)
405 printf("Received %zd bytes from %s:%s\n",
406 nread, host, service);
407 else
408 fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
409
410 if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,
411 peer_addrlen) != nread)
412 {
413 fprintf(stderr, "Error sending response\n");
414 }
415 }
416 }
417
418 Client program
419
420 #include <netdb.h>
421 #include <stdio.h>
422 #include <stdlib.h>
423 #include <string.h>
424 #include <sys/socket.h>
425 #include <sys/types.h>
426 #include <unistd.h>
427
428 #define BUF_SIZE 500
429
430 int
431 main(int argc, char *argv[])
432 {
433 int sfd, s;
434 char buf[BUF_SIZE];
435 size_t len;
436 ssize_t nread;
437 struct addrinfo hints;
438 struct addrinfo *result, *rp;
439
440 if (argc < 3) {
441 fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
442 exit(EXIT_FAILURE);
443 }
444
445 /* Obtain address(es) matching host/port. */
446
447 memset(&hints, 0, sizeof(hints));
448 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
449 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
450 hints.ai_flags = 0;
451 hints.ai_protocol = 0; /* Any protocol */
452
453 s = getaddrinfo(argv[1], argv[2], &hints, &result);
454 if (s != 0) {
455 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
456 exit(EXIT_FAILURE);
457 }
458
459 /* getaddrinfo() returns a list of address structures.
460 Try each address until we successfully connect(2).
461 If socket(2) (or connect(2)) fails, we (close the socket
462 and) try the next address. */
463
464 for (rp = result; rp != NULL; rp = rp->ai_next) {
465 sfd = socket(rp->ai_family, rp->ai_socktype,
466 rp->ai_protocol);
467 if (sfd == -1)
468 continue;
469
470 if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
471 break; /* Success */
472
473 close(sfd);
474 }
475
476 freeaddrinfo(result); /* No longer needed */
477
478 if (rp == NULL) { /* No address succeeded */
479 fprintf(stderr, "Could not connect\n");
480 exit(EXIT_FAILURE);
481 }
482
483 /* Send remaining command-line arguments as separate
484 datagrams, and read responses from server. */
485
486 for (size_t j = 3; j < argc; j++) {
487 len = strlen(argv[j]) + 1;
488 /* +1 for terminating null byte */
489
490 if (len > BUF_SIZE) {
491 fprintf(stderr,
492 "Ignoring long message in argument %zu\n", j);
493 continue;
494 }
495
496 if (write(sfd, argv[j], len) != len) {
497 fprintf(stderr, "partial/failed write\n");
498 exit(EXIT_FAILURE);
499 }
500
501 nread = read(sfd, buf, BUF_SIZE);
502 if (nread == -1) {
503 perror("read");
504 exit(EXIT_FAILURE);
505 }
506
507 printf("Received %zd bytes: %s\n", nread, buf);
508 }
509
510 exit(EXIT_SUCCESS);
511 }
512
514 getaddrinfo_a(3), gethostbyname(3), getnameinfo(3), inet(3),
515 gai.conf(5), hostname(7), ip(7)
516
517
518
519Linux man-pages 6.05 2023-07-20 getaddrinfo(3)