Don't abort immediately on successful lookup in getaddrinfo.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob597189f744470ac85de89394ad6dd8a3b1824da2
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 no_data = 0;
706 nss_gethostbyname4_r fct4
707 = __nss_lookup_function (nip, "gethostbyname4_r");
708 if (fct4 != NULL)
710 int herrno;
712 while (1)
714 rc = 0;
715 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
716 tmpbuflen, &rc, &herrno,
717 NULL));
718 if (status == NSS_STATUS_SUCCESS)
719 break;
720 if (status != NSS_STATUS_TRYAGAIN
721 || rc != ERANGE || herrno != NETDB_INTERNAL)
723 if (status == NSS_STATUS_TRYAGAIN
724 && herrno == TRY_AGAIN)
725 no_data = EAI_AGAIN;
726 else
727 no_data = herrno == NO_DATA;
728 break;
730 tmpbuf = extend_alloca (tmpbuf,
731 tmpbuflen, 2 * tmpbuflen);
734 no_inet6_data = no_data;
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 else
823 /* We can have different states for AF_INET and
824 AF_INET6. Try to find a useful one for both. */
825 if (inet6_status == NSS_STATUS_TRYAGAIN)
826 status = NSS_STATUS_TRYAGAIN;
827 else if (status == NSS_STATUS_UNAVAIL
828 && inet6_status != NSS_STATUS_UNAVAIL)
829 status = inet6_status;
832 else
833 status = NSS_STATUS_UNAVAIL;
836 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
837 break;
839 if (nip->next == NULL)
840 no_more = -1;
841 else
842 nip = nip->next;
845 _res.options = old_res_options;
847 if (no_data != 0 && no_inet6_data != 0)
849 /* If both requests timed out report this. */
850 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
851 return -EAI_AGAIN;
853 /* We made requests but they turned out no data. The name
854 is known, though. */
855 return GAIH_OKIFUNSPEC | -EAI_NODATA;
859 process_list:
860 if (at->family == AF_UNSPEC)
861 return GAIH_OKIFUNSPEC | -EAI_NONAME;
863 else
865 struct gaih_addrtuple *atr;
866 atr = at = __alloca (sizeof (struct gaih_addrtuple));
867 memset (at, '\0', sizeof (struct gaih_addrtuple));
869 if (req->ai_family == AF_UNSPEC)
871 at->next = __alloca (sizeof (struct gaih_addrtuple));
872 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
875 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
877 at->family = AF_INET6;
878 if ((req->ai_flags & AI_PASSIVE) == 0)
879 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
880 atr = at->next;
883 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
885 atr->family = AF_INET;
886 if ((req->ai_flags & AI_PASSIVE) == 0)
887 atr->addr[0] = htonl (INADDR_LOOPBACK);
892 struct gaih_servtuple *st2;
893 struct gaih_addrtuple *at2 = at;
894 size_t socklen;
895 sa_family_t family;
898 buffer is the size of an unformatted IPv6 address in printable format.
900 while (at2 != NULL)
902 /* Only the first entry gets the canonical name. */
903 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
905 if (canon == NULL)
907 struct hostent *h = NULL;
908 int herrno;
909 struct hostent th;
910 size_t tmpbuflen = 512;
911 char *tmpbuf = NULL;
915 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
916 rc = __gethostbyaddr_r (at2->addr,
917 ((at2->family == AF_INET6)
918 ? sizeof (struct in6_addr)
919 : sizeof (struct in_addr)),
920 at2->family, &th, tmpbuf,
921 tmpbuflen, &h, &herrno);
923 while (rc == ERANGE && herrno == NETDB_INTERNAL);
925 if (rc != 0 && herrno == NETDB_INTERNAL)
927 __set_h_errno (herrno);
928 return -EAI_SYSTEM;
931 if (h != NULL)
932 canon = h->h_name;
933 else
935 assert (orig_name != NULL);
936 /* If the canonical name cannot be determined, use
937 the passed in string. */
938 canon = orig_name;
942 #ifdef HAVE_LIBIDN
943 if (req->ai_flags & AI_CANONIDN)
945 int idn_flags = 0;
946 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
947 idn_flags |= IDNA_ALLOW_UNASSIGNED;
948 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
949 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
951 char *out;
952 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
953 if (rc != IDNA_SUCCESS)
955 if (rc == IDNA_MALLOC_ERROR)
956 return -EAI_MEMORY;
957 if (rc == IDNA_DLOPEN_ERROR)
958 return -EAI_SYSTEM;
959 return -EAI_IDN_ENCODE;
961 /* In case the output string is the same as the input
962 string no new string has been allocated and we
963 make a copy. */
964 if (out == canon)
965 goto make_copy;
967 else
968 #endif
970 #ifdef HAVE_LIBIDN
971 make_copy:
972 #endif
973 canon = strdup (canon);
974 if (canon == NULL)
975 return -EAI_MEMORY;
979 family = at2->family;
980 if (family == AF_INET6)
982 socklen = sizeof (struct sockaddr_in6);
984 /* If we looked up IPv4 mapped address discard them here if
985 the caller isn't interested in all address and we have
986 found at least one IPv6 address. */
987 if (got_ipv6
988 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
989 && IN6_IS_ADDR_V4MAPPED (at2->addr))
990 goto ignore;
992 else
993 socklen = sizeof (struct sockaddr_in);
995 for (st2 = st; st2 != NULL; st2 = st2->next)
997 struct addrinfo *ai;
998 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
999 if (ai == NULL)
1001 free ((char *) canon);
1002 return -EAI_MEMORY;
1005 ai->ai_flags = req->ai_flags;
1006 ai->ai_family = family;
1007 ai->ai_socktype = st2->socktype;
1008 ai->ai_protocol = st2->protocol;
1009 ai->ai_addrlen = socklen;
1010 ai->ai_addr = (void *) (ai + 1);
1012 /* We only add the canonical name once. */
1013 ai->ai_canonname = (char *) canon;
1014 canon = NULL;
1016 #ifdef _HAVE_SA_LEN
1017 ai->ai_addr->sa_len = socklen;
1018 #endif /* _HAVE_SA_LEN */
1019 ai->ai_addr->sa_family = family;
1021 /* In case of an allocation error the list must be NULL
1022 terminated. */
1023 ai->ai_next = NULL;
1025 if (family == AF_INET6)
1027 struct sockaddr_in6 *sin6p =
1028 (struct sockaddr_in6 *) ai->ai_addr;
1030 sin6p->sin6_port = st2->port;
1031 sin6p->sin6_flowinfo = 0;
1032 memcpy (&sin6p->sin6_addr,
1033 at2->addr, sizeof (struct in6_addr));
1034 sin6p->sin6_scope_id = at2->scopeid;
1036 else
1038 struct sockaddr_in *sinp =
1039 (struct sockaddr_in *) ai->ai_addr;
1040 sinp->sin_port = st2->port;
1041 memcpy (&sinp->sin_addr,
1042 at2->addr, sizeof (struct in_addr));
1043 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1046 pai = &(ai->ai_next);
1049 ++*naddrs;
1051 ignore:
1052 at2 = at2->next;
1055 return 0;
1059 struct sort_result
1061 struct addrinfo *dest_addr;
1062 /* Using sockaddr_storage is for now overkill. We only support IPv4
1063 and IPv6 so far. If this changes at some point we can adjust the
1064 type here. */
1065 struct sockaddr_in6 source_addr;
1066 uint8_t source_addr_len;
1067 bool got_source_addr;
1068 uint8_t source_addr_flags;
1069 uint8_t prefixlen;
1070 uint32_t index;
1071 int32_t native;
1074 struct sort_result_combo
1076 struct sort_result *results;
1077 int nresults;
1081 #if __BYTE_ORDER == __BIG_ENDIAN
1082 # define htonl_c(n) n
1083 #else
1084 # define htonl_c(n) __bswap_constant_32 (n)
1085 #endif
1087 static const struct scopeentry
1089 union
1091 char addr[4];
1092 uint32_t addr32;
1094 uint32_t netmask;
1095 int32_t scope;
1096 } default_scopes[] =
1098 /* Link-local addresses: scope 2. */
1099 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1100 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1101 /* Site-local addresses: scope 5. */
1102 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1103 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1104 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1105 /* Default: scope 14. */
1106 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1109 /* The label table. */
1110 static const struct scopeentry *scopes;
1113 static int
1114 get_scope (const struct sockaddr_in6 *in6)
1116 int scope;
1117 if (in6->sin6_family == PF_INET6)
1119 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1121 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1122 /* RFC 4291 2.5.3 says that the loopback address is to be
1123 treated like a link-local address. */
1124 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1125 scope = 2;
1126 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1127 scope = 5;
1128 else
1129 /* XXX Is this the correct default behavior? */
1130 scope = 14;
1132 else
1133 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1135 else if (in6->sin6_family == PF_INET)
1137 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1139 size_t cnt = 0;
1140 while (1)
1142 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1143 == scopes[cnt].addr32)
1144 return scopes[cnt].scope;
1146 ++cnt;
1148 /* NOTREACHED */
1150 else
1151 /* XXX What is a good default? */
1152 scope = 15;
1154 return scope;
1158 struct prefixentry
1160 struct in6_addr prefix;
1161 unsigned int bits;
1162 int val;
1166 /* The label table. */
1167 static const struct prefixentry *labels;
1169 /* Default labels. */
1170 static const struct prefixentry default_labels[] =
1172 /* See RFC 3484 for the details. */
1173 { { .__in6_u
1174 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1176 }, 128, 0 },
1177 { { .__in6_u
1178 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1180 }, 16, 2 },
1181 { { .__in6_u
1182 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1184 }, 96, 3 },
1185 { { .__in6_u
1186 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1188 }, 96, 4 },
1189 /* The next two entries differ from RFC 3484. We need to treat
1190 IPv6 site-local addresses special because they are never NATed,
1191 unlike site-locale IPv4 addresses. If this would not happen, on
1192 machines which have only IPv4 and IPv6 site-local addresses, the
1193 sorting would prefer the IPv6 site-local addresses, causing
1194 unnecessary delays when trying to connect to a global IPv6 address
1195 through a site-local IPv6 address. */
1196 { { .__in6_u
1197 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1199 }, 10, 5 },
1200 { { .__in6_u
1201 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1203 }, 7, 6 },
1204 /* Additional rule for Teredo tunnels. */
1205 { { .__in6_u
1206 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1208 }, 32, 7 },
1209 { { .__in6_u
1210 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1212 }, 0, 1 }
1216 /* The precedence table. */
1217 static const struct prefixentry *precedence;
1219 /* The default precedences. */
1220 static const struct prefixentry default_precedence[] =
1222 /* See RFC 3484 for the details. */
1223 { { .__in6_u
1224 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1226 }, 128, 50 },
1227 { { .__in6_u
1228 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1230 }, 16, 30 },
1231 { { .__in6_u
1232 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1234 }, 96, 20 },
1235 { { .__in6_u
1236 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1237 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1238 }, 96, 10 },
1239 { { .__in6_u
1240 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1242 }, 0, 40 }
1246 static int
1247 match_prefix (const struct sockaddr_in6 *in6,
1248 const struct prefixentry *list, int default_val)
1250 int idx;
1251 struct sockaddr_in6 in6_mem;
1253 if (in6->sin6_family == PF_INET)
1255 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1257 /* Construct a V4-to-6 mapped address. */
1258 in6_mem.sin6_family = PF_INET6;
1259 in6_mem.sin6_port = in->sin_port;
1260 in6_mem.sin6_flowinfo = 0;
1261 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1262 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1263 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1264 in6_mem.sin6_scope_id = 0;
1266 in6 = &in6_mem;
1268 else if (in6->sin6_family != PF_INET6)
1269 return default_val;
1271 for (idx = 0; ; ++idx)
1273 unsigned int bits = list[idx].bits;
1274 const uint8_t *mask = list[idx].prefix.s6_addr;
1275 const uint8_t *val = in6->sin6_addr.s6_addr;
1277 while (bits >= 8)
1279 if (*mask != *val)
1280 break;
1282 ++mask;
1283 ++val;
1284 bits -= 8;
1287 if (bits < 8)
1289 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1290 /* Match! */
1291 break;
1295 return list[idx].val;
1299 static int
1300 get_label (const struct sockaddr_in6 *in6)
1302 /* XXX What is a good default value? */
1303 return match_prefix (in6, labels, INT_MAX);
1307 static int
1308 get_precedence (const struct sockaddr_in6 *in6)
1310 /* XXX What is a good default value? */
1311 return match_prefix (in6, precedence, 0);
1315 /* Find last bit set in a word. */
1316 static int
1317 fls (uint32_t a)
1319 uint32_t mask;
1320 int n;
1321 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1322 if ((a & mask) != 0)
1323 break;
1324 return n;
1328 static int
1329 rfc3484_sort (const void *p1, const void *p2, void *arg)
1331 const size_t idx1 = *(const size_t *) p1;
1332 const size_t idx2 = *(const size_t *) p2;
1333 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1334 struct sort_result *a1 = &src->results[idx1];
1335 struct sort_result *a2 = &src->results[idx2];
1337 /* Rule 1: Avoid unusable destinations.
1338 We have the got_source_addr flag set if the destination is reachable. */
1339 if (a1->got_source_addr && ! a2->got_source_addr)
1340 return -1;
1341 if (! a1->got_source_addr && a2->got_source_addr)
1342 return 1;
1345 /* Rule 2: Prefer matching scope. Only interesting if both
1346 destination addresses are IPv6. */
1347 int a1_dst_scope
1348 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1350 int a2_dst_scope
1351 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1353 if (a1->got_source_addr)
1355 int a1_src_scope = get_scope (&a1->source_addr);
1356 int a2_src_scope = get_scope (&a2->source_addr);
1358 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1359 return -1;
1360 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1361 return 1;
1365 /* Rule 3: Avoid deprecated addresses. */
1366 if (a1->got_source_addr)
1368 if (!(a1->source_addr_flags & in6ai_deprecated)
1369 && (a2->source_addr_flags & in6ai_deprecated))
1370 return -1;
1371 if ((a1->source_addr_flags & in6ai_deprecated)
1372 && !(a2->source_addr_flags & in6ai_deprecated))
1373 return 1;
1376 /* Rule 4: Prefer home addresses. */
1377 if (a1->got_source_addr)
1379 if (!(a1->source_addr_flags & in6ai_homeaddress)
1380 && (a2->source_addr_flags & in6ai_homeaddress))
1381 return 1;
1382 if ((a1->source_addr_flags & in6ai_homeaddress)
1383 && !(a2->source_addr_flags & in6ai_homeaddress))
1384 return -1;
1387 /* Rule 5: Prefer matching label. */
1388 if (a1->got_source_addr)
1390 int a1_dst_label
1391 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1392 int a1_src_label = get_label (&a1->source_addr);
1394 int a2_dst_label
1395 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1396 int a2_src_label = get_label (&a2->source_addr);
1398 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1399 return -1;
1400 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1401 return 1;
1405 /* Rule 6: Prefer higher precedence. */
1406 int a1_prec
1407 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1408 int a2_prec
1409 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1411 if (a1_prec > a2_prec)
1412 return -1;
1413 if (a1_prec < a2_prec)
1414 return 1;
1417 /* Rule 7: Prefer native transport. */
1418 if (a1->got_source_addr)
1420 /* The same interface index means the same interface which means
1421 there is no difference in transport. This should catch many
1422 (most?) cases. */
1423 if (a1->index != a2->index)
1425 int a1_native = a1->native;
1426 int a2_native = a2->native;
1428 if (a1_native == -1 || a2_native == -1)
1430 uint32_t a1_index;
1431 if (a1_native == -1)
1433 /* If we do not have the information use 'native' as
1434 the default. */
1435 a1_native = 0;
1436 a1_index = a1->index;
1438 else
1439 a1_index = 0xffffffffu;
1441 uint32_t a2_index;
1442 if (a2_native == -1)
1444 /* If we do not have the information use 'native' as
1445 the default. */
1446 a2_native = 0;
1447 a2_index = a2->index;
1449 else
1450 a2_index = 0xffffffffu;
1452 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1454 /* Fill in the results in all the records. */
1455 for (int i = 0; i < src->nresults; ++i)
1456 if (src->results[i].index == a1_index)
1458 assert (src->results[i].native == -1
1459 || src->results[i].native == a1_native);
1460 src->results[i].native = a1_native;
1462 else if (src->results[i].index == a2_index)
1464 assert (src->results[i].native == -1
1465 || src->results[i].native == a2_native);
1466 src->results[i].native = a2_native;
1470 if (a1_native && !a2_native)
1471 return -1;
1472 if (!a1_native && a2_native)
1473 return 1;
1478 /* Rule 8: Prefer smaller scope. */
1479 if (a1_dst_scope < a2_dst_scope)
1480 return -1;
1481 if (a1_dst_scope > a2_dst_scope)
1482 return 1;
1485 /* Rule 9: Use longest matching prefix. */
1486 if (a1->got_source_addr
1487 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1489 int bit1 = 0;
1490 int bit2 = 0;
1492 if (a1->dest_addr->ai_family == PF_INET)
1494 assert (a1->source_addr.sin6_family == PF_INET);
1495 assert (a2->source_addr.sin6_family == PF_INET);
1497 /* Outside of subnets, as defined by the network masks,
1498 common address prefixes for IPv4 addresses make no sense.
1499 So, define a non-zero value only if source and
1500 destination address are on the same subnet. */
1501 struct sockaddr_in *in1_dst
1502 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1503 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1504 struct sockaddr_in *in1_src
1505 = (struct sockaddr_in *) &a1->source_addr;
1506 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1507 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1509 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1510 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1512 struct sockaddr_in *in2_dst
1513 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1514 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1515 struct sockaddr_in *in2_src
1516 = (struct sockaddr_in *) &a2->source_addr;
1517 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1518 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1520 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1521 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1523 else if (a1->dest_addr->ai_family == PF_INET6)
1525 assert (a1->source_addr.sin6_family == PF_INET6);
1526 assert (a2->source_addr.sin6_family == PF_INET6);
1528 struct sockaddr_in6 *in1_dst;
1529 struct sockaddr_in6 *in1_src;
1530 struct sockaddr_in6 *in2_dst;
1531 struct sockaddr_in6 *in2_src;
1533 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1534 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1535 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1536 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1538 int i;
1539 for (i = 0; i < 4; ++i)
1540 if (in1_dst->sin6_addr.s6_addr32[i]
1541 != in1_src->sin6_addr.s6_addr32[i]
1542 || (in2_dst->sin6_addr.s6_addr32[i]
1543 != in2_src->sin6_addr.s6_addr32[i]))
1544 break;
1546 if (i < 4)
1548 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1549 ^ in1_src->sin6_addr.s6_addr32[i]));
1550 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1551 ^ in2_src->sin6_addr.s6_addr32[i]));
1555 if (bit1 > bit2)
1556 return -1;
1557 if (bit1 < bit2)
1558 return 1;
1562 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1563 compare with the value indicating the order in which the entries
1564 have been received from the services. NB: no two entries can have
1565 the same order so the test will never return zero. */
1566 return idx1 < idx2 ? -1 : 1;
1570 static int
1571 in6aicmp (const void *p1, const void *p2)
1573 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1574 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1576 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1580 /* Name of the config file for RFC 3484 sorting (for now). */
1581 #define GAICONF_FNAME "/etc/gai.conf"
1584 /* Non-zero if we are supposed to reload the config file automatically
1585 whenever it changed. */
1586 static int gaiconf_reload_flag;
1588 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1589 static int gaiconf_reload_flag_ever_set;
1591 /* Last modification time. */
1592 static struct timespec gaiconf_mtime;
1595 libc_freeres_fn(fini)
1597 if (labels != default_labels)
1599 const struct prefixentry *old = labels;
1600 labels = default_labels;
1601 free ((void *) old);
1604 if (precedence != default_precedence)
1606 const struct prefixentry *old = precedence;
1607 precedence = default_precedence;
1608 free ((void *) old);
1611 if (scopes != default_scopes)
1613 const struct scopeentry *old = scopes;
1614 scopes = default_scopes;
1615 free ((void *) old);
1620 struct prefixlist
1622 struct prefixentry entry;
1623 struct prefixlist *next;
1627 struct scopelist
1629 struct scopeentry entry;
1630 struct scopelist *next;
1634 static void
1635 free_prefixlist (struct prefixlist *list)
1637 while (list != NULL)
1639 struct prefixlist *oldp = list;
1640 list = list->next;
1641 free (oldp);
1646 static void
1647 free_scopelist (struct scopelist *list)
1649 while (list != NULL)
1651 struct scopelist *oldp = list;
1652 list = list->next;
1653 free (oldp);
1658 static int
1659 prefixcmp (const void *p1, const void *p2)
1661 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1662 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1664 if (e1->bits < e2->bits)
1665 return 1;
1666 if (e1->bits == e2->bits)
1667 return 0;
1668 return -1;
1672 static int
1673 scopecmp (const void *p1, const void *p2)
1675 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1676 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1678 if (e1->netmask > e2->netmask)
1679 return -1;
1680 if (e1->netmask == e2->netmask)
1681 return 0;
1682 return 1;
1686 static void
1687 gaiconf_init (void)
1689 struct prefixlist *labellist = NULL;
1690 size_t nlabellist = 0;
1691 bool labellist_nullbits = false;
1692 struct prefixlist *precedencelist = NULL;
1693 size_t nprecedencelist = 0;
1694 bool precedencelist_nullbits = false;
1695 struct scopelist *scopelist = NULL;
1696 size_t nscopelist = 0;
1697 bool scopelist_nullbits = false;
1699 FILE *fp = fopen (GAICONF_FNAME, "rc");
1700 if (fp != NULL)
1702 struct stat64 st;
1703 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1705 fclose (fp);
1706 goto no_file;
1709 char *line = NULL;
1710 size_t linelen = 0;
1712 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1714 while (!feof_unlocked (fp))
1716 ssize_t n = __getline (&line, &linelen, fp);
1717 if (n <= 0)
1718 break;
1720 /* Handle comments. No escaping possible so this is easy. */
1721 char *cp = strchr (line, '#');
1722 if (cp != NULL)
1723 *cp = '\0';
1725 cp = line;
1726 while (isspace (*cp))
1727 ++cp;
1729 char *cmd = cp;
1730 while (*cp != '\0' && !isspace (*cp))
1731 ++cp;
1732 size_t cmdlen = cp - cmd;
1734 if (*cp != '\0')
1735 *cp++ = '\0';
1736 while (isspace (*cp))
1737 ++cp;
1739 char *val1 = cp;
1740 while (*cp != '\0' && !isspace (*cp))
1741 ++cp;
1742 size_t val1len = cp - cmd;
1744 /* We always need at least two values. */
1745 if (val1len == 0)
1746 continue;
1748 if (*cp != '\0')
1749 *cp++ = '\0';
1750 while (isspace (*cp))
1751 ++cp;
1753 char *val2 = cp;
1754 while (*cp != '\0' && !isspace (*cp))
1755 ++cp;
1757 /* Ignore the rest of the line. */
1758 *cp = '\0';
1760 struct prefixlist **listp;
1761 size_t *lenp;
1762 bool *nullbitsp;
1763 switch (cmdlen)
1765 case 5:
1766 if (strcmp (cmd, "label") == 0)
1768 struct in6_addr prefix;
1769 unsigned long int bits;
1770 unsigned long int val;
1771 char *endp;
1773 listp = &labellist;
1774 lenp = &nlabellist;
1775 nullbitsp = &labellist_nullbits;
1777 new_elem:
1778 bits = 128;
1779 __set_errno (0);
1780 cp = strchr (val1, '/');
1781 if (cp != NULL)
1782 *cp++ = '\0';
1783 if (inet_pton (AF_INET6, val1, &prefix)
1784 && (cp == NULL
1785 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1786 || errno != ERANGE)
1787 && *endp == '\0'
1788 && bits <= 128
1789 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1790 || errno != ERANGE)
1791 && *endp == '\0'
1792 && val <= INT_MAX)
1794 struct prefixlist *newp = malloc (sizeof (*newp));
1795 if (newp == NULL)
1797 free (line);
1798 fclose (fp);
1799 goto no_file;
1802 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1803 newp->entry.bits = bits;
1804 newp->entry.val = val;
1805 newp->next = *listp;
1806 *listp = newp;
1807 ++*lenp;
1808 *nullbitsp |= bits == 0;
1811 break;
1813 case 6:
1814 if (strcmp (cmd, "reload") == 0)
1816 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1817 if (gaiconf_reload_flag)
1818 gaiconf_reload_flag_ever_set = 1;
1820 break;
1822 case 7:
1823 if (strcmp (cmd, "scopev4") == 0)
1825 struct in6_addr prefix;
1826 unsigned long int bits;
1827 unsigned long int val;
1828 char *endp;
1830 bits = 32;
1831 __set_errno (0);
1832 cp = strchr (val1, '/');
1833 if (cp != NULL)
1834 *cp++ = '\0';
1835 if (inet_pton (AF_INET6, val1, &prefix))
1837 bits = 128;
1838 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1839 && (cp == NULL
1840 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1841 || errno != ERANGE)
1842 && *endp == '\0'
1843 && bits >= 96
1844 && bits <= 128
1845 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1846 || errno != ERANGE)
1847 && *endp == '\0'
1848 && val <= INT_MAX)
1850 struct scopelist *newp;
1851 new_scope:
1852 newp = malloc (sizeof (*newp));
1853 if (newp == NULL)
1855 free (line);
1856 fclose (fp);
1857 goto no_file;
1860 newp->entry.netmask = htonl (bits != 96
1861 ? (0xffffffff
1862 << (128 - bits))
1863 : 0);
1864 newp->entry.addr32 = (prefix.s6_addr32[3]
1865 & newp->entry.netmask);
1866 newp->entry.scope = val;
1867 newp->next = scopelist;
1868 scopelist = newp;
1869 ++nscopelist;
1870 scopelist_nullbits |= bits == 96;
1873 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1874 && (cp == NULL
1875 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1876 || errno != ERANGE)
1877 && *endp == '\0'
1878 && bits <= 32
1879 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1880 || errno != ERANGE)
1881 && *endp == '\0'
1882 && val <= INT_MAX)
1884 bits += 96;
1885 goto new_scope;
1888 break;
1890 case 10:
1891 if (strcmp (cmd, "precedence") == 0)
1893 listp = &precedencelist;
1894 lenp = &nprecedencelist;
1895 nullbitsp = &precedencelist_nullbits;
1896 goto new_elem;
1898 break;
1902 free (line);
1904 fclose (fp);
1906 /* Create the array for the labels. */
1907 struct prefixentry *new_labels;
1908 if (nlabellist > 0)
1910 if (!labellist_nullbits)
1911 ++nlabellist;
1912 new_labels = malloc (nlabellist * sizeof (*new_labels));
1913 if (new_labels == NULL)
1914 goto no_file;
1916 int i = nlabellist;
1917 if (!labellist_nullbits)
1919 --i;
1920 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1921 new_labels[i].bits = 0;
1922 new_labels[i].val = 1;
1925 struct prefixlist *l = labellist;
1926 while (i-- > 0)
1928 new_labels[i] = l->entry;
1929 l = l->next;
1931 free_prefixlist (labellist);
1933 /* Sort the entries so that the most specific ones are at
1934 the beginning. */
1935 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1937 else
1938 new_labels = (struct prefixentry *) default_labels;
1940 struct prefixentry *new_precedence;
1941 if (nprecedencelist > 0)
1943 if (!precedencelist_nullbits)
1944 ++nprecedencelist;
1945 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1946 if (new_precedence == NULL)
1948 if (new_labels != default_labels)
1949 free (new_labels);
1950 goto no_file;
1953 int i = nprecedencelist;
1954 if (!precedencelist_nullbits)
1956 --i;
1957 memset (&new_precedence[i].prefix, '\0',
1958 sizeof (struct in6_addr));
1959 new_precedence[i].bits = 0;
1960 new_precedence[i].val = 40;
1963 struct prefixlist *l = precedencelist;
1964 while (i-- > 0)
1966 new_precedence[i] = l->entry;
1967 l = l->next;
1969 free_prefixlist (precedencelist);
1971 /* Sort the entries so that the most specific ones are at
1972 the beginning. */
1973 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1974 prefixcmp);
1976 else
1977 new_precedence = (struct prefixentry *) default_precedence;
1979 struct scopeentry *new_scopes;
1980 if (nscopelist > 0)
1982 if (!scopelist_nullbits)
1983 ++nscopelist;
1984 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1985 if (new_scopes == NULL)
1987 if (new_labels != default_labels)
1988 free (new_labels);
1989 if (new_precedence != default_precedence)
1990 free (new_precedence);
1991 goto no_file;
1994 int i = nscopelist;
1995 if (!scopelist_nullbits)
1997 --i;
1998 new_scopes[i].addr32 = 0;
1999 new_scopes[i].netmask = 0;
2000 new_scopes[i].scope = 14;
2003 struct scopelist *l = scopelist;
2004 while (i-- > 0)
2006 new_scopes[i] = l->entry;
2007 l = l->next;
2009 free_scopelist (scopelist);
2011 /* Sort the entries so that the most specific ones are at
2012 the beginning. */
2013 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2014 scopecmp);
2016 else
2017 new_scopes = (struct scopeentry *) default_scopes;
2019 /* Now we are ready to replace the values. */
2020 const struct prefixentry *old = labels;
2021 labels = new_labels;
2022 if (old != default_labels)
2023 free ((void *) old);
2025 old = precedence;
2026 precedence = new_precedence;
2027 if (old != default_precedence)
2028 free ((void *) old);
2030 const struct scopeentry *oldscope = scopes;
2031 scopes = new_scopes;
2032 if (oldscope != default_scopes)
2033 free ((void *) oldscope);
2035 gaiconf_mtime = st.st_mtim;
2037 else
2039 no_file:
2040 free_prefixlist (labellist);
2041 free_prefixlist (precedencelist);
2042 free_scopelist (scopelist);
2044 /* If we previously read the file but it is gone now, free the
2045 old data and use the builtin one. Leave the reload flag
2046 alone. */
2047 fini ();
2052 static void
2053 gaiconf_reload (void)
2055 struct stat64 st;
2056 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2057 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2058 gaiconf_init ();
2063 getaddrinfo (const char *name, const char *service,
2064 const struct addrinfo *hints, struct addrinfo **pai)
2066 int i = 0, last_i = 0;
2067 int nresults = 0;
2068 struct addrinfo *p = NULL;
2069 struct gaih_service gaih_service, *pservice;
2070 struct addrinfo local_hints;
2072 if (name != NULL && name[0] == '*' && name[1] == 0)
2073 name = NULL;
2075 if (service != NULL && service[0] == '*' && service[1] == 0)
2076 service = NULL;
2078 if (name == NULL && service == NULL)
2079 return EAI_NONAME;
2081 if (hints == NULL)
2082 hints = &default_hints;
2084 if (hints->ai_flags
2085 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2086 #ifdef HAVE_LIBIDN
2087 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2088 |AI_IDN_USE_STD3_ASCII_RULES
2089 #endif
2090 |AI_NUMERICSERV|AI_ALL))
2091 return EAI_BADFLAGS;
2093 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2094 return EAI_BADFLAGS;
2096 struct in6addrinfo *in6ai = NULL;
2097 size_t in6ailen = 0;
2098 bool seen_ipv4 = false;
2099 bool seen_ipv6 = false;
2100 /* We might need information about what interfaces are available.
2101 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2102 cannot cache the results since new interfaces could be added at
2103 any time. */
2104 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2106 if (hints->ai_flags & AI_ADDRCONFIG)
2108 /* Now make a decision on what we return, if anything. */
2109 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2111 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2112 narrow down the search. */
2113 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2115 local_hints = *hints;
2116 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2117 hints = &local_hints;
2120 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2121 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2123 /* We cannot possibly return a valid answer. */
2124 free (in6ai);
2125 return EAI_NONAME;
2129 if (service && service[0])
2131 char *c;
2132 gaih_service.name = service;
2133 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2134 if (*c != '\0')
2136 if (hints->ai_flags & AI_NUMERICSERV)
2138 free (in6ai);
2139 return EAI_NONAME;
2142 gaih_service.num = -1;
2145 pservice = &gaih_service;
2147 else
2148 pservice = NULL;
2150 struct addrinfo **end = &p;
2152 unsigned int naddrs = 0;
2153 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2154 || hints->ai_family == AF_INET6)
2156 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2157 if (last_i != 0)
2159 freeaddrinfo (p);
2160 free (in6ai);
2162 return -(last_i & GAIH_EAI);
2164 while (*end)
2166 end = &((*end)->ai_next);
2167 ++nresults;
2170 else
2172 free (in6ai);
2173 return EAI_FAMILY;
2176 if (naddrs > 1)
2178 /* Read the config file. */
2179 __libc_once_define (static, once);
2180 __typeof (once) old_once = once;
2181 __libc_once (once, gaiconf_init);
2182 /* Sort results according to RFC 3484. */
2183 struct sort_result results[nresults];
2184 size_t order[nresults];
2185 struct addrinfo *q;
2186 struct addrinfo *last = NULL;
2187 char *canonname = NULL;
2189 /* If we have information about deprecated and temporary addresses
2190 sort the array now. */
2191 if (in6ai != NULL)
2192 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2194 int fd = -1;
2195 int af = AF_UNSPEC;
2197 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2199 results[i].dest_addr = q;
2200 results[i].native = -1;
2201 order[i] = i;
2203 /* If we just looked up the address for a different
2204 protocol, reuse the result. */
2205 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2206 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2208 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2209 results[i - 1].source_addr_len);
2210 results[i].source_addr_len = results[i - 1].source_addr_len;
2211 results[i].got_source_addr = results[i - 1].got_source_addr;
2212 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2213 results[i].prefixlen = results[i - 1].prefixlen;
2214 results[i].index = results[i - 1].index;
2216 else
2218 results[i].got_source_addr = false;
2219 results[i].source_addr_flags = 0;
2220 results[i].prefixlen = 0;
2221 results[i].index = 0xffffffffu;
2223 /* We overwrite the type with SOCK_DGRAM since we do not
2224 want connect() to connect to the other side. If we
2225 cannot determine the source address remember this
2226 fact. */
2227 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2229 if (fd != -1)
2230 close_retry:
2231 close_not_cancel_no_status (fd);
2232 af = q->ai_family;
2233 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2235 else
2237 /* Reset the connection. */
2238 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2239 __connect (fd, &sa, sizeof (sa));
2242 socklen_t sl = sizeof (results[i].source_addr);
2243 if (fd != -1
2244 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2245 && __getsockname (fd,
2246 (struct sockaddr *) &results[i].source_addr,
2247 &sl) == 0)
2249 results[i].source_addr_len = sl;
2250 results[i].got_source_addr = true;
2252 if (in6ai != NULL)
2254 /* See whether the source address is on the list of
2255 deprecated or temporary addresses. */
2256 struct in6addrinfo tmp;
2258 if (q->ai_family == AF_INET && af == AF_INET)
2260 struct sockaddr_in *sinp
2261 = (struct sockaddr_in *) &results[i].source_addr;
2262 tmp.addr[0] = 0;
2263 tmp.addr[1] = 0;
2264 tmp.addr[2] = htonl (0xffff);
2265 tmp.addr[3] = sinp->sin_addr.s_addr;
2267 else
2269 struct sockaddr_in6 *sin6p
2270 = (struct sockaddr_in6 *) &results[i].source_addr;
2271 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2274 struct in6addrinfo *found
2275 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2276 in6aicmp);
2277 if (found != NULL)
2279 results[i].source_addr_flags = found->flags;
2280 results[i].prefixlen = found->prefixlen;
2281 results[i].index = found->index;
2285 if (q->ai_family == AF_INET && af == AF_INET6)
2287 /* We have to convert the address. The socket is
2288 IPv6 and the request is for IPv4. */
2289 struct sockaddr_in6 *sin6
2290 = (struct sockaddr_in6 *) &results[i].source_addr;
2291 struct sockaddr_in *sin
2292 = (struct sockaddr_in *) &results[i].source_addr;
2293 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2294 sin->sin_family = AF_INET;
2295 /* We do not have to initialize sin_port since this
2296 fields has the same position and size in the IPv6
2297 structure. */
2298 assert (offsetof (struct sockaddr_in, sin_port)
2299 == offsetof (struct sockaddr_in6, sin6_port));
2300 assert (sizeof (sin->sin_port)
2301 == sizeof (sin6->sin6_port));
2302 memcpy (&sin->sin_addr,
2303 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2304 results[i].source_addr_len = sizeof (struct sockaddr_in);
2307 else if (errno == EAFNOSUPPORT && af == AF_INET6
2308 && q->ai_family == AF_INET)
2309 /* This could mean IPv6 sockets are IPv6-only. */
2310 goto close_retry;
2311 else
2312 /* Just make sure that if we have to process the same
2313 address again we do not copy any memory. */
2314 results[i].source_addr_len = 0;
2317 /* Remember the canonical name. */
2318 if (q->ai_canonname != NULL)
2320 assert (canonname == NULL);
2321 canonname = q->ai_canonname;
2322 q->ai_canonname = NULL;
2326 if (fd != -1)
2327 close_not_cancel_no_status (fd);
2329 /* We got all the source addresses we can get, now sort using
2330 the information. */
2331 struct sort_result_combo src
2332 = { .results = results, .nresults = nresults };
2333 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2335 __libc_lock_define_initialized (static, lock);
2337 __libc_lock_lock (lock);
2338 if (old_once && gaiconf_reload_flag)
2339 gaiconf_reload ();
2340 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2341 __libc_lock_unlock (lock);
2343 else
2344 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2346 /* Queue the results up as they come out of sorting. */
2347 q = p = results[order[0]].dest_addr;
2348 for (i = 1; i < nresults; ++i)
2349 q = q->ai_next = results[order[i]].dest_addr;
2350 q->ai_next = NULL;
2352 /* Fill in the canonical name into the new first entry. */
2353 p->ai_canonname = canonname;
2356 free (in6ai);
2358 if (p)
2360 *pai = p;
2361 return 0;
2364 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2366 libc_hidden_def (getaddrinfo)
2368 static_link_warning (getaddrinfo)
2370 void
2371 freeaddrinfo (struct addrinfo *ai)
2373 struct addrinfo *p;
2375 while (ai != NULL)
2377 p = ai;
2378 ai = ai->ai_next;
2379 free (p->ai_canonname);
2380 free (p);
2383 libc_hidden_def (freeaddrinfo)