.
[glibc/history.git] / sysdeps / posix / getaddrinfo.c
blobd346c621fbe8028ea4e91bb711611f5c061f8d00
1 /* The Inner Net License, Version 2.00
3 The author(s) grant permission for redistribution and use in source and
4 binary forms, with or without modification, of the software and documentation
5 provided that the following conditions are met:
7 0. If you receive a version of the software that is specifically labelled
8 as not being for redistribution (check the version message and/or README),
9 you are not permitted to redistribute that version of the software in any
10 way or form.
11 1. All terms of the all other applicable copyrights and licenses must be
12 followed.
13 2. Redistributions of source code must retain the authors' copyright
14 notice(s), this list of conditions, and the following disclaimer.
15 3. Redistributions in binary form must reproduce the authors' copyright
16 notice(s), this list of conditions, and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 4. [The copyright holder has authorized the removal of this clause.]
19 5. Neither the name(s) of the author(s) nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
23 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
38 #include <assert.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <ifaddrs.h>
42 #include <netdb.h>
43 #include <nss.h>
44 #include <resolv.h>
45 #include <stdbool.h>
46 #include <stdio.h>
47 #include <stdio_ext.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <arpa/inet.h>
51 #include <net/if.h>
52 #include <netinet/in.h>
53 #include <sys/socket.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 #include <sys/un.h>
57 #include <sys/utsname.h>
58 #include <unistd.h>
59 #include <nsswitch.h>
60 #include <bits/libc-lock.h>
61 #include <not-cancel.h>
62 #include <nscd/nscd-client.h>
63 #include <nscd/nscd_proto.h>
64 #include <resolv/res_hconf.h>
66 #ifdef HAVE_LIBIDN
67 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
68 extern int __idna_to_unicode_lzlz (const char *input, char **output,
69 int flags);
70 # include <libidn/idna.h>
71 #endif
73 #define GAIH_OKIFUNSPEC 0x0100
74 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
76 #ifndef UNIX_PATH_MAX
77 # define UNIX_PATH_MAX 108
78 #endif
80 struct gaih_service
82 const char *name;
83 int num;
86 struct gaih_servtuple
88 struct gaih_servtuple *next;
89 int socktype;
90 int protocol;
91 int port;
94 static const struct gaih_servtuple nullserv;
97 struct gaih_typeproto
99 int socktype;
100 int protocol;
101 uint8_t protoflag;
102 bool defaultflag;
103 char name[8];
106 /* Values for `protoflag'. */
107 #define GAI_PROTO_NOSERVICE 1
108 #define GAI_PROTO_PROTOANY 2
110 static const struct gaih_typeproto gaih_inet_typeproto[] =
112 { 0, 0, 0, false, "" },
113 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
114 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
115 #if defined SOCK_DCCP && defined IPPROTO_DCCP
116 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
117 #endif
118 #ifdef IPPROTO_UDPLITE
119 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
120 #endif
121 #ifdef IPPROTO_SCTP
122 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
123 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
124 #endif
125 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
126 { 0, 0, 0, false, "" }
129 struct gaih
131 int family;
132 int (*gaih)(const char *name, const struct gaih_service *service,
133 const struct addrinfo *req, struct addrinfo **pai,
134 unsigned int *naddrs);
137 static const struct addrinfo default_hints =
139 .ai_flags = AI_DEFAULT,
140 .ai_family = PF_UNSPEC,
141 .ai_socktype = 0,
142 .ai_protocol = 0,
143 .ai_addrlen = 0,
144 .ai_addr = NULL,
145 .ai_canonname = NULL,
146 .ai_next = NULL
150 static int
151 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
152 const struct addrinfo *req, struct gaih_servtuple *st)
154 struct servent *s;
155 size_t tmpbuflen = 1024;
156 struct servent ts;
157 char *tmpbuf;
158 int r;
162 tmpbuf = __alloca (tmpbuflen);
164 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
165 &s);
166 if (r != 0 || s == NULL)
168 if (r == ERANGE)
169 tmpbuflen *= 2;
170 else
171 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
174 while (r);
176 st->next = NULL;
177 st->socktype = tp->socktype;
178 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
179 ? req->ai_protocol : tp->protocol);
180 st->port = s->s_port;
182 return 0;
185 #define gethosts(_family, _type) \
187 int i; \
188 int herrno; \
189 struct hostent th; \
190 struct hostent *h; \
191 char *localcanon = NULL; \
192 no_data = 0; \
193 while (1) { \
194 rc = 0; \
195 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
196 &rc, &herrno, NULL, &localcanon)); \
197 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
198 break; \
199 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
201 if (status == NSS_STATUS_SUCCESS && rc == 0) \
202 h = &th; \
203 else \
204 h = NULL; \
205 if (rc != 0) \
207 if (herrno == NETDB_INTERNAL) \
209 __set_h_errno (herrno); \
210 _res.options = old_res_options; \
211 return -EAI_SYSTEM; \
213 if (herrno == TRY_AGAIN) \
214 no_data = EAI_AGAIN; \
215 else \
216 no_data = herrno == NO_DATA; \
218 else if (h != NULL) \
220 for (i = 0; h->h_addr_list[i]; i++) \
222 if (*pat == NULL) \
224 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
225 (*pat)->scopeid = 0; \
227 uint32_t *addr = (*pat)->addr; \
228 (*pat)->next = NULL; \
229 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
230 if (_family == AF_INET && req->ai_family == AF_INET6) \
232 (*pat)->family = AF_INET6; \
233 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
234 addr[2] = htonl (0xffff); \
235 addr[1] = 0; \
236 addr[0] = 0; \
238 else \
240 (*pat)->family = _family; \
241 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
243 pat = &((*pat)->next); \
246 if (localcanon != NULL && canon == NULL) \
247 canon = strdupa (localcanon); \
249 if (_family == AF_INET6 && i > 0) \
250 got_ipv6 = true; \
255 typedef enum nss_status (*nss_gethostbyname4_r)
256 (const char *name, struct gaih_addrtuple **pat,
257 char *buffer, size_t buflen, int *errnop,
258 int *h_errnop, int32_t *ttlp);
259 typedef enum nss_status (*nss_gethostbyname3_r)
260 (const char *name, int af, struct hostent *host,
261 char *buffer, size_t buflen, int *errnop,
262 int *h_errnop, int32_t *ttlp, char **canonp);
263 typedef enum nss_status (*nss_getcanonname_r)
264 (const char *name, char *buffer, size_t buflen, char **result,
265 int *errnop, int *h_errnop);
266 extern service_user *__nss_hosts_database attribute_hidden;
269 static int
270 gaih_inet (const char *name, const struct gaih_service *service,
271 const struct addrinfo *req, struct addrinfo **pai,
272 unsigned int *naddrs)
274 const struct gaih_typeproto *tp = gaih_inet_typeproto;
275 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
276 struct gaih_addrtuple *at = NULL;
277 int rc;
278 bool got_ipv6 = false;
279 const char *canon = NULL;
280 const char *orig_name = name;
282 if (req->ai_protocol || req->ai_socktype)
284 ++tp;
286 while (tp->name[0]
287 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
288 || (req->ai_protocol != 0
289 && !(tp->protoflag & GAI_PROTO_PROTOANY)
290 && req->ai_protocol != tp->protocol)))
291 ++tp;
293 if (! tp->name[0])
295 if (req->ai_socktype)
296 return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
297 else
298 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
302 int port = 0;
303 if (service != NULL)
305 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
306 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
308 if (service->num < 0)
310 if (tp->name[0])
312 st = (struct gaih_servtuple *)
313 __alloca (sizeof (struct gaih_servtuple));
315 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
316 return rc;
318 else
320 struct gaih_servtuple **pst = &st;
321 for (tp++; tp->name[0]; tp++)
323 struct gaih_servtuple *newp;
325 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
326 continue;
328 if (req->ai_socktype != 0
329 && req->ai_socktype != tp->socktype)
330 continue;
331 if (req->ai_protocol != 0
332 && !(tp->protoflag & GAI_PROTO_PROTOANY)
333 && req->ai_protocol != tp->protocol)
334 continue;
336 newp = (struct gaih_servtuple *)
337 __alloca (sizeof (struct gaih_servtuple));
339 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
341 if (rc & GAIH_OKIFUNSPEC)
342 continue;
343 return rc;
346 *pst = newp;
347 pst = &(newp->next);
349 if (st == (struct gaih_servtuple *) &nullserv)
350 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
353 else
355 port = htons (service->num);
356 goto got_port;
359 else
361 got_port:
363 if (req->ai_socktype || req->ai_protocol)
365 st = __alloca (sizeof (struct gaih_servtuple));
366 st->next = NULL;
367 st->socktype = tp->socktype;
368 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
369 ? req->ai_protocol : tp->protocol);
370 st->port = port;
372 else
374 /* Neither socket type nor protocol is set. Return all socket types
375 we know about. */
376 struct gaih_servtuple **lastp = &st;
377 for (++tp; tp->name[0]; ++tp)
378 if (tp->defaultflag)
380 struct gaih_servtuple *newp;
382 newp = __alloca (sizeof (struct gaih_servtuple));
383 newp->next = NULL;
384 newp->socktype = tp->socktype;
385 newp->protocol = tp->protocol;
386 newp->port = port;
388 *lastp = newp;
389 lastp = &newp->next;
394 if (name != NULL)
396 at = __alloca (sizeof (struct gaih_addrtuple));
398 at->family = AF_UNSPEC;
399 at->scopeid = 0;
400 at->next = NULL;
402 #ifdef HAVE_LIBIDN
403 if (req->ai_flags & AI_IDN)
405 int idn_flags = 0;
406 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
407 idn_flags |= IDNA_ALLOW_UNASSIGNED;
408 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
409 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
411 char *p = NULL;
412 rc = __idna_to_ascii_lz (name, &p, idn_flags);
413 if (rc != IDNA_SUCCESS)
415 if (rc == IDNA_MALLOC_ERROR)
416 return -EAI_MEMORY;
417 if (rc == IDNA_DLOPEN_ERROR)
418 return -EAI_SYSTEM;
419 return -EAI_IDN_ENCODE;
421 /* In case the output string is the same as the input string
422 no new string has been allocated. */
423 if (p != name)
425 name = strdupa (p);
426 free (p);
429 #endif
431 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
433 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
434 at->family = AF_INET;
435 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
437 at->addr[3] = at->addr[0];
438 at->addr[2] = htonl (0xffff);
439 at->addr[1] = 0;
440 at->addr[0] = 0;
441 at->family = AF_INET6;
443 else
444 return -EAI_ADDRFAMILY;
446 if (req->ai_flags & AI_CANONNAME)
447 canon = name;
449 else if (at->family == AF_UNSPEC)
451 char *namebuf = (char *) name;
452 char *scope_delim = strchr (name, SCOPE_DELIMITER);
454 if (__builtin_expect (scope_delim != NULL, 0))
456 namebuf = alloca (scope_delim - name + 1);
457 *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
460 if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
462 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
463 at->family = AF_INET6;
464 else if (req->ai_family == AF_INET
465 && IN6_IS_ADDR_V4MAPPED (at->addr))
467 at->addr[0] = at->addr[3];
468 at->family = AF_INET;
470 else
471 return -EAI_ADDRFAMILY;
473 if (scope_delim != NULL)
475 int try_numericscope = 0;
476 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
477 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
479 at->scopeid = if_nametoindex (scope_delim + 1);
480 if (at->scopeid == 0)
481 try_numericscope = 1;
483 else
484 try_numericscope = 1;
486 if (try_numericscope != 0)
488 char *end;
489 assert (sizeof (uint32_t) <= sizeof (unsigned long));
490 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
491 10);
492 if (*end != '\0')
493 return GAIH_OKIFUNSPEC | -EAI_NONAME;
497 if (req->ai_flags & AI_CANONNAME)
498 canon = name;
502 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
504 struct gaih_addrtuple **pat = &at;
505 int no_data = 0;
506 int no_inet6_data = 0;
507 service_user *nip = NULL;
508 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
509 enum nss_status status = NSS_STATUS_UNAVAIL;
510 int no_more;
511 int old_res_options;
513 /* If we do not have to look for IPv4 and IPv6 together, use
514 the simple, old functions. */
515 if (req->ai_family == AF_INET
516 || (req->ai_family == AF_INET6
517 && ((req->ai_flags & AI_V4MAPPED) == 0
518 || (req->ai_flags & AI_ALL) == 0)))
520 int family = req->ai_family;
521 size_t tmpbuflen = 512;
522 char *tmpbuf = alloca (tmpbuflen);
523 int rc;
524 struct hostent th;
525 struct hostent *h;
526 int herrno;
528 simple_again:
529 while (1)
531 rc = __gethostbyname2_r (name, family, &th, tmpbuf,
532 tmpbuflen, &h, &herrno);
533 if (rc != ERANGE || herrno != NETDB_INTERNAL)
534 break;
535 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
538 if (rc == 0)
540 if (h == NULL)
542 if (req->ai_family == AF_INET6
543 && (req->ai_flags & AI_V4MAPPED)
544 && family == AF_INET6)
546 /* Try again, this time looking for IPv4
547 addresses. */
548 family = AF_INET;
549 goto simple_again;
552 else
554 /* We found data, now convert it into the list. */
555 for (int i = 0; h->h_addr_list[i]; ++i)
557 if (*pat == NULL)
559 *pat = __alloca (sizeof (struct gaih_addrtuple));
560 (*pat)->scopeid = 0;
562 (*pat)->next = NULL;
563 (*pat)->family = req->ai_family;
564 if (family == req->ai_family)
565 memcpy ((*pat)->addr, h->h_addr_list[i],
566 h->h_length);
567 else
569 uint32_t *addr = (uint32_t *) (*pat)->addr;
570 addr[3] = *(uint32_t *) h->h_addr_list[i];
571 addr[2] = htonl (0xffff);
572 addr[1] = 0;
573 addr[0] = 0;
575 pat = &((*pat)->next);
579 else
581 if (herrno == NETDB_INTERNAL)
583 __set_h_errno (herrno);
584 return -EAI_SYSTEM;
586 if (herrno == TRY_AGAIN)
588 return -EAI_AGAIN;
590 /* We made requests but they turned out no data.
591 The name is known, though. */
592 return GAIH_OKIFUNSPEC | -EAI_NODATA;
595 goto process_list;
598 #ifdef USE_NSCD
599 if (__nss_not_use_nscd_hosts > 0
600 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
601 __nss_not_use_nscd_hosts = 0;
603 if (!__nss_not_use_nscd_hosts)
605 /* Try to use nscd. */
606 struct nscd_ai_result *air = NULL;
607 int herrno;
608 int err = __nscd_getai (name, &air, &herrno);
609 if (air != NULL)
611 /* Transform into gaih_addrtuple list. */
612 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
613 char *addrs = air->addrs;
615 for (int i = 0; i < air->naddrs; ++i)
617 socklen_t size = (air->family[i] == AF_INET
618 ? INADDRSZ : IN6ADDRSZ);
619 if (*pat == NULL)
621 *pat = __alloca (sizeof (struct gaih_addrtuple));
622 (*pat)->scopeid = 0;
624 uint32_t *pataddr = (*pat)->addr;
625 (*pat)->next = NULL;
626 if (added_canon || air->canon == NULL)
627 (*pat)->name = NULL;
628 else
629 canon = (*pat)->name = strdupa (air->canon);
631 if (air->family[i] == AF_INET
632 && req->ai_family == AF_INET6
633 && (req->ai_flags & AI_V4MAPPED))
635 (*pat)->family = AF_INET6;
636 pataddr[3] = *(uint32_t *) addrs;
637 pataddr[2] = htonl (0xffff);
638 pataddr[1] = 0;
639 pataddr[0] = 0;
640 pat = &((*pat)->next);
641 added_canon = true;
643 else if (req->ai_family == AF_UNSPEC
644 || air->family[i] == req->ai_family)
646 (*pat)->family = air->family[i];
647 memcpy (pataddr, addrs, size);
648 pat = &((*pat)->next);
649 added_canon = true;
650 if (air->family[i] == AF_INET6)
651 got_ipv6 = true;
653 addrs += size;
656 free (air);
658 if (at->family == AF_UNSPEC)
659 return GAIH_OKIFUNSPEC | -EAI_NONAME;
661 goto process_list;
663 else if (err == 0)
664 /* The database contains a negative entry. */
665 return 0;
666 else if (__nss_not_use_nscd_hosts == 0)
668 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
669 return -EAI_MEMORY;
670 if (herrno == TRY_AGAIN)
671 return -EAI_AGAIN;
672 return -EAI_SYSTEM;
675 #endif
677 if (__nss_hosts_database != NULL)
679 no_more = 0;
680 nip = __nss_hosts_database;
682 else
683 no_more = __nss_database_lookup ("hosts", NULL,
684 "dns [!UNAVAIL=return] files",
685 &nip);
687 /* Initialize configurations. */
688 if (__builtin_expect (!_res_hconf.initialized, 0))
689 _res_hconf_init ();
690 if (__res_maybe_init (&_res, 0) == -1)
691 no_more = 1;
693 /* If we are looking for both IPv4 and IPv6 address we don't
694 want the lookup functions to automatically promote IPv4
695 addresses to IPv6 addresses. Currently this is decided
696 by setting the RES_USE_INET6 bit in _res.options. */
697 old_res_options = _res.options;
698 _res.options &= ~RES_USE_INET6;
700 size_t tmpbuflen = 1024;
701 char *tmpbuf = alloca (tmpbuflen);
703 while (!no_more)
705 nss_gethostbyname4_r fct4
706 = __nss_lookup_function (nip, "gethostbyname4_r");
707 if (fct4 != NULL)
709 int herrno;
711 while (1)
713 rc = 0;
714 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
715 tmpbuflen, &rc, &herrno,
716 NULL));
717 if (status == NSS_STATUS_SUCCESS)
718 break;
719 if (status != NSS_STATUS_TRYAGAIN
720 || rc != ERANGE || herrno != NETDB_INTERNAL)
722 if (herrno == NETDB_INTERNAL)
724 __set_h_errno (herrno);
725 _res.options = old_res_options;
726 return -EAI_SYSTEM;
728 if (herrno == TRY_AGAIN)
729 no_data = EAI_AGAIN;
730 else
731 no_data = herrno == NO_DATA;
732 break;
734 tmpbuf = extend_alloca (tmpbuf,
735 tmpbuflen, 2 * tmpbuflen);
738 no_inet6_data = no_data;
740 if (status == NSS_STATUS_SUCCESS)
742 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
743 canon = (*pat)->name;
745 while (*pat != NULL)
746 pat = &((*pat)->next);
749 else
751 nss_gethostbyname3_r fct = NULL;
752 if (req->ai_flags & AI_CANONNAME)
753 /* No need to use this function if we do not look for
754 the canonical name. The function does not exist in
755 all NSS modules and therefore the lookup would
756 often fail. */
757 fct = __nss_lookup_function (nip, "gethostbyname3_r");
758 if (fct == NULL)
759 /* We are cheating here. The gethostbyname2_r
760 function does not have the same interface as
761 gethostbyname3_r but the extra arguments the
762 latter takes are added at the end. So the
763 gethostbyname2_r code will just ignore them. */
764 fct = __nss_lookup_function (nip, "gethostbyname2_r");
766 if (fct != NULL)
768 if (req->ai_family == AF_INET6
769 || req->ai_family == AF_UNSPEC)
771 gethosts (AF_INET6, struct in6_addr);
772 no_inet6_data = no_data;
773 inet6_status = status;
775 if (req->ai_family == AF_INET
776 || req->ai_family == AF_UNSPEC
777 || (req->ai_family == AF_INET6
778 && (req->ai_flags & AI_V4MAPPED)
779 /* Avoid generating the mapped addresses if we
780 know we are not going to need them. */
781 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
783 gethosts (AF_INET, struct in_addr);
785 if (req->ai_family == AF_INET)
787 no_inet6_data = no_data;
788 inet6_status = status;
792 /* If we found one address for AF_INET or AF_INET6,
793 don't continue the search. */
794 if (inet6_status == NSS_STATUS_SUCCESS
795 || status == NSS_STATUS_SUCCESS)
797 if ((req->ai_flags & AI_CANONNAME) != 0
798 && canon == NULL)
800 /* If we need the canonical name, get it
801 from the same service as the result. */
802 nss_getcanonname_r cfct;
803 int herrno;
805 cfct = __nss_lookup_function (nip,
806 "getcanonname_r");
807 if (cfct != NULL)
809 const size_t max_fqdn_len = 256;
810 char *buf = alloca (max_fqdn_len);
811 char *s;
813 if (DL_CALL_FCT (cfct, (at->name ?: name,
814 buf, max_fqdn_len,
815 &s, &rc, &herrno))
816 == NSS_STATUS_SUCCESS)
817 canon = s;
818 else
819 /* Set to name now to avoid using
820 gethostbyaddr. */
821 canon = name;
825 break;
828 /* We can have different states for AF_INET and
829 AF_INET6. Try to find a useful one for both. */
830 if (inet6_status == NSS_STATUS_TRYAGAIN)
831 status = NSS_STATUS_TRYAGAIN;
832 else if (status == NSS_STATUS_UNAVAIL
833 && inet6_status != NSS_STATUS_UNAVAIL)
834 status = inet6_status;
838 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
839 break;
841 if (nip->next == NULL)
842 no_more = -1;
843 else
844 nip = nip->next;
847 _res.options = old_res_options;
849 if (no_data != 0 && no_inet6_data != 0)
851 /* If both requests timed out report this. */
852 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
853 return -EAI_AGAIN;
855 /* We made requests but they turned out no data. The name
856 is known, though. */
857 return GAIH_OKIFUNSPEC | -EAI_NODATA;
861 process_list:
862 if (at->family == AF_UNSPEC)
863 return GAIH_OKIFUNSPEC | -EAI_NONAME;
865 else
867 struct gaih_addrtuple *atr;
868 atr = at = __alloca (sizeof (struct gaih_addrtuple));
869 memset (at, '\0', sizeof (struct gaih_addrtuple));
871 if (req->ai_family == AF_UNSPEC)
873 at->next = __alloca (sizeof (struct gaih_addrtuple));
874 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
877 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
879 at->family = AF_INET6;
880 if ((req->ai_flags & AI_PASSIVE) == 0)
881 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
882 atr = at->next;
885 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
887 atr->family = AF_INET;
888 if ((req->ai_flags & AI_PASSIVE) == 0)
889 atr->addr[0] = htonl (INADDR_LOOPBACK);
894 struct gaih_servtuple *st2;
895 struct gaih_addrtuple *at2 = at;
896 size_t socklen;
897 sa_family_t family;
900 buffer is the size of an unformatted IPv6 address in printable format.
902 while (at2 != NULL)
904 /* Only the first entry gets the canonical name. */
905 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
907 if (canon == NULL)
909 struct hostent *h = NULL;
910 int herrno;
911 struct hostent th;
912 size_t tmpbuflen = 512;
913 char *tmpbuf = NULL;
917 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
918 rc = __gethostbyaddr_r (at2->addr,
919 ((at2->family == AF_INET6)
920 ? sizeof (struct in6_addr)
921 : sizeof (struct in_addr)),
922 at2->family, &th, tmpbuf,
923 tmpbuflen, &h, &herrno);
925 while (rc == ERANGE && herrno == NETDB_INTERNAL);
927 if (rc != 0 && herrno == NETDB_INTERNAL)
929 __set_h_errno (herrno);
930 return -EAI_SYSTEM;
933 if (h != NULL)
934 canon = h->h_name;
935 else
937 assert (orig_name != NULL);
938 /* If the canonical name cannot be determined, use
939 the passed in string. */
940 canon = orig_name;
944 #ifdef HAVE_LIBIDN
945 if (req->ai_flags & AI_CANONIDN)
947 int idn_flags = 0;
948 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
949 idn_flags |= IDNA_ALLOW_UNASSIGNED;
950 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
951 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
953 char *out;
954 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
955 if (rc != IDNA_SUCCESS)
957 if (rc == IDNA_MALLOC_ERROR)
958 return -EAI_MEMORY;
959 if (rc == IDNA_DLOPEN_ERROR)
960 return -EAI_SYSTEM;
961 return -EAI_IDN_ENCODE;
963 /* In case the output string is the same as the input
964 string no new string has been allocated and we
965 make a copy. */
966 if (out == canon)
967 goto make_copy;
969 else
970 #endif
972 #ifdef HAVE_LIBIDN
973 make_copy:
974 #endif
975 canon = strdup (canon);
976 if (canon == NULL)
977 return -EAI_MEMORY;
981 family = at2->family;
982 if (family == AF_INET6)
984 socklen = sizeof (struct sockaddr_in6);
986 /* If we looked up IPv4 mapped address discard them here if
987 the caller isn't interested in all address and we have
988 found at least one IPv6 address. */
989 if (got_ipv6
990 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
991 && IN6_IS_ADDR_V4MAPPED (at2->addr))
992 goto ignore;
994 else
995 socklen = sizeof (struct sockaddr_in);
997 for (st2 = st; st2 != NULL; st2 = st2->next)
999 struct addrinfo *ai;
1000 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1001 if (ai == NULL)
1003 free ((char *) canon);
1004 return -EAI_MEMORY;
1007 ai->ai_flags = req->ai_flags;
1008 ai->ai_family = family;
1009 ai->ai_socktype = st2->socktype;
1010 ai->ai_protocol = st2->protocol;
1011 ai->ai_addrlen = socklen;
1012 ai->ai_addr = (void *) (ai + 1);
1014 /* We only add the canonical name once. */
1015 ai->ai_canonname = (char *) canon;
1016 canon = NULL;
1018 #ifdef _HAVE_SA_LEN
1019 ai->ai_addr->sa_len = socklen;
1020 #endif /* _HAVE_SA_LEN */
1021 ai->ai_addr->sa_family = family;
1023 /* In case of an allocation error the list must be NULL
1024 terminated. */
1025 ai->ai_next = NULL;
1027 if (family == AF_INET6)
1029 struct sockaddr_in6 *sin6p =
1030 (struct sockaddr_in6 *) ai->ai_addr;
1032 sin6p->sin6_port = st2->port;
1033 sin6p->sin6_flowinfo = 0;
1034 memcpy (&sin6p->sin6_addr,
1035 at2->addr, sizeof (struct in6_addr));
1036 sin6p->sin6_scope_id = at2->scopeid;
1038 else
1040 struct sockaddr_in *sinp =
1041 (struct sockaddr_in *) ai->ai_addr;
1042 sinp->sin_port = st2->port;
1043 memcpy (&sinp->sin_addr,
1044 at2->addr, sizeof (struct in_addr));
1045 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1048 pai = &(ai->ai_next);
1051 ++*naddrs;
1053 ignore:
1054 at2 = at2->next;
1057 return 0;
1061 struct sort_result
1063 struct addrinfo *dest_addr;
1064 /* Using sockaddr_storage is for now overkill. We only support IPv4
1065 and IPv6 so far. If this changes at some point we can adjust the
1066 type here. */
1067 struct sockaddr_in6 source_addr;
1068 uint8_t source_addr_len;
1069 bool got_source_addr;
1070 uint8_t source_addr_flags;
1071 uint8_t prefixlen;
1072 uint32_t index;
1073 int32_t native;
1076 struct sort_result_combo
1078 struct sort_result *results;
1079 int nresults;
1083 #if __BYTE_ORDER == __BIG_ENDIAN
1084 # define htonl_c(n) n
1085 #else
1086 # define htonl_c(n) __bswap_constant_32 (n)
1087 #endif
1089 static const struct scopeentry
1091 union
1093 char addr[4];
1094 uint32_t addr32;
1096 uint32_t netmask;
1097 int32_t scope;
1098 } default_scopes[] =
1100 /* Link-local addresses: scope 2. */
1101 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1102 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1103 /* Site-local addresses: scope 5. */
1104 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1105 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1106 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1107 /* Default: scope 14. */
1108 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1111 /* The label table. */
1112 static const struct scopeentry *scopes;
1115 static int
1116 get_scope (const struct sockaddr_in6 *in6)
1118 int scope;
1119 if (in6->sin6_family == PF_INET6)
1121 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1123 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1124 /* RFC 4291 2.5.3 says that the loopback address is to be
1125 treated like a link-local address. */
1126 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1127 scope = 2;
1128 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1129 scope = 5;
1130 else
1131 /* XXX Is this the correct default behavior? */
1132 scope = 14;
1134 else
1135 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1137 else if (in6->sin6_family == PF_INET)
1139 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1141 size_t cnt = 0;
1142 while (1)
1144 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1145 == scopes[cnt].addr32)
1146 return scopes[cnt].scope;
1148 ++cnt;
1150 /* NOTREACHED */
1152 else
1153 /* XXX What is a good default? */
1154 scope = 15;
1156 return scope;
1160 struct prefixentry
1162 struct in6_addr prefix;
1163 unsigned int bits;
1164 int val;
1168 /* The label table. */
1169 static const struct prefixentry *labels;
1171 /* Default labels. */
1172 static const struct prefixentry default_labels[] =
1174 /* See RFC 3484 for the details. */
1175 { { .__in6_u
1176 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1178 }, 128, 0 },
1179 { { .__in6_u
1180 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1182 }, 16, 2 },
1183 { { .__in6_u
1184 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1186 }, 96, 3 },
1187 { { .__in6_u
1188 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1189 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1190 }, 96, 4 },
1191 /* The next two entries differ from RFC 3484. We need to treat
1192 IPv6 site-local addresses special because they are never NATed,
1193 unlike site-locale IPv4 addresses. If this would not happen, on
1194 machines which have only IPv4 and IPv6 site-local addresses, the
1195 sorting would prefer the IPv6 site-local addresses, causing
1196 unnecessary delays when trying to connect to a global IPv6 address
1197 through a site-local IPv6 address. */
1198 { { .__in6_u
1199 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1201 }, 10, 5 },
1202 { { .__in6_u
1203 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1205 }, 7, 6 },
1206 /* Additional rule for Teredo tunnels. */
1207 { { .__in6_u
1208 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1210 }, 32, 7 },
1211 { { .__in6_u
1212 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1214 }, 0, 1 }
1218 /* The precedence table. */
1219 static const struct prefixentry *precedence;
1221 /* The default precedences. */
1222 static const struct prefixentry default_precedence[] =
1224 /* See RFC 3484 for the details. */
1225 { { .__in6_u
1226 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1228 }, 128, 50 },
1229 { { .__in6_u
1230 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1232 }, 16, 30 },
1233 { { .__in6_u
1234 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1236 }, 96, 20 },
1237 { { .__in6_u
1238 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1239 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1240 }, 96, 10 },
1241 { { .__in6_u
1242 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1244 }, 0, 40 }
1248 static int
1249 match_prefix (const struct sockaddr_in6 *in6,
1250 const struct prefixentry *list, int default_val)
1252 int idx;
1253 struct sockaddr_in6 in6_mem;
1255 if (in6->sin6_family == PF_INET)
1257 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1259 /* Construct a V4-to-6 mapped address. */
1260 in6_mem.sin6_family = PF_INET6;
1261 in6_mem.sin6_port = in->sin_port;
1262 in6_mem.sin6_flowinfo = 0;
1263 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1264 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1265 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1266 in6_mem.sin6_scope_id = 0;
1268 in6 = &in6_mem;
1270 else if (in6->sin6_family != PF_INET6)
1271 return default_val;
1273 for (idx = 0; ; ++idx)
1275 unsigned int bits = list[idx].bits;
1276 const uint8_t *mask = list[idx].prefix.s6_addr;
1277 const uint8_t *val = in6->sin6_addr.s6_addr;
1279 while (bits >= 8)
1281 if (*mask != *val)
1282 break;
1284 ++mask;
1285 ++val;
1286 bits -= 8;
1289 if (bits < 8)
1291 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1292 /* Match! */
1293 break;
1297 return list[idx].val;
1301 static int
1302 get_label (const struct sockaddr_in6 *in6)
1304 /* XXX What is a good default value? */
1305 return match_prefix (in6, labels, INT_MAX);
1309 static int
1310 get_precedence (const struct sockaddr_in6 *in6)
1312 /* XXX What is a good default value? */
1313 return match_prefix (in6, precedence, 0);
1317 /* Find last bit set in a word. */
1318 static int
1319 fls (uint32_t a)
1321 uint32_t mask;
1322 int n;
1323 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1324 if ((a & mask) != 0)
1325 break;
1326 return n;
1330 static int
1331 rfc3484_sort (const void *p1, const void *p2, void *arg)
1333 const size_t idx1 = *(const size_t *) p1;
1334 const size_t idx2 = *(const size_t *) p2;
1335 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1336 struct sort_result *a1 = &src->results[idx1];
1337 struct sort_result *a2 = &src->results[idx2];
1339 /* Rule 1: Avoid unusable destinations.
1340 We have the got_source_addr flag set if the destination is reachable. */
1341 if (a1->got_source_addr && ! a2->got_source_addr)
1342 return -1;
1343 if (! a1->got_source_addr && a2->got_source_addr)
1344 return 1;
1347 /* Rule 2: Prefer matching scope. Only interesting if both
1348 destination addresses are IPv6. */
1349 int a1_dst_scope
1350 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1352 int a2_dst_scope
1353 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1355 if (a1->got_source_addr)
1357 int a1_src_scope = get_scope (&a1->source_addr);
1358 int a2_src_scope = get_scope (&a2->source_addr);
1360 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1361 return -1;
1362 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1363 return 1;
1367 /* Rule 3: Avoid deprecated addresses. */
1368 if (a1->got_source_addr)
1370 if (!(a1->source_addr_flags & in6ai_deprecated)
1371 && (a2->source_addr_flags & in6ai_deprecated))
1372 return -1;
1373 if ((a1->source_addr_flags & in6ai_deprecated)
1374 && !(a2->source_addr_flags & in6ai_deprecated))
1375 return 1;
1378 /* Rule 4: Prefer home addresses. */
1379 if (a1->got_source_addr)
1381 if (!(a1->source_addr_flags & in6ai_homeaddress)
1382 && (a2->source_addr_flags & in6ai_homeaddress))
1383 return 1;
1384 if ((a1->source_addr_flags & in6ai_homeaddress)
1385 && !(a2->source_addr_flags & in6ai_homeaddress))
1386 return -1;
1389 /* Rule 5: Prefer matching label. */
1390 if (a1->got_source_addr)
1392 int a1_dst_label
1393 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1394 int a1_src_label = get_label (&a1->source_addr);
1396 int a2_dst_label
1397 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1398 int a2_src_label = get_label (&a2->source_addr);
1400 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1401 return -1;
1402 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1403 return 1;
1407 /* Rule 6: Prefer higher precedence. */
1408 int a1_prec
1409 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1410 int a2_prec
1411 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1413 if (a1_prec > a2_prec)
1414 return -1;
1415 if (a1_prec < a2_prec)
1416 return 1;
1419 /* Rule 7: Prefer native transport. */
1420 if (a1->got_source_addr)
1422 /* The same interface index means the same interface which means
1423 there is no difference in transport. This should catch many
1424 (most?) cases. */
1425 if (a1->index != a2->index)
1427 int a1_native = a1->native;
1428 int a2_native = a2->native;
1430 if (a1_native == -1 || a2_native == -1)
1432 uint32_t a1_index;
1433 if (a1_native == -1)
1435 /* If we do not have the information use 'native' as
1436 the default. */
1437 a1_native = 0;
1438 a1_index = a1->index;
1440 else
1441 a1_index = 0xffffffffu;
1443 uint32_t a2_index;
1444 if (a2_native == -1)
1446 /* If we do not have the information use 'native' as
1447 the default. */
1448 a2_native = 0;
1449 a2_index = a2->index;
1451 else
1452 a2_index = 0xffffffffu;
1454 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1456 /* Fill in the results in all the records. */
1457 for (int i = 0; i < src->nresults; ++i)
1458 if (src->results[i].index == a1_index)
1460 assert (src->results[i].native == -1
1461 || src->results[i].native == a1_native);
1462 src->results[i].native = a1_native;
1464 else if (src->results[i].index == a2_index)
1466 assert (src->results[i].native == -1
1467 || src->results[i].native == a2_native);
1468 src->results[i].native = a2_native;
1472 if (a1_native && !a2_native)
1473 return -1;
1474 if (!a1_native && a2_native)
1475 return 1;
1480 /* Rule 8: Prefer smaller scope. */
1481 if (a1_dst_scope < a2_dst_scope)
1482 return -1;
1483 if (a1_dst_scope > a2_dst_scope)
1484 return 1;
1487 /* Rule 9: Use longest matching prefix. */
1488 if (a1->got_source_addr
1489 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1491 int bit1 = 0;
1492 int bit2 = 0;
1494 if (a1->dest_addr->ai_family == PF_INET)
1496 assert (a1->source_addr.sin6_family == PF_INET);
1497 assert (a2->source_addr.sin6_family == PF_INET);
1499 /* Outside of subnets, as defined by the network masks,
1500 common address prefixes for IPv4 addresses make no sense.
1501 So, define a non-zero value only if source and
1502 destination address are on the same subnet. */
1503 struct sockaddr_in *in1_dst
1504 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1505 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1506 struct sockaddr_in *in1_src
1507 = (struct sockaddr_in *) &a1->source_addr;
1508 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1509 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1511 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1512 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1514 struct sockaddr_in *in2_dst
1515 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1516 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1517 struct sockaddr_in *in2_src
1518 = (struct sockaddr_in *) &a2->source_addr;
1519 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1520 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1522 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1523 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1525 else if (a1->dest_addr->ai_family == PF_INET6)
1527 assert (a1->source_addr.sin6_family == PF_INET6);
1528 assert (a2->source_addr.sin6_family == PF_INET6);
1530 struct sockaddr_in6 *in1_dst;
1531 struct sockaddr_in6 *in1_src;
1532 struct sockaddr_in6 *in2_dst;
1533 struct sockaddr_in6 *in2_src;
1535 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1536 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1537 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1538 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1540 int i;
1541 for (i = 0; i < 4; ++i)
1542 if (in1_dst->sin6_addr.s6_addr32[i]
1543 != in1_src->sin6_addr.s6_addr32[i]
1544 || (in2_dst->sin6_addr.s6_addr32[i]
1545 != in2_src->sin6_addr.s6_addr32[i]))
1546 break;
1548 if (i < 4)
1550 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1551 ^ in1_src->sin6_addr.s6_addr32[i]));
1552 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1553 ^ in2_src->sin6_addr.s6_addr32[i]));
1557 if (bit1 > bit2)
1558 return -1;
1559 if (bit1 < bit2)
1560 return 1;
1564 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1565 compare with the value indicating the order in which the entries
1566 have been received from the services. NB: no two entries can have
1567 the same order so the test will never return zero. */
1568 return idx1 < idx2 ? -1 : 1;
1572 static int
1573 in6aicmp (const void *p1, const void *p2)
1575 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1576 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1578 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1582 /* Name of the config file for RFC 3484 sorting (for now). */
1583 #define GAICONF_FNAME "/etc/gai.conf"
1586 /* Non-zero if we are supposed to reload the config file automatically
1587 whenever it changed. */
1588 static int gaiconf_reload_flag;
1590 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1591 static int gaiconf_reload_flag_ever_set;
1593 /* Last modification time. */
1594 static struct timespec gaiconf_mtime;
1597 libc_freeres_fn(fini)
1599 if (labels != default_labels)
1601 const struct prefixentry *old = labels;
1602 labels = default_labels;
1603 free ((void *) old);
1606 if (precedence != default_precedence)
1608 const struct prefixentry *old = precedence;
1609 precedence = default_precedence;
1610 free ((void *) old);
1613 if (scopes != default_scopes)
1615 const struct scopeentry *old = scopes;
1616 scopes = default_scopes;
1617 free ((void *) old);
1622 struct prefixlist
1624 struct prefixentry entry;
1625 struct prefixlist *next;
1629 struct scopelist
1631 struct scopeentry entry;
1632 struct scopelist *next;
1636 static void
1637 free_prefixlist (struct prefixlist *list)
1639 while (list != NULL)
1641 struct prefixlist *oldp = list;
1642 list = list->next;
1643 free (oldp);
1648 static void
1649 free_scopelist (struct scopelist *list)
1651 while (list != NULL)
1653 struct scopelist *oldp = list;
1654 list = list->next;
1655 free (oldp);
1660 static int
1661 prefixcmp (const void *p1, const void *p2)
1663 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1664 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1666 if (e1->bits < e2->bits)
1667 return 1;
1668 if (e1->bits == e2->bits)
1669 return 0;
1670 return -1;
1674 static int
1675 scopecmp (const void *p1, const void *p2)
1677 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1678 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1680 if (e1->netmask > e2->netmask)
1681 return -1;
1682 if (e1->netmask == e2->netmask)
1683 return 0;
1684 return 1;
1688 static void
1689 gaiconf_init (void)
1691 struct prefixlist *labellist = NULL;
1692 size_t nlabellist = 0;
1693 bool labellist_nullbits = false;
1694 struct prefixlist *precedencelist = NULL;
1695 size_t nprecedencelist = 0;
1696 bool precedencelist_nullbits = false;
1697 struct scopelist *scopelist = NULL;
1698 size_t nscopelist = 0;
1699 bool scopelist_nullbits = false;
1701 FILE *fp = fopen (GAICONF_FNAME, "rc");
1702 if (fp != NULL)
1704 struct stat64 st;
1705 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1707 fclose (fp);
1708 goto no_file;
1711 char *line = NULL;
1712 size_t linelen = 0;
1714 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1716 while (!feof_unlocked (fp))
1718 ssize_t n = __getline (&line, &linelen, fp);
1719 if (n <= 0)
1720 break;
1722 /* Handle comments. No escaping possible so this is easy. */
1723 char *cp = strchr (line, '#');
1724 if (cp != NULL)
1725 *cp = '\0';
1727 cp = line;
1728 while (isspace (*cp))
1729 ++cp;
1731 char *cmd = cp;
1732 while (*cp != '\0' && !isspace (*cp))
1733 ++cp;
1734 size_t cmdlen = cp - cmd;
1736 if (*cp != '\0')
1737 *cp++ = '\0';
1738 while (isspace (*cp))
1739 ++cp;
1741 char *val1 = cp;
1742 while (*cp != '\0' && !isspace (*cp))
1743 ++cp;
1744 size_t val1len = cp - cmd;
1746 /* We always need at least two values. */
1747 if (val1len == 0)
1748 continue;
1750 if (*cp != '\0')
1751 *cp++ = '\0';
1752 while (isspace (*cp))
1753 ++cp;
1755 char *val2 = cp;
1756 while (*cp != '\0' && !isspace (*cp))
1757 ++cp;
1759 /* Ignore the rest of the line. */
1760 *cp = '\0';
1762 struct prefixlist **listp;
1763 size_t *lenp;
1764 bool *nullbitsp;
1765 switch (cmdlen)
1767 case 5:
1768 if (strcmp (cmd, "label") == 0)
1770 struct in6_addr prefix;
1771 unsigned long int bits;
1772 unsigned long int val;
1773 char *endp;
1775 listp = &labellist;
1776 lenp = &nlabellist;
1777 nullbitsp = &labellist_nullbits;
1779 new_elem:
1780 bits = 128;
1781 __set_errno (0);
1782 cp = strchr (val1, '/');
1783 if (cp != NULL)
1784 *cp++ = '\0';
1785 if (inet_pton (AF_INET6, val1, &prefix)
1786 && (cp == NULL
1787 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1788 || errno != ERANGE)
1789 && *endp == '\0'
1790 && bits <= 128
1791 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1792 || errno != ERANGE)
1793 && *endp == '\0'
1794 && val <= INT_MAX)
1796 struct prefixlist *newp = malloc (sizeof (*newp));
1797 if (newp == NULL)
1799 free (line);
1800 fclose (fp);
1801 goto no_file;
1804 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1805 newp->entry.bits = bits;
1806 newp->entry.val = val;
1807 newp->next = *listp;
1808 *listp = newp;
1809 ++*lenp;
1810 *nullbitsp |= bits == 0;
1813 break;
1815 case 6:
1816 if (strcmp (cmd, "reload") == 0)
1818 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1819 if (gaiconf_reload_flag)
1820 gaiconf_reload_flag_ever_set = 1;
1822 break;
1824 case 7:
1825 if (strcmp (cmd, "scopev4") == 0)
1827 struct in6_addr prefix;
1828 unsigned long int bits;
1829 unsigned long int val;
1830 char *endp;
1832 bits = 32;
1833 __set_errno (0);
1834 cp = strchr (val1, '/');
1835 if (cp != NULL)
1836 *cp++ = '\0';
1837 if (inet_pton (AF_INET6, val1, &prefix))
1839 bits = 128;
1840 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1841 && (cp == NULL
1842 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1843 || errno != ERANGE)
1844 && *endp == '\0'
1845 && bits >= 96
1846 && bits <= 128
1847 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1848 || errno != ERANGE)
1849 && *endp == '\0'
1850 && val <= INT_MAX)
1852 struct scopelist *newp;
1853 new_scope:
1854 newp = malloc (sizeof (*newp));
1855 if (newp == NULL)
1857 free (line);
1858 fclose (fp);
1859 goto no_file;
1862 newp->entry.netmask = htonl (bits != 96
1863 ? (0xffffffff
1864 << (128 - bits))
1865 : 0);
1866 newp->entry.addr32 = (prefix.s6_addr32[3]
1867 & newp->entry.netmask);
1868 newp->entry.scope = val;
1869 newp->next = scopelist;
1870 scopelist = newp;
1871 ++nscopelist;
1872 scopelist_nullbits |= bits == 96;
1875 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1876 && (cp == NULL
1877 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1878 || errno != ERANGE)
1879 && *endp == '\0'
1880 && bits <= 32
1881 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1882 || errno != ERANGE)
1883 && *endp == '\0'
1884 && val <= INT_MAX)
1886 bits += 96;
1887 goto new_scope;
1890 break;
1892 case 10:
1893 if (strcmp (cmd, "precedence") == 0)
1895 listp = &precedencelist;
1896 lenp = &nprecedencelist;
1897 nullbitsp = &precedencelist_nullbits;
1898 goto new_elem;
1900 break;
1904 free (line);
1906 fclose (fp);
1908 /* Create the array for the labels. */
1909 struct prefixentry *new_labels;
1910 if (nlabellist > 0)
1912 if (!labellist_nullbits)
1913 ++nlabellist;
1914 new_labels = malloc (nlabellist * sizeof (*new_labels));
1915 if (new_labels == NULL)
1916 goto no_file;
1918 int i = nlabellist;
1919 if (!labellist_nullbits)
1921 --i;
1922 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1923 new_labels[i].bits = 0;
1924 new_labels[i].val = 1;
1927 struct prefixlist *l = labellist;
1928 while (i-- > 0)
1930 new_labels[i] = l->entry;
1931 l = l->next;
1933 free_prefixlist (labellist);
1935 /* Sort the entries so that the most specific ones are at
1936 the beginning. */
1937 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1939 else
1940 new_labels = (struct prefixentry *) default_labels;
1942 struct prefixentry *new_precedence;
1943 if (nprecedencelist > 0)
1945 if (!precedencelist_nullbits)
1946 ++nprecedencelist;
1947 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1948 if (new_precedence == NULL)
1950 if (new_labels != default_labels)
1951 free (new_labels);
1952 goto no_file;
1955 int i = nprecedencelist;
1956 if (!precedencelist_nullbits)
1958 --i;
1959 memset (&new_precedence[i].prefix, '\0',
1960 sizeof (struct in6_addr));
1961 new_precedence[i].bits = 0;
1962 new_precedence[i].val = 40;
1965 struct prefixlist *l = precedencelist;
1966 while (i-- > 0)
1968 new_precedence[i] = l->entry;
1969 l = l->next;
1971 free_prefixlist (precedencelist);
1973 /* Sort the entries so that the most specific ones are at
1974 the beginning. */
1975 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1976 prefixcmp);
1978 else
1979 new_precedence = (struct prefixentry *) default_precedence;
1981 struct scopeentry *new_scopes;
1982 if (nscopelist > 0)
1984 if (!scopelist_nullbits)
1985 ++nscopelist;
1986 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1987 if (new_scopes == NULL)
1989 if (new_labels != default_labels)
1990 free (new_labels);
1991 if (new_precedence != default_precedence)
1992 free (new_precedence);
1993 goto no_file;
1996 int i = nscopelist;
1997 if (!scopelist_nullbits)
1999 --i;
2000 new_scopes[i].addr32 = 0;
2001 new_scopes[i].netmask = 0;
2002 new_scopes[i].scope = 14;
2005 struct scopelist *l = scopelist;
2006 while (i-- > 0)
2008 new_scopes[i] = l->entry;
2009 l = l->next;
2011 free_scopelist (scopelist);
2013 /* Sort the entries so that the most specific ones are at
2014 the beginning. */
2015 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2016 scopecmp);
2018 else
2019 new_scopes = (struct scopeentry *) default_scopes;
2021 /* Now we are ready to replace the values. */
2022 const struct prefixentry *old = labels;
2023 labels = new_labels;
2024 if (old != default_labels)
2025 free ((void *) old);
2027 old = precedence;
2028 precedence = new_precedence;
2029 if (old != default_precedence)
2030 free ((void *) old);
2032 const struct scopeentry *oldscope = scopes;
2033 scopes = new_scopes;
2034 if (oldscope != default_scopes)
2035 free ((void *) oldscope);
2037 gaiconf_mtime = st.st_mtim;
2039 else
2041 no_file:
2042 free_prefixlist (labellist);
2043 free_prefixlist (precedencelist);
2044 free_scopelist (scopelist);
2046 /* If we previously read the file but it is gone now, free the
2047 old data and use the builtin one. Leave the reload flag
2048 alone. */
2049 fini ();
2054 static void
2055 gaiconf_reload (void)
2057 struct stat64 st;
2058 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2059 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2060 gaiconf_init ();
2065 getaddrinfo (const char *name, const char *service,
2066 const struct addrinfo *hints, struct addrinfo **pai)
2068 int i = 0, last_i = 0;
2069 int nresults = 0;
2070 struct addrinfo *p = NULL;
2071 struct gaih_service gaih_service, *pservice;
2072 struct addrinfo local_hints;
2074 if (name != NULL && name[0] == '*' && name[1] == 0)
2075 name = NULL;
2077 if (service != NULL && service[0] == '*' && service[1] == 0)
2078 service = NULL;
2080 if (name == NULL && service == NULL)
2081 return EAI_NONAME;
2083 if (hints == NULL)
2084 hints = &default_hints;
2086 if (hints->ai_flags
2087 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2088 #ifdef HAVE_LIBIDN
2089 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2090 |AI_IDN_USE_STD3_ASCII_RULES
2091 #endif
2092 |AI_NUMERICSERV|AI_ALL))
2093 return EAI_BADFLAGS;
2095 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2096 return EAI_BADFLAGS;
2098 struct in6addrinfo *in6ai = NULL;
2099 size_t in6ailen = 0;
2100 bool seen_ipv4 = false;
2101 bool seen_ipv6 = false;
2102 /* We might need information about what interfaces are available.
2103 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2104 cannot cache the results since new interfaces could be added at
2105 any time. */
2106 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2108 if (hints->ai_flags & AI_ADDRCONFIG)
2110 /* Now make a decision on what we return, if anything. */
2111 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2113 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2114 narrow down the search. */
2115 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2117 local_hints = *hints;
2118 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2119 hints = &local_hints;
2122 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2123 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2125 /* We cannot possibly return a valid answer. */
2126 free (in6ai);
2127 return EAI_NONAME;
2131 if (service && service[0])
2133 char *c;
2134 gaih_service.name = service;
2135 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2136 if (*c != '\0')
2138 if (hints->ai_flags & AI_NUMERICSERV)
2140 free (in6ai);
2141 return EAI_NONAME;
2144 gaih_service.num = -1;
2147 pservice = &gaih_service;
2149 else
2150 pservice = NULL;
2152 struct addrinfo **end = &p;
2154 unsigned int naddrs = 0;
2155 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2156 || hints->ai_family == AF_INET6)
2158 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2159 if (last_i != 0)
2161 freeaddrinfo (p);
2162 free (in6ai);
2164 return -(last_i & GAIH_EAI);
2166 while (*end)
2168 end = &((*end)->ai_next);
2169 ++nresults;
2172 else
2174 free (in6ai);
2175 return EAI_FAMILY;
2178 if (naddrs > 1)
2180 /* Read the config file. */
2181 __libc_once_define (static, once);
2182 __typeof (once) old_once = once;
2183 __libc_once (once, gaiconf_init);
2184 /* Sort results according to RFC 3484. */
2185 struct sort_result results[nresults];
2186 size_t order[nresults];
2187 struct addrinfo *q;
2188 struct addrinfo *last = NULL;
2189 char *canonname = NULL;
2191 /* If we have information about deprecated and temporary addresses
2192 sort the array now. */
2193 if (in6ai != NULL)
2194 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2196 int fd = -1;
2197 int af = AF_UNSPEC;
2199 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2201 results[i].dest_addr = q;
2202 results[i].native = -1;
2203 order[i] = i;
2205 /* If we just looked up the address for a different
2206 protocol, reuse the result. */
2207 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2208 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2210 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2211 results[i - 1].source_addr_len);
2212 results[i].source_addr_len = results[i - 1].source_addr_len;
2213 results[i].got_source_addr = results[i - 1].got_source_addr;
2214 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2215 results[i].prefixlen = results[i - 1].prefixlen;
2216 results[i].index = results[i - 1].index;
2218 else
2220 results[i].got_source_addr = false;
2221 results[i].source_addr_flags = 0;
2222 results[i].prefixlen = 0;
2223 results[i].index = 0xffffffffu;
2225 /* We overwrite the type with SOCK_DGRAM since we do not
2226 want connect() to connect to the other side. If we
2227 cannot determine the source address remember this
2228 fact. */
2229 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2231 if (fd != -1)
2232 close_retry:
2233 close_not_cancel_no_status (fd);
2234 af = q->ai_family;
2235 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2237 else
2239 /* Reset the connection. */
2240 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2241 __connect (fd, &sa, sizeof (sa));
2244 socklen_t sl = sizeof (results[i].source_addr);
2245 if (fd != -1
2246 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2247 && __getsockname (fd,
2248 (struct sockaddr *) &results[i].source_addr,
2249 &sl) == 0)
2251 results[i].source_addr_len = sl;
2252 results[i].got_source_addr = true;
2254 if (in6ai != NULL)
2256 /* See whether the source address is on the list of
2257 deprecated or temporary addresses. */
2258 struct in6addrinfo tmp;
2260 if (q->ai_family == AF_INET && af == AF_INET)
2262 struct sockaddr_in *sinp
2263 = (struct sockaddr_in *) &results[i].source_addr;
2264 tmp.addr[0] = 0;
2265 tmp.addr[1] = 0;
2266 tmp.addr[2] = htonl (0xffff);
2267 tmp.addr[3] = sinp->sin_addr.s_addr;
2269 else
2271 struct sockaddr_in6 *sin6p
2272 = (struct sockaddr_in6 *) &results[i].source_addr;
2273 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2276 struct in6addrinfo *found
2277 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2278 in6aicmp);
2279 if (found != NULL)
2281 results[i].source_addr_flags = found->flags;
2282 results[i].prefixlen = found->prefixlen;
2283 results[i].index = found->index;
2287 if (q->ai_family == AF_INET && af == AF_INET6)
2289 /* We have to convert the address. The socket is
2290 IPv6 and the request is for IPv4. */
2291 struct sockaddr_in6 *sin6
2292 = (struct sockaddr_in6 *) &results[i].source_addr;
2293 struct sockaddr_in *sin
2294 = (struct sockaddr_in *) &results[i].source_addr;
2295 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2296 sin->sin_family = AF_INET;
2297 /* We do not have to initialize sin_port since this
2298 fields has the same position and size in the IPv6
2299 structure. */
2300 assert (offsetof (struct sockaddr_in, sin_port)
2301 == offsetof (struct sockaddr_in6, sin6_port));
2302 assert (sizeof (sin->sin_port)
2303 == sizeof (sin6->sin6_port));
2304 memcpy (&sin->sin_addr,
2305 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2306 results[i].source_addr_len = sizeof (struct sockaddr_in);
2309 else if (errno == EAFNOSUPPORT && af == AF_INET6
2310 && q->ai_family == AF_INET)
2311 /* This could mean IPv6 sockets are IPv6-only. */
2312 goto close_retry;
2313 else
2314 /* Just make sure that if we have to process the same
2315 address again we do not copy any memory. */
2316 results[i].source_addr_len = 0;
2319 /* Remember the canonical name. */
2320 if (q->ai_canonname != NULL)
2322 assert (canonname == NULL);
2323 canonname = q->ai_canonname;
2324 q->ai_canonname = NULL;
2328 if (fd != -1)
2329 close_not_cancel_no_status (fd);
2331 /* We got all the source addresses we can get, now sort using
2332 the information. */
2333 struct sort_result_combo src
2334 = { .results = results, .nresults = nresults };
2335 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2337 __libc_lock_define_initialized (static, lock);
2339 __libc_lock_lock (lock);
2340 if (old_once && gaiconf_reload_flag)
2341 gaiconf_reload ();
2342 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2343 __libc_lock_unlock (lock);
2345 else
2346 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2348 /* Queue the results up as they come out of sorting. */
2349 q = p = results[order[0]].dest_addr;
2350 for (i = 1; i < nresults; ++i)
2351 q = q->ai_next = results[order[i]].dest_addr;
2352 q->ai_next = NULL;
2354 /* Fill in the canonical name into the new first entry. */
2355 p->ai_canonname = canonname;
2358 free (in6ai);
2360 if (p)
2362 *pai = p;
2363 return 0;
2366 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2368 libc_hidden_def (getaddrinfo)
2370 static_link_warning (getaddrinfo)
2372 void
2373 freeaddrinfo (struct addrinfo *ai)
2375 struct addrinfo *p;
2377 while (ai != NULL)
2379 p = ai;
2380 ai = ai->ai_next;
2381 free (p->ai_canonname);
2382 free (p);
2385 libc_hidden_def (freeaddrinfo)