summaryrefslogtreecommitdiffstats
path: root/newlib/libc/sys/linux/net/getaddrinfo.3
blob: eca8b03b2f1849ab7cadac95aef9c82aa7b0e30a (plain)
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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
GETADDRINFO(3)                     BSD Library Functions Manual                    GETADDRINFO(3)

NAME
     getaddrinfo, freeaddrinfo, gai_strerror -- nodename-to-address translation in protocol-inde-
     pendent manner

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <sys/types.h>
     #include <sys/socket.h>
     #include <netdb.h>

     int
     getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints,
         struct addrinfo **res);

     void
     freeaddrinfo(struct addrinfo *ai);

     char *
     gai_strerror(int ecode);

DESCRIPTION
     The getaddrinfo() function is defined for protocol-independent nodename-to-address transla-
     tion.  It performs the functionality of gethostbyname(3) and getservbyname(3), but in a more
     sophisticated manner.

     The addrinfo structure is defined as a result of including the <netdb.h> header:

     struct addrinfo {
          int     ai_flags;     /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
          int     ai_family;    /* PF_xxx */
          int     ai_socktype;  /* SOCK_xxx */
          int     ai_protocol;  /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
          size_t  ai_addrlen;   /* length of ai_addr */
          char   *ai_canonname; /* canonical name for nodename */
          struct sockaddr  *ai_addr; /* binary address */
          struct addrinfo  *ai_next; /* next structure in linked list */
     };

     The nodename and servname arguments are pointers to null-terminated strings or NULL.  One or
     both of these two arguments must be a non-NULL pointer.  In the normal client scenario, both
     the nodename and servname are specified.  In the normal server scenario, only the servname
     is specified.  A non-NULL nodename string can be either a node name or a numeric host ad-
     dress string (i.e., a dotted-decimal IPv4 address or an IPv6 hex address).  A non-NULL
     servname string can be either a service name or a decimal port number.

     The caller can optionally pass an addrinfo structure, pointed to by the third argument, to
     provide hints concerning the type of socket that the caller supports.  In this hints struc-
     ture all members other than ai_flags, ai_family, ai_socktype, and ai_protocol must be zero
     or a NULL pointer.  A value of PF_UNSPEC for ai_family means the caller will accept any pro-
     tocol family.  A value of 0 for ai_socktype means the caller will accept any socket type.  A
     value of 0 for ai_protocol means the caller will accept any protocol.  For example, if the
     caller handles only TCP and not UDP, then the ai_socktype member of the hints structure
     should be set to SOCK_STREAM when getaddrinfo() is called.  If the caller handles only IPv4
     and not IPv6, then the ai_family member of the hints structure should be set to PF_INET when
     getaddrinfo() is called.  If the third argument to getaddrinfo() is a NULL pointer, this is
     the same as if the caller had filled in an addrinfo structure initialized to zero with
     ai_family set to PF_UNSPEC.

     Upon successful return a pointer to a linked list of one or more addrinfo structures is re-
     turned through the final argument.  The caller can process each addrinfo structure in this
     list by following the ai_next pointer, until a NULL pointer is encountered.  In each re-
     turned addrinfo structure the three members ai_family, ai_socktype, and ai_protocol are the
     corresponding arguments for a call to the socket() function.  In each addrinfo structure the
     ai_addr member points to a filled-in socket address structure whose length is specified by
     the ai_addrlen member.

     If the AI_PASSIVE bit is set in the ai_flags member of the hints structure, then the caller
     plans to use the returned socket address structure in a call to bind().  In this case, if
     the nodename argument is a NULL pointer, then the IP address portion of the socket address
     structure will be set to INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 ad-
     dress.

     If the AI_PASSIVE bit is not set in the ai_flags member of the hints structure, then the re-
     turned socket address structure will be ready for a call to connect() (for a connection-ori-
     ented protocol) or either connect(), sendto(), or sendmsg() (for a connectionless protocol).
     In this case, if the nodename argument is a NULL pointer, then the IP address portion of the
     socket address structure will be set to the loopback address.

     If the AI_CANONNAME bit is set in the ai_flags member of the hints structure, then upon suc-
     cessful return the ai_canonname member of the first addrinfo structure in the linked list
     will point to a null-terminated string containing the canonical name of the specified
     nodename.

     If the AI_NUMERICHOST bit is set in the ai_flags member of the hints structure, then a
     non-NULL nodename string must be a numeric host address string.  Otherwise an error of
     EAI_NONAME is returned.  This flag prevents any type of name resolution service (e.g., the
     DNS) from being called.

     The arguments to getaddrinfo() must be sufficiently consistent and unambiguous.  Here are
     some problem cases you may encounter:

     +o   getaddrinfo() will fail if the members in the hints structure are not consistent.  For
         example, for internet address families, getaddrinfo() will fail if you specify
         SOCK_STREAM to ai_socktype while you specify IPPROTO_UDP to ai_protocol.

     +o   If you specify a servname which is defined only for certain ai_socktype, getaddrinfo()
         will fail because the arguments are not consistent.  For example, getaddrinfo() will re-
         turn an error if you ask for "tftp" service on SOCK_STREAM.

     +o   For internet address families, if you specify servname while you set ai_socktype to
         SOCK_RAW, getaddrinfo() will fail, because service names are not defined for the inter-
         net SOCK_RAW space.

     +o   If you specify numeric servname, while leaving ai_socktype and ai_protocol unspecified,
         getaddrinfo() will fail.  This is because the numeric servname does not identify any
         socket type, and getaddrinfo() is not allowed to glob the argument in such case.

     All of the information returned by getaddrinfo() is dynamically allocated: the addrinfo
     structures, the socket address structures, and canonical node name strings pointed to by the
     addrinfo structures.  To return this information to the system the function freeaddrinfo()
     is called.  The addrinfo structure pointed to by the ai argument is freed, along with any
     dynamic storage pointed to by the structure.  This operation is repeated until a NULL
     ai_next pointer is encountered.

     To aid applications in printing error messages based on the EAI_xxx codes returned by
     getaddrinfo(), gai_strerror() is defined.  The argument is one of the EAI_xxx values defined
     earlier and the return value points to a string describing the error.  If the argument is
     not one of the EAI_xxx values, the function still returns a pointer to a string whose con-
     tents indicate an unknown error.

