Fix one case of last checkin.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob2e0c7248f09e60976fe91dfbe6724564bd0b5c31
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;
820 status = NSS_STATUS_SUCCESS;
822 else
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;
833 else
834 status = NSS_STATUS_UNAVAIL;
837 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
838 break;
840 if (nip->next == NULL)
841 no_more = -1;
842 else
843 nip = nip->next;
846 _res.options = old_res_options;
848 if (no_data != 0 && no_inet6_data != 0)
850 /* If both requests timed out report this. */
851 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
852 return -EAI_AGAIN;
854 /* We made requests but they turned out no data. The name
855 is known, though. */
856 return GAIH_OKIFUNSPEC | -EAI_NODATA;
860 process_list:
861 if (at->family == AF_UNSPEC)
862 return GAIH_OKIFUNSPEC | -EAI_NONAME;
864 else
866 struct gaih_addrtuple *atr;
867 atr = at = __alloca (sizeof (struct gaih_addrtuple));
868 memset (at, '\0', sizeof (struct gaih_addrtuple));
870 if (req->ai_family == AF_UNSPEC)
872 at->next = __alloca (sizeof (struct gaih_addrtuple));
873 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
876 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
878 at->family = AF_INET6;
879 if ((req->ai_flags & AI_PASSIVE) == 0)
880 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
881 atr = at->next;
884 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
886 atr->family = AF_INET;
887 if ((req->ai_flags & AI_PASSIVE) == 0)
888 atr->addr[0] = htonl (INADDR_LOOPBACK);
893 struct gaih_servtuple *st2;
894 struct gaih_addrtuple *at2 = at;
895 size_t socklen;
896 sa_family_t family;
899 buffer is the size of an unformatted IPv6 address in printable format.
901 while (at2 != NULL)
903 /* Only the first entry gets the canonical name. */
904 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
906 if (canon == NULL)
908 struct hostent *h = NULL;
909 int herrno;
910 struct hostent th;
911 size_t tmpbuflen = 512;
912 char *tmpbuf = NULL;
916 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
917 rc = __gethostbyaddr_r (at2->addr,
918 ((at2->family == AF_INET6)
919 ? sizeof (struct in6_addr)
920 : sizeof (struct in_addr)),
921 at2->family, &th, tmpbuf,
922 tmpbuflen, &h, &herrno);
924 while (rc == ERANGE && herrno == NETDB_INTERNAL);
926 if (rc != 0 && herrno == NETDB_INTERNAL)
928 __set_h_errno (herrno);
929 return -EAI_SYSTEM;
932 if (h != NULL)
933 canon = h->h_name;
934 else
936 assert (orig_name != NULL);
937 /* If the canonical name cannot be determined, use
938 the passed in string. */
939 canon = orig_name;
943 #ifdef HAVE_LIBIDN
944 if (req->ai_flags & AI_CANONIDN)
946 int idn_flags = 0;
947 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
948 idn_flags |= IDNA_ALLOW_UNASSIGNED;
949 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
950 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
952 char *out;
953 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
954 if (rc != IDNA_SUCCESS)
956 if (rc == IDNA_MALLOC_ERROR)
957 return -EAI_MEMORY;
958 if (rc == IDNA_DLOPEN_ERROR)
959 return -EAI_SYSTEM;
960 return -EAI_IDN_ENCODE;
962 /* In case the output string is the same as the input
963 string no new string has been allocated and we
964 make a copy. */
965 if (out == canon)
966 goto make_copy;
968 else
969 #endif
971 #ifdef HAVE_LIBIDN
972 make_copy:
973 #endif
974 canon = strdup (canon);
975 if (canon == NULL)
976 return -EAI_MEMORY;
980 family = at2->family;
981 if (family == AF_INET6)
983 socklen = sizeof (struct sockaddr_in6);
985 /* If we looked up IPv4 mapped address discard them here if
986 the caller isn't interested in all address and we have
987 found at least one IPv6 address. */
988 if (got_ipv6
989 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
990 && IN6_IS_ADDR_V4MAPPED (at2->addr))
991 goto ignore;
993 else
994 socklen = sizeof (struct sockaddr_in);
996 for (st2 = st; st2 != NULL; st2 = st2->next)
998 struct addrinfo *ai;
999 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1000 if (ai == NULL)
1002 free ((char *) canon);
1003 return -EAI_MEMORY;
1006 ai->ai_flags = req->ai_flags;
1007 ai->ai_family = family;
1008 ai->ai_socktype = st2->socktype;
1009 ai->ai_protocol = st2->protocol;
1010 ai->ai_addrlen = socklen;
1011 ai->ai_addr = (void *) (ai + 1);
1013 /* We only add the canonical name once. */
1014 ai->ai_canonname = (char *) canon;
1015 canon = NULL;
1017 #ifdef _HAVE_SA_LEN
1018 ai->ai_addr->sa_len = socklen;
1019 #endif /* _HAVE_SA_LEN */
1020 ai->ai_addr->sa_family = family;
1022 /* In case of an allocation error the list must be NULL
1023 terminated. */
1024 ai->ai_next = NULL;
1026 if (family == AF_INET6)
1028 struct sockaddr_in6 *sin6p =
1029 (struct sockaddr_in6 *) ai->ai_addr;
1031 sin6p->sin6_port = st2->port;
1032 sin6p->sin6_flowinfo = 0;
1033 memcpy (&sin6p->sin6_addr,
1034 at2->addr, sizeof (struct in6_addr));
1035 sin6p->sin6_scope_id = at2->scopeid;
1037 else
1039 struct sockaddr_in *sinp =
1040 (struct sockaddr_in *) ai->ai_addr;
1041 sinp->sin_port = st2->port;
1042 memcpy (&sinp->sin_addr,
1043 at2->addr, sizeof (struct in_addr));
1044 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1047 pai = &(ai->ai_next);
1050 ++*naddrs;
1052 ignore:
1053 at2 = at2->next;
1056 return 0;
1060 struct sort_result
1062 struct addrinfo *dest_addr;
1063 /* Using sockaddr_storage is for now overkill. We only support IPv4
1064 and IPv6 so far. If this changes at some point we can adjust the
1065 type here. */
1066 struct sockaddr_in6 source_addr;
1067 uint8_t source_addr_len;
1068 bool got_source_addr;
1069 uint8_t source_addr_flags;
1070 uint8_t prefixlen;
1071 uint32_t index;
1072 int32_t native;
1075 struct sort_result_combo
1077 struct sort_result *results;
1078 int nresults;
1082 #if __BYTE_ORDER == __BIG_ENDIAN
1083 # define htonl_c(n) n
1084 #else
1085 # define htonl_c(n) __bswap_constant_32 (n)
1086 #endif
1088 static const struct scopeentry
1090 union
1092 char addr[4];
1093 uint32_t addr32;
1095 uint32_t netmask;
1096 int32_t scope;
1097 } default_scopes[] =
1099 /* Link-local addresses: scope 2. */
1100 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1101 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1102 /* Site-local addresses: scope 5. */
1103 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1104 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1105 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1106 /* Default: scope 14. */
1107 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1110 /* The label table. */
1111 static const struct scopeentry *scopes;
1114 static int
1115 get_scope (const struct sockaddr_in6 *in6)
1117 int scope;
1118 if (in6->sin6_family == PF_INET6)
1120 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1122 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1123 /* RFC 4291 2.5.3 says that the loopback address is to be
1124 treated like a link-local address. */
1125 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1126 scope = 2;
1127 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1128 scope = 5;
1129 else
1130 /* XXX Is this the correct default behavior? */
1131 scope = 14;
1133 else
1134 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1136 else if (in6->sin6_family == PF_INET)
1138 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1140 size_t cnt = 0;
1141 while (1)
1143 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1144 == scopes[cnt].addr32)
1145 return scopes[cnt].scope;
1147 ++cnt;
1149 /* NOTREACHED */
1151 else
1152 /* XXX What is a good default? */
1153 scope = 15;
1155 return scope;
1159 struct prefixentry
1161 struct in6_addr prefix;
1162 unsigned int bits;
1163 int val;
1167 /* The label table. */
1168 static const struct prefixentry *labels;
1170 /* Default labels. */
1171 static const struct prefixentry default_labels[] =
1173 /* See RFC 3484 for the details. */
1174 { { .__in6_u
1175 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1177 }, 128, 0 },
1178 { { .__in6_u
1179 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1181 }, 16, 2 },
1182 { { .__in6_u
1183 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1185 }, 96, 3 },
1186 { { .__in6_u
1187 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1189 }, 96, 4 },
1190 /* The next two entries differ from RFC 3484. We need to treat
1191 IPv6 site-local addresses special because they are never NATed,
1192 unlike site-locale IPv4 addresses. If this would not happen, on
1193 machines which have only IPv4 and IPv6 site-local addresses, the
1194 sorting would prefer the IPv6 site-local addresses, causing
1195 unnecessary delays when trying to connect to a global IPv6 address
1196 through a site-local IPv6 address. */
1197 { { .__in6_u
1198 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1200 }, 10, 5 },
1201 { { .__in6_u
1202 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1204 }, 7, 6 },
1205 /* Additional rule for Teredo tunnels. */
1206 { { .__in6_u
1207 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1209 }, 32, 7 },
1210 { { .__in6_u
1211 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1213 }, 0, 1 }
1217 /* The precedence table. */
1218 static const struct prefixentry *precedence;
1220 /* The default precedences. */
1221 static const struct prefixentry default_precedence[] =
1223 /* See RFC 3484 for the details. */
1224 { { .__in6_u
1225 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1227 }, 128, 50 },
1228 { { .__in6_u
1229 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1231 }, 16, 30 },
1232 { { .__in6_u
1233 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1235 }, 96, 20 },
1236 { { .__in6_u
1237 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1238 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1239 }, 96, 10 },
1240 { { .__in6_u
1241 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1243 }, 0, 40 }
1247 static int
1248 match_prefix (const struct sockaddr_in6 *in6,
1249 const struct prefixentry *list, int default_val)
1251 int idx;
1252 struct sockaddr_in6 in6_mem;
1254 if (in6->sin6_family == PF_INET)
1256 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1258 /* Construct a V4-to-6 mapped address. */
1259 in6_mem.sin6_family = PF_INET6;
1260 in6_mem.sin6_port = in->sin_port;
1261 in6_mem.sin6_flowinfo = 0;
1262 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1263 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1264 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1265 in6_mem.sin6_scope_id = 0;
1267 in6 = &in6_mem;
1269 else if (in6->sin6_family != PF_INET6)
1270 return default_val;
1272 for (idx = 0; ; ++idx)
1274 unsigned int bits = list[idx].bits;
1275 const uint8_t *mask = list[idx].prefix.s6_addr;
1276 const uint8_t *val = in6->sin6_addr.s6_addr;
1278 while (bits >= 8)
1280 if (*mask != *val)
1281 break;
1283 ++mask;
1284 ++val;
1285 bits -= 8;
1288 if (bits < 8)
1290 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1291 /* Match! */
1292 break;
1296 return list[idx].val;
1300 static int
1301 get_label (const struct sockaddr_in6 *in6)
1303 /* XXX What is a good default value? */
1304 return match_prefix (in6, labels, INT_MAX);
1308 static int
1309 get_precedence (const struct sockaddr_in6 *in6)
1311 /* XXX What is a good default value? */
1312 return match_prefix (in6, precedence, 0);
1316 /* Find last bit set in a word. */
1317 static int
1318 fls (uint32_t a)
1320 uint32_t mask;
1321 int n;
1322 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1323 if ((a & mask) != 0)
1324 break;
1325 return n;
1329 static int
1330 rfc3484_sort (const void *p1, const void *p2, void *arg)
1332 const size_t idx1 = *(const size_t *) p1;
1333 const size_t idx2 = *(const size_t *) p2;
1334 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1335 struct sort_result *a1 = &src->results[idx1];
1336 struct sort_result *a2 = &src->results[idx2];
1338 /* Rule 1: Avoid unusable destinations.
1339 We have the got_source_addr flag set if the destination is reachable. */
1340 if (a1->got_source_addr && ! a2->got_source_addr)
1341 return -1;
1342 if (! a1->got_source_addr && a2->got_source_addr)
1343 return 1;
1346 /* Rule 2: Prefer matching scope. Only interesting if both
1347 destination addresses are IPv6. */
1348 int a1_dst_scope
1349 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1351 int a2_dst_scope
1352 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1354 if (a1->got_source_addr)
1356 int a1_src_scope = get_scope (&a1->source_addr);
1357 int a2_src_scope = get_scope (&a2->source_addr);
1359 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1360 return -1;
1361 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1362 return 1;
1366 /* Rule 3: Avoid deprecated addresses. */
1367 if (a1->got_source_addr)
1369 if (!(a1->source_addr_flags & in6ai_deprecated)
1370 && (a2->source_addr_flags & in6ai_deprecated))
1371 return -1;
1372 if ((a1->source_addr_flags & in6ai_deprecated)
1373 && !(a2->source_addr_flags & in6ai_deprecated))
1374 return 1;
1377 /* Rule 4: Prefer home addresses. */
1378 if (a1->got_source_addr)
1380 if (!(a1->source_addr_flags & in6ai_homeaddress)
1381 && (a2->source_addr_flags & in6ai_homeaddress))
1382 return 1;
1383 if ((a1->source_addr_flags & in6ai_homeaddress)
1384 && !(a2->source_addr_flags & in6ai_homeaddress))
1385 return -1;
1388 /* Rule 5: Prefer matching label. */
1389 if (a1->got_source_addr)
1391 int a1_dst_label
1392 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1393 int a1_src_label = get_label (&a1->source_addr);
1395 int a2_dst_label
1396 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1397 int a2_src_label = get_label (&a2->source_addr);
1399 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1400 return -1;
1401 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1402 return 1;
1406 /* Rule 6: Prefer higher precedence. */
1407 int a1_prec
1408 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1409 int a2_prec
1410 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1412 if (a1_prec > a2_prec)
1413 return -1;
1414 if (a1_prec < a2_prec)
1415 return 1;
1418 /* Rule 7: Prefer native transport. */
1419 if (a1->got_source_addr)
1421 /* The same interface index means the same interface which means
1422 there is no difference in transport. This should catch many
1423 (most?) cases. */
1424 if (a1->index != a2->index)
1426 int a1_native = a1->native;
1427 int a2_native = a2->native;
1429 if (a1_native == -1 || a2_native == -1)
1431 uint32_t a1_index;
1432 if (a1_native == -1)
1434 /* If we do not have the information use 'native' as
1435 the default. */
1436 a1_native = 0;
1437 a1_index = a1->index;
1439 else
1440 a1_index = 0xffffffffu;
1442 uint32_t a2_index;
1443 if (a2_native == -1)
1445 /* If we do not have the information use 'native' as
1446 the default. */
1447 a2_native = 0;
1448 a2_index = a2->index;
1450 else
1451 a2_index = 0xffffffffu;
1453 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1455 /* Fill in the results in all the records. */
1456 for (int i = 0; i < src->nresults; ++i)
1457 if (src->results[i].index == a1_index)
1459 assert (src->results[i].native == -1
1460 || src->results[i].native == a1_native);
1461 src->results[i].native = a1_native;
1463 else if (src->results[i].index == a2_index)
1465 assert (src->results[i].native == -1
1466 || src->results[i].native == a2_native);
1467 src->results[i].native = a2_native;
1471 if (a1_native && !a2_native)
1472 return -1;
1473 if (!a1_native && a2_native)
1474 return 1;
1479 /* Rule 8: Prefer smaller scope. */
1480 if (a1_dst_scope < a2_dst_scope)
1481 return -1;
1482 if (a1_dst_scope > a2_dst_scope)
1483 return 1;
1486 /* Rule 9: Use longest matching prefix. */
1487 if (a1->got_source_addr
1488 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1490 int bit1 = 0;
1491 int bit2 = 0;
1493 if (a1->dest_addr->ai_family == PF_INET)
1495 assert (a1->source_addr.sin6_family == PF_INET);
1496 assert (a2->source_addr.sin6_family == PF_INET);
1498 /* Outside of subnets, as defined by the network masks,
1499 common address prefixes for IPv4 addresses make no sense.
1500 So, define a non-zero value only if source and
1501 destination address are on the same subnet. */
1502 struct sockaddr_in *in1_dst
1503 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1504 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1505 struct sockaddr_in *in1_src
1506 = (struct sockaddr_in *) &a1->source_addr;
1507 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1508 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1510 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1511 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1513 struct sockaddr_in *in2_dst
1514 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1515 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1516 struct sockaddr_in *in2_src
1517 = (struct sockaddr_in *) &a2->source_addr;
1518 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1519 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1521 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1522 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1524 else if (a1->dest_addr->ai_family == PF_INET6)
1526 assert (a1->source_addr.sin6_family == PF_INET6);
1527 assert (a2->source_addr.sin6_family == PF_INET6);
1529 struct sockaddr_in6 *in1_dst;
1530 struct sockaddr_in6 *in1_src;
1531 struct sockaddr_in6 *in2_dst;
1532 struct sockaddr_in6 *in2_src;
1534 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1535 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1536 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1537 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1539 int i;
1540 for (i = 0; i < 4; ++i)
1541 if (in1_dst->sin6_addr.s6_addr32[i]
1542 != in1_src->sin6_addr.s6_addr32[i]
1543 || (in2_dst->sin6_addr.s6_addr32[i]
1544 != in2_src->sin6_addr.s6_addr32[i]))
1545 break;
1547 if (i < 4)
1549 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1550 ^ in1_src->sin6_addr.s6_addr32[i]));
1551 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1552 ^ in2_src->sin6_addr.s6_addr32[i]));
1556 if (bit1 > bit2)
1557 return -1;
1558 if (bit1 < bit2)
1559 return 1;
1563 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1564 compare with the value indicating the order in which the entries
1565 have been received from the services. NB: no two entries can have
1566 the same order so the test will never return zero. */
1567 return idx1 < idx2 ? -1 : 1;
1571 static int
1572 in6aicmp (const void *p1, const void *p2)
1574 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1575 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1577 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1581 /* Name of the config file for RFC 3484 sorting (for now). */
1582 #define GAICONF_FNAME "/etc/gai.conf"
1585 /* Non-zero if we are supposed to reload the config file automatically
1586 whenever it changed. */
1587 static int gaiconf_reload_flag;
1589 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1590 static int gaiconf_reload_flag_ever_set;
1592 /* Last modification time. */
1593 static struct timespec gaiconf_mtime;
1596 libc_freeres_fn(fini)
1598 if (labels != default_labels)
1600 const struct prefixentry *old = labels;
1601 labels = default_labels;
1602 free ((void *) old);
1605 if (precedence != default_precedence)
1607 const struct prefixentry *old = precedence;
1608 precedence = default_precedence;
1609 free ((void *) old);
1612 if (scopes != default_scopes)
1614 const struct scopeentry *old = scopes;
1615 scopes = default_scopes;
1616 free ((void *) old);
1621 struct prefixlist
1623 struct prefixentry entry;
1624 struct prefixlist *next;
1628 struct scopelist
1630 struct scopeentry entry;
1631 struct scopelist *next;
1635 static void
1636 free_prefixlist (struct prefixlist *list)
1638 while (list != NULL)
1640 struct prefixlist *oldp = list;
1641 list = list->next;
1642 free (oldp);
1647 static void
1648 free_scopelist (struct scopelist *list)
1650 while (list != NULL)
1652 struct scopelist *oldp = list;
1653 list = list->next;
1654 free (oldp);
1659 static int
1660 prefixcmp (const void *p1, const void *p2)
1662 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1663 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1665 if (e1->bits < e2->bits)
1666 return 1;
1667 if (e1->bits == e2->bits)
1668 return 0;
1669 return -1;
1673 static int
1674 scopecmp (const void *p1, const void *p2)
1676 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1677 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1679 if (e1->netmask > e2->netmask)
1680 return -1;
1681 if (e1->netmask == e2->netmask)
1682 return 0;
1683 return 1;
1687 static void
1688 gaiconf_init (void)
1690 struct prefixlist *labellist = NULL;
1691 size_t nlabellist = 0;
1692 bool labellist_nullbits = false;
1693 struct prefixlist *precedencelist = NULL;
1694 size_t nprecedencelist = 0;
1695 bool precedencelist_nullbits = false;
1696 struct scopelist *scopelist = NULL;
1697 size_t nscopelist = 0;
1698 bool scopelist_nullbits = false;
1700 FILE *fp = fopen (GAICONF_FNAME, "rc");
1701 if (fp != NULL)
1703 struct stat64 st;
1704 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1706 fclose (fp);
1707 goto no_file;
1710 char *line = NULL;
1711 size_t linelen = 0;
1713 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1715 while (!feof_unlocked (fp))
1717 ssize_t n = __getline (&line, &linelen, fp);
1718 if (n <= 0)
1719 break;
1721 /* Handle comments. No escaping possible so this is easy. */
1722 char *cp = strchr (line, '#');
1723 if (cp != NULL)
1724 *cp = '\0';
1726 cp = line;
1727 while (isspace (*cp))
1728 ++cp;
1730 char *cmd = cp;
1731 while (*cp != '\0' && !isspace (*cp))
1732 ++cp;
1733 size_t cmdlen = cp - cmd;
1735 if (*cp != '\0')
1736 *cp++ = '\0';
1737 while (isspace (*cp))
1738 ++cp;
1740 char *val1 = cp;
1741 while (*cp != '\0' && !isspace (*cp))
1742 ++cp;
1743 size_t val1len = cp - cmd;
1745 /* We always need at least two values. */
1746 if (val1len == 0)
1747 continue;
1749 if (*cp != '\0')
1750 *cp++ = '\0';
1751 while (isspace (*cp))
1752 ++cp;
1754 char *val2 = cp;
1755 while (*cp != '\0' && !isspace (*cp))
1756 ++cp;
1758 /* Ignore the rest of the line. */
1759 *cp = '\0';
1761 struct prefixlist **listp;
1762 size_t *lenp;
1763 bool *nullbitsp;
1764 switch (cmdlen)
1766 case 5:
1767 if (strcmp (cmd, "label") == 0)
1769 struct in6_addr prefix;
1770 unsigned long int bits;
1771 unsigned long int val;
1772 char *endp;
1774 listp = &labellist;
1775 lenp = &nlabellist;
1776 nullbitsp = &labellist_nullbits;
1778 new_elem:
1779 bits = 128;
1780 __set_errno (0);
1781 cp = strchr (val1, '/');
1782 if (cp != NULL)
1783 *cp++ = '\0';
1784 if (inet_pton (AF_INET6, val1, &prefix)
1785 && (cp == NULL
1786 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1787 || errno != ERANGE)
1788 && *endp == '\0'
1789 && bits <= 128
1790 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1791 || errno != ERANGE)
1792 && *endp == '\0'
1793 && val <= INT_MAX)
1795 struct prefixlist *newp = malloc (sizeof (*newp));
1796 if (newp == NULL)
1798 free (line);
1799 fclose (fp);
1800 goto no_file;
1803 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1804 newp->entry.bits = bits;
1805 newp->entry.val = val;
1806 newp->next = *listp;
1807 *listp = newp;
1808 ++*lenp;
1809 *nullbitsp |= bits == 0;
1812 break;
1814 case 6:
1815 if (strcmp (cmd, "reload") == 0)
1817 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1818 if (gaiconf_reload_flag)
1819 gaiconf_reload_flag_ever_set = 1;
1821 break;
1823 case 7:
1824 if (strcmp (cmd, "scopev4") == 0)
1826 struct in6_addr prefix;
1827 unsigned long int bits;
1828 unsigned long int val;
1829 char *endp;
1831 bits = 32;
1832 __set_errno (0);
1833 cp = strchr (val1, '/');
1834 if (cp != NULL)
1835 *cp++ = '\0';
1836 if (inet_pton (AF_INET6, val1, &prefix))
1838 bits = 128;
1839 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1840 && (cp == NULL
1841 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1842 || errno != ERANGE)
1843 && *endp == '\0'
1844 && bits >= 96
1845 && bits <= 128
1846 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1847 || errno != ERANGE)
1848 && *endp == '\0'
1849 && val <= INT_MAX)
1851 struct scopelist *newp;
1852 new_scope:
1853 newp = malloc (sizeof (*newp));
1854 if (newp == NULL)
1856 free (line);
1857 fclose (fp);
1858 goto no_file;
1861 newp->entry.netmask = htonl (bits != 96
1862 ? (0xffffffff
1863 << (128 - bits))
1864 : 0);
1865 newp->entry.addr32 = (prefix.s6_addr32[3]
1866 & newp->entry.netmask);
1867 newp->entry.scope = val;
1868 newp->next = scopelist;
1869 scopelist = newp;
1870 ++nscopelist;
1871 scopelist_nullbits |= bits == 96;
1874 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1875 && (cp == NULL
1876 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1877 || errno != ERANGE)
1878 && *endp == '\0'
1879 && bits <= 32
1880 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1881 || errno != ERANGE)
1882 && *endp == '\0'
1883 && val <= INT_MAX)
1885 bits += 96;
1886 goto new_scope;
1889 break;
1891 case 10:
1892 if (strcmp (cmd, "precedence") == 0)
1894 listp = &precedencelist;
1895 lenp = &nprecedencelist;
1896 nullbitsp = &precedencelist_nullbits;
1897 goto new_elem;
1899 break;
1903 free (line);
1905 fclose (fp);
1907 /* Create the array for the labels. */
1908 struct prefixentry *new_labels;
1909 if (nlabellist > 0)
1911 if (!labellist_nullbits)
1912 ++nlabellist;
1913 new_labels = malloc (nlabellist * sizeof (*new_labels));
1914 if (new_labels == NULL)
1915 goto no_file;
1917 int i = nlabellist;
1918 if (!labellist_nullbits)
1920 --i;
1921 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1922 new_labels[i].bits = 0;
1923 new_labels[i].val = 1;
1926 struct prefixlist *l = labellist;
1927 while (i-- > 0)
1929 new_labels[i] = l->entry;
1930 l = l->next;
1932 free_prefixlist (labellist);
1934 /* Sort the entries so that the most specific ones are at
1935 the beginning. */
1936 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1938 else
1939 new_labels = (struct prefixentry *) default_labels;
1941 struct prefixentry *new_precedence;
1942 if (nprecedencelist > 0)
1944 if (!precedencelist_nullbits)
1945 ++nprecedencelist;
1946 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1947 if (new_precedence == NULL)
1949 if (new_labels != default_labels)
1950 free (new_labels);
1951 goto no_file;
1954 int i = nprecedencelist;
1955 if (!precedencelist_nullbits)
1957 --i;
1958 memset (&new_precedence[i].prefix, '\0',
1959 sizeof (struct in6_addr));
1960 new_precedence[i].bits = 0;
1961 new_precedence[i].val = 40;
1964 struct prefixlist *l = precedencelist;
1965 while (i-- > 0)
1967 new_precedence[i] = l->entry;
1968 l = l->next;
1970 free_prefixlist (precedencelist);
1972 /* Sort the entries so that the most specific ones are at
1973 the beginning. */
1974 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1975 prefixcmp);
1977 else
1978 new_precedence = (struct prefixentry *) default_precedence;
1980 struct scopeentry *new_scopes;
1981 if (nscopelist > 0)
1983 if (!scopelist_nullbits)
1984 ++nscopelist;
1985 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1986 if (new_scopes == NULL)
1988 if (new_labels != default_labels)
1989 free (new_labels);
1990 if (new_precedence != default_precedence)
1991 free (new_precedence);
1992 goto no_file;
1995 int i = nscopelist;
1996 if (!scopelist_nullbits)
1998 --i;
1999 new_scopes[i].addr32 = 0;
2000 new_scopes[i].netmask = 0;
2001 new_scopes[i].scope = 14;
2004 struct scopelist *l = scopelist;
2005 while (i-- > 0)
2007 new_scopes[i] = l->entry;
2008 l = l->next;
2010 free_scopelist (scopelist);
2012 /* Sort the entries so that the most specific ones are at
2013 the beginning. */
2014 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2015 scopecmp);
2017 else
2018 new_scopes = (struct scopeentry *) default_scopes;
2020 /* Now we are ready to replace the values. */
2021 const struct prefixentry *old = labels;
2022 labels = new_labels;
2023 if (old != default_labels)
2024 free ((void *) old);
2026 old = precedence;
2027 precedence = new_precedence;
2028 if (old != default_precedence)
2029 free ((void *) old);
2031 const struct scopeentry *oldscope = scopes;
2032 scopes = new_scopes;
2033 if (oldscope != default_scopes)
2034 free ((void *) oldscope);
2036 gaiconf_mtime = st.st_mtim;
2038 else
2040 no_file:
2041 free_prefixlist (labellist);
2042 free_prefixlist (precedencelist);
2043 free_scopelist (scopelist);
2045 /* If we previously read the file but it is gone now, free the
2046 old data and use the builtin one. Leave the reload flag
2047 alone. */
2048 fini ();
2053 static void
2054 gaiconf_reload (void)
2056 struct stat64 st;
2057 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2058 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2059 gaiconf_init ();
2064 getaddrinfo (const char *name, const char *service,
2065 const struct addrinfo *hints, struct addrinfo **pai)
2067 int i = 0, last_i = 0;
2068 int nresults = 0;
2069 struct addrinfo *p = NULL;
2070 struct gaih_service gaih_service, *pservice;
2071 struct addrinfo local_hints;
2073 if (name != NULL && name[0] == '*' && name[1] == 0)
2074 name = NULL;
2076 if (service != NULL && service[0] == '*' && service[1] == 0)
2077 service = NULL;
2079 if (name == NULL && service == NULL)
2080 return EAI_NONAME;
2082 if (hints == NULL)
2083 hints = &default_hints;
2085 if (hints->ai_flags
2086 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2087 #ifdef HAVE_LIBIDN
2088 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2089 |AI_IDN_USE_STD3_ASCII_RULES
2090 #endif
2091 |AI_NUMERICSERV|AI_ALL))
2092 return EAI_BADFLAGS;
2094 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2095 return EAI_BADFLAGS;
2097 struct in6addrinfo *in6ai = NULL;
2098 size_t in6ailen = 0;
2099 bool seen_ipv4 = false;
2100 bool seen_ipv6 = false;
2101 /* We might need information about what interfaces are available.
2102 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2103 cannot cache the results since new interfaces could be added at
2104 any time. */
2105 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2107 if (hints->ai_flags & AI_ADDRCONFIG)
2109 /* Now make a decision on what we return, if anything. */
2110 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2112 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2113 narrow down the search. */
2114 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2116 local_hints = *hints;
2117 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2118 hints = &local_hints;
2121 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2122 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2124 /* We cannot possibly return a valid answer. */
2125 free (in6ai);
2126 return EAI_NONAME;
2130 if (service && service[0])
2132 char *c;
2133 gaih_service.name = service;
2134 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2135 if (*c != '\0')
2137 if (hints->ai_flags & AI_NUMERICSERV)
2139 free (in6ai);
2140 return EAI_NONAME;
2143 gaih_service.num = -1;
2146 pservice = &gaih_service;
2148 else
2149 pservice = NULL;
2151 struct addrinfo **end = &p;
2153 unsigned int naddrs = 0;
2154 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2155 || hints->ai_family == AF_INET6)
2157 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2158 if (last_i != 0)
2160 freeaddrinfo (p);
2161 free (in6ai);
2163 return -(last_i & GAIH_EAI);
2165 while (*end)
2167 end = &((*end)->ai_next);
2168 ++nresults;
2171 else
2173 free (in6ai);
2174 return EAI_FAMILY;
2177 if (naddrs > 1)
2179 /* Read the config file. */
2180 __libc_once_define (static, once);
2181 __typeof (once) old_once = once;
2182 __libc_once (once, gaiconf_init);
2183 /* Sort results according to RFC 3484. */
2184 struct sort_result results[nresults];
2185 size_t order[nresults];
2186 struct addrinfo *q;
2187 struct addrinfo *last = NULL;
2188 char *canonname = NULL;
2190 /* If we have information about deprecated and temporary addresses
2191 sort the array now. */
2192 if (in6ai != NULL)
2193 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2195 int fd = -1;
2196 int af = AF_UNSPEC;
2198 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2200 results[i].dest_addr = q;
2201 results[i].native = -1;
2202 order[i] = i;
2204 /* If we just looked up the address for a different
2205 protocol, reuse the result. */
2206 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2207 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2209 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2210 results[i - 1].source_addr_len);
2211 results[i].source_addr_len = results[i - 1].source_addr_len;
2212 results[i].got_source_addr = results[i - 1].got_source_addr;
2213 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2214 results[i].prefixlen = results[i - 1].prefixlen;
2215 results[i].index = results[i - 1].index;
2217 else
2219 results[i].got_source_addr = false;
2220 results[i].source_addr_flags = 0;
2221 results[i].prefixlen = 0;
2222 results[i].index = 0xffffffffu;
2224 /* We overwrite the type with SOCK_DGRAM since we do not
2225 want connect() to connect to the other side. If we
2226 cannot determine the source address remember this
2227 fact. */
2228 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2230 if (fd != -1)
2231 close_retry:
2232 close_not_cancel_no_status (fd);
2233 af = q->ai_family;
2234 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2236 else
2238 /* Reset the connection. */
2239 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2240 __connect (fd, &sa, sizeof (sa));
2243 socklen_t sl = sizeof (results[i].source_addr);
2244 if (fd != -1
2245 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2246 && __getsockname (fd,
2247 (struct sockaddr *) &results[i].source_addr,
2248 &sl) == 0)
2250 results[i].source_addr_len = sl;
2251 results[i].got_source_addr = true;
2253 if (in6ai != NULL)
2255 /* See whether the source address is on the list of
2256 deprecated or temporary addresses. */
2257 struct in6addrinfo tmp;
2259 if (q->ai_family == AF_INET && af == AF_INET)
2261 struct sockaddr_in *sinp
2262 = (struct sockaddr_in *) &results[i].source_addr;
2263 tmp.addr[0] = 0;
2264 tmp.addr[1] = 0;
2265 tmp.addr[2] = htonl (0xffff);
2266 tmp.addr[3] = sinp->sin_addr.s_addr;
2268 else
2270 struct sockaddr_in6 *sin6p
2271 = (struct sockaddr_in6 *) &results[i].source_addr;
2272 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2275 struct in6addrinfo *found
2276 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2277 in6aicmp);
2278 if (found != NULL)
2280 results[i].source_addr_flags = found->flags;
2281 results[i].prefixlen = found->prefixlen;
2282 results[i].index = found->index;
2286 if (q->ai_family == AF_INET && af == AF_INET6)
2288 /* We have to convert the address. The socket is
2289 IPv6 and the request is for IPv4. */
2290 struct sockaddr_in6 *sin6
2291 = (struct sockaddr_in6 *) &results[i].source_addr;
2292 struct sockaddr_in *sin
2293 = (struct sockaddr_in *) &results[i].source_addr;
2294 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2295 sin->sin_family = AF_INET;
2296 /* We do not have to initialize sin_port since this
2297 fields has the same position and size in the IPv6
2298 structure. */
2299 assert (offsetof (struct sockaddr_in, sin_port)
2300 == offsetof (struct sockaddr_in6, sin6_port));
2301 assert (sizeof (sin->sin_port)
2302 == sizeof (sin6->sin6_port));
2303 memcpy (&sin->sin_addr,
2304 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2305 results[i].source_addr_len = sizeof (struct sockaddr_in);
2308 else if (errno == EAFNOSUPPORT && af == AF_INET6
2309 && q->ai_family == AF_INET)
2310 /* This could mean IPv6 sockets are IPv6-only. */
2311 goto close_retry;
2312 else
2313 /* Just make sure that if we have to process the same
2314 address again we do not copy any memory. */
2315 results[i].source_addr_len = 0;
2318 /* Remember the canonical name. */
2319 if (q->ai_canonname != NULL)
2321 assert (canonname == NULL);
2322 canonname = q->ai_canonname;
2323 q->ai_canonname = NULL;
2327 if (fd != -1)
2328 close_not_cancel_no_status (fd);
2330 /* We got all the source addresses we can get, now sort using
2331 the information. */
2332 struct sort_result_combo src
2333 = { .results = results, .nresults = nresults };
2334 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2336 __libc_lock_define_initialized (static, lock);
2338 __libc_lock_lock (lock);
2339 if (old_once && gaiconf_reload_flag)
2340 gaiconf_reload ();
2341 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2342 __libc_lock_unlock (lock);
2344 else
2345 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2347 /* Queue the results up as they come out of sorting. */
2348 q = p = results[order[0]].dest_addr;
2349 for (i = 1; i < nresults; ++i)
2350 q = q->ai_next = results[order[i]].dest_addr;
2351 q->ai_next = NULL;
2353 /* Fill in the canonical name into the new first entry. */
2354 p->ai_canonname = canonname;
2357 free (in6ai);
2359 if (p)
2361 *pai = p;
2362 return 0;
2365 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2367 libc_hidden_def (getaddrinfo)
2369 static_link_warning (getaddrinfo)
2371 void
2372 freeaddrinfo (struct addrinfo *ai)
2374 struct addrinfo *p;
2376 while (ai != NULL)
2378 p = ai;
2379 ai = ai->ai_next;
2380 free (p->ai_canonname);
2381 free (p);
2384 libc_hidden_def (freeaddrinfo)