2.9
[glibc/nacl-glibc.git] / sysdeps / posix / getaddrinfo.c
blob97f3af99385df5811764031e78c85d610a550d64
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 <nss.h>
44 #include <resolv.h>
45 #include <stdbool.h>
46 #include <stdio.h>
47 #include <stdio_ext.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <arpa/inet.h>
51 #include <net/if.h>
52 #include <netinet/in.h>
53 #include <sys/socket.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 #include <sys/un.h>
57 #include <sys/utsname.h>
58 #include <unistd.h>
59 #include <nsswitch.h>
60 #include <bits/libc-lock.h>
61 #include <not-cancel.h>
62 #include <nscd/nscd-client.h>
63 #include <nscd/nscd_proto.h>
64 #include <resolv/res_hconf.h>
66 #ifdef HAVE_LIBIDN
67 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
68 extern int __idna_to_unicode_lzlz (const char *input, char **output,
69 int flags);
70 # include <libidn/idna.h>
71 #endif
73 #define GAIH_OKIFUNSPEC 0x0100
74 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
76 #ifndef UNIX_PATH_MAX
77 # define UNIX_PATH_MAX 108
78 #endif
80 struct gaih_service
82 const char *name;
83 int num;
86 struct gaih_servtuple
88 struct gaih_servtuple *next;
89 int socktype;
90 int protocol;
91 int port;
94 static const struct gaih_servtuple nullserv;
97 struct gaih_typeproto
99 int socktype;
100 int protocol;
101 uint8_t protoflag;
102 bool defaultflag;
103 char name[8];
106 /* Values for `protoflag'. */
107 #define GAI_PROTO_NOSERVICE 1
108 #define GAI_PROTO_PROTOANY 2
110 static const struct gaih_typeproto gaih_inet_typeproto[] =
112 { 0, 0, 0, false, "" },
113 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
114 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
115 #if defined SOCK_DCCP && defined IPPROTO_DCCP
116 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
117 #endif
118 #ifdef IPPROTO_UDPLITE
119 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
120 #endif
121 #ifdef IPPROTO_SCTP
122 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
123 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
124 #endif
125 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
126 { 0, 0, 0, false, "" }
129 struct gaih
131 int family;
132 int (*gaih)(const char *name, const struct gaih_service *service,
133 const struct addrinfo *req, struct addrinfo **pai,
134 unsigned int *naddrs);
137 static const struct addrinfo default_hints =
139 .ai_flags = AI_DEFAULT,
140 .ai_family = PF_UNSPEC,
141 .ai_socktype = 0,
142 .ai_protocol = 0,
143 .ai_addrlen = 0,
144 .ai_addr = NULL,
145 .ai_canonname = NULL,
146 .ai_next = NULL
150 static int
151 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
152 const struct addrinfo *req, struct gaih_servtuple *st)
154 struct servent *s;
155 size_t tmpbuflen = 1024;
156 struct servent ts;
157 char *tmpbuf;
158 int r;
162 tmpbuf = __alloca (tmpbuflen);
164 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
165 &s);
166 if (r != 0 || s == NULL)
168 if (r == ERANGE)
169 tmpbuflen *= 2;
170 else
171 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
174 while (r);
176 st->next = NULL;
177 st->socktype = tp->socktype;
178 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
179 ? req->ai_protocol : tp->protocol);
180 st->port = s->s_port;
182 return 0;
185 #define gethosts(_family, _type) \
187 int i; \
188 int herrno; \
189 struct hostent th; \
190 struct hostent *h; \
191 char *localcanon = NULL; \
192 no_data = 0; \
193 while (1) { \
194 rc = 0; \
195 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
196 &rc, &herrno, NULL, &localcanon)); \
197 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
198 break; \
199 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
201 if (status == NSS_STATUS_SUCCESS && rc == 0) \
202 h = &th; \
203 else \
204 h = NULL; \
205 if (rc != 0) \
207 if (herrno == NETDB_INTERNAL) \
209 __set_h_errno (herrno); \
210 _res.options = old_res_options; \
211 return -EAI_SYSTEM; \
213 if (herrno == TRY_AGAIN) \
214 no_data = EAI_AGAIN; \
215 else \
216 no_data = herrno == NO_DATA; \
218 else if (h != NULL) \
220 for (i = 0; h->h_addr_list[i]; i++) \
222 if (*pat == NULL) \
224 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
225 (*pat)->scopeid = 0; \
227 uint32_t *addr = (*pat)->addr; \
228 (*pat)->next = NULL; \
229 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
230 if (_family == AF_INET && req->ai_family == AF_INET6) \
232 (*pat)->family = AF_INET6; \
233 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
234 addr[2] = htonl (0xffff); \
235 addr[1] = 0; \
236 addr[0] = 0; \
238 else \
240 (*pat)->family = _family; \
241 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
243 pat = &((*pat)->next); \
246 if (localcanon != NULL && canon == NULL) \
247 canon = strdupa (localcanon); \
249 if (_family == AF_INET6 && i > 0) \
250 got_ipv6 = true; \
255 typedef enum nss_status (*nss_gethostbyname4_r)
256 (const char *name, struct gaih_addrtuple **pat,
257 char *buffer, size_t buflen, int *errnop,
258 int *h_errnop, int32_t *ttlp);
259 typedef enum nss_status (*nss_gethostbyname3_r)
260 (const char *name, int af, struct hostent *host,
261 char *buffer, size_t buflen, int *errnop,
262 int *h_errnop, int32_t *ttlp, char **canonp);
263 typedef enum nss_status (*nss_getcanonname_r)
264 (const char *name, char *buffer, size_t buflen, char **result,
265 int *errnop, int *h_errnop);
266 extern service_user *__nss_hosts_database attribute_hidden;
269 static int
270 gaih_inet (const char *name, const struct gaih_service *service,
271 const struct addrinfo *req, struct addrinfo **pai,
272 unsigned int *naddrs)
274 const struct gaih_typeproto *tp = gaih_inet_typeproto;
275 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
276 struct gaih_addrtuple *at = NULL;
277 int rc;
278 bool got_ipv6 = false;
279 const char *canon = NULL;
280 const char *orig_name = name;
282 if (req->ai_protocol || req->ai_socktype)
284 ++tp;
286 while (tp->name[0]
287 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
288 || (req->ai_protocol != 0
289 && !(tp->protoflag & GAI_PROTO_PROTOANY)
290 && req->ai_protocol != tp->protocol)))
291 ++tp;
293 if (! tp->name[0])
295 if (req->ai_socktype)
296 return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
297 else
298 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
302 int port = 0;
303 if (service != NULL)
305 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
306 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
308 if (service->num < 0)
310 if (tp->name[0])
312 st = (struct gaih_servtuple *)
313 __alloca (sizeof (struct gaih_servtuple));
315 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
316 return rc;
318 else
320 struct gaih_servtuple **pst = &st;
321 for (tp++; tp->name[0]; tp++)
323 struct gaih_servtuple *newp;
325 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
326 continue;
328 if (req->ai_socktype != 0
329 && req->ai_socktype != tp->socktype)
330 continue;
331 if (req->ai_protocol != 0
332 && !(tp->protoflag & GAI_PROTO_PROTOANY)
333 && req->ai_protocol != tp->protocol)
334 continue;
336 newp = (struct gaih_servtuple *)
337 __alloca (sizeof (struct gaih_servtuple));
339 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
341 if (rc & GAIH_OKIFUNSPEC)
342 continue;
343 return rc;
346 *pst = newp;
347 pst = &(newp->next);
349 if (st == (struct gaih_servtuple *) &nullserv)
350 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
353 else
355 port = htons (service->num);
356 goto got_port;
359 else
361 got_port:
363 if (req->ai_socktype || req->ai_protocol)
365 st = __alloca (sizeof (struct gaih_servtuple));
366 st->next = NULL;
367 st->socktype = tp->socktype;
368 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
369 ? req->ai_protocol : tp->protocol);
370 st->port = port;
372 else
374 /* Neither socket type nor protocol is set. Return all socket types
375 we know about. */
376 struct gaih_servtuple **lastp = &st;
377 for (++tp; tp->name[0]; ++tp)
378 if (tp->defaultflag)
380 struct gaih_servtuple *newp;
382 newp = __alloca (sizeof (struct gaih_servtuple));
383 newp->next = NULL;
384 newp->socktype = tp->socktype;
385 newp->protocol = tp->protocol;
386 newp->port = port;
388 *lastp = newp;
389 lastp = &newp->next;
394 if (name != NULL)
396 at = __alloca (sizeof (struct gaih_addrtuple));
398 at->family = AF_UNSPEC;
399 at->scopeid = 0;
400 at->next = NULL;
402 #ifdef HAVE_LIBIDN
403 if (req->ai_flags & AI_IDN)
405 int idn_flags = 0;
406 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
407 idn_flags |= IDNA_ALLOW_UNASSIGNED;
408 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
409 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
411 char *p = NULL;
412 rc = __idna_to_ascii_lz (name, &p, idn_flags);
413 if (rc != IDNA_SUCCESS)
415 if (rc == IDNA_MALLOC_ERROR)
416 return -EAI_MEMORY;
417 if (rc == IDNA_DLOPEN_ERROR)
418 return -EAI_SYSTEM;
419 return -EAI_IDN_ENCODE;
421 /* In case the output string is the same as the input string
422 no new string has been allocated. */
423 if (p != name)
425 name = strdupa (p);
426 free (p);
429 #endif
431 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
433 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
434 at->family = AF_INET;
435 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
437 at->addr[3] = at->addr[0];
438 at->addr[2] = htonl (0xffff);
439 at->addr[1] = 0;
440 at->addr[0] = 0;
441 at->family = AF_INET6;
443 else
444 return -EAI_ADDRFAMILY;
446 if (req->ai_flags & AI_CANONNAME)
447 canon = name;
449 else if (at->family == AF_UNSPEC)
451 char *namebuf = (char *) name;
452 char *scope_delim = strchr (name, SCOPE_DELIMITER);
454 if (__builtin_expect (scope_delim != NULL, 0))
456 namebuf = alloca (scope_delim - name + 1);
457 *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
460 if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
462 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
463 at->family = AF_INET6;
464 else if (req->ai_family == AF_INET
465 && IN6_IS_ADDR_V4MAPPED (at->addr))
467 at->addr[0] = at->addr[3];
468 at->family = AF_INET;
470 else
471 return -EAI_ADDRFAMILY;
473 if (scope_delim != NULL)
475 int try_numericscope = 0;
476 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
477 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
479 at->scopeid = if_nametoindex (scope_delim + 1);
480 if (at->scopeid == 0)
481 try_numericscope = 1;
483 else
484 try_numericscope = 1;
486 if (try_numericscope != 0)
488 char *end;
489 assert (sizeof (uint32_t) <= sizeof (unsigned long));
490 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
491 10);
492 if (*end != '\0')
493 return GAIH_OKIFUNSPEC | -EAI_NONAME;
497 if (req->ai_flags & AI_CANONNAME)
498 canon = name;
502 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
504 struct gaih_addrtuple **pat = &at;
505 int no_data = 0;
506 int no_inet6_data = 0;
507 service_user *nip = NULL;
508 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
509 enum nss_status status = NSS_STATUS_UNAVAIL;
510 int no_more;
511 int old_res_options;
513 /* If we do not have to look for IPv4 and IPv6 together, use
514 the simple, old functions. */
515 if (req->ai_family == AF_INET
516 || (req->ai_family == AF_INET6
517 && ((req->ai_flags & AI_V4MAPPED) == 0
518 || (req->ai_flags & AI_ALL) == 0)))
520 int family = req->ai_family;
521 size_t tmpbuflen = 512;
522 char *tmpbuf = alloca (tmpbuflen);
523 int rc;
524 struct hostent th;
525 struct hostent *h;
526 int herrno;
528 simple_again:
529 while (1)
531 rc = __gethostbyname2_r (name, family, &th, tmpbuf,
532 tmpbuflen, &h, &herrno);
533 if (rc != ERANGE || herrno != NETDB_INTERNAL)
534 break;
535 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
538 if (rc == 0)
540 if (h == NULL)
542 if (req->ai_family == AF_INET6
543 && (req->ai_flags & AI_V4MAPPED)
544 && family == AF_INET6)
546 /* Try again, this time looking for IPv4
547 addresses. */
548 family = AF_INET;
549 goto simple_again;
552 else
554 /* We found data, now convert it into the list. */
555 for (int i = 0; h->h_addr_list[i]; ++i)
557 if (*pat == NULL)
559 *pat = __alloca (sizeof (struct gaih_addrtuple));
560 (*pat)->scopeid = 0;
562 (*pat)->next = NULL;
563 (*pat)->family = req->ai_family;
564 if (family == req->ai_family)
565 memcpy ((*pat)->addr, h->h_addr_list[i],
566 h->h_length);
567 else
569 uint32_t *addr = (uint32_t *) (*pat)->addr;
570 addr[3] = *(uint32_t *) h->h_addr_list[i];
571 addr[2] = htonl (0xffff);
572 addr[1] = 0;
573 addr[0] = 0;
575 pat = &((*pat)->next);
579 else
581 if (herrno == NETDB_INTERNAL)
583 __set_h_errno (herrno);
584 return -EAI_SYSTEM;
586 if (herrno == TRY_AGAIN)
588 return -EAI_AGAIN;
590 /* We made requests but they turned out no data.
591 The name is known, though. */
592 return GAIH_OKIFUNSPEC | -EAI_NODATA;
595 goto process_list;
598 #ifdef USE_NSCD
599 if (__nss_not_use_nscd_hosts > 0
600 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
601 __nss_not_use_nscd_hosts = 0;
603 if (!__nss_not_use_nscd_hosts)
605 /* Try to use nscd. */
606 struct nscd_ai_result *air = NULL;
607 int herrno;
608 int err = __nscd_getai (name, &air, &herrno);
609 if (air != NULL)
611 /* Transform into gaih_addrtuple list. */
612 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
613 char *addrs = air->addrs;
615 for (int i = 0; i < air->naddrs; ++i)
617 socklen_t size = (air->family[i] == AF_INET
618 ? INADDRSZ : IN6ADDRSZ);
619 if (*pat == NULL)
621 *pat = __alloca (sizeof (struct gaih_addrtuple));
622 (*pat)->scopeid = 0;
624 uint32_t *pataddr = (*pat)->addr;
625 (*pat)->next = NULL;
626 if (added_canon || air->canon == NULL)
627 (*pat)->name = NULL;
628 else
629 canon = (*pat)->name = strdupa (air->canon);
631 if (air->family[i] == AF_INET
632 && req->ai_family == AF_INET6
633 && (req->ai_flags & AI_V4MAPPED))
635 (*pat)->family = AF_INET6;
636 pataddr[3] = *(uint32_t *) addrs;
637 pataddr[2] = htonl (0xffff);
638 pataddr[1] = 0;
639 pataddr[0] = 0;
640 pat = &((*pat)->next);
641 added_canon = true;
643 else if (req->ai_family == AF_UNSPEC
644 || air->family[i] == req->ai_family)
646 (*pat)->family = air->family[i];
647 memcpy (pataddr, addrs, size);
648 pat = &((*pat)->next);
649 added_canon = true;
650 if (air->family[i] == AF_INET6)
651 got_ipv6 = true;
653 addrs += size;
656 free (air);
658 if (at->family == AF_UNSPEC)
659 return GAIH_OKIFUNSPEC | -EAI_NONAME;
661 goto process_list;
663 else if (err == 0)
664 /* The database contains a negative entry. */
665 return 0;
666 else if (__nss_not_use_nscd_hosts == 0)
668 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
669 return -EAI_MEMORY;
670 if (herrno == TRY_AGAIN)
671 return -EAI_AGAIN;
672 return -EAI_SYSTEM;
675 #endif
677 if (__nss_hosts_database != NULL)
679 no_more = 0;
680 nip = __nss_hosts_database;
682 else
683 no_more = __nss_database_lookup ("hosts", NULL,
684 "dns [!UNAVAIL=return] files",
685 &nip);
687 /* Initialize configurations. */
688 if (__builtin_expect (!_res_hconf.initialized, 0))
689 _res_hconf_init ();
690 if (__res_maybe_init (&_res, 0) == -1)
691 no_more = 1;
693 /* If we are looking for both IPv4 and IPv6 address we don't
694 want the lookup functions to automatically promote IPv4
695 addresses to IPv6 addresses. Currently this is decided
696 by setting the RES_USE_INET6 bit in _res.options. */
697 old_res_options = _res.options;
698 _res.options &= ~RES_USE_INET6;
700 size_t tmpbuflen = 1024;
701 char *tmpbuf = alloca (tmpbuflen);
703 while (!no_more)
705 nss_gethostbyname4_r fct4
706 = __nss_lookup_function (nip, "gethostbyname4_r");
707 if (fct4 != NULL)
709 int herrno;
711 while (1)
713 rc = 0;
714 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
715 tmpbuflen, &rc, &herrno,
716 NULL));
717 if (status != NSS_STATUS_TRYAGAIN
718 || rc != ERANGE || herrno != NETDB_INTERNAL)
720 if (herrno == NETDB_INTERNAL)
722 __set_h_errno (herrno);
723 _res.options = old_res_options;
724 return -EAI_SYSTEM;
726 if (herrno == TRY_AGAIN)
727 no_data = EAI_AGAIN;
728 else
729 no_data = herrno == NO_DATA;
730 break;
732 tmpbuf = extend_alloca (tmpbuf,
733 tmpbuflen, 2 * tmpbuflen);
736 if (status == NSS_STATUS_SUCCESS)
738 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
739 canon = (*pat)->name;
741 while (*pat != NULL)
742 pat = &((*pat)->next);
745 else
747 nss_gethostbyname3_r fct = NULL;
748 if (req->ai_flags & AI_CANONNAME)
749 /* No need to use this function if we do not look for
750 the canonical name. The function does not exist in
751 all NSS modules and therefore the lookup would
752 often fail. */
753 fct = __nss_lookup_function (nip, "gethostbyname3_r");
754 if (fct == NULL)
755 /* We are cheating here. The gethostbyname2_r
756 function does not have the same interface as
757 gethostbyname3_r but the extra arguments the
758 latter takes are added at the end. So the
759 gethostbyname2_r code will just ignore them. */
760 fct = __nss_lookup_function (nip, "gethostbyname2_r");
762 if (fct != NULL)
764 if (req->ai_family == AF_INET6
765 || req->ai_family == AF_UNSPEC)
767 gethosts (AF_INET6, struct in6_addr);
768 no_inet6_data = no_data;
769 inet6_status = status;
771 if (req->ai_family == AF_INET
772 || req->ai_family == AF_UNSPEC
773 || (req->ai_family == AF_INET6
774 && (req->ai_flags & AI_V4MAPPED)
775 /* Avoid generating the mapped addresses if we
776 know we are not going to need them. */
777 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
779 gethosts (AF_INET, struct in_addr);
781 if (req->ai_family == AF_INET)
783 no_inet6_data = no_data;
784 inet6_status = status;
788 /* If we found one address for AF_INET or AF_INET6,
789 don't continue the search. */
790 if (inet6_status == NSS_STATUS_SUCCESS
791 || status == NSS_STATUS_SUCCESS)
793 if ((req->ai_flags & AI_CANONNAME) != 0
794 && canon == NULL)
796 /* If we need the canonical name, get it
797 from the same service as the result. */
798 nss_getcanonname_r cfct;
799 int herrno;
801 cfct = __nss_lookup_function (nip,
802 "getcanonname_r");
803 if (cfct != NULL)
805 const size_t max_fqdn_len = 256;
806 char *buf = alloca (max_fqdn_len);
807 char *s;
809 if (DL_CALL_FCT (cfct, (at->name ?: name,
810 buf, max_fqdn_len,
811 &s, &rc, &herrno))
812 == NSS_STATUS_SUCCESS)
813 canon = s;
814 else
815 /* Set to name now to avoid using
816 gethostbyaddr. */
817 canon = name;
821 break;
824 /* We can have different states for AF_INET and
825 AF_INET6. Try to find a useful one for both. */
826 if (inet6_status == NSS_STATUS_TRYAGAIN)
827 status = NSS_STATUS_TRYAGAIN;
828 else if (status == NSS_STATUS_UNAVAIL
829 && inet6_status != NSS_STATUS_UNAVAIL)
830 status = inet6_status;
834 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
835 break;
837 if (nip->next == NULL)
838 no_more = -1;
839 else
840 nip = nip->next;
843 _res.options = old_res_options;
845 if (no_data != 0 && no_inet6_data != 0)
847 /* If both requests timed out report this. */
848 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
849 return -EAI_AGAIN;
851 /* We made requests but they turned out no data. The name
852 is known, though. */
853 return GAIH_OKIFUNSPEC | -EAI_NODATA;
857 process_list:
858 if (at->family == AF_UNSPEC)
859 return GAIH_OKIFUNSPEC | -EAI_NONAME;
861 else
863 struct gaih_addrtuple *atr;
864 atr = at = __alloca (sizeof (struct gaih_addrtuple));
865 memset (at, '\0', sizeof (struct gaih_addrtuple));
867 if (req->ai_family == AF_UNSPEC)
869 at->next = __alloca (sizeof (struct gaih_addrtuple));
870 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
873 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
875 at->family = AF_INET6;
876 if ((req->ai_flags & AI_PASSIVE) == 0)
877 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
878 atr = at->next;
881 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
883 atr->family = AF_INET;
884 if ((req->ai_flags & AI_PASSIVE) == 0)
885 atr->addr[0] = htonl (INADDR_LOOPBACK);
890 struct gaih_servtuple *st2;
891 struct gaih_addrtuple *at2 = at;
892 size_t socklen;
893 sa_family_t family;
896 buffer is the size of an unformatted IPv6 address in printable format.
898 while (at2 != NULL)
900 /* Only the first entry gets the canonical name. */
901 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
903 if (canon == NULL)
905 struct hostent *h = NULL;
906 int herrno;
907 struct hostent th;
908 size_t tmpbuflen = 512;
909 char *tmpbuf = NULL;
913 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
914 rc = __gethostbyaddr_r (at2->addr,
915 ((at2->family == AF_INET6)
916 ? sizeof (struct in6_addr)
917 : sizeof (struct in_addr)),
918 at2->family, &th, tmpbuf,
919 tmpbuflen, &h, &herrno);
921 while (rc == ERANGE && herrno == NETDB_INTERNAL);
923 if (rc != 0 && herrno == NETDB_INTERNAL)
925 __set_h_errno (herrno);
926 return -EAI_SYSTEM;
929 if (h != NULL)
930 canon = h->h_name;
931 else
933 assert (orig_name != NULL);
934 /* If the canonical name cannot be determined, use
935 the passed in string. */
936 canon = orig_name;
940 #ifdef HAVE_LIBIDN
941 if (req->ai_flags & AI_CANONIDN)
943 int idn_flags = 0;
944 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
945 idn_flags |= IDNA_ALLOW_UNASSIGNED;
946 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
947 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
949 char *out;
950 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
951 if (rc != IDNA_SUCCESS)
953 if (rc == IDNA_MALLOC_ERROR)
954 return -EAI_MEMORY;
955 if (rc == IDNA_DLOPEN_ERROR)
956 return -EAI_SYSTEM;
957 return -EAI_IDN_ENCODE;
959 /* In case the output string is the same as the input
960 string no new string has been allocated and we
961 make a copy. */
962 if (out == canon)
963 goto make_copy;
965 else
966 #endif
968 #ifdef HAVE_LIBIDN
969 make_copy:
970 #endif
971 canon = strdup (canon);
972 if (canon == NULL)
973 return -EAI_MEMORY;
977 family = at2->family;
978 if (family == AF_INET6)
980 socklen = sizeof (struct sockaddr_in6);
982 /* If we looked up IPv4 mapped address discard them here if
983 the caller isn't interested in all address and we have
984 found at least one IPv6 address. */
985 if (got_ipv6
986 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
987 && IN6_IS_ADDR_V4MAPPED (at2->addr))
988 goto ignore;
990 else
991 socklen = sizeof (struct sockaddr_in);
993 for (st2 = st; st2 != NULL; st2 = st2->next)
995 struct addrinfo *ai;
996 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
997 if (ai == NULL)
999 free ((char *) canon);
1000 return -EAI_MEMORY;
1003 ai->ai_flags = req->ai_flags;
1004 ai->ai_family = family;
1005 ai->ai_socktype = st2->socktype;
1006 ai->ai_protocol = st2->protocol;
1007 ai->ai_addrlen = socklen;
1008 ai->ai_addr = (void *) (ai + 1);
1010 /* We only add the canonical name once. */
1011 ai->ai_canonname = (char *) canon;
1012 canon = NULL;
1014 #ifdef _HAVE_SA_LEN
1015 ai->ai_addr->sa_len = socklen;
1016 #endif /* _HAVE_SA_LEN */
1017 ai->ai_addr->sa_family = family;
1019 /* In case of an allocation error the list must be NULL
1020 terminated. */
1021 ai->ai_next = NULL;
1023 if (family == AF_INET6)
1025 struct sockaddr_in6 *sin6p =
1026 (struct sockaddr_in6 *) ai->ai_addr;
1028 sin6p->sin6_port = st2->port;
1029 sin6p->sin6_flowinfo = 0;
1030 memcpy (&sin6p->sin6_addr,
1031 at2->addr, sizeof (struct in6_addr));
1032 sin6p->sin6_scope_id = at2->scopeid;
1034 else
1036 struct sockaddr_in *sinp =
1037 (struct sockaddr_in *) ai->ai_addr;
1038 sinp->sin_port = st2->port;
1039 memcpy (&sinp->sin_addr,
1040 at2->addr, sizeof (struct in_addr));
1041 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1044 pai = &(ai->ai_next);
1047 ++*naddrs;
1049 ignore:
1050 at2 = at2->next;
1053 return 0;
1057 struct sort_result
1059 struct addrinfo *dest_addr;
1060 /* Using sockaddr_storage is for now overkill. We only support IPv4
1061 and IPv6 so far. If this changes at some point we can adjust the
1062 type here. */
1063 struct sockaddr_in6 source_addr;
1064 uint8_t source_addr_len;
1065 bool got_source_addr;
1066 uint8_t source_addr_flags;
1067 uint8_t prefixlen;
1068 uint32_t index;
1069 int32_t native;
1072 struct sort_result_combo
1074 struct sort_result *results;
1075 int nresults;
1079 #if __BYTE_ORDER == __BIG_ENDIAN
1080 # define htonl_c(n) n
1081 #else
1082 # define htonl_c(n) __bswap_constant_32 (n)
1083 #endif
1085 static const struct scopeentry
1087 union
1089 char addr[4];
1090 uint32_t addr32;
1092 uint32_t netmask;
1093 int32_t scope;
1094 } default_scopes[] =
1096 /* Link-local addresses: scope 2. */
1097 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1098 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1099 /* Site-local addresses: scope 5. */
1100 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1101 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1102 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1103 /* Default: scope 14. */
1104 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1107 /* The label table. */
1108 static const struct scopeentry *scopes;
1111 static int
1112 get_scope (const struct sockaddr_in6 *in6)
1114 int scope;
1115 if (in6->sin6_family == PF_INET6)
1117 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1119 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1120 /* RFC 4291 2.5.3 says that the loopback address is to be
1121 treated like a link-local address. */
1122 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1123 scope = 2;
1124 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1125 scope = 5;
1126 else
1127 /* XXX Is this the correct default behavior? */
1128 scope = 14;
1130 else
1131 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1133 else if (in6->sin6_family == PF_INET)
1135 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1137 size_t cnt = 0;
1138 while (1)
1140 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1141 == scopes[cnt].addr32)
1142 return scopes[cnt].scope;
1144 ++cnt;
1146 /* NOTREACHED */
1148 else
1149 /* XXX What is a good default? */
1150 scope = 15;
1152 return scope;
1156 struct prefixentry
1158 struct in6_addr prefix;
1159 unsigned int bits;
1160 int val;
1164 /* The label table. */
1165 static const struct prefixentry *labels;
1167 /* Default labels. */
1168 static const struct prefixentry default_labels[] =
1170 /* See RFC 3484 for the details. */
1171 { { .__in6_u
1172 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1174 }, 128, 0 },
1175 { { .__in6_u
1176 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1178 }, 16, 2 },
1179 { { .__in6_u
1180 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1182 }, 96, 3 },
1183 { { .__in6_u
1184 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1186 }, 96, 4 },
1187 /* The next two entries differ from RFC 3484. We need to treat
1188 IPv6 site-local addresses special because they are never NATed,
1189 unlike site-locale IPv4 addresses. If this would not happen, on
1190 machines which have only IPv4 and IPv6 site-local addresses, the
1191 sorting would prefer the IPv6 site-local addresses, causing
1192 unnecessary delays when trying to connect to a global IPv6 address
1193 through a site-local IPv6 address. */
1194 { { .__in6_u
1195 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1197 }, 10, 5 },
1198 { { .__in6_u
1199 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1201 }, 7, 6 },
1202 /* Additional rule for Teredo tunnels. */
1203 { { .__in6_u
1204 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1206 }, 32, 7 },
1207 { { .__in6_u
1208 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1210 }, 0, 1 }
1214 /* The precedence table. */
1215 static const struct prefixentry *precedence;
1217 /* The default precedences. */
1218 static const struct prefixentry default_precedence[] =
1220 /* See RFC 3484 for the details. */
1221 { { .__in6_u
1222 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1224 }, 128, 50 },
1225 { { .__in6_u
1226 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1228 }, 16, 30 },
1229 { { .__in6_u
1230 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1232 }, 96, 20 },
1233 { { .__in6_u
1234 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1236 }, 96, 10 },
1237 { { .__in6_u
1238 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1240 }, 0, 40 }
1244 static int
1245 match_prefix (const struct sockaddr_in6 *in6,
1246 const struct prefixentry *list, int default_val)
1248 int idx;
1249 struct sockaddr_in6 in6_mem;
1251 if (in6->sin6_family == PF_INET)
1253 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1255 /* Construct a V4-to-6 mapped address. */
1256 in6_mem.sin6_family = PF_INET6;
1257 in6_mem.sin6_port = in->sin_port;
1258 in6_mem.sin6_flowinfo = 0;
1259 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1260 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1261 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1262 in6_mem.sin6_scope_id = 0;
1264 in6 = &in6_mem;
1266 else if (in6->sin6_family != PF_INET6)
1267 return default_val;
1269 for (idx = 0; ; ++idx)
1271 unsigned int bits = list[idx].bits;
1272 const uint8_t *mask = list[idx].prefix.s6_addr;
1273 const uint8_t *val = in6->sin6_addr.s6_addr;
1275 while (bits >= 8)
1277 if (*mask != *val)
1278 break;
1280 ++mask;
1281 ++val;
1282 bits -= 8;
1285 if (bits < 8)
1287 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1288 /* Match! */
1289 break;
1293 return list[idx].val;
1297 static int
1298 get_label (const struct sockaddr_in6 *in6)
1300 /* XXX What is a good default value? */
1301 return match_prefix (in6, labels, INT_MAX);
1305 static int
1306 get_precedence (const struct sockaddr_in6 *in6)
1308 /* XXX What is a good default value? */
1309 return match_prefix (in6, precedence, 0);
1313 /* Find last bit set in a word. */
1314 static int
1315 fls (uint32_t a)
1317 uint32_t mask;
1318 int n;
1319 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1320 if ((a & mask) != 0)
1321 break;
1322 return n;
1326 static int
1327 rfc3484_sort (const void *p1, const void *p2, void *arg)
1329 const size_t idx1 = *(const size_t *) p1;
1330 const size_t idx2 = *(const size_t *) p2;
1331 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1332 struct sort_result *a1 = &src->results[idx1];
1333 struct sort_result *a2 = &src->results[idx2];
1335 /* Rule 1: Avoid unusable destinations.
1336 We have the got_source_addr flag set if the destination is reachable. */
1337 if (a1->got_source_addr && ! a2->got_source_addr)
1338 return -1;
1339 if (! a1->got_source_addr && a2->got_source_addr)
1340 return 1;
1343 /* Rule 2: Prefer matching scope. Only interesting if both
1344 destination addresses are IPv6. */
1345 int a1_dst_scope
1346 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1348 int a2_dst_scope
1349 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1351 if (a1->got_source_addr)
1353 int a1_src_scope = get_scope (&a1->source_addr);
1354 int a2_src_scope = get_scope (&a2->source_addr);
1356 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1357 return -1;
1358 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1359 return 1;
1363 /* Rule 3: Avoid deprecated addresses. */
1364 if (a1->got_source_addr)
1366 if (!(a1->source_addr_flags & in6ai_deprecated)
1367 && (a2->source_addr_flags & in6ai_deprecated))
1368 return -1;
1369 if ((a1->source_addr_flags & in6ai_deprecated)
1370 && !(a2->source_addr_flags & in6ai_deprecated))
1371 return 1;
1374 /* Rule 4: Prefer home addresses. */
1375 if (a1->got_source_addr)
1377 if (!(a1->source_addr_flags & in6ai_homeaddress)
1378 && (a2->source_addr_flags & in6ai_homeaddress))
1379 return 1;
1380 if ((a1->source_addr_flags & in6ai_homeaddress)
1381 && !(a2->source_addr_flags & in6ai_homeaddress))
1382 return -1;
1385 /* Rule 5: Prefer matching label. */
1386 if (a1->got_source_addr)
1388 int a1_dst_label
1389 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1390 int a1_src_label = get_label (&a1->source_addr);
1392 int a2_dst_label
1393 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1394 int a2_src_label = get_label (&a2->source_addr);
1396 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1397 return -1;
1398 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1399 return 1;
1403 /* Rule 6: Prefer higher precedence. */
1404 int a1_prec
1405 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1406 int a2_prec
1407 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1409 if (a1_prec > a2_prec)
1410 return -1;
1411 if (a1_prec < a2_prec)
1412 return 1;
1415 /* Rule 7: Prefer native transport. */
1416 if (a1->got_source_addr)
1418 /* The same interface index means the same interface which means
1419 there is no difference in transport. This should catch many
1420 (most?) cases. */
1421 if (a1->index != a2->index)
1423 int a1_native = a1->native;
1424 int a2_native = a2->native;
1426 if (a1_native == -1 || a2_native == -1)
1428 uint32_t a1_index;
1429 if (a1_native == -1)
1431 /* If we do not have the information use 'native' as
1432 the default. */
1433 a1_native = 0;
1434 a1_index = a1->index;
1436 else
1437 a1_index = 0xffffffffu;
1439 uint32_t a2_index;
1440 if (a2_native == -1)
1442 /* If we do not have the information use 'native' as
1443 the default. */
1444 a2_native = 0;
1445 a2_index = a2->index;
1447 else
1448 a2_index = 0xffffffffu;
1450 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1452 /* Fill in the results in all the records. */
1453 for (int i = 0; i < src->nresults; ++i)
1454 if (src->results[i].index == a1_index)
1456 assert (src->results[i].native == -1
1457 || src->results[i].native == a1_native);
1458 src->results[i].native = a1_native;
1460 else if (src->results[i].index == a2_index)
1462 assert (src->results[i].native == -1
1463 || src->results[i].native == a2_native);
1464 src->results[i].native = a2_native;
1468 if (a1_native && !a2_native)
1469 return -1;
1470 if (!a1_native && a2_native)
1471 return 1;
1476 /* Rule 8: Prefer smaller scope. */
1477 if (a1_dst_scope < a2_dst_scope)
1478 return -1;
1479 if (a1_dst_scope > a2_dst_scope)
1480 return 1;
1483 /* Rule 9: Use longest matching prefix. */
1484 if (a1->got_source_addr
1485 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1487 int bit1 = 0;
1488 int bit2 = 0;
1490 if (a1->dest_addr->ai_family == PF_INET)
1492 assert (a1->source_addr.sin6_family == PF_INET);
1493 assert (a2->source_addr.sin6_family == PF_INET);
1495 /* Outside of subnets, as defined by the network masks,
1496 common address prefixes for IPv4 addresses make no sense.
1497 So, define a non-zero value only if source and
1498 destination address are on the same subnet. */
1499 struct sockaddr_in *in1_dst
1500 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1501 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1502 struct sockaddr_in *in1_src
1503 = (struct sockaddr_in *) &a1->source_addr;
1504 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1505 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1507 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1508 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1510 struct sockaddr_in *in2_dst
1511 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1512 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1513 struct sockaddr_in *in2_src
1514 = (struct sockaddr_in *) &a2->source_addr;
1515 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1516 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1518 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1519 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1521 else if (a1->dest_addr->ai_family == PF_INET6)
1523 assert (a1->source_addr.sin6_family == PF_INET6);
1524 assert (a2->source_addr.sin6_family == PF_INET6);
1526 struct sockaddr_in6 *in1_dst;
1527 struct sockaddr_in6 *in1_src;
1528 struct sockaddr_in6 *in2_dst;
1529 struct sockaddr_in6 *in2_src;
1531 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1532 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1533 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1534 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1536 int i;
1537 for (i = 0; i < 4; ++i)
1538 if (in1_dst->sin6_addr.s6_addr32[i]
1539 != in1_src->sin6_addr.s6_addr32[i]
1540 || (in2_dst->sin6_addr.s6_addr32[i]
1541 != in2_src->sin6_addr.s6_addr32[i]))
1542 break;
1544 if (i < 4)
1546 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1547 ^ in1_src->sin6_addr.s6_addr32[i]));
1548 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1549 ^ in2_src->sin6_addr.s6_addr32[i]));
1553 if (bit1 > bit2)
1554 return -1;
1555 if (bit1 < bit2)
1556 return 1;
1560 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1561 compare with the value indicating the order in which the entries
1562 have been received from the services. NB: no two entries can have
1563 the same order so the test will never return zero. */
1564 return idx1 < idx2 ? -1 : 1;
1568 static int
1569 in6aicmp (const void *p1, const void *p2)
1571 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1572 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1574 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1578 /* Name of the config file for RFC 3484 sorting (for now). */
1579 #define GAICONF_FNAME "/etc/gai.conf"
1582 /* Non-zero if we are supposed to reload the config file automatically
1583 whenever it changed. */
1584 static int gaiconf_reload_flag;
1586 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1587 static int gaiconf_reload_flag_ever_set;
1589 /* Last modification time. */
1590 static struct timespec gaiconf_mtime;
1593 libc_freeres_fn(fini)
1595 if (labels != default_labels)
1597 const struct prefixentry *old = labels;
1598 labels = default_labels;
1599 free ((void *) old);
1602 if (precedence != default_precedence)
1604 const struct prefixentry *old = precedence;
1605 precedence = default_precedence;
1606 free ((void *) old);
1609 if (scopes != default_scopes)
1611 const struct scopeentry *old = scopes;
1612 scopes = default_scopes;
1613 free ((void *) old);
1618 struct prefixlist
1620 struct prefixentry entry;
1621 struct prefixlist *next;
1625 struct scopelist
1627 struct scopeentry entry;
1628 struct scopelist *next;
1632 static void
1633 free_prefixlist (struct prefixlist *list)
1635 while (list != NULL)
1637 struct prefixlist *oldp = list;
1638 list = list->next;
1639 free (oldp);
1644 static void
1645 free_scopelist (struct scopelist *list)
1647 while (list != NULL)
1649 struct scopelist *oldp = list;
1650 list = list->next;
1651 free (oldp);
1656 static int
1657 prefixcmp (const void *p1, const void *p2)
1659 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1660 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1662 if (e1->bits < e2->bits)
1663 return 1;
1664 if (e1->bits == e2->bits)
1665 return 0;
1666 return -1;
1670 static int
1671 scopecmp (const void *p1, const void *p2)
1673 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1674 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1676 if (e1->netmask > e2->netmask)
1677 return -1;
1678 if (e1->netmask == e2->netmask)
1679 return 0;
1680 return 1;
1684 static void
1685 gaiconf_init (void)
1687 struct prefixlist *labellist = NULL;
1688 size_t nlabellist = 0;
1689 bool labellist_nullbits = false;
1690 struct prefixlist *precedencelist = NULL;
1691 size_t nprecedencelist = 0;
1692 bool precedencelist_nullbits = false;
1693 struct scopelist *scopelist = NULL;
1694 size_t nscopelist = 0;
1695 bool scopelist_nullbits = false;
1697 FILE *fp = fopen (GAICONF_FNAME, "rc");
1698 if (fp != NULL)
1700 struct stat64 st;
1701 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1703 fclose (fp);
1704 goto no_file;
1707 char *line = NULL;
1708 size_t linelen = 0;
1710 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1712 while (!feof_unlocked (fp))
1714 ssize_t n = __getline (&line, &linelen, fp);
1715 if (n <= 0)
1716 break;
1718 /* Handle comments. No escaping possible so this is easy. */
1719 char *cp = strchr (line, '#');
1720 if (cp != NULL)
1721 *cp = '\0';
1723 cp = line;
1724 while (isspace (*cp))
1725 ++cp;
1727 char *cmd = cp;
1728 while (*cp != '\0' && !isspace (*cp))
1729 ++cp;
1730 size_t cmdlen = cp - cmd;
1732 if (*cp != '\0')
1733 *cp++ = '\0';
1734 while (isspace (*cp))
1735 ++cp;
1737 char *val1 = cp;
1738 while (*cp != '\0' && !isspace (*cp))
1739 ++cp;
1740 size_t val1len = cp - cmd;
1742 /* We always need at least two values. */
1743 if (val1len == 0)
1744 continue;
1746 if (*cp != '\0')
1747 *cp++ = '\0';
1748 while (isspace (*cp))
1749 ++cp;
1751 char *val2 = cp;
1752 while (*cp != '\0' && !isspace (*cp))
1753 ++cp;
1755 /* Ignore the rest of the line. */
1756 *cp = '\0';
1758 struct prefixlist **listp;
1759 size_t *lenp;
1760 bool *nullbitsp;
1761 switch (cmdlen)
1763 case 5:
1764 if (strcmp (cmd, "label") == 0)
1766 struct in6_addr prefix;
1767 unsigned long int bits;
1768 unsigned long int val;
1769 char *endp;
1771 listp = &labellist;
1772 lenp = &nlabellist;
1773 nullbitsp = &labellist_nullbits;
1775 new_elem:
1776 bits = 128;
1777 __set_errno (0);
1778 cp = strchr (val1, '/');
1779 if (cp != NULL)
1780 *cp++ = '\0';
1781 if (inet_pton (AF_INET6, val1, &prefix)
1782 && (cp == NULL
1783 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1784 || errno != ERANGE)
1785 && *endp == '\0'
1786 && bits <= 128
1787 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1788 || errno != ERANGE)
1789 && *endp == '\0'
1790 && val <= INT_MAX)
1792 struct prefixlist *newp = malloc (sizeof (*newp));
1793 if (newp == NULL)
1795 free (line);
1796 fclose (fp);
1797 goto no_file;
1800 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1801 newp->entry.bits = bits;
1802 newp->entry.val = val;
1803 newp->next = *listp;
1804 *listp = newp;
1805 ++*lenp;
1806 *nullbitsp |= bits == 0;
1809 break;
1811 case 6:
1812 if (strcmp (cmd, "reload") == 0)
1814 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1815 if (gaiconf_reload_flag)
1816 gaiconf_reload_flag_ever_set = 1;
1818 break;
1820 case 7:
1821 if (strcmp (cmd, "scopev4") == 0)
1823 struct in6_addr prefix;
1824 unsigned long int bits;
1825 unsigned long int val;
1826 char *endp;
1828 bits = 32;
1829 __set_errno (0);
1830 cp = strchr (val1, '/');
1831 if (cp != NULL)
1832 *cp++ = '\0';
1833 if (inet_pton (AF_INET6, val1, &prefix))
1835 bits = 128;
1836 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1837 && (cp == NULL
1838 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1839 || errno != ERANGE)
1840 && *endp == '\0'
1841 && bits >= 96
1842 && bits <= 128
1843 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1844 || errno != ERANGE)
1845 && *endp == '\0'
1846 && val <= INT_MAX)
1848 struct scopelist *newp;
1849 new_scope:
1850 newp = malloc (sizeof (*newp));
1851 if (newp == NULL)
1853 free (line);
1854 fclose (fp);
1855 goto no_file;
1858 newp->entry.netmask = htonl (bits != 96
1859 ? (0xffffffff
1860 << (128 - bits))
1861 : 0);
1862 newp->entry.addr32 = (prefix.s6_addr32[3]
1863 & newp->entry.netmask);
1864 newp->entry.scope = val;
1865 newp->next = scopelist;
1866 scopelist = newp;
1867 ++nscopelist;
1868 scopelist_nullbits |= bits == 96;
1871 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1872 && (cp == NULL
1873 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1874 || errno != ERANGE)
1875 && *endp == '\0'
1876 && bits <= 32
1877 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1878 || errno != ERANGE)
1879 && *endp == '\0'
1880 && val <= INT_MAX)
1882 bits += 96;
1883 goto new_scope;
1886 break;
1888 case 10:
1889 if (strcmp (cmd, "precedence") == 0)
1891 listp = &precedencelist;
1892 lenp = &nprecedencelist;
1893 nullbitsp = &precedencelist_nullbits;
1894 goto new_elem;
1896 break;
1900 free (line);
1902 fclose (fp);
1904 /* Create the array for the labels. */
1905 struct prefixentry *new_labels;
1906 if (nlabellist > 0)
1908 if (!labellist_nullbits)
1909 ++nlabellist;
1910 new_labels = malloc (nlabellist * sizeof (*new_labels));
1911 if (new_labels == NULL)
1912 goto no_file;
1914 int i = nlabellist;
1915 if (!labellist_nullbits)
1917 --i;
1918 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1919 new_labels[i].bits = 0;
1920 new_labels[i].val = 1;
1923 struct prefixlist *l = labellist;
1924 while (i-- > 0)
1926 new_labels[i] = l->entry;
1927 l = l->next;
1929 free_prefixlist (labellist);
1931 /* Sort the entries so that the most specific ones are at
1932 the beginning. */
1933 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1935 else
1936 new_labels = (struct prefixentry *) default_labels;
1938 struct prefixentry *new_precedence;
1939 if (nprecedencelist > 0)
1941 if (!precedencelist_nullbits)
1942 ++nprecedencelist;
1943 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1944 if (new_precedence == NULL)
1946 if (new_labels != default_labels)
1947 free (new_labels);
1948 goto no_file;
1951 int i = nprecedencelist;
1952 if (!precedencelist_nullbits)
1954 --i;
1955 memset (&new_precedence[i].prefix, '\0',
1956 sizeof (struct in6_addr));
1957 new_precedence[i].bits = 0;
1958 new_precedence[i].val = 40;
1961 struct prefixlist *l = precedencelist;
1962 while (i-- > 0)
1964 new_precedence[i] = l->entry;
1965 l = l->next;
1967 free_prefixlist (precedencelist);
1969 /* Sort the entries so that the most specific ones are at
1970 the beginning. */
1971 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1972 prefixcmp);
1974 else
1975 new_precedence = (struct prefixentry *) default_precedence;
1977 struct scopeentry *new_scopes;
1978 if (nscopelist > 0)
1980 if (!scopelist_nullbits)
1981 ++nscopelist;
1982 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1983 if (new_scopes == NULL)
1985 if (new_labels != default_labels)
1986 free (new_labels);
1987 if (new_precedence != default_precedence)
1988 free (new_precedence);
1989 goto no_file;
1992 int i = nscopelist;
1993 if (!scopelist_nullbits)
1995 --i;
1996 new_scopes[i].addr32 = 0;
1997 new_scopes[i].netmask = 0;
1998 new_scopes[i].scope = 14;
2001 struct scopelist *l = scopelist;
2002 while (i-- > 0)
2004 new_scopes[i] = l->entry;
2005 l = l->next;
2007 free_scopelist (scopelist);
2009 /* Sort the entries so that the most specific ones are at
2010 the beginning. */
2011 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2012 scopecmp);
2014 else
2015 new_scopes = (struct scopeentry *) default_scopes;
2017 /* Now we are ready to replace the values. */
2018 const struct prefixentry *old = labels;
2019 labels = new_labels;
2020 if (old != default_labels)
2021 free ((void *) old);
2023 old = precedence;
2024 precedence = new_precedence;
2025 if (old != default_precedence)
2026 free ((void *) old);
2028 const struct scopeentry *oldscope = scopes;
2029 scopes = new_scopes;
2030 if (oldscope != default_scopes)
2031 free ((void *) oldscope);
2033 gaiconf_mtime = st.st_mtim;
2035 else
2037 no_file:
2038 free_prefixlist (labellist);
2039 free_prefixlist (precedencelist);
2040 free_scopelist (scopelist);
2042 /* If we previously read the file but it is gone now, free the
2043 old data and use the builtin one. Leave the reload flag
2044 alone. */
2045 fini ();
2050 static void
2051 gaiconf_reload (void)
2053 struct stat64 st;
2054 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2055 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2056 gaiconf_init ();
2061 getaddrinfo (const char *name, const char *service,
2062 const struct addrinfo *hints, struct addrinfo **pai)
2064 int i = 0, last_i = 0;
2065 int nresults = 0;
2066 struct addrinfo *p = NULL;
2067 struct gaih_service gaih_service, *pservice;
2068 struct addrinfo local_hints;
2070 if (name != NULL && name[0] == '*' && name[1] == 0)
2071 name = NULL;
2073 if (service != NULL && service[0] == '*' && service[1] == 0)
2074 service = NULL;
2076 if (name == NULL && service == NULL)
2077 return EAI_NONAME;
2079 if (hints == NULL)
2080 hints = &default_hints;
2082 if (hints->ai_flags
2083 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2084 #ifdef HAVE_LIBIDN
2085 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2086 |AI_IDN_USE_STD3_ASCII_RULES
2087 #endif
2088 |AI_NUMERICSERV|AI_ALL))
2089 return EAI_BADFLAGS;
2091 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2092 return EAI_BADFLAGS;
2094 struct in6addrinfo *in6ai = NULL;
2095 size_t in6ailen = 0;
2096 bool seen_ipv4 = false;
2097 bool seen_ipv6 = false;
2098 /* We might need information about what interfaces are available.
2099 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2100 cannot cache the results since new interfaces could be added at
2101 any time. */
2102 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2104 if (hints->ai_flags & AI_ADDRCONFIG)
2106 /* Now make a decision on what we return, if anything. */
2107 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2109 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2110 narrow down the search. */
2111 if (! seen_ipv4 || ! seen_ipv6)
2113 local_hints = *hints;
2114 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2115 hints = &local_hints;
2118 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2119 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2121 /* We cannot possibly return a valid answer. */
2122 free (in6ai);
2123 return EAI_NONAME;
2127 if (service && service[0])
2129 char *c;
2130 gaih_service.name = service;
2131 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2132 if (*c != '\0')
2134 if (hints->ai_flags & AI_NUMERICSERV)
2136 free (in6ai);
2137 return EAI_NONAME;
2140 gaih_service.num = -1;
2143 pservice = &gaih_service;
2145 else
2146 pservice = NULL;
2148 struct addrinfo **end = &p;
2150 unsigned int naddrs = 0;
2151 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2152 || hints->ai_family == AF_INET6)
2154 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2155 if (last_i != 0)
2157 freeaddrinfo (p);
2158 free (in6ai);
2160 return -(last_i & GAIH_EAI);
2162 while (*end)
2164 end = &((*end)->ai_next);
2165 ++nresults;
2168 else
2170 free (in6ai);
2171 return EAI_FAMILY;
2174 if (naddrs > 1)
2176 /* Read the config file. */
2177 __libc_once_define (static, once);
2178 __typeof (once) old_once = once;
2179 __libc_once (once, gaiconf_init);
2180 /* Sort results according to RFC 3484. */
2181 struct sort_result results[nresults];
2182 size_t order[nresults];
2183 struct addrinfo *q;
2184 struct addrinfo *last = NULL;
2185 char *canonname = NULL;
2187 /* If we have information about deprecated and temporary addresses
2188 sort the array now. */
2189 if (in6ai != NULL)
2190 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2192 int fd = -1;
2193 int af = AF_UNSPEC;
2195 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2197 results[i].dest_addr = q;
2198 results[i].native = -1;
2199 order[i] = i;
2201 /* If we just looked up the address for a different
2202 protocol, reuse the result. */
2203 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2204 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2206 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2207 results[i - 1].source_addr_len);
2208 results[i].source_addr_len = results[i - 1].source_addr_len;
2209 results[i].got_source_addr = results[i - 1].got_source_addr;
2210 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2211 results[i].prefixlen = results[i - 1].prefixlen;
2212 results[i].index = results[i - 1].index;
2214 else
2216 results[i].got_source_addr = false;
2217 results[i].source_addr_flags = 0;
2218 results[i].prefixlen = 0;
2219 results[i].index = 0xffffffffu;
2221 /* We overwrite the type with SOCK_DGRAM since we do not
2222 want connect() to connect to the other side. If we
2223 cannot determine the source address remember this
2224 fact. */
2225 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2227 if (fd != -1)
2228 close_retry:
2229 close_not_cancel_no_status (fd);
2230 af = q->ai_family;
2231 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2233 else
2235 /* Reset the connection. */
2236 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2237 __connect (fd, &sa, sizeof (sa));
2240 socklen_t sl = sizeof (results[i].source_addr);
2241 if (fd != -1
2242 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2243 && __getsockname (fd,
2244 (struct sockaddr *) &results[i].source_addr,
2245 &sl) == 0)
2247 results[i].source_addr_len = sl;
2248 results[i].got_source_addr = true;
2250 if (in6ai != NULL)
2252 /* See whether the source address is on the list of
2253 deprecated or temporary addresses. */
2254 struct in6addrinfo tmp;
2256 if (q->ai_family == AF_INET && af == AF_INET)
2258 struct sockaddr_in *sinp
2259 = (struct sockaddr_in *) &results[i].source_addr;
2260 tmp.addr[0] = 0;
2261 tmp.addr[1] = 0;
2262 tmp.addr[2] = htonl (0xffff);
2263 tmp.addr[3] = sinp->sin_addr.s_addr;
2265 else
2267 struct sockaddr_in6 *sin6p
2268 = (struct sockaddr_in6 *) &results[i].source_addr;
2269 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2272 struct in6addrinfo *found
2273 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2274 in6aicmp);
2275 if (found != NULL)
2277 results[i].source_addr_flags = found->flags;
2278 results[i].prefixlen = found->prefixlen;
2279 results[i].index = found->index;
2283 if (q->ai_family == AF_INET && af == AF_INET6)
2285 /* We have to convert the address. The socket is
2286 IPv6 and the request is for IPv4. */
2287 struct sockaddr_in6 *sin6
2288 = (struct sockaddr_in6 *) &results[i].source_addr;
2289 struct sockaddr_in *sin
2290 = (struct sockaddr_in *) &results[i].source_addr;
2291 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2292 sin->sin_family = AF_INET;
2293 /* We do not have to initialize sin_port since this
2294 fields has the same position and size in the IPv6
2295 structure. */
2296 assert (offsetof (struct sockaddr_in, sin_port)
2297 == offsetof (struct sockaddr_in6, sin6_port));
2298 assert (sizeof (sin->sin_port)
2299 == sizeof (sin6->sin6_port));
2300 memcpy (&sin->sin_addr,
2301 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2302 results[i].source_addr_len = sizeof (struct sockaddr_in);
2305 else if (errno == EAFNOSUPPORT && af == AF_INET6
2306 && q->ai_family == AF_INET)
2307 /* This could mean IPv6 sockets are IPv6-only. */
2308 goto close_retry;
2309 else
2310 /* Just make sure that if we have to process the same
2311 address again we do not copy any memory. */
2312 results[i].source_addr_len = 0;
2315 /* Remember the canonical name. */
2316 if (q->ai_canonname != NULL)
2318 assert (canonname == NULL);
2319 canonname = q->ai_canonname;
2320 q->ai_canonname = NULL;
2324 if (fd != -1)
2325 close_not_cancel_no_status (fd);
2327 /* We got all the source addresses we can get, now sort using
2328 the information. */
2329 struct sort_result_combo src
2330 = { .results = results, .nresults = nresults };
2331 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2333 __libc_lock_define_initialized (static, lock);
2335 __libc_lock_lock (lock);
2336 if (old_once && gaiconf_reload_flag)
2337 gaiconf_reload ();
2338 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2339 __libc_lock_unlock (lock);
2341 else
2342 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2344 /* Queue the results up as they come out of sorting. */
2345 q = p = results[order[0]].dest_addr;
2346 for (i = 1; i < nresults; ++i)
2347 q = q->ai_next = results[order[i]].dest_addr;
2348 q->ai_next = NULL;
2350 /* Fill in the canonical name into the new first entry. */
2351 p->ai_canonname = canonname;
2354 free (in6ai);
2356 if (p)
2358 *pai = p;
2359 return 0;
2362 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2364 libc_hidden_def (getaddrinfo)
2366 static_link_warning (getaddrinfo)
2368 void
2369 freeaddrinfo (struct addrinfo *ai)
2371 struct addrinfo *p;
2373 while (ai != NULL)
2375 p = ai;
2376 ai = ai->ai_next;
2377 free (p->ai_canonname);
2378 free (p);
2381 libc_hidden_def (freeaddrinfo)