EXTENSIONS
     This implementation supports numeric IPv6 address notation with the experimental scope iden-
     tifier.  By appending a percent sign and scope identifier to the address, you can specify
     the value of the sin6_scope_id field of the socket address.  This makes management of scoped
     address easier, and allows cut-and-paste input of scoped addresses.

     At the moment the code supports only link-local addresses in this format.  The scope identi-
     fier is hardcoded to name of hardware interface associated with the link, (such as ne0).
     For example, "fe80::1%ne0", which means "fe80::1 on the link associated with the ne0
     interface".

     This implementation is still very experimental and non-standard.  The current implementation
     assumes a one-to-one relationship between interfaces and links, which is not necessarily
     true according to the specification.

EXAMPLES
     The following code tries to connect to "www.kame.net" service "http".  via stream socket.
     It loops through all the addresses available, regardless of the address family.  If the des-
     tination resolves to an IPv4 address, it will use an AF_INET socket.  Similarly, if it re-
     solves to IPv6, an AF_INET6 socket is used.  Observe that there is no hardcoded reference to
     particular address family.  The code works even if getaddrinfo() returns addresses that are
     not IPv4/v6.

           struct addrinfo hints, *res, *res0;
           int error;
           int s;
           const char *cause = NULL;

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = PF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
           error = getaddrinfo("www.kame.net", "http", &hints, &res0);
           if (error) {
                   errx(1, "%s", gai_strerror(error));
                   /*NOTREACHED*/
           }
           s = -1;
           cause = "no addresses";
           errno = EADDRNOTAVAIL;
           for (res = res0; res; res = res->ai_next) {
                   s = socket(res->ai_family, res->ai_socktype,
                       res->ai_protocol);
                   if (s < 0) {
                           cause = "socket";
                           continue;
                   }

                   if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                           cause = "connect";
                           close(s);
                           s = -1;
                           continue;
                   }

                   break;  /* okay we got one */
           }
           if (s < 0) {
                   err(1, cause);
                   /*NOTREACHED*/
           }
           freeaddrinfo(res0);

     The following example tries to open a wildcard listening socket onto service "http", for all
     the address families available.

           struct addrinfo hints, *res, *res0;
           int error;
           int s[MAXSOCK];
           int nsock;
           const char *cause = NULL;

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = PF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
           hints.ai_flags = AI_PASSIVE;
           error = getaddrinfo(NULL, "http", &hints, &res0);
           if (error) {
                   errx(1, "%s", gai_strerror(error));
                   /*NOTREACHED*/
           }
           nsock = 0;
           for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
                   s[nsock] = socket(res->ai_family, res->ai_socktype,
                       res->ai_protocol);
                   if (s[nsock] < 0) {
                           cause = "socket";
                           continue;
                   }

                   if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) {
                           cause = "bind";
                           close(s[nsock]);
                           continue;
                   }

                   if (listen(s[nsock], SOMAXCONN) < 0) {
                           cause = "listen";
                           close(s[nsock]);
                           continue;
                   }

                   nsock++;
           }
           if (nsock == 0) {
                   err(1, cause);
                   /*NOTREACHED*/
           }
           freeaddrinfo(res0);

