Updated to fedora-glibc-20080515T0735
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob8908fc10c3a87464f9f7f3ae2bc6d55aa00562cd
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 && __nss_not_use_nscd_hosts == 0)
665 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
666 return -EAI_MEMORY;
667 if (herrno == TRY_AGAIN)
668 return -EAI_AGAIN;
669 return -EAI_SYSTEM;
672 #endif
674 if (__nss_hosts_database != NULL)
676 no_more = 0;
677 nip = __nss_hosts_database;
679 else
680 no_more = __nss_database_lookup ("hosts", NULL,
681 "dns [!UNAVAIL=return] files",
682 &nip);
684 if (__res_maybe_init (&_res, 0) == -1)
685 no_more = 1;
687 /* If we are looking for both IPv4 and IPv6 address we don't
688 want the lookup functions to automatically promote IPv4
689 addresses to IPv6 addresses. Currently this is decided
690 by setting the RES_USE_INET6 bit in _res.options. */
691 old_res_options = _res.options;
692 _res.options &= ~RES_USE_INET6;
694 size_t tmpbuflen = 512;
695 char *tmpbuf = alloca (tmpbuflen);
697 while (!no_more)
699 nss_gethostbyname4_r fct4
700 = __nss_lookup_function (nip, "gethostbyname4_r");
701 if (fct4 != NULL)
703 int herrno;
705 while (1)
707 rc = 0;
708 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
709 tmpbuflen, &rc, &herrno,
710 NULL));
711 if (status != NSS_STATUS_TRYAGAIN
712 || rc != ERANGE || herrno != NETDB_INTERNAL)
714 if (herrno == NETDB_INTERNAL)
716 __set_h_errno (herrno);
717 _res.options = old_res_options;
718 return -EAI_SYSTEM;
720 if (herrno == TRY_AGAIN)
721 no_data = EAI_AGAIN;
722 else
723 no_data = herrno == NO_DATA;
724 break;
726 tmpbuf = extend_alloca (tmpbuf,
727 tmpbuflen, 2 * tmpbuflen);
730 if (status == NSS_STATUS_SUCCESS)
732 canon = (*pat)->name;
734 while (*pat != NULL)
735 pat = &((*pat)->next);
738 else
740 nss_gethostbyname3_r fct = NULL;
741 if (req->ai_flags & AI_CANONNAME)
742 /* No need to use this function if we do not look for
743 the canonical name. The function does not exist in
744 all NSS modules and therefore the lookup would
745 often fail. */
746 fct = __nss_lookup_function (nip, "gethostbyname3_r");
747 if (fct == NULL)
748 /* We are cheating here. The gethostbyname2_r
749 function does not have the same interface as
750 gethostbyname3_r but the extra arguments the
751 latter takes are added at the end. So the
752 gethostbyname2_r code will just ignore them. */
753 fct = __nss_lookup_function (nip, "gethostbyname2_r");
755 if (fct != NULL)
757 if (req->ai_family == AF_INET6
758 || req->ai_family == AF_UNSPEC)
760 gethosts (AF_INET6, struct in6_addr);
761 no_inet6_data = no_data;
762 inet6_status = status;
764 if (req->ai_family == AF_INET
765 || req->ai_family == AF_UNSPEC
766 || (req->ai_family == AF_INET6
767 && (req->ai_flags & AI_V4MAPPED)
768 /* Avoid generating the mapped addresses if we
769 know we are not going to need them. */
770 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
772 gethosts (AF_INET, struct in_addr);
774 if (req->ai_family == AF_INET)
776 no_inet6_data = no_data;
777 inet6_status = status;
781 /* If we found one address for AF_INET or AF_INET6,
782 don't continue the search. */
783 if (inet6_status == NSS_STATUS_SUCCESS
784 || status == NSS_STATUS_SUCCESS)
786 if ((req->ai_flags & AI_CANONNAME) != 0
787 && canon == NULL)
789 /* If we need the canonical name, get it
790 from the same service as the result. */
791 nss_getcanonname_r cfct;
792 int herrno;
794 cfct = __nss_lookup_function (nip,
795 "getcanonname_r");
796 if (cfct != NULL)
798 const size_t max_fqdn_len = 256;
799 char *buf = alloca (max_fqdn_len);
800 char *s;
802 if (DL_CALL_FCT (cfct, (at->name ?: name,
803 buf, max_fqdn_len,
804 &s, &rc, &herrno))
805 == NSS_STATUS_SUCCESS)
806 canon = s;
807 else
808 /* Set to name now to avoid using
809 gethostbyaddr. */
810 canon = name;
814 break;
817 /* We can have different states for AF_INET and
818 AF_INET6. Try to find a useful one for both. */
819 if (inet6_status == NSS_STATUS_TRYAGAIN)
820 status = NSS_STATUS_TRYAGAIN;
821 else if (status == NSS_STATUS_UNAVAIL
822 && inet6_status != NSS_STATUS_UNAVAIL)
823 status = inet6_status;
827 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
828 break;
830 if (nip->next == NULL)
831 no_more = -1;
832 else
833 nip = nip->next;
836 _res.options = old_res_options;
838 if (no_data != 0 && no_inet6_data != 0)
840 /* If both requests timed out report this. */
841 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
842 return -EAI_AGAIN;
844 /* We made requests but they turned out no data. The name
845 is known, though. */
846 return GAIH_OKIFUNSPEC | -EAI_NODATA;
850 process_list:
851 if (at->family == AF_UNSPEC)
852 return GAIH_OKIFUNSPEC | -EAI_NONAME;
854 else
856 struct gaih_addrtuple *atr;
857 atr = at = __alloca (sizeof (struct gaih_addrtuple));
858 memset (at, '\0', sizeof (struct gaih_addrtuple));
860 if (req->ai_family == AF_UNSPEC)
862 at->next = __alloca (sizeof (struct gaih_addrtuple));
863 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
866 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
868 at->family = AF_INET6;
869 if ((req->ai_flags & AI_PASSIVE) == 0)
870 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
871 atr = at->next;
874 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
876 atr->family = AF_INET;
877 if ((req->ai_flags & AI_PASSIVE) == 0)
878 atr->addr[0] = htonl (INADDR_LOOPBACK);
882 if (pai == NULL)
883 return 0;
886 struct gaih_servtuple *st2;
887 struct gaih_addrtuple *at2 = at;
888 size_t socklen;
889 sa_family_t family;
892 buffer is the size of an unformatted IPv6 address in printable format.
894 while (at2 != NULL)
896 /* Only the first entry gets the canonical name. */
897 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
899 if (canon == NULL)
901 struct hostent *h = NULL;
902 int herrno;
903 struct hostent th;
904 size_t tmpbuflen = 512;
905 char *tmpbuf = NULL;
909 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
910 rc = __gethostbyaddr_r (at2->addr,
911 ((at2->family == AF_INET6)
912 ? sizeof (struct in6_addr)
913 : sizeof (struct in_addr)),
914 at2->family, &th, tmpbuf,
915 tmpbuflen, &h, &herrno);
917 while (rc == ERANGE && herrno == NETDB_INTERNAL);
919 if (rc != 0 && herrno == NETDB_INTERNAL)
921 __set_h_errno (herrno);
922 return -EAI_SYSTEM;
925 if (h != NULL)
926 canon = h->h_name;
927 else
929 assert (orig_name != NULL);
930 /* If the canonical name cannot be determined, use
931 the passed in string. */
932 canon = orig_name;
936 #ifdef HAVE_LIBIDN
937 if (req->ai_flags & AI_CANONIDN)
939 int idn_flags = 0;
940 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
941 idn_flags |= IDNA_ALLOW_UNASSIGNED;
942 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
943 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
945 char *out;
946 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
947 if (rc != IDNA_SUCCESS)
949 if (rc == IDNA_MALLOC_ERROR)
950 return -EAI_MEMORY;
951 if (rc == IDNA_DLOPEN_ERROR)
952 return -EAI_SYSTEM;
953 return -EAI_IDN_ENCODE;
955 /* In case the output string is the same as the input
956 string no new string has been allocated. Otherwise
957 make a copy. */
958 if (out == canon)
959 goto make_copy;
961 else
962 #endif
964 #ifdef HAVE_LIBIDN
965 make_copy:
966 #endif
967 canon = strdup (canon);
968 if (canon == NULL)
969 return -EAI_MEMORY;
973 family = at2->family;
974 if (family == AF_INET6)
976 socklen = sizeof (struct sockaddr_in6);
978 /* If we looked up IPv4 mapped address discard them here if
979 the caller isn't interested in all address and we have
980 found at least one IPv6 address. */
981 if (got_ipv6
982 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
983 && IN6_IS_ADDR_V4MAPPED (at2->addr))
984 goto ignore;
986 else
987 socklen = sizeof (struct sockaddr_in);
989 for (st2 = st; st2 != NULL; st2 = st2->next)
991 struct addrinfo *ai;
992 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
993 if (ai == NULL)
995 free ((char *) canon);
996 return -EAI_MEMORY;
999 ai->ai_flags = req->ai_flags;
1000 ai->ai_family = family;
1001 ai->ai_socktype = st2->socktype;
1002 ai->ai_protocol = st2->protocol;
1003 ai->ai_addrlen = socklen;
1004 ai->ai_addr = (void *) (ai + 1);
1006 /* We only add the canonical name once. */
1007 ai->ai_canonname = (char *) canon;
1008 canon = NULL;
1010 #ifdef _HAVE_SA_LEN
1011 ai->ai_addr->sa_len = socklen;
1012 #endif /* _HAVE_SA_LEN */
1013 ai->ai_addr->sa_family = family;
1015 /* In case of an allocation error the list must be NULL
1016 terminated. */
1017 ai->ai_next = NULL;
1019 if (family == AF_INET6)
1021 struct sockaddr_in6 *sin6p =
1022 (struct sockaddr_in6 *) ai->ai_addr;
1024 sin6p->sin6_port = st2->port;
1025 sin6p->sin6_flowinfo = 0;
1026 memcpy (&sin6p->sin6_addr,
1027 at2->addr, sizeof (struct in6_addr));
1028 sin6p->sin6_scope_id = at2->scopeid;
1030 else
1032 struct sockaddr_in *sinp =
1033 (struct sockaddr_in *) ai->ai_addr;
1034 sinp->sin_port = st2->port;
1035 memcpy (&sinp->sin_addr,
1036 at2->addr, sizeof (struct in_addr));
1037 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1040 pai = &(ai->ai_next);
1043 ++*naddrs;
1045 ignore:
1046 at2 = at2->next;
1049 return 0;
1053 struct sort_result
1055 struct addrinfo *dest_addr;
1056 /* Using sockaddr_storage is for now overkill. We only support IPv4
1057 and IPv6 so far. If this changes at some point we can adjust the
1058 type here. */
1059 struct sockaddr_in6 source_addr;
1060 uint8_t source_addr_len;
1061 bool got_source_addr;
1062 uint8_t source_addr_flags;
1063 uint8_t prefixlen;
1064 uint32_t index;
1065 int32_t native;
1068 struct sort_result_combo
1070 struct sort_result *results;
1071 int nresults;
1075 #if __BYTE_ORDER == __BIG_ENDIAN
1076 # define htonl_c(n) n
1077 #else
1078 # define htonl_c(n) __bswap_constant_32 (n)
1079 #endif
1081 static const struct scopeentry
1083 union
1085 char addr[4];
1086 uint32_t addr32;
1088 uint32_t netmask;
1089 int32_t scope;
1090 } default_scopes[] =
1092 /* Link-local addresses: scope 2. */
1093 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1094 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1095 /* Site-local addresses: scope 5. */
1096 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1097 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1098 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1099 /* Default: scope 14. */
1100 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1103 /* The label table. */
1104 static const struct scopeentry *scopes;
1107 static int
1108 get_scope (const struct sockaddr_in6 *in6)
1110 int scope;
1111 if (in6->sin6_family == PF_INET6)
1113 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1115 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1116 /* RFC 4291 2.5.3 says that the loopback address is to be
1117 treated like a link-local address. */
1118 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1119 scope = 2;
1120 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1121 scope = 5;
1122 else
1123 /* XXX Is this the correct default behavior? */
1124 scope = 14;
1126 else
1127 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1129 else if (in6->sin6_family == PF_INET)
1131 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1133 size_t cnt = 0;
1134 while (1)
1136 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1137 == scopes[cnt].addr32)
1138 return scopes[cnt].scope;
1140 ++cnt;
1142 /* NOTREACHED */
1144 else
1145 /* XXX What is a good default? */
1146 scope = 15;
1148 return scope;
1152 struct prefixentry
1154 struct in6_addr prefix;
1155 unsigned int bits;
1156 int val;
1160 /* The label table. */
1161 static const struct prefixentry *labels;
1163 /* Default labels. */
1164 static const struct prefixentry default_labels[] =
1166 /* See RFC 3484 for the details. */
1167 { { .__in6_u
1168 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1170 }, 128, 0 },
1171 { { .__in6_u
1172 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1174 }, 16, 2 },
1175 { { .__in6_u
1176 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1178 }, 96, 3 },
1179 { { .__in6_u
1180 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1182 }, 96, 4 },
1183 /* The next two entries differ from RFC 3484. We need to treat
1184 IPv6 site-local addresses special because they are never NATed,
1185 unlike site-locale IPv4 addresses. If this would not happen, on
1186 machines which have only IPv4 and IPv6 site-local addresses, the
1187 sorting would prefer the IPv6 site-local addresses, causing
1188 unnecessary delays when trying to connect to a global IPv6 address
1189 through a site-local IPv6 address. */
1190 { { .__in6_u
1191 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1193 }, 10, 5 },
1194 { { .__in6_u
1195 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1197 }, 7, 6 },
1198 /* Additional rule for Teredo tunnels. */
1199 { { .__in6_u
1200 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1202 }, 32, 7 },
1203 { { .__in6_u
1204 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1206 }, 0, 1 }
1210 /* The precedence table. */
1211 static const struct prefixentry *precedence;
1213 /* The default precedences. */
1214 static const struct prefixentry default_precedence[] =
1216 /* See RFC 3484 for the details. */
1217 { { .__in6_u
1218 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1220 }, 128, 50 },
1221 { { .__in6_u
1222 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1224 }, 16, 30 },
1225 { { .__in6_u
1226 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1228 }, 96, 20 },
1229 { { .__in6_u
1230 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1232 }, 96, 10 },
1233 { { .__in6_u
1234 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1236 }, 0, 40 }
1240 static int
1241 match_prefix (const struct sockaddr_in6 *in6,
1242 const struct prefixentry *list, int default_val)
1244 int idx;
1245 struct sockaddr_in6 in6_mem;
1247 if (in6->sin6_family == PF_INET)
1249 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1251 /* Construct a V4-to-6 mapped address. */
1252 in6_mem.sin6_family = PF_INET6;
1253 in6_mem.sin6_port = in->sin_port;
1254 in6_mem.sin6_flowinfo = 0;
1255 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1256 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1257 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1258 in6_mem.sin6_scope_id = 0;
1260 in6 = &in6_mem;
1262 else if (in6->sin6_family != PF_INET6)
1263 return default_val;
1265 for (idx = 0; ; ++idx)
1267 unsigned int bits = list[idx].bits;
1268 const uint8_t *mask = list[idx].prefix.s6_addr;
1269 const uint8_t *val = in6->sin6_addr.s6_addr;
1271 while (bits >= 8)
1273 if (*mask != *val)
1274 break;
1276 ++mask;
1277 ++val;
1278 bits -= 8;
1281 if (bits < 8)
1283 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1284 /* Match! */
1285 break;
1289 return list[idx].val;
1293 static int
1294 get_label (const struct sockaddr_in6 *in6)
1296 /* XXX What is a good default value? */
1297 return match_prefix (in6, labels, INT_MAX);
1301 static int
1302 get_precedence (const struct sockaddr_in6 *in6)
1304 /* XXX What is a good default value? */
1305 return match_prefix (in6, precedence, 0);
1309 /* Find last bit set in a word. */
1310 static int
1311 fls (uint32_t a)
1313 uint32_t mask;
1314 int n;
1315 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1316 if ((a & mask) != 0)
1317 break;
1318 return n;
1322 static int
1323 rfc3484_sort (const void *p1, const void *p2, void *arg)
1325 const size_t idx1 = *(const size_t *) p1;
1326 const size_t idx2 = *(const size_t *) p2;
1327 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1328 struct sort_result *a1 = &src->results[idx1];
1329 struct sort_result *a2 = &src->results[idx2];
1331 /* Rule 1: Avoid unusable destinations.
1332 We have the got_source_addr flag set if the destination is reachable. */
1333 if (a1->got_source_addr && ! a2->got_source_addr)
1334 return -1;
1335 if (! a1->got_source_addr && a2->got_source_addr)
1336 return 1;
1339 /* Rule 2: Prefer matching scope. Only interesting if both
1340 destination addresses are IPv6. */
1341 int a1_dst_scope
1342 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1344 int a2_dst_scope
1345 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1347 if (a1->got_source_addr)
1349 int a1_src_scope = get_scope (&a1->source_addr);
1350 int a2_src_scope = get_scope (&a2->source_addr);
1352 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1353 return -1;
1354 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1355 return 1;
1359 /* Rule 3: Avoid deprecated addresses. */
1360 if (a1->got_source_addr)
1362 if (!(a1->source_addr_flags & in6ai_deprecated)
1363 && (a2->source_addr_flags & in6ai_deprecated))
1364 return -1;
1365 if ((a1->source_addr_flags & in6ai_deprecated)
1366 && !(a2->source_addr_flags & in6ai_deprecated))
1367 return 1;
1370 /* Rule 4: Prefer home addresses. */
1371 if (a1->got_source_addr)
1373 if (!(a1->source_addr_flags & in6ai_homeaddress)
1374 && (a2->source_addr_flags & in6ai_homeaddress))
1375 return 1;
1376 if ((a1->source_addr_flags & in6ai_homeaddress)
1377 && !(a2->source_addr_flags & in6ai_homeaddress))
1378 return -1;
1381 /* Rule 5: Prefer matching label. */
1382 if (a1->got_source_addr)
1384 int a1_dst_label
1385 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1386 int a1_src_label = get_label (&a1->source_addr);
1388 int a2_dst_label
1389 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1390 int a2_src_label = get_label (&a2->source_addr);
1392 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1393 return -1;
1394 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1395 return 1;
1399 /* Rule 6: Prefer higher precedence. */
1400 int a1_prec
1401 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1402 int a2_prec
1403 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1405 if (a1_prec > a2_prec)
1406 return -1;
1407 if (a1_prec < a2_prec)
1408 return 1;
1411 /* Rule 7: Prefer native transport. */
1412 if (a1->got_source_addr)
1414 /* The same interface index means the same interface which means
1415 there is no difference in transport. This should catch many
1416 (most?) cases. */
1417 if (a1->index != a2->index)
1419 int a1_native = a1->native;
1420 int a2_native = a2->native;
1422 if (a1_native == -1 || a2_native == -1)
1424 uint32_t a1_index;
1425 if (a1_native == -1)
1427 /* If we do not have the information use 'native' as
1428 the default. */
1429 a1_native = 0;
1430 a1_index = a1->index;
1432 else
1433 a1_index = 0xffffffffu;
1435 uint32_t a2_index;
1436 if (a2_native == -1)
1438 /* If we do not have the information use 'native' as
1439 the default. */
1440 a2_native = 0;
1441 a2_index = a2->index;
1443 else
1444 a2_index = 0xffffffffu;
1446 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1448 /* Fill in the results in all the records. */
1449 for (int i = 0; i < src->nresults; ++i)
1450 if (src->results[i].index == a1_index)
1452 assert (src->results[i].native == -1
1453 || src->results[i].native == a1_native);
1454 src->results[i].native = a1_native;
1456 else if (src->results[i].index == a2_index)
1458 assert (src->results[i].native == -1
1459 || src->results[i].native == a2_native);
1460 src->results[i].native = a2_native;
1464 if (a1_native && !a2_native)
1465 return -1;
1466 if (!a1_native && a2_native)
1467 return 1;
1472 /* Rule 8: Prefer smaller scope. */
1473 if (a1_dst_scope < a2_dst_scope)
1474 return -1;
1475 if (a1_dst_scope > a2_dst_scope)
1476 return 1;
1479 /* Rule 9: Use longest matching prefix. */
1480 if (a1->got_source_addr
1481 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1483 int bit1 = 0;
1484 int bit2 = 0;
1486 if (a1->dest_addr->ai_family == PF_INET)
1488 assert (a1->source_addr.sin6_family == PF_INET);
1489 assert (a2->source_addr.sin6_family == PF_INET);
1491 /* Outside of subnets, as defined by the network masks,
1492 common address prefixes for IPv4 addresses make no sense.
1493 So, define a non-zero value only if source and
1494 destination address are on the same subnet. */
1495 struct sockaddr_in *in1_dst
1496 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1497 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1498 struct sockaddr_in *in1_src
1499 = (struct sockaddr_in *) &a1->source_addr;
1500 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1501 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1503 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1504 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1506 struct sockaddr_in *in2_dst
1507 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1508 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1509 struct sockaddr_in *in2_src
1510 = (struct sockaddr_in *) &a2->source_addr;
1511 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1512 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1514 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1515 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1517 else if (a1->dest_addr->ai_family == PF_INET6)
1519 assert (a1->source_addr.sin6_family == PF_INET6);
1520 assert (a2->source_addr.sin6_family == PF_INET6);
1522 struct sockaddr_in6 *in1_dst;
1523 struct sockaddr_in6 *in1_src;
1524 struct sockaddr_in6 *in2_dst;
1525 struct sockaddr_in6 *in2_src;
1527 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1528 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1529 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1530 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1532 int i;
1533 for (i = 0; i < 4; ++i)
1534 if (in1_dst->sin6_addr.s6_addr32[i]
1535 != in1_src->sin6_addr.s6_addr32[i]
1536 || (in2_dst->sin6_addr.s6_addr32[i]
1537 != in2_src->sin6_addr.s6_addr32[i]))
1538 break;
1540 if (i < 4)
1542 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1543 ^ in1_src->sin6_addr.s6_addr32[i]));
1544 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1545 ^ in2_src->sin6_addr.s6_addr32[i]));
1549 if (bit1 > bit2)
1550 return -1;
1551 if (bit1 < bit2)
1552 return 1;
1556 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1557 compare with the value indicating the order in which the entries
1558 have been received from the services. NB: no two entries can have
1559 the same order so the test will never return zero. */
1560 return idx1 < idx2 ? -1 : 1;
1564 static int
1565 in6aicmp (const void *p1, const void *p2)
1567 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1568 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1570 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1574 /* Name of the config file for RFC 3484 sorting (for now). */
1575 #define GAICONF_FNAME "/etc/gai.conf"
1578 /* Non-zero if we are supposed to reload the config file automatically
1579 whenever it changed. */
1580 static int gaiconf_reload_flag;
1582 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1583 static int gaiconf_reload_flag_ever_set;
1585 /* Last modification time. */
1586 static struct timespec gaiconf_mtime;
1589 libc_freeres_fn(fini)
1591 if (labels != default_labels)
1593 const struct prefixentry *old = labels;
1594 labels = default_labels;
1595 free ((void *) old);
1598 if (precedence != default_precedence)
1600 const struct prefixentry *old = precedence;
1601 precedence = default_precedence;
1602 free ((void *) old);
1605 if (scopes != default_scopes)
1607 const struct scopeentry *old = scopes;
1608 scopes = default_scopes;
1609 free ((void *) old);
1614 struct prefixlist
1616 struct prefixentry entry;
1617 struct prefixlist *next;
1621 struct scopelist
1623 struct scopeentry entry;
1624 struct scopelist *next;
1628 static void
1629 free_prefixlist (struct prefixlist *list)
1631 while (list != NULL)
1633 struct prefixlist *oldp = list;
1634 list = list->next;
1635 free (oldp);
1640 static void
1641 free_scopelist (struct scopelist *list)
1643 while (list != NULL)
1645 struct scopelist *oldp = list;
1646 list = list->next;
1647 free (oldp);
1652 static int
1653 prefixcmp (const void *p1, const void *p2)
1655 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1656 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1658 if (e1->bits < e2->bits)
1659 return 1;
1660 if (e1->bits == e2->bits)
1661 return 0;
1662 return -1;
1666 static int
1667 scopecmp (const void *p1, const void *p2)
1669 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1670 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1672 if (e1->netmask > e2->netmask)
1673 return -1;
1674 if (e1->netmask == e2->netmask)
1675 return 0;
1676 return 1;
1680 static void
1681 gaiconf_init (void)
1683 struct prefixlist *labellist = NULL;
1684 size_t nlabellist = 0;
1685 bool labellist_nullbits = false;
1686 struct prefixlist *precedencelist = NULL;
1687 size_t nprecedencelist = 0;
1688 bool precedencelist_nullbits = false;
1689 struct scopelist *scopelist = NULL;
1690 size_t nscopelist = 0;
1691 bool scopelist_nullbits = false;
1693 FILE *fp = fopen (GAICONF_FNAME, "rc");
1694 if (fp != NULL)
1696 struct stat64 st;
1697 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1699 fclose (fp);
1700 goto no_file;
1703 char *line = NULL;
1704 size_t linelen = 0;
1706 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1708 while (!feof_unlocked (fp))
1710 ssize_t n = __getline (&line, &linelen, fp);
1711 if (n <= 0)
1712 break;
1714 /* Handle comments. No escaping possible so this is easy. */
1715 char *cp = strchr (line, '#');
1716 if (cp != NULL)
1717 *cp = '\0';
1719 cp = line;
1720 while (isspace (*cp))
1721 ++cp;
1723 char *cmd = cp;
1724 while (*cp != '\0' && !isspace (*cp))
1725 ++cp;
1726 size_t cmdlen = cp - cmd;
1728 if (*cp != '\0')
1729 *cp++ = '\0';
1730 while (isspace (*cp))
1731 ++cp;
1733 char *val1 = cp;
1734 while (*cp != '\0' && !isspace (*cp))
1735 ++cp;
1736 size_t val1len = cp - cmd;
1738 /* We always need at least two values. */
1739 if (val1len == 0)
1740 continue;
1742 if (*cp != '\0')
1743 *cp++ = '\0';
1744 while (isspace (*cp))
1745 ++cp;
1747 char *val2 = cp;
1748 while (*cp != '\0' && !isspace (*cp))
1749 ++cp;
1751 /* Ignore the rest of the line. */
1752 *cp = '\0';
1754 struct prefixlist **listp;
1755 size_t *lenp;
1756 bool *nullbitsp;
1757 switch (cmdlen)
1759 case 5:
1760 if (strcmp (cmd, "label") == 0)
1762 struct in6_addr prefix;
1763 unsigned long int bits;
1764 unsigned long int val;
1765 char *endp;
1767 listp = &labellist;
1768 lenp = &nlabellist;
1769 nullbitsp = &labellist_nullbits;
1771 new_elem:
1772 bits = 128;
1773 __set_errno (0);
1774 cp = strchr (val1, '/');
1775 if (cp != NULL)
1776 *cp++ = '\0';
1777 if (inet_pton (AF_INET6, val1, &prefix)
1778 && (cp == NULL
1779 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1780 || errno != ERANGE)
1781 && *endp == '\0'
1782 && bits <= 128
1783 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1784 || errno != ERANGE)
1785 && *endp == '\0'
1786 && val <= INT_MAX)
1788 struct prefixlist *newp = malloc (sizeof (*newp));
1789 if (newp == NULL)
1791 free (line);
1792 fclose (fp);
1793 goto no_file;
1796 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1797 newp->entry.bits = bits;
1798 newp->entry.val = val;
1799 newp->next = *listp;
1800 *listp = newp;
1801 ++*lenp;
1802 *nullbitsp |= bits == 0;
1805 break;
1807 case 6:
1808 if (strcmp (cmd, "reload") == 0)
1810 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1811 if (gaiconf_reload_flag)
1812 gaiconf_reload_flag_ever_set = 1;
1814 break;
1816 case 7:
1817 if (strcmp (cmd, "scopev4") == 0)
1819 struct in6_addr prefix;
1820 unsigned long int bits;
1821 unsigned long int val;
1822 char *endp;
1824 bits = 32;
1825 __set_errno (0);
1826 cp = strchr (val1, '/');
1827 if (cp != NULL)
1828 *cp++ = '\0';
1829 if (inet_pton (AF_INET6, val1, &prefix))
1831 bits = 128;
1832 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1833 && (cp == NULL
1834 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1835 || errno != ERANGE)
1836 && *endp == '\0'
1837 && bits >= 96
1838 && bits <= 128
1839 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1840 || errno != ERANGE)
1841 && *endp == '\0'
1842 && val <= INT_MAX)
1844 struct scopelist *newp;
1845 new_scope:
1846 newp = malloc (sizeof (*newp));
1847 if (newp == NULL)
1849 free (line);
1850 fclose (fp);
1851 goto no_file;
1854 newp->entry.netmask = htonl (bits != 96
1855 ? (0xffffffff
1856 << (128 - bits))
1857 : 0);
1858 newp->entry.addr32 = (prefix.s6_addr32[3]
1859 & newp->entry.netmask);
1860 newp->entry.scope = val;
1861 newp->next = scopelist;
1862 scopelist = newp;
1863 ++nscopelist;
1864 scopelist_nullbits |= bits == 96;
1867 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1868 && (cp == NULL
1869 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1870 || errno != ERANGE)
1871 && *endp == '\0'
1872 && bits <= 32
1873 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1874 || errno != ERANGE)
1875 && *endp == '\0'
1876 && val <= INT_MAX)
1878 bits += 96;
1879 goto new_scope;
1882 break;
1884 case 10:
1885 if (strcmp (cmd, "precedence") == 0)
1887 listp = &precedencelist;
1888 lenp = &nprecedencelist;
1889 nullbitsp = &precedencelist_nullbits;
1890 goto new_elem;
1892 break;
1896 free (line);
1898 fclose (fp);
1900 /* Create the array for the labels. */
1901 struct prefixentry *new_labels;
1902 if (nlabellist > 0)
1904 if (!labellist_nullbits)
1905 ++nlabellist;
1906 new_labels = malloc (nlabellist * sizeof (*new_labels));
1907 if (new_labels == NULL)
1908 goto no_file;
1910 int i = nlabellist;
1911 if (!labellist_nullbits)
1913 --i;
1914 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1915 new_labels[i].bits = 0;
1916 new_labels[i].val = 1;
1919 struct prefixlist *l = labellist;
1920 while (i-- > 0)
1922 new_labels[i] = l->entry;
1923 l = l->next;
1925 free_prefixlist (labellist);
1927 /* Sort the entries so that the most specific ones are at
1928 the beginning. */
1929 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1931 else
1932 new_labels = (struct prefixentry *) default_labels;
1934 struct prefixentry *new_precedence;
1935 if (nprecedencelist > 0)
1937 if (!precedencelist_nullbits)
1938 ++nprecedencelist;
1939 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1940 if (new_precedence == NULL)
1942 if (new_labels != default_labels)
1943 free (new_labels);
1944 goto no_file;
1947 int i = nprecedencelist;
1948 if (!precedencelist_nullbits)
1950 --i;
1951 memset (&new_precedence[i].prefix, '\0',
1952 sizeof (struct in6_addr));
1953 new_precedence[i].bits = 0;
1954 new_precedence[i].val = 40;
1957 struct prefixlist *l = precedencelist;
1958 while (i-- > 0)
1960 new_precedence[i] = l->entry;
1961 l = l->next;
1963 free_prefixlist (precedencelist);
1965 /* Sort the entries so that the most specific ones are at
1966 the beginning. */
1967 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1968 prefixcmp);
1970 else
1971 new_precedence = (struct prefixentry *) default_precedence;
1973 struct scopeentry *new_scopes;
1974 if (nscopelist > 0)
1976 if (!scopelist_nullbits)
1977 ++nscopelist;
1978 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1979 if (new_scopes == NULL)
1981 if (new_labels != default_labels)
1982 free (new_labels);
1983 if (new_precedence != default_precedence)
1984 free (new_precedence);
1985 goto no_file;
1988 int i = nscopelist;
1989 if (!scopelist_nullbits)
1991 --i;
1992 new_scopes[i].addr32 = 0;
1993 new_scopes[i].netmask = 0;
1994 new_scopes[i].scope = 14;
1997 struct scopelist *l = scopelist;
1998 while (i-- > 0)
2000 new_scopes[i] = l->entry;
2001 l = l->next;
2003 free_scopelist (scopelist);
2005 /* Sort the entries so that the most specific ones are at
2006 the beginning. */
2007 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2008 scopecmp);
2010 else
2011 new_scopes = (struct scopeentry *) default_scopes;
2013 /* Now we are ready to replace the values. */
2014 const struct prefixentry *old = labels;
2015 labels = new_labels;
2016 if (old != default_labels)
2017 free ((void *) old);
2019 old = precedence;
2020 precedence = new_precedence;
2021 if (old != default_precedence)
2022 free ((void *) old);
2024 const struct scopeentry *oldscope = scopes;
2025 scopes = new_scopes;
2026 if (oldscope != default_scopes)
2027 free ((void *) oldscope);
2029 gaiconf_mtime = st.st_mtim;
2031 else
2033 no_file:
2034 free_prefixlist (labellist);
2035 free_prefixlist (precedencelist);
2036 free_scopelist (scopelist);
2038 /* If we previously read the file but it is gone now, free the
2039 old data and use the builtin one. Leave the reload flag
2040 alone. */
2041 fini ();
2046 static void
2047 gaiconf_reload (void)
2049 struct stat64 st;
2050 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2051 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2052 gaiconf_init ();
2057 getaddrinfo (const char *name, const char *service,
2058 const struct addrinfo *hints, struct addrinfo **pai)
2060 int i = 0, last_i = 0;
2061 int nresults = 0;
2062 struct addrinfo *p = NULL;
2063 struct gaih_service gaih_service, *pservice;
2064 struct addrinfo local_hints;
2066 if (name != NULL && name[0] == '*' && name[1] == 0)
2067 name = NULL;
2069 if (service != NULL && service[0] == '*' && service[1] == 0)
2070 service = NULL;
2072 if (name == NULL && service == NULL)
2073 return EAI_NONAME;
2075 if (hints == NULL)
2076 hints = &default_hints;
2078 if (hints->ai_flags
2079 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2080 #ifdef HAVE_LIBIDN
2081 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2082 |AI_IDN_USE_STD3_ASCII_RULES
2083 #endif
2084 |AI_NUMERICSERV|AI_ALL))
2085 return EAI_BADFLAGS;
2087 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2088 return EAI_BADFLAGS;
2090 /* Initialize configurations. */
2091 if (__builtin_expect (!_res_hconf.initialized, 0))
2092 _res_hconf_init ();
2094 struct in6addrinfo *in6ai = NULL;
2095 size_t in6ailen = 0;
2096 bool seen_ipv4 = false;
2097 bool seen_ipv6 = false;
2098 /* We might need information about what interfaces are available.
2099 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2100 cannot cache the results since new interfaces could be added at
2101 any time. */
2102 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2104 if (hints->ai_flags & AI_ADDRCONFIG)
2106 /* Now make a decision on what we return, if anything. */
2107 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2109 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2110 narrow down the search. */
2111 if (! seen_ipv4 || ! seen_ipv6)
2113 local_hints = *hints;
2114 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2115 hints = &local_hints;
2118 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2119 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2121 /* We cannot possibly return a valid answer. */
2122 free (in6ai);
2123 return EAI_NONAME;
2127 if (service && service[0])
2129 char *c;
2130 gaih_service.name = service;
2131 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2132 if (*c != '\0')
2134 if (hints->ai_flags & AI_NUMERICSERV)
2136 free (in6ai);
2137 return EAI_NONAME;
2140 gaih_service.num = -1;
2143 pservice = &gaih_service;
2145 else
2146 pservice = NULL;
2148 struct addrinfo **end;
2149 if (pai)
2150 end = &p;
2151 else
2152 end = NULL;
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 if (end)
2167 while (*end)
2169 end = &((*end)->ai_next);
2170 ++nresults;
2173 else
2175 free (in6ai);
2176 return EAI_FAMILY;
2179 if (naddrs > 1)
2181 /* Read the config file. */
2182 __libc_once_define (static, once);
2183 __typeof (once) old_once = once;
2184 __libc_once (once, gaiconf_init);
2185 /* Sort results according to RFC 3484. */
2186 struct sort_result results[nresults];
2187 size_t order[nresults];
2188 struct addrinfo *q;
2189 struct addrinfo *last = NULL;
2190 char *canonname = NULL;
2192 /* If we have information about deprecated and temporary addresses
2193 sort the array now. */
2194 if (in6ai != NULL)
2195 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2197 int fd = -1;
2198 int af = AF_UNSPEC;
2200 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2202 results[i].dest_addr = q;
2203 results[i].native = -1;
2204 order[i] = i;
2206 /* If we just looked up the address for a different
2207 protocol, reuse the result. */
2208 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2209 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2211 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2212 results[i - 1].source_addr_len);
2213 results[i].source_addr_len = results[i - 1].source_addr_len;
2214 results[i].got_source_addr = results[i - 1].got_source_addr;
2215 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2216 results[i].prefixlen = results[i - 1].prefixlen;
2217 results[i].index = results[i - 1].index;
2219 else
2221 results[i].got_source_addr = false;
2222 results[i].source_addr_flags = 0;
2223 results[i].prefixlen = 0;
2224 results[i].index = 0xffffffffu;
2226 /* We overwrite the type with SOCK_DGRAM since we do not
2227 want connect() to connect to the other side. If we
2228 cannot determine the source address remember this
2229 fact. */
2230 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2232 if (fd != -1)
2233 close_retry:
2234 close_not_cancel_no_status (fd);
2235 af = q->ai_family;
2236 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2238 else
2240 /* Reset the connection. */
2241 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2242 __connect (fd, &sa, sizeof (sa));
2245 socklen_t sl = sizeof (results[i].source_addr);
2246 if (fd != -1
2247 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2248 && __getsockname (fd,
2249 (struct sockaddr *) &results[i].source_addr,
2250 &sl) == 0)
2252 results[i].source_addr_len = sl;
2253 results[i].got_source_addr = true;
2255 if (in6ai != NULL)
2257 /* See whether the source address is on the list of
2258 deprecated or temporary addresses. */
2259 struct in6addrinfo tmp;
2261 if (q->ai_family == AF_INET && af == AF_INET)
2263 struct sockaddr_in *sinp
2264 = (struct sockaddr_in *) &results[i].source_addr;
2265 tmp.addr[0] = 0;
2266 tmp.addr[1] = 0;
2267 tmp.addr[2] = htonl (0xffff);
2268 tmp.addr[3] = sinp->sin_addr.s_addr;
2270 else
2272 struct sockaddr_in6 *sin6p
2273 = (struct sockaddr_in6 *) &results[i].source_addr;
2274 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2277 struct in6addrinfo *found
2278 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2279 in6aicmp);
2280 if (found != NULL)
2282 results[i].source_addr_flags = found->flags;
2283 results[i].prefixlen = found->prefixlen;
2284 results[i].index = found->index;
2288 if (q->ai_family == AF_INET && af == AF_INET6)
2290 /* We have to convert the address. The socket is
2291 IPv6 and the request is for IPv4. */
2292 struct sockaddr_in6 *sin6
2293 = (struct sockaddr_in6 *) &results[i].source_addr;
2294 struct sockaddr_in *sin
2295 = (struct sockaddr_in *) &results[i].source_addr;
2296 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2297 sin->sin_family = AF_INET;
2298 /* We do not have to initialize sin_port since this
2299 fields has the same position and size in the IPv6
2300 structure. */
2301 assert (offsetof (struct sockaddr_in, sin_port)
2302 == offsetof (struct sockaddr_in6, sin6_port));
2303 assert (sizeof (sin->sin_port)
2304 == sizeof (sin6->sin6_port));
2305 memcpy (&sin->sin_addr,
2306 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2307 results[i].source_addr_len = sizeof (struct sockaddr_in);
2310 else if (errno == EAFNOSUPPORT && af == AF_INET6
2311 && q->ai_family == AF_INET)
2312 /* This could mean IPv6 sockets are IPv6-only. */
2313 goto close_retry;
2314 else
2315 /* Just make sure that if we have to process the same
2316 address again we do not copy any memory. */
2317 results[i].source_addr_len = 0;
2320 /* Remember the canonical name. */
2321 if (q->ai_canonname != NULL)
2323 assert (canonname == NULL);
2324 canonname = q->ai_canonname;
2325 q->ai_canonname = NULL;
2329 if (fd != -1)
2330 close_not_cancel_no_status (fd);
2332 /* We got all the source addresses we can get, now sort using
2333 the information. */
2334 struct sort_result_combo src
2335 = { .results = results, .nresults = nresults };
2336 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2338 __libc_lock_define_initialized (static, lock);
2340 __libc_lock_lock (lock);
2341 if (old_once && gaiconf_reload_flag)
2342 gaiconf_reload ();
2343 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2344 __libc_lock_unlock (lock);
2346 else
2347 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2349 /* Queue the results up as they come out of sorting. */
2350 q = p = results[order[0]].dest_addr;
2351 for (i = 1; i < nresults; ++i)
2352 q = q->ai_next = results[order[i]].dest_addr;
2353 q->ai_next = NULL;
2355 /* Fill in the canonical name into the new first entry. */
2356 p->ai_canonname = canonname;
2359 free (in6ai);
2361 if (p)
2363 *pai = p;
2364 return 0;
2367 if (pai == NULL && last_i == 0)
2368 return 0;
2370 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2372 libc_hidden_def (getaddrinfo)
2374 static_link_warning (getaddrinfo)
2376 void
2377 freeaddrinfo (struct addrinfo *ai)
2379 struct addrinfo *p;
2381 while (ai != NULL)
2383 p = ai;
2384 ai = ai->ai_next;
2385 free (p->ai_canonname);
2386 free (p);
2389 libc_hidden_def (freeaddrinfo)