* posix/gai.conf: Fix comment for scope nullbits.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob9a27efdf83cbee3b624e04e3a99cfc827b63d68e
1 /* The Inner Net License, Version 2.00
3 The author(s) grant permission for redistribution and use in source and
4 binary forms, with or without modification, of the software and documentation
5 provided that the following conditions are met:
7 0. If you receive a version of the software that is specifically labelled
8 as not being for redistribution (check the version message and/or README),
9 you are not permitted to redistribute that version of the software in any
10 way or form.
11 1. All terms of the all other applicable copyrights and licenses must be
12 followed.
13 2. Redistributions of source code must retain the authors' copyright
14 notice(s), this list of conditions, and the following disclaimer.
15 3. Redistributions in binary form must reproduce the authors' copyright
16 notice(s), this list of conditions, and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 4. [The copyright holder has authorized the removal of this clause.]
19 5. Neither the name(s) of the author(s) nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
23 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
38 #include <assert.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <ifaddrs.h>
42 #include <netdb.h>
43 #include <resolv.h>
44 #include <stdbool.h>
45 #include <stdio.h>
46 #include <stdio_ext.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <arpa/inet.h>
50 #include <net/if.h>
51 #include <netinet/in.h>
52 #include <sys/socket.h>
53 #include <sys/stat.h>
54 #include <sys/types.h>
55 #include <sys/un.h>
56 #include <sys/utsname.h>
57 #include <unistd.h>
58 #include <nsswitch.h>
59 #include <bits/libc-lock.h>
60 #include <not-cancel.h>
61 #include <nscd/nscd-client.h>
62 #include <nscd/nscd_proto.h>
64 #ifdef HAVE_LIBIDN
65 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
66 extern int __idna_to_unicode_lzlz (const char *input, char **output,
67 int flags);
68 # include <libidn/idna.h>
69 #endif
71 #define GAIH_OKIFUNSPEC 0x0100
72 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
74 #ifndef UNIX_PATH_MAX
75 # define UNIX_PATH_MAX 108
76 #endif
78 struct gaih_service
80 const char *name;
81 int num;
84 struct gaih_servtuple
86 struct gaih_servtuple *next;
87 int socktype;
88 int protocol;
89 int port;
92 static const struct gaih_servtuple nullserv;
94 struct gaih_addrtuple
96 struct gaih_addrtuple *next;
97 char *name;
98 int family;
99 uint32_t addr[4];
100 uint32_t scopeid;
103 struct gaih_typeproto
105 int socktype;
106 int protocol;
107 char name[4];
108 int protoflag;
111 /* Values for `protoflag'. */
112 #define GAI_PROTO_NOSERVICE 1
113 #define GAI_PROTO_PROTOANY 2
115 static const struct gaih_typeproto gaih_inet_typeproto[] =
117 { 0, 0, "", 0 },
118 { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 },
119 { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 },
120 { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
121 { 0, 0, "", 0 }
124 struct gaih
126 int family;
127 int (*gaih)(const char *name, const struct gaih_service *service,
128 const struct addrinfo *req, struct addrinfo **pai,
129 unsigned int *naddrs);
132 static const struct addrinfo default_hints =
134 .ai_flags = AI_DEFAULT,
135 .ai_family = PF_UNSPEC,
136 .ai_socktype = 0,
137 .ai_protocol = 0,
138 .ai_addrlen = 0,
139 .ai_addr = NULL,
140 .ai_canonname = NULL,
141 .ai_next = NULL
145 static int
146 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
147 const struct addrinfo *req, struct gaih_servtuple *st)
149 struct servent *s;
150 size_t tmpbuflen = 1024;
151 struct servent ts;
152 char *tmpbuf;
153 int r;
157 tmpbuf = __alloca (tmpbuflen);
159 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
160 &s);
161 if (r != 0 || s == NULL)
163 if (r == ERANGE)
164 tmpbuflen *= 2;
165 else
166 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
169 while (r);
171 st->next = NULL;
172 st->socktype = tp->socktype;
173 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
174 ? req->ai_protocol : tp->protocol);
175 st->port = s->s_port;
177 return 0;
180 #define gethosts(_family, _type) \
182 int i; \
183 int herrno; \
184 struct hostent th; \
185 struct hostent *h; \
186 char *localcanon = NULL; \
187 no_data = 0; \
188 while (1) { \
189 rc = 0; \
190 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
191 &rc, &herrno, NULL, &localcanon)); \
192 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
193 break; \
194 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
196 if (status == NSS_STATUS_SUCCESS && rc == 0) \
197 h = &th; \
198 else \
199 h = NULL; \
200 if (rc != 0) \
202 if (herrno == NETDB_INTERNAL) \
204 __set_h_errno (herrno); \
205 return -EAI_SYSTEM; \
207 if (herrno == TRY_AGAIN) \
208 no_data = EAI_AGAIN; \
209 else \
210 no_data = herrno == NO_DATA; \
212 else if (h != NULL) \
214 for (i = 0; h->h_addr_list[i]; i++) \
216 if (*pat == NULL) \
218 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
219 (*pat)->scopeid = 0; \
221 uint32_t *addr = (*pat)->addr; \
222 (*pat)->next = NULL; \
223 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
224 if (_family == AF_INET && req->ai_family == AF_INET6) \
226 (*pat)->family = AF_INET6; \
227 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
228 addr[2] = htonl (0xffff); \
229 addr[1] = 0; \
230 addr[0] = 0; \
232 else \
234 (*pat)->family = _family; \
235 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
237 pat = &((*pat)->next); \
240 if (localcanon != NULL && canon == NULL) \
241 canon = strdupa (localcanon); \
243 if (_family == AF_INET6 && i > 0) \
244 got_ipv6 = true; \
249 typedef enum nss_status (*nss_gethostbyname3_r)
250 (const char *name, int af, struct hostent *host,
251 char *buffer, size_t buflen, int *errnop,
252 int *h_errnop, int32_t *ttlp, char **canonp);
253 typedef enum nss_status (*nss_getcanonname_r)
254 (const char *name, char *buffer, size_t buflen, char **result,
255 int *errnop, int *h_errnop);
256 extern service_user *__nss_hosts_database attribute_hidden;
259 static int
260 gaih_inet (const char *name, const struct gaih_service *service,
261 const struct addrinfo *req, struct addrinfo **pai,
262 unsigned int *naddrs)
264 const struct gaih_typeproto *tp = gaih_inet_typeproto;
265 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
266 struct gaih_addrtuple *at = NULL;
267 int rc;
268 bool got_ipv6 = false;
269 const char *canon = NULL;
270 const char *orig_name = name;
272 if (req->ai_protocol || req->ai_socktype)
274 ++tp;
276 while (tp->name[0]
277 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
278 || (req->ai_protocol != 0
279 && !(tp->protoflag & GAI_PROTO_PROTOANY)
280 && req->ai_protocol != tp->protocol)))
281 ++tp;
283 if (! tp->name[0])
285 if (req->ai_socktype)
286 return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
287 else
288 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
292 int port = 0;
293 if (service != NULL)
295 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
296 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
298 if (service->num < 0)
300 if (tp->name[0])
302 st = (struct gaih_servtuple *)
303 __alloca (sizeof (struct gaih_servtuple));
305 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
306 return rc;
308 else
310 struct gaih_servtuple **pst = &st;
311 for (tp++; tp->name[0]; tp++)
313 struct gaih_servtuple *newp;
315 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
316 continue;
318 if (req->ai_socktype != 0
319 && req->ai_socktype != tp->socktype)
320 continue;
321 if (req->ai_protocol != 0
322 && !(tp->protoflag & GAI_PROTO_PROTOANY)
323 && req->ai_protocol != tp->protocol)
324 continue;
326 newp = (struct gaih_servtuple *)
327 __alloca (sizeof (struct gaih_servtuple));
329 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
331 if (rc & GAIH_OKIFUNSPEC)
332 continue;
333 return rc;
336 *pst = newp;
337 pst = &(newp->next);
339 if (st == (struct gaih_servtuple *) &nullserv)
340 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
343 else
345 port = htons (service->num);
346 goto got_port;
349 else
351 got_port:
353 if (req->ai_socktype || req->ai_protocol)
355 st = __alloca (sizeof (struct gaih_servtuple));
356 st->next = NULL;
357 st->socktype = tp->socktype;
358 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
359 ? req->ai_protocol : tp->protocol);
360 st->port = port;
362 else
364 /* Neither socket type nor protocol is set. Return all socket types
365 we know about. */
366 struct gaih_servtuple **lastp = &st;
367 for (++tp; tp->name[0]; ++tp)
369 struct gaih_servtuple *newp;
371 newp = __alloca (sizeof (struct gaih_servtuple));
372 newp->next = NULL;
373 newp->socktype = tp->socktype;
374 newp->protocol = tp->protocol;
375 newp->port = port;
377 *lastp = newp;
378 lastp = &newp->next;
383 if (name != NULL)
385 at = __alloca (sizeof (struct gaih_addrtuple));
387 at->family = AF_UNSPEC;
388 at->scopeid = 0;
389 at->next = NULL;
391 #ifdef HAVE_LIBIDN
392 if (req->ai_flags & AI_IDN)
394 int idn_flags = 0;
395 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
396 idn_flags |= IDNA_ALLOW_UNASSIGNED;
397 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
398 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
400 char *p = NULL;
401 rc = __idna_to_ascii_lz (name, &p, idn_flags);
402 if (rc != IDNA_SUCCESS)
404 if (rc == IDNA_MALLOC_ERROR)
405 return -EAI_MEMORY;
406 if (rc == IDNA_DLOPEN_ERROR)
407 return -EAI_SYSTEM;
408 return -EAI_IDN_ENCODE;
410 /* In case the output string is the same as the input string
411 no new string has been allocated. */
412 if (p != name)
414 name = strdupa (p);
415 free (p);
418 #endif
420 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
422 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
423 at->family = AF_INET;
424 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
426 at->addr[3] = at->addr[0];
427 at->addr[2] = htonl (0xffff);
428 at->addr[1] = 0;
429 at->addr[0] = 0;
430 at->family = AF_INET6;
432 else
433 return -EAI_ADDRFAMILY;
435 if (req->ai_flags & AI_CANONNAME)
436 canon = name;
438 else if (at->family == AF_UNSPEC)
440 char *namebuf = (char *) name;
441 char *scope_delim = strchr (name, SCOPE_DELIMITER);
443 if (__builtin_expect (scope_delim != NULL, 0))
445 namebuf = alloca (scope_delim - name + 1);
446 *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
449 if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
451 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
452 at->family = AF_INET6;
453 else if (req->ai_family == AF_INET
454 && IN6_IS_ADDR_V4MAPPED (at->addr))
456 at->addr[0] = at->addr[3];
457 at->family = AF_INET;
459 else
460 return -EAI_ADDRFAMILY;
462 if (scope_delim != NULL)
464 int try_numericscope = 0;
465 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
466 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
468 at->scopeid = if_nametoindex (scope_delim + 1);
469 if (at->scopeid == 0)
470 try_numericscope = 1;
472 else
473 try_numericscope = 1;
475 if (try_numericscope != 0)
477 char *end;
478 assert (sizeof (uint32_t) <= sizeof (unsigned long));
479 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
480 10);
481 if (*end != '\0')
482 return GAIH_OKIFUNSPEC | -EAI_NONAME;
486 if (req->ai_flags & AI_CANONNAME)
487 canon = name;
491 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
493 struct gaih_addrtuple **pat = &at;
494 int no_data = 0;
495 int no_inet6_data = 0;
496 service_user *nip = NULL;
497 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
498 enum nss_status status = NSS_STATUS_UNAVAIL;
499 int no_more;
500 int old_res_options;
502 /* If we do not have to look for IPv4 and IPv6 together, use
503 the simple, old functions. */
504 if (req->ai_family == AF_INET
505 || (req->ai_family == AF_INET6
506 && ((req->ai_flags & AI_V4MAPPED) == 0
507 || (req->ai_flags & AI_ALL) == 0)))
509 int family = req->ai_family;
510 size_t tmpbuflen = 512;
511 char *tmpbuf = alloca (tmpbuflen);
512 int rc;
513 struct hostent th;
514 struct hostent *h;
515 int herrno;
517 simple_again:
518 while (1)
520 rc = __gethostbyname2_r (name, family, &th, tmpbuf,
521 tmpbuflen, &h, &herrno);
522 if (rc != ERANGE || herrno != NETDB_INTERNAL)
523 break;
524 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
527 if (rc == 0)
529 if (h == NULL)
531 if (req->ai_family == AF_INET6
532 && (req->ai_flags & AI_V4MAPPED)
533 && family == AF_INET6)
535 /* Try again, this time looking for IPv4
536 addresses. */
537 family = AF_INET;
538 goto simple_again;
541 else
543 /* We found data, now convert it into the list. */
544 for (int i = 0; h->h_addr_list[i]; ++i)
546 if (*pat == NULL)
548 *pat = __alloca (sizeof (struct gaih_addrtuple));
549 (*pat)->scopeid = 0;
551 (*pat)->next = NULL;
552 (*pat)->family = req->ai_family;
553 if (family == req->ai_family)
554 memcpy ((*pat)->addr, h->h_addr_list[i],
555 h->h_length);
556 else
558 uint32_t *addr = (uint32_t *) (*pat)->addr;
559 addr[3] = *(uint32_t *) h->h_addr_list[i];
560 addr[2] = htonl (0xffff);
561 addr[1] = 0;
562 addr[0] = 0;
564 pat = &((*pat)->next);
568 else
570 if (herrno == NETDB_INTERNAL)
572 __set_h_errno (herrno);
573 return -EAI_SYSTEM;
575 if (herrno == TRY_AGAIN)
577 return -EAI_AGAIN;
579 /* We made requests but they turned out no data.
580 The name is known, though. */
581 return GAIH_OKIFUNSPEC | -EAI_NODATA;
584 goto process_list;
587 #ifdef USE_NSCD
588 if (__nss_not_use_nscd_hosts > 0
589 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
590 __nss_not_use_nscd_hosts = 0;
592 if (!__nss_not_use_nscd_hosts)
594 /* Try to use nscd. */
595 struct nscd_ai_result *air = NULL;
596 int herrno;
597 int err = __nscd_getai (name, &air, &herrno);
598 if (air != NULL)
600 /* Transform into gaih_addrtuple list. */
601 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
602 char *addrs = air->addrs;
604 for (int i = 0; i < air->naddrs; ++i)
606 socklen_t size = (air->family[i] == AF_INET
607 ? INADDRSZ : IN6ADDRSZ);
608 if (*pat == NULL)
610 *pat = __alloca (sizeof (struct gaih_addrtuple));
611 (*pat)->scopeid = 0;
613 uint32_t *pataddr = (*pat)->addr;
614 (*pat)->next = NULL;
615 if (added_canon || air->canon == NULL)
616 (*pat)->name = NULL;
617 else
618 canon = (*pat)->name = strdupa (air->canon);
620 if (air->family[i] == AF_INET
621 && req->ai_family == AF_INET6
622 && (req->ai_flags & AI_V4MAPPED))
624 (*pat)->family = AF_INET6;
625 pataddr[3] = *(uint32_t *) addrs;
626 pataddr[2] = htonl (0xffff);
627 pataddr[1] = 0;
628 pataddr[0] = 0;
629 pat = &((*pat)->next);
630 added_canon = true;
632 else if (req->ai_family == AF_UNSPEC
633 || air->family[i] == req->ai_family)
635 (*pat)->family = air->family[i];
636 memcpy (pataddr, addrs, size);
637 pat = &((*pat)->next);
638 added_canon = true;
639 if (air->family[i] == AF_INET6)
640 got_ipv6 = true;
642 addrs += size;
645 free (air);
647 if (at->family == AF_UNSPEC)
648 return GAIH_OKIFUNSPEC | -EAI_NONAME;
650 goto process_list;
652 else if (err != 0 && __nss_not_use_nscd_hosts == 0)
654 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
655 return -EAI_MEMORY;
656 if (herrno == TRY_AGAIN)
657 return -EAI_AGAIN;
658 return -EAI_SYSTEM;
661 #endif
663 if (__nss_hosts_database != NULL)
665 no_more = 0;
666 nip = __nss_hosts_database;
668 else
669 no_more = __nss_database_lookup ("hosts", NULL,
670 "dns [!UNAVAIL=return] files",
671 &nip);
673 if (__res_maybe_init (&_res, 0) == -1)
674 no_more = 1;
676 /* If we are looking for both IPv4 and IPv6 address we don't
677 want the lookup functions to automatically promote IPv4
678 addresses to IPv6 addresses. Currently this is decided
679 by setting the RES_USE_INET6 bit in _res.options. */
680 old_res_options = _res.options;
681 _res.options &= ~RES_USE_INET6;
683 size_t tmpbuflen = 512;
684 char *tmpbuf = alloca (tmpbuflen);
686 while (!no_more)
688 nss_gethostbyname3_r fct = NULL;
689 if (req->ai_flags & AI_CANONNAME)
690 /* No need to use this function if we do not look for
691 the canonical name. The function does not exist in
692 all NSS modules and therefore the lookup would
693 often fail. */
694 fct = __nss_lookup_function (nip, "gethostbyname3_r");
695 if (fct == NULL)
696 /* We are cheating here. The gethostbyname2_r function does
697 not have the same interface as gethostbyname3_r but the
698 extra arguments the latter takes are added at the end.
699 So the gethostbyname2_r code will just ignore them. */
700 fct = __nss_lookup_function (nip, "gethostbyname2_r");
702 if (fct != NULL)
704 if (req->ai_family == AF_INET6
705 || req->ai_family == AF_UNSPEC)
707 gethosts (AF_INET6, struct in6_addr);
708 no_inet6_data = no_data;
709 inet6_status = status;
711 if (req->ai_family == AF_INET
712 || req->ai_family == AF_UNSPEC
713 || (req->ai_family == AF_INET6
714 && (req->ai_flags & AI_V4MAPPED)
715 /* Avoid generating the mapped addresses if we
716 know we are not going to need them. */
717 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
719 gethosts (AF_INET, struct in_addr);
721 if (req->ai_family == AF_INET)
723 no_inet6_data = no_data;
724 inet6_status = status;
728 /* If we found one address for AF_INET or AF_INET6,
729 don't continue the search. */
730 if (inet6_status == NSS_STATUS_SUCCESS
731 || status == NSS_STATUS_SUCCESS)
733 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
735 /* If we need the canonical name, get it
736 from the same service as the result. */
737 nss_getcanonname_r cfct;
738 int herrno;
740 cfct = __nss_lookup_function (nip, "getcanonname_r");
741 if (cfct != NULL)
743 const size_t max_fqdn_len = 256;
744 char *buf = alloca (max_fqdn_len);
745 char *s;
747 if (DL_CALL_FCT (cfct, (at->name ?: name, buf,
748 max_fqdn_len, &s, &rc,
749 &herrno))
750 == NSS_STATUS_SUCCESS)
751 canon = s;
752 else
753 /* Set to name now to avoid using
754 gethostbyaddr. */
755 canon = name;
759 break;
762 /* We can have different states for AF_INET and
763 AF_INET6. Try to find a useful one for both. */
764 if (inet6_status == NSS_STATUS_TRYAGAIN)
765 status = NSS_STATUS_TRYAGAIN;
766 else if (status == NSS_STATUS_UNAVAIL
767 && inet6_status != NSS_STATUS_UNAVAIL)
768 status = inet6_status;
771 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
772 break;
774 if (nip->next == NULL)
775 no_more = -1;
776 else
777 nip = nip->next;
780 _res.options = old_res_options;
782 if (no_data != 0 && no_inet6_data != 0)
784 /* If both requests timed out report this. */
785 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
786 return -EAI_AGAIN;
788 /* We made requests but they turned out no data. The name
789 is known, though. */
790 return GAIH_OKIFUNSPEC | -EAI_NODATA;
794 process_list:
795 if (at->family == AF_UNSPEC)
796 return GAIH_OKIFUNSPEC | -EAI_NONAME;
798 else
800 struct gaih_addrtuple *atr;
801 atr = at = __alloca (sizeof (struct gaih_addrtuple));
802 memset (at, '\0', sizeof (struct gaih_addrtuple));
804 if (req->ai_family == AF_UNSPEC)
806 at->next = __alloca (sizeof (struct gaih_addrtuple));
807 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
810 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
812 at->family = AF_INET6;
813 if ((req->ai_flags & AI_PASSIVE) == 0)
814 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
815 atr = at->next;
818 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
820 atr->family = AF_INET;
821 if ((req->ai_flags & AI_PASSIVE) == 0)
822 atr->addr[0] = htonl (INADDR_LOOPBACK);
826 if (pai == NULL)
827 return 0;
830 struct gaih_servtuple *st2;
831 struct gaih_addrtuple *at2 = at;
832 size_t socklen;
833 sa_family_t family;
836 buffer is the size of an unformatted IPv6 address in printable format.
838 while (at2 != NULL)
840 /* Only the first entry gets the canonical name. */
841 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
843 if (canon == NULL)
845 struct hostent *h = NULL;
846 int herrno;
847 struct hostent th;
848 size_t tmpbuflen = 512;
849 char *tmpbuf = NULL;
853 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
854 rc = __gethostbyaddr_r (at2->addr,
855 ((at2->family == AF_INET6)
856 ? sizeof (struct in6_addr)
857 : sizeof (struct in_addr)),
858 at2->family, &th, tmpbuf,
859 tmpbuflen, &h, &herrno);
861 while (rc == ERANGE && herrno == NETDB_INTERNAL);
863 if (rc != 0 && herrno == NETDB_INTERNAL)
865 __set_h_errno (herrno);
866 return -EAI_SYSTEM;
869 if (h != NULL)
870 canon = h->h_name;
871 else
873 assert (orig_name != NULL);
874 /* If the canonical name cannot be determined, use
875 the passed in string. */
876 canon = orig_name;
880 #ifdef HAVE_LIBIDN
881 if (req->ai_flags & AI_CANONIDN)
883 int idn_flags = 0;
884 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
885 idn_flags |= IDNA_ALLOW_UNASSIGNED;
886 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
887 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
889 char *out;
890 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
891 if (rc != IDNA_SUCCESS)
893 if (rc == IDNA_MALLOC_ERROR)
894 return -EAI_MEMORY;
895 if (rc == IDNA_DLOPEN_ERROR)
896 return -EAI_SYSTEM;
897 return -EAI_IDN_ENCODE;
899 /* In case the output string is the same as the input
900 string no new string has been allocated. Otherwise
901 make a copy. */
902 if (out == canon)
903 goto make_copy;
905 else
906 #endif
908 #ifdef HAVE_LIBIDN
909 make_copy:
910 #endif
911 canon = strdup (canon);
912 if (canon == NULL)
913 return -EAI_MEMORY;
917 family = at2->family;
918 if (family == AF_INET6)
920 socklen = sizeof (struct sockaddr_in6);
922 /* If we looked up IPv4 mapped address discard them here if
923 the caller isn't interested in all address and we have
924 found at least one IPv6 address. */
925 if (got_ipv6
926 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
927 && IN6_IS_ADDR_V4MAPPED (at2->addr))
928 goto ignore;
930 else
931 socklen = sizeof (struct sockaddr_in);
933 for (st2 = st; st2 != NULL; st2 = st2->next)
935 struct addrinfo *ai;
936 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
937 if (ai == NULL)
939 free ((char *) canon);
940 return -EAI_MEMORY;
943 ai->ai_flags = req->ai_flags;
944 ai->ai_family = family;
945 ai->ai_socktype = st2->socktype;
946 ai->ai_protocol = st2->protocol;
947 ai->ai_addrlen = socklen;
948 ai->ai_addr = (void *) (ai + 1);
950 /* We only add the canonical name once. */
951 ai->ai_canonname = (char *) canon;
952 canon = NULL;
954 #ifdef _HAVE_SA_LEN
955 ai->ai_addr->sa_len = socklen;
956 #endif /* _HAVE_SA_LEN */
957 ai->ai_addr->sa_family = family;
959 /* In case of an allocation error the list must be NULL
960 terminated. */
961 ai->ai_next = NULL;
963 if (family == AF_INET6)
965 struct sockaddr_in6 *sin6p =
966 (struct sockaddr_in6 *) ai->ai_addr;
968 sin6p->sin6_port = st2->port;
969 sin6p->sin6_flowinfo = 0;
970 memcpy (&sin6p->sin6_addr,
971 at2->addr, sizeof (struct in6_addr));
972 sin6p->sin6_scope_id = at2->scopeid;
974 else
976 struct sockaddr_in *sinp =
977 (struct sockaddr_in *) ai->ai_addr;
978 sinp->sin_port = st2->port;
979 memcpy (&sinp->sin_addr,
980 at2->addr, sizeof (struct in_addr));
981 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
984 pai = &(ai->ai_next);
987 ++*naddrs;
989 ignore:
990 at2 = at2->next;
993 return 0;
997 struct sort_result
999 struct addrinfo *dest_addr;
1000 /* Using sockaddr_storage is for now overkill. We only support IPv4
1001 and IPv6 so far. If this changes at some point we can adjust the
1002 type here. */
1003 struct sockaddr_in6 source_addr;
1004 uint8_t source_addr_len;
1005 bool got_source_addr;
1006 uint8_t source_addr_flags;
1007 uint8_t prefixlen;
1008 uint32_t index;
1009 int32_t native;
1012 struct sort_result_combo
1014 struct sort_result *results;
1015 int nresults;
1019 #if __BYTE_ORDER == __BIG_ENDIAN
1020 # define htonl_c(n) n
1021 #else
1022 # define htonl_c(n) __bswap_constant_32 (n)
1023 #endif
1025 static const struct scopeentry
1027 union
1029 char addr[4];
1030 uint32_t addr32;
1032 uint32_t netmask;
1033 int32_t scope;
1034 } default_scopes[] =
1036 /* Link-local addresses: scope 2. */
1037 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1038 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1039 /* Site-local addresses: scope 5. */
1040 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1041 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1042 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1043 /* Default: scope 14. */
1044 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1047 /* The label table. */
1048 static const struct scopeentry *scopes;
1051 static int
1052 get_scope (const struct sockaddr_in6 *in6)
1054 int scope;
1055 if (in6->sin6_family == PF_INET6)
1057 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1059 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
1060 scope = 2;
1061 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1062 scope = 5;
1063 else
1064 /* XXX Is this the correct default behavior? */
1065 scope = 14;
1067 else
1068 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1070 else if (in6->sin6_family == PF_INET)
1072 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1074 size_t cnt = 0;
1075 while (1)
1077 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1078 == scopes[cnt].addr32)
1079 return scopes[cnt].scope;
1081 ++cnt;
1083 /* NOTREACHED */
1085 else
1086 /* XXX What is a good default? */
1087 scope = 15;
1089 return scope;
1093 struct prefixentry
1095 struct in6_addr prefix;
1096 unsigned int bits;
1097 int val;
1101 /* The label table. */
1102 static const struct prefixentry *labels;
1104 /* Default labels. */
1105 static const struct prefixentry default_labels[] =
1107 /* See RFC 3484 for the details. */
1108 { { .__in6_u
1109 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1111 }, 128, 0 },
1112 { { .__in6_u
1113 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1115 }, 16, 2 },
1116 { { .__in6_u
1117 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1119 }, 96, 3 },
1120 { { .__in6_u
1121 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1122 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1123 }, 96, 4 },
1124 /* The next two entries differ from RFC 3484. We need to treat
1125 IPv6 site-local addresses special because they are never NATed,
1126 unlike site-locale IPv4 addresses. If this would not happen, on
1127 machines which have only IPv4 and IPv6 site-local addresses, the
1128 sorting would prefer the IPv6 site-local addresses, causing
1129 unnecessary delays when trying to connect to a global IPv6 address
1130 through a site-local IPv6 address. */
1131 { { .__in6_u
1132 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1134 }, 10, 5 },
1135 { { .__in6_u
1136 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1138 }, 7, 6 },
1139 /* Additional rule for Teredo tunnels. */
1140 { { .__in6_u
1141 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1143 }, 32, 7 },
1144 { { .__in6_u
1145 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1147 }, 0, 1 }
1151 /* The precedence table. */
1152 static const struct prefixentry *precedence;
1154 /* The default precedences. */
1155 static const struct prefixentry default_precedence[] =
1157 /* See RFC 3484 for the details. */
1158 { { .__in6_u
1159 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1161 }, 128, 50 },
1162 { { .__in6_u
1163 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1165 }, 16, 30 },
1166 { { .__in6_u
1167 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1169 }, 96, 20 },
1170 { { .__in6_u
1171 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1173 }, 96, 10 },
1174 { { .__in6_u
1175 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1177 }, 0, 40 }
1181 static int
1182 match_prefix (const struct sockaddr_in6 *in6,
1183 const struct prefixentry *list, int default_val)
1185 int idx;
1186 struct sockaddr_in6 in6_mem;
1188 if (in6->sin6_family == PF_INET)
1190 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1192 /* Convert to IPv6 address. */
1193 in6_mem.sin6_family = PF_INET6;
1194 in6_mem.sin6_port = in->sin_port;
1195 in6_mem.sin6_flowinfo = 0;
1196 if (in->sin_addr.s_addr == htonl (0x7f000001))
1197 in6_mem.sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
1198 else
1200 /* Construct a V4-to-6 mapped address. */
1201 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1202 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1203 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1204 in6_mem.sin6_scope_id = 0;
1207 in6 = &in6_mem;
1209 else if (in6->sin6_family != PF_INET6)
1210 return default_val;
1212 for (idx = 0; ; ++idx)
1214 unsigned int bits = list[idx].bits;
1215 const uint8_t *mask = list[idx].prefix.s6_addr;
1216 const uint8_t *val = in6->sin6_addr.s6_addr;
1218 while (bits >= 8)
1220 if (*mask != *val)
1221 break;
1223 ++mask;
1224 ++val;
1225 bits -= 8;
1228 if (bits < 8)
1230 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1231 /* Match! */
1232 break;
1236 return list[idx].val;
1240 static int
1241 get_label (const struct sockaddr_in6 *in6)
1243 /* XXX What is a good default value? */
1244 return match_prefix (in6, labels, INT_MAX);
1248 static int
1249 get_precedence (const struct sockaddr_in6 *in6)
1251 /* XXX What is a good default value? */
1252 return match_prefix (in6, precedence, 0);
1256 /* Find last bit set in a word. */
1257 static int
1258 fls (uint32_t a)
1260 uint32_t mask;
1261 int n;
1262 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1263 if ((a & mask) != 0)
1264 break;
1265 return n;
1269 static int
1270 rfc3484_sort (const void *p1, const void *p2, void *arg)
1272 const size_t idx1 = *(const size_t *) p1;
1273 const size_t idx2 = *(const size_t *) p2;
1274 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1275 struct sort_result *a1 = &src->results[idx1];
1276 struct sort_result *a2 = &src->results[idx2];
1278 /* Rule 1: Avoid unusable destinations.
1279 We have the got_source_addr flag set if the destination is reachable. */
1280 if (a1->got_source_addr && ! a2->got_source_addr)
1281 return -1;
1282 if (! a1->got_source_addr && a2->got_source_addr)
1283 return 1;
1286 /* Rule 2: Prefer matching scope. Only interesting if both
1287 destination addresses are IPv6. */
1288 int a1_dst_scope
1289 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1291 int a2_dst_scope
1292 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1294 if (a1->got_source_addr)
1296 int a1_src_scope = get_scope (&a1->source_addr);
1297 int a2_src_scope = get_scope (&a2->source_addr);
1299 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1300 return -1;
1301 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1302 return 1;
1306 /* Rule 3: Avoid deprecated addresses. */
1307 if (a1->got_source_addr)
1309 if (!(a1->source_addr_flags & in6ai_deprecated)
1310 && (a2->source_addr_flags & in6ai_deprecated))
1311 return -1;
1312 if ((a1->source_addr_flags & in6ai_deprecated)
1313 && !(a2->source_addr_flags & in6ai_deprecated))
1314 return 1;
1317 /* Rule 4: Prefer home addresses. */
1318 if (a1->got_source_addr)
1320 if (!(a1->source_addr_flags & in6ai_homeaddress)
1321 && (a2->source_addr_flags & in6ai_homeaddress))
1322 return 1;
1323 if ((a1->source_addr_flags & in6ai_homeaddress)
1324 && !(a2->source_addr_flags & in6ai_homeaddress))
1325 return -1;
1328 /* Rule 5: Prefer matching label. */
1329 if (a1->got_source_addr)
1331 int a1_dst_label
1332 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1333 int a1_src_label = get_label (&a1->source_addr);
1335 int a2_dst_label
1336 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1337 int a2_src_label = get_label (&a2->source_addr);
1339 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1340 return -1;
1341 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1342 return 1;
1346 /* Rule 6: Prefer higher precedence. */
1347 int a1_prec
1348 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1349 int a2_prec
1350 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1352 if (a1_prec > a2_prec)
1353 return -1;
1354 if (a1_prec < a2_prec)
1355 return 1;
1358 /* Rule 7: Prefer native transport. */
1359 if (a1->got_source_addr)
1361 /* The same interface index means the same interface which means
1362 there is no difference in transport. This should catch many
1363 (most?) cases. */
1364 if (a1->index != a2->index)
1366 int a1_native = a1->native;
1367 int a2_native = a2->native;
1369 if (a1_native == -1 || a2_native == -1)
1371 uint32_t a1_index;
1372 if (a1_native == -1)
1374 /* If we do not have the information use 'native' as
1375 the default. */
1376 a1_native = 0;
1377 a1_index = a1->index;
1379 else
1380 a1_index = 0xffffffffu;
1382 uint32_t a2_index;
1383 if (a2_native == -1)
1385 /* If we do not have the information use 'native' as
1386 the default. */
1387 a2_native = 0;
1388 a2_index = a2->index;
1390 else
1391 a2_index = 0xffffffffu;
1393 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1395 /* Fill in the results in all the records. */
1396 for (int i = 0; i < src->nresults; ++i)
1397 if (src->results[i].index == a1_index)
1399 assert (src->results[i].native == -1
1400 || src->results[i].native == a1_native);
1401 src->results[i].native = a1_native;
1403 else if (src->results[i].index == a2_index)
1405 assert (src->results[i].native == -1
1406 || src->results[i].native == a2_native);
1407 src->results[i].native = a2_native;
1411 if (a1_native && !a2_native)
1412 return -1;
1413 if (!a1_native && a2_native)
1414 return 1;
1419 /* Rule 8: Prefer smaller scope. */
1420 if (a1_dst_scope < a2_dst_scope)
1421 return -1;
1422 if (a1_dst_scope > a2_dst_scope)
1423 return 1;
1426 /* Rule 9: Use longest matching prefix. */
1427 if (a1->got_source_addr
1428 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1430 int bit1 = 0;
1431 int bit2 = 0;
1433 if (a1->dest_addr->ai_family == PF_INET)
1435 assert (a1->source_addr.sin6_family == PF_INET);
1436 assert (a2->source_addr.sin6_family == PF_INET);
1438 /* Outside of subnets, as defined by the network masks,
1439 common address prefixes for IPv4 addresses make no sense.
1440 So, define a non-zero value only if source and
1441 destination address are on the same subnet. */
1442 struct sockaddr_in *in1_dst
1443 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1444 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1445 struct sockaddr_in *in1_src
1446 = (struct sockaddr_in *) &a1->source_addr;
1447 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1448 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1450 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1451 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1453 struct sockaddr_in *in2_dst
1454 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1455 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1456 struct sockaddr_in *in2_src
1457 = (struct sockaddr_in *) &a2->source_addr;
1458 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1459 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1461 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1462 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1464 else if (a1->dest_addr->ai_family == PF_INET6)
1466 assert (a1->source_addr.sin6_family == PF_INET6);
1467 assert (a2->source_addr.sin6_family == PF_INET6);
1469 struct sockaddr_in6 *in1_dst;
1470 struct sockaddr_in6 *in1_src;
1471 struct sockaddr_in6 *in2_dst;
1472 struct sockaddr_in6 *in2_src;
1474 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1475 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1476 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1477 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1479 int i;
1480 for (i = 0; i < 4; ++i)
1481 if (in1_dst->sin6_addr.s6_addr32[i]
1482 != in1_src->sin6_addr.s6_addr32[i]
1483 || (in2_dst->sin6_addr.s6_addr32[i]
1484 != in2_src->sin6_addr.s6_addr32[i]))
1485 break;
1487 if (i < 4)
1489 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1490 ^ in1_src->sin6_addr.s6_addr32[i]));
1491 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1492 ^ in2_src->sin6_addr.s6_addr32[i]));
1496 if (bit1 > bit2)
1497 return -1;
1498 if (bit1 < bit2)
1499 return 1;
1503 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1504 compare with the value indicating the order in which the entries
1505 have been received from the services. NB: no two entries can have
1506 the same order so the test will never return zero. */
1507 return idx1 < idx2 ? -1 : 1;
1511 static int
1512 in6aicmp (const void *p1, const void *p2)
1514 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1515 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1517 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1521 /* Name of the config file for RFC 3484 sorting (for now). */
1522 #define GAICONF_FNAME "/etc/gai.conf"
1525 /* Non-zero if we are supposed to reload the config file automatically
1526 whenever it changed. */
1527 static int gaiconf_reload_flag;
1529 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1530 static int gaiconf_reload_flag_ever_set;
1532 /* Last modification time. */
1533 static struct timespec gaiconf_mtime;
1536 libc_freeres_fn(fini)
1538 if (labels != default_labels)
1540 const struct prefixentry *old = labels;
1541 labels = default_labels;
1542 free ((void *) old);
1545 if (precedence != default_precedence)
1547 const struct prefixentry *old = precedence;
1548 precedence = default_precedence;
1549 free ((void *) old);
1552 if (scopes != default_scopes)
1554 const struct scopeentry *old = scopes;
1555 scopes = default_scopes;
1556 free ((void *) old);
1561 struct prefixlist
1563 struct prefixentry entry;
1564 struct prefixlist *next;
1568 struct scopelist
1570 struct scopeentry entry;
1571 struct scopelist *next;
1575 static void
1576 free_prefixlist (struct prefixlist *list)
1578 while (list != NULL)
1580 struct prefixlist *oldp = list;
1581 list = list->next;
1582 free (oldp);
1587 static void
1588 free_scopelist (struct scopelist *list)
1590 while (list != NULL)
1592 struct scopelist *oldp = list;
1593 list = list->next;
1594 free (oldp);
1599 static int
1600 prefixcmp (const void *p1, const void *p2)
1602 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1603 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1605 if (e1->bits < e2->bits)
1606 return 1;
1607 if (e1->bits == e2->bits)
1608 return 0;
1609 return -1;
1613 static int
1614 scopecmp (const void *p1, const void *p2)
1616 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1617 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1619 if (e1->netmask > e2->netmask)
1620 return -1;
1621 if (e1->netmask == e2->netmask)
1622 return 0;
1623 return 1;
1627 static void
1628 gaiconf_init (void)
1630 struct prefixlist *labellist = NULL;
1631 size_t nlabellist = 0;
1632 bool labellist_nullbits = false;
1633 struct prefixlist *precedencelist = NULL;
1634 size_t nprecedencelist = 0;
1635 bool precedencelist_nullbits = false;
1636 struct scopelist *scopelist = NULL;
1637 size_t nscopelist = 0;
1638 bool scopelist_nullbits = false;
1640 FILE *fp = fopen (GAICONF_FNAME, "rc");
1641 if (fp != NULL)
1643 struct stat64 st;
1644 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1646 fclose (fp);
1647 goto no_file;
1650 char *line = NULL;
1651 size_t linelen = 0;
1653 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1655 while (!feof_unlocked (fp))
1657 ssize_t n = __getline (&line, &linelen, fp);
1658 if (n <= 0)
1659 break;
1661 /* Handle comments. No escaping possible so this is easy. */
1662 char *cp = strchr (line, '#');
1663 if (cp != NULL)
1664 *cp = '\0';
1666 cp = line;
1667 while (isspace (*cp))
1668 ++cp;
1670 char *cmd = cp;
1671 while (*cp != '\0' && !isspace (*cp))
1672 ++cp;
1673 size_t cmdlen = cp - cmd;
1675 if (*cp != '\0')
1676 *cp++ = '\0';
1677 while (isspace (*cp))
1678 ++cp;
1680 char *val1 = cp;
1681 while (*cp != '\0' && !isspace (*cp))
1682 ++cp;
1683 size_t val1len = cp - cmd;
1685 /* We always need at least two values. */
1686 if (val1len == 0)
1687 continue;
1689 if (*cp != '\0')
1690 *cp++ = '\0';
1691 while (isspace (*cp))
1692 ++cp;
1694 char *val2 = cp;
1695 while (*cp != '\0' && !isspace (*cp))
1696 ++cp;
1698 /* Ignore the rest of the line. */
1699 *cp = '\0';
1701 struct prefixlist **listp;
1702 size_t *lenp;
1703 bool *nullbitsp;
1704 switch (cmdlen)
1706 case 5:
1707 if (strcmp (cmd, "label") == 0)
1709 struct in6_addr prefix;
1710 unsigned long int bits;
1711 unsigned long int val;
1712 char *endp;
1714 listp = &labellist;
1715 lenp = &nlabellist;
1716 nullbitsp = &labellist_nullbits;
1718 new_elem:
1719 bits = 128;
1720 __set_errno (0);
1721 cp = strchr (val1, '/');
1722 if (cp != NULL)
1723 *cp++ = '\0';
1724 if (inet_pton (AF_INET6, val1, &prefix)
1725 && (cp == NULL
1726 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1727 || errno != ERANGE)
1728 && *endp == '\0'
1729 && bits <= 128
1730 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1731 || errno != ERANGE)
1732 && *endp == '\0'
1733 && val <= INT_MAX)
1735 struct prefixlist *newp = malloc (sizeof (*newp));
1736 if (newp == NULL)
1738 free (line);
1739 fclose (fp);
1740 goto no_file;
1743 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1744 newp->entry.bits = bits;
1745 newp->entry.val = val;
1746 newp->next = *listp;
1747 *listp = newp;
1748 ++*lenp;
1749 *nullbitsp |= bits == 0;
1752 break;
1754 case 6:
1755 if (strcmp (cmd, "reload") == 0)
1757 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1758 if (gaiconf_reload_flag)
1759 gaiconf_reload_flag_ever_set = 1;
1761 break;
1763 case 7:
1764 if (strcmp (cmd, "scopev4") == 0)
1766 struct in6_addr prefix;
1767 unsigned long int bits;
1768 unsigned long int val;
1769 char *endp;
1771 bits = 32;
1772 __set_errno (0);
1773 cp = strchr (val1, '/');
1774 if (cp != NULL)
1775 *cp++ = '\0';
1776 if (inet_pton (AF_INET6, val1, &prefix))
1778 bits = 128;
1779 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1780 && (cp == NULL
1781 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1782 || errno != ERANGE)
1783 && *endp == '\0'
1784 && bits >= 96
1785 && bits <= 128
1786 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1787 || errno != ERANGE)
1788 && *endp == '\0'
1789 && val <= INT_MAX)
1791 struct scopelist *newp;
1792 new_scope:
1793 newp = malloc (sizeof (*newp));
1794 if (newp == NULL)
1796 free (line);
1797 fclose (fp);
1798 goto no_file;
1801 newp->entry.netmask = htonl (bits != 96
1802 ? (0xffffffff
1803 << (128 - bits))
1804 : 0);
1805 newp->entry.addr32 = (prefix.s6_addr32[3]
1806 & newp->entry.netmask);
1807 newp->entry.scope = val;
1808 newp->next = scopelist;
1809 scopelist = newp;
1810 ++nscopelist;
1811 scopelist_nullbits |= bits == 96;
1814 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1815 && (cp == NULL
1816 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1817 || errno != ERANGE)
1818 && *endp == '\0'
1819 && bits <= 32
1820 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1821 || errno != ERANGE)
1822 && *endp == '\0'
1823 && val <= INT_MAX)
1825 bits += 96;
1826 goto new_scope;
1829 break;
1831 case 10:
1832 if (strcmp (cmd, "precedence") == 0)
1834 listp = &precedencelist;
1835 lenp = &nprecedencelist;
1836 nullbitsp = &precedencelist_nullbits;
1837 goto new_elem;
1839 break;
1843 free (line);
1845 fclose (fp);
1847 /* Create the array for the labels. */
1848 struct prefixentry *new_labels;
1849 if (nlabellist > 0)
1851 if (!labellist_nullbits)
1852 ++nlabellist;
1853 new_labels = malloc (nlabellist * sizeof (*new_labels));
1854 if (new_labels == NULL)
1855 goto no_file;
1857 int i = nlabellist;
1858 if (!labellist_nullbits)
1860 --i;
1861 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1862 new_labels[i].bits = 0;
1863 new_labels[i].val = 1;
1866 struct prefixlist *l = labellist;
1867 while (i-- > 0)
1869 new_labels[i] = l->entry;
1870 l = l->next;
1872 free_prefixlist (labellist);
1874 /* Sort the entries so that the most specific ones are at
1875 the beginning. */
1876 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1878 else
1879 new_labels = (struct prefixentry *) default_labels;
1881 struct prefixentry *new_precedence;
1882 if (nprecedencelist > 0)
1884 if (!precedencelist_nullbits)
1885 ++nprecedencelist;
1886 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1887 if (new_precedence == NULL)
1889 if (new_labels != default_labels)
1890 free (new_labels);
1891 goto no_file;
1894 int i = nprecedencelist;
1895 if (!precedencelist_nullbits)
1897 --i;
1898 memset (&new_precedence[i].prefix, '\0',
1899 sizeof (struct in6_addr));
1900 new_precedence[i].bits = 0;
1901 new_precedence[i].val = 40;
1904 struct prefixlist *l = precedencelist;
1905 while (i-- > 0)
1907 new_precedence[i] = l->entry;
1908 l = l->next;
1910 free_prefixlist (precedencelist);
1912 /* Sort the entries so that the most specific ones are at
1913 the beginning. */
1914 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1915 prefixcmp);
1917 else
1918 new_precedence = (struct prefixentry *) default_precedence;
1920 struct scopeentry *new_scopes;
1921 if (nscopelist > 0)
1923 if (!scopelist_nullbits)
1924 ++nscopelist;
1925 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1926 if (new_scopes == NULL)
1928 if (new_labels != default_labels)
1929 free (new_labels);
1930 if (new_precedence != default_precedence)
1931 free (new_precedence);
1932 goto no_file;
1935 int i = nscopelist;
1936 if (!scopelist_nullbits)
1938 --i;
1939 new_scopes[i].addr32 = 0;
1940 new_scopes[i].netmask = 0;
1941 new_scopes[i].scope = 14;
1944 struct scopelist *l = scopelist;
1945 while (i-- > 0)
1947 new_scopes[i] = l->entry;
1948 l = l->next;
1950 free_scopelist (scopelist);
1952 /* Sort the entries so that the most specific ones are at
1953 the beginning. */
1954 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
1955 scopecmp);
1957 else
1958 new_scopes = (struct scopeentry *) default_scopes;
1960 /* Now we are ready to replace the values. */
1961 const struct prefixentry *old = labels;
1962 labels = new_labels;
1963 if (old != default_labels)
1964 free ((void *) old);
1966 old = precedence;
1967 precedence = new_precedence;
1968 if (old != default_precedence)
1969 free ((void *) old);
1971 const struct scopeentry *oldscope = scopes;
1972 scopes = new_scopes;
1973 if (oldscope != default_scopes)
1974 free ((void *) oldscope);
1976 gaiconf_mtime = st.st_mtim;
1978 else
1980 no_file:
1981 free_prefixlist (labellist);
1982 free_prefixlist (precedencelist);
1983 free_scopelist (scopelist);
1985 /* If we previously read the file but it is gone now, free the
1986 old data and use the builtin one. Leave the reload flag
1987 alone. */
1988 fini ();
1993 static void
1994 gaiconf_reload (void)
1996 struct stat64 st;
1997 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
1998 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
1999 gaiconf_init ();
2004 getaddrinfo (const char *name, const char *service,
2005 const struct addrinfo *hints, struct addrinfo **pai)
2007 int i = 0, last_i = 0;
2008 int nresults = 0;
2009 struct addrinfo *p = NULL;
2010 struct gaih_service gaih_service, *pservice;
2011 struct addrinfo local_hints;
2013 if (name != NULL && name[0] == '*' && name[1] == 0)
2014 name = NULL;
2016 if (service != NULL && service[0] == '*' && service[1] == 0)
2017 service = NULL;
2019 if (name == NULL && service == NULL)
2020 return EAI_NONAME;
2022 if (hints == NULL)
2023 hints = &default_hints;
2025 if (hints->ai_flags
2026 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2027 #ifdef HAVE_LIBIDN
2028 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2029 |AI_IDN_USE_STD3_ASCII_RULES
2030 #endif
2031 |AI_NUMERICSERV|AI_ALL))
2032 return EAI_BADFLAGS;
2034 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2035 return EAI_BADFLAGS;
2037 struct in6addrinfo *in6ai = NULL;
2038 size_t in6ailen = 0;
2039 bool seen_ipv4 = false;
2040 bool seen_ipv6 = false;
2041 /* We might need information about what interfaces are available.
2042 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2043 cannot cache the results since new interfaces could be added at
2044 any time. */
2045 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2047 if (hints->ai_flags & AI_ADDRCONFIG)
2049 /* Now make a decision on what we return, if anything. */
2050 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2052 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2053 narrow down the search. */
2054 if (! seen_ipv4 || ! seen_ipv6)
2056 local_hints = *hints;
2057 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2058 hints = &local_hints;
2061 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2062 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2064 /* We cannot possibly return a valid answer. */
2065 free (in6ai);
2066 return EAI_NONAME;
2070 if (service && service[0])
2072 char *c;
2073 gaih_service.name = service;
2074 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2075 if (*c != '\0')
2077 if (hints->ai_flags & AI_NUMERICSERV)
2079 free (in6ai);
2080 return EAI_NONAME;
2083 gaih_service.num = -1;
2086 pservice = &gaih_service;
2088 else
2089 pservice = NULL;
2091 struct addrinfo **end;
2092 if (pai)
2093 end = &p;
2094 else
2095 end = NULL;
2097 unsigned int naddrs = 0;
2098 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2099 || hints->ai_family == AF_INET6)
2101 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2102 if (last_i != 0)
2104 freeaddrinfo (p);
2105 free (in6ai);
2107 return -(last_i & GAIH_EAI);
2109 if (end)
2110 while (*end)
2112 end = &((*end)->ai_next);
2113 ++nresults;
2116 else
2118 free (in6ai);
2119 return EAI_FAMILY;
2122 if (naddrs > 1)
2124 /* Read the config file. */
2125 __libc_once_define (static, once);
2126 __typeof (once) old_once = once;
2127 __libc_once (once, gaiconf_init);
2128 /* Sort results according to RFC 3484. */
2129 struct sort_result results[nresults];
2130 size_t order[nresults];
2131 struct addrinfo *q;
2132 struct addrinfo *last = NULL;
2133 char *canonname = NULL;
2135 /* If we have information about deprecated and temporary addresses
2136 sort the array now. */
2137 if (in6ai != NULL)
2138 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2140 int fd = -1;
2141 int af = AF_UNSPEC;
2143 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2145 results[i].dest_addr = q;
2146 results[i].native = -1;
2147 order[i] = i;
2149 /* If we just looked up the address for a different
2150 protocol, reuse the result. */
2151 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2152 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2154 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2155 results[i - 1].source_addr_len);
2156 results[i].source_addr_len = results[i - 1].source_addr_len;
2157 results[i].got_source_addr = results[i - 1].got_source_addr;
2158 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2159 results[i].prefixlen = results[i - 1].prefixlen;
2160 results[i].index = results[i - 1].index;
2162 else
2164 results[i].got_source_addr = false;
2165 results[i].source_addr_flags = 0;
2166 results[i].prefixlen = 0;
2167 results[i].index = 0xffffffffu;
2169 /* We overwrite the type with SOCK_DGRAM since we do not
2170 want connect() to connect to the other side. If we
2171 cannot determine the source address remember this
2172 fact. */
2173 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2175 if (fd != -1)
2176 close_retry:
2177 close_not_cancel_no_status (fd);
2178 af = q->ai_family;
2179 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2181 else
2183 /* Reset the connection. */
2184 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2185 __connect (fd, &sa, sizeof (sa));
2188 socklen_t sl = sizeof (results[i].source_addr);
2189 if (fd != -1
2190 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2191 && __getsockname (fd,
2192 (struct sockaddr *) &results[i].source_addr,
2193 &sl) == 0)
2195 results[i].source_addr_len = sl;
2196 results[i].got_source_addr = true;
2198 if (in6ai != NULL)
2200 /* See whether the source address is on the list of
2201 deprecated or temporary addresses. */
2202 struct in6addrinfo tmp;
2204 if (q->ai_family == AF_INET && af == AF_INET)
2206 struct sockaddr_in *sinp
2207 = (struct sockaddr_in *) &results[i].source_addr;
2208 tmp.addr[0] = 0;
2209 tmp.addr[1] = 0;
2210 tmp.addr[2] = htonl (0xffff);
2211 tmp.addr[3] = sinp->sin_addr.s_addr;
2213 else
2215 struct sockaddr_in6 *sin6p
2216 = (struct sockaddr_in6 *) &results[i].source_addr;
2217 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2220 struct in6addrinfo *found
2221 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2222 in6aicmp);
2223 if (found != NULL)
2225 results[i].source_addr_flags = found->flags;
2226 results[i].prefixlen = found->prefixlen;
2227 results[i].index = found->index;
2231 if (q->ai_family == AF_INET && af == AF_INET6)
2233 /* We have to convert the address. The socket is
2234 IPv6 and the request is for IPv4. */
2235 struct sockaddr_in6 *sin6
2236 = (struct sockaddr_in6 *) &results[i].source_addr;
2237 struct sockaddr_in *sin
2238 = (struct sockaddr_in *) &results[i].source_addr;
2239 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2240 sin->sin_family = AF_INET;
2241 /* We do not have to initialize sin_port since this
2242 fields has the same position and size in the IPv6
2243 structure. */
2244 assert (offsetof (struct sockaddr_in, sin_port)
2245 == offsetof (struct sockaddr_in6, sin6_port));
2246 assert (sizeof (sin->sin_port)
2247 == sizeof (sin6->sin6_port));
2248 memcpy (&sin->sin_addr,
2249 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2250 results[i].source_addr_len = sizeof (struct sockaddr_in);
2253 else if (errno == EAFNOSUPPORT && af == AF_INET6
2254 && q->ai_family == AF_INET)
2255 /* This could mean IPv6 sockets are IPv6-only. */
2256 goto close_retry;
2257 else
2258 /* Just make sure that if we have to process the same
2259 address again we do not copy any memory. */
2260 results[i].source_addr_len = 0;
2263 /* Remember the canonical name. */
2264 if (q->ai_canonname != NULL)
2266 assert (canonname == NULL);
2267 canonname = q->ai_canonname;
2268 q->ai_canonname = NULL;
2272 if (fd != -1)
2273 close_not_cancel_no_status (fd);
2275 /* We got all the source addresses we can get, now sort using
2276 the information. */
2277 struct sort_result_combo src
2278 = { .results = results, .nresults = nresults };
2279 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2281 __libc_lock_define_initialized (static, lock);
2283 __libc_lock_lock (lock);
2284 if (old_once && gaiconf_reload_flag)
2285 gaiconf_reload ();
2286 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2287 __libc_lock_unlock (lock);
2289 else
2290 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2292 /* Queue the results up as they come out of sorting. */
2293 q = p = results[order[0]].dest_addr;
2294 for (i = 1; i < nresults; ++i)
2295 q = q->ai_next = results[order[i]].dest_addr;
2296 q->ai_next = NULL;
2298 /* Fill in the canonical name into the new first entry. */
2299 p->ai_canonname = canonname;
2302 free (in6ai);
2304 if (p)
2306 *pai = p;
2307 return 0;
2310 if (pai == NULL && last_i == 0)
2311 return 0;
2313 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2315 libc_hidden_def (getaddrinfo)
2317 static_link_warning (getaddrinfo)
2319 void
2320 freeaddrinfo (struct addrinfo *ai)
2322 struct addrinfo *p;
2324 while (ai != NULL)
2326 p = ai;
2327 ai = ai->ai_next;
2328 free (p->ai_canonname);
2329 free (p);
2332 libc_hidden_def (freeaddrinfo)