FILES
     /etc/hosts
     /etc/nsswitch.conf
     /etc/resolv.conf

DIAGNOSTICS
     Error return status from getaddrinfo() is zero on success and non-zero on errors.  Non-zero
     error codes are defined in <netdb.h>, and as follows:

     EAI_ADDRFAMILY  Address family for nodename not supported.
     EAI_AGAIN       Temporary failure in name resolution.
     EAI_BADFLAGS    Invalid value for ai_flags.
     EAI_FAIL        Non-recoverable failure in name resolution.
     EAI_FAMILY      ai_family not supported.
     EAI_MEMORY      Memory allocation failure.
     EAI_NODATA      No address associated with nodename.
     EAI_NONAME      nodename nor servname provided, or not known.
     EAI_SERVICE     servname not supported for ai_socktype.
     EAI_SOCKTYPE    ai_socktype not supported.
     EAI_SYSTEM      System error returned in errno.
     EAI_BADHINTS    Invalid value for hints.
     EAI_PROTOCOL    Resolved protocol is unknown.
     EAI_MAX         Unknown error.

     If called with an appropriate argument, gai_strerror() returns a pointer to a string de-
     scribing the given error code.  If the argument is not one of the EAI_xxx values, the func-
     tion still returns a pointer to a string whose contents indicate an unknown error.

SEE ALSO
     gethostbyname(3), getnameinfo(3), getservbyname(3), hosts(5), resolv.conf(5), services(5),
     hostname(7), named(8)

     R. Gilligan, S. Thomson, J. Bound, and W. Stevens, Basic Socket Interface Extensions for
     IPv6, RFC2553, March 1999.

     Tatsuya Jinmei and Atsushi Onoe, An Extension of Format for IPv6 Scoped Addresses, internet
     draft, draft-ietf-ipngwg-scopedaddr-format-02.txt, work in progress material.

     Craig Metz, "Protocol Independence Using the Sockets API", Proceedings of the freenix track:
     2000 USENIX annual technical conference, June 2000.

HISTORY
     The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.

STANDARDS
     The getaddrinfo() function is defined in IEEE Std 1003.1g-2000 ("POSIX.1"), and documented
     in "Basic Socket Interface Extensions for IPv6" (RFC2553).

BUGS
     The current implementation is not thread-safe.

     The text was shamelessly copied from RFC2553.

BSD                                        May 25, 1995                                       BSD