Remove duplicate definitions of O_DSYNC and O_RSYNC for Linux/sparc.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob62c38f69be1ac34cefb14feec7a03ba47a144f1c
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 (status == NSS_STATUS_TRYAGAIN
723 && herrno == TRY_AGAIN)
724 no_data = EAI_AGAIN;
725 else
726 no_data = herrno == NO_DATA;
727 break;
729 tmpbuf = extend_alloca (tmpbuf,
730 tmpbuflen, 2 * tmpbuflen);
733 no_inet6_data = no_data;
735 if (status == NSS_STATUS_SUCCESS)
737 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
738 canon = (*pat)->name;
740 while (*pat != NULL)
741 pat = &((*pat)->next);
744 else
746 nss_gethostbyname3_r fct = NULL;
747 if (req->ai_flags & AI_CANONNAME)
748 /* No need to use this function if we do not look for
749 the canonical name. The function does not exist in
750 all NSS modules and therefore the lookup would
751 often fail. */
752 fct = __nss_lookup_function (nip, "gethostbyname3_r");
753 if (fct == NULL)
754 /* We are cheating here. The gethostbyname2_r
755 function does not have the same interface as
756 gethostbyname3_r but the extra arguments the
757 latter takes are added at the end. So the
758 gethostbyname2_r code will just ignore them. */
759 fct = __nss_lookup_function (nip, "gethostbyname2_r");
761 if (fct != NULL)
763 if (req->ai_family == AF_INET6
764 || req->ai_family == AF_UNSPEC)
766 gethosts (AF_INET6, struct in6_addr);
767 no_inet6_data = no_data;
768 inet6_status = status;
770 if (req->ai_family == AF_INET
771 || req->ai_family == AF_UNSPEC
772 || (req->ai_family == AF_INET6
773 && (req->ai_flags & AI_V4MAPPED)
774 /* Avoid generating the mapped addresses if we
775 know we are not going to need them. */
776 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
778 gethosts (AF_INET, struct in_addr);
780 if (req->ai_family == AF_INET)
782 no_inet6_data = no_data;
783 inet6_status = status;
787 /* If we found one address for AF_INET or AF_INET6,
788 don't continue the search. */
789 if (inet6_status == NSS_STATUS_SUCCESS
790 || status == NSS_STATUS_SUCCESS)
792 if ((req->ai_flags & AI_CANONNAME) != 0
793 && canon == NULL)
795 /* If we need the canonical name, get it
796 from the same service as the result. */
797 nss_getcanonname_r cfct;
798 int herrno;
800 cfct = __nss_lookup_function (nip,
801 "getcanonname_r");
802 if (cfct != NULL)
804 const size_t max_fqdn_len = 256;
805 char *buf = alloca (max_fqdn_len);
806 char *s;
808 if (DL_CALL_FCT (cfct, (at->name ?: name,
809 buf, max_fqdn_len,
810 &s, &rc, &herrno))
811 == NSS_STATUS_SUCCESS)
812 canon = s;
813 else
814 /* Set to name now to avoid using
815 gethostbyaddr. */
816 canon = name;
820 break;
823 /* We can have different states for AF_INET and
824 AF_INET6. Try to find a useful one for both. */
825 if (inet6_status == NSS_STATUS_TRYAGAIN)
826 status = NSS_STATUS_TRYAGAIN;
827 else if (status == NSS_STATUS_UNAVAIL
828 && inet6_status != NSS_STATUS_UNAVAIL)
829 status = inet6_status;
831 else
832 status = NSS_STATUS_UNAVAIL;
835 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
836 break;
838 if (nip->next == NULL)
839 no_more = -1;
840 else
841 nip = nip->next;
844 _res.options = old_res_options;
846 if (no_data != 0 && no_inet6_data != 0)
848 /* If both requests timed out report this. */
849 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
850 return -EAI_AGAIN;
852 /* We made requests but they turned out no data. The name
853 is known, though. */
854 return GAIH_OKIFUNSPEC | -EAI_NODATA;
858 process_list:
859 if (at->family == AF_UNSPEC)
860 return GAIH_OKIFUNSPEC | -EAI_NONAME;
862 else
864 struct gaih_addrtuple *atr;
865 atr = at = __alloca (sizeof (struct gaih_addrtuple));
866 memset (at, '\0', sizeof (struct gaih_addrtuple));
868 if (req->ai_family == AF_UNSPEC)
870 at->next = __alloca (sizeof (struct gaih_addrtuple));
871 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
874 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
876 at->family = AF_INET6;
877 if ((req->ai_flags & AI_PASSIVE) == 0)
878 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
879 atr = at->next;
882 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
884 atr->family = AF_INET;
885 if ((req->ai_flags & AI_PASSIVE) == 0)
886 atr->addr[0] = htonl (INADDR_LOOPBACK);
891 struct gaih_servtuple *st2;
892 struct gaih_addrtuple *at2 = at;
893 size_t socklen;
894 sa_family_t family;
897 buffer is the size of an unformatted IPv6 address in printable format.
899 while (at2 != NULL)
901 /* Only the first entry gets the canonical name. */
902 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
904 if (canon == NULL)
906 struct hostent *h = NULL;
907 int herrno;
908 struct hostent th;
909 size_t tmpbuflen = 512;
910 char *tmpbuf = NULL;
914 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
915 rc = __gethostbyaddr_r (at2->addr,
916 ((at2->family == AF_INET6)
917 ? sizeof (struct in6_addr)
918 : sizeof (struct in_addr)),
919 at2->family, &th, tmpbuf,
920 tmpbuflen, &h, &herrno);
922 while (rc == ERANGE && herrno == NETDB_INTERNAL);
924 if (rc != 0 && herrno == NETDB_INTERNAL)
926 __set_h_errno (herrno);
927 return -EAI_SYSTEM;
930 if (h != NULL)
931 canon = h->h_name;
932 else
934 assert (orig_name != NULL);
935 /* If the canonical name cannot be determined, use
936 the passed in string. */
937 canon = orig_name;
941 #ifdef HAVE_LIBIDN
942 if (req->ai_flags & AI_CANONIDN)
944 int idn_flags = 0;
945 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
946 idn_flags |= IDNA_ALLOW_UNASSIGNED;
947 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
948 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
950 char *out;
951 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
952 if (rc != IDNA_SUCCESS)
954 if (rc == IDNA_MALLOC_ERROR)
955 return -EAI_MEMORY;
956 if (rc == IDNA_DLOPEN_ERROR)
957 return -EAI_SYSTEM;
958 return -EAI_IDN_ENCODE;
960 /* In case the output string is the same as the input
961 string no new string has been allocated and we
962 make a copy. */
963 if (out == canon)
964 goto make_copy;
966 else
967 #endif
969 #ifdef HAVE_LIBIDN
970 make_copy:
971 #endif
972 canon = strdup (canon);
973 if (canon == NULL)
974 return -EAI_MEMORY;
978 family = at2->family;
979 if (family == AF_INET6)
981 socklen = sizeof (struct sockaddr_in6);
983 /* If we looked up IPv4 mapped address discard them here if
984 the caller isn't interested in all address and we have
985 found at least one IPv6 address. */
986 if (got_ipv6
987 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
988 && IN6_IS_ADDR_V4MAPPED (at2->addr))
989 goto ignore;
991 else
992 socklen = sizeof (struct sockaddr_in);
994 for (st2 = st; st2 != NULL; st2 = st2->next)
996 struct addrinfo *ai;
997 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
998 if (ai == NULL)
1000 free ((char *) canon);
1001 return -EAI_MEMORY;
1004 ai->ai_flags = req->ai_flags;
1005 ai->ai_family = family;
1006 ai->ai_socktype = st2->socktype;
1007 ai->ai_protocol = st2->protocol;
1008 ai->ai_addrlen = socklen;
1009 ai->ai_addr = (void *) (ai + 1);
1011 /* We only add the canonical name once. */
1012 ai->ai_canonname = (char *) canon;
1013 canon = NULL;
1015 #ifdef _HAVE_SA_LEN
1016 ai->ai_addr->sa_len = socklen;
1017 #endif /* _HAVE_SA_LEN */
1018 ai->ai_addr->sa_family = family;
1020 /* In case of an allocation error the list must be NULL
1021 terminated. */
1022 ai->ai_next = NULL;
1024 if (family == AF_INET6)
1026 struct sockaddr_in6 *sin6p =
1027 (struct sockaddr_in6 *) ai->ai_addr;
1029 sin6p->sin6_port = st2->port;
1030 sin6p->sin6_flowinfo = 0;
1031 memcpy (&sin6p->sin6_addr,
1032 at2->addr, sizeof (struct in6_addr));
1033 sin6p->sin6_scope_id = at2->scopeid;
1035 else
1037 struct sockaddr_in *sinp =
1038 (struct sockaddr_in *) ai->ai_addr;
1039 sinp->sin_port = st2->port;
1040 memcpy (&sinp->sin_addr,
1041 at2->addr, sizeof (struct in_addr));
1042 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1045 pai = &(ai->ai_next);
1048 ++*naddrs;
1050 ignore:
1051 at2 = at2->next;
1054 return 0;
1058 struct sort_result
1060 struct addrinfo *dest_addr;
1061 /* Using sockaddr_storage is for now overkill. We only support IPv4
1062 and IPv6 so far. If this changes at some point we can adjust the
1063 type here. */
1064 struct sockaddr_in6 source_addr;
1065 uint8_t source_addr_len;
1066 bool got_source_addr;
1067 uint8_t source_addr_flags;
1068 uint8_t prefixlen;
1069 uint32_t index;
1070 int32_t native;
1073 struct sort_result_combo
1075 struct sort_result *results;
1076 int nresults;
1080 #if __BYTE_ORDER == __BIG_ENDIAN
1081 # define htonl_c(n) n
1082 #else
1083 # define htonl_c(n) __bswap_constant_32 (n)
1084 #endif
1086 static const struct scopeentry
1088 union
1090 char addr[4];
1091 uint32_t addr32;
1093 uint32_t netmask;
1094 int32_t scope;
1095 } default_scopes[] =
1097 /* Link-local addresses: scope 2. */
1098 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1099 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1100 /* Site-local addresses: scope 5. */
1101 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1102 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1103 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1104 /* Default: scope 14. */
1105 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1108 /* The label table. */
1109 static const struct scopeentry *scopes;
1112 static int
1113 get_scope (const struct sockaddr_in6 *in6)
1115 int scope;
1116 if (in6->sin6_family == PF_INET6)
1118 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1120 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1121 /* RFC 4291 2.5.3 says that the loopback address is to be
1122 treated like a link-local address. */
1123 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1124 scope = 2;
1125 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1126 scope = 5;
1127 else
1128 /* XXX Is this the correct default behavior? */
1129 scope = 14;
1131 else
1132 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1134 else if (in6->sin6_family == PF_INET)
1136 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1138 size_t cnt = 0;
1139 while (1)
1141 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1142 == scopes[cnt].addr32)
1143 return scopes[cnt].scope;
1145 ++cnt;
1147 /* NOTREACHED */
1149 else
1150 /* XXX What is a good default? */
1151 scope = 15;
1153 return scope;
1157 struct prefixentry
1159 struct in6_addr prefix;
1160 unsigned int bits;
1161 int val;
1165 /* The label table. */
1166 static const struct prefixentry *labels;
1168 /* Default labels. */
1169 static const struct prefixentry default_labels[] =
1171 /* See RFC 3484 for the details. */
1172 { { .__in6_u
1173 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1175 }, 128, 0 },
1176 { { .__in6_u
1177 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1179 }, 16, 2 },
1180 { { .__in6_u
1181 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1183 }, 96, 3 },
1184 { { .__in6_u
1185 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1187 }, 96, 4 },
1188 /* The next two entries differ from RFC 3484. We need to treat
1189 IPv6 site-local addresses special because they are never NATed,
1190 unlike site-locale IPv4 addresses. If this would not happen, on
1191 machines which have only IPv4 and IPv6 site-local addresses, the
1192 sorting would prefer the IPv6 site-local addresses, causing
1193 unnecessary delays when trying to connect to a global IPv6 address
1194 through a site-local IPv6 address. */
1195 { { .__in6_u
1196 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1198 }, 10, 5 },
1199 { { .__in6_u
1200 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1202 }, 7, 6 },
1203 /* Additional rule for Teredo tunnels. */
1204 { { .__in6_u
1205 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1207 }, 32, 7 },
1208 { { .__in6_u
1209 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1211 }, 0, 1 }
1215 /* The precedence table. */
1216 static const struct prefixentry *precedence;
1218 /* The default precedences. */
1219 static const struct prefixentry default_precedence[] =
1221 /* See RFC 3484 for the details. */
1222 { { .__in6_u
1223 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1225 }, 128, 50 },
1226 { { .__in6_u
1227 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1229 }, 16, 30 },
1230 { { .__in6_u
1231 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1233 }, 96, 20 },
1234 { { .__in6_u
1235 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1237 }, 96, 10 },
1238 { { .__in6_u
1239 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1241 }, 0, 40 }
1245 static int
1246 match_prefix (const struct sockaddr_in6 *in6,
1247 const struct prefixentry *list, int default_val)
1249 int idx;
1250 struct sockaddr_in6 in6_mem;
1252 if (in6->sin6_family == PF_INET)
1254 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1256 /* Construct a V4-to-6 mapped address. */
1257 in6_mem.sin6_family = PF_INET6;
1258 in6_mem.sin6_port = in->sin_port;
1259 in6_mem.sin6_flowinfo = 0;
1260 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1261 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1262 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1263 in6_mem.sin6_scope_id = 0;
1265 in6 = &in6_mem;
1267 else if (in6->sin6_family != PF_INET6)
1268 return default_val;
1270 for (idx = 0; ; ++idx)
1272 unsigned int bits = list[idx].bits;
1273 const uint8_t *mask = list[idx].prefix.s6_addr;
1274 const uint8_t *val = in6->sin6_addr.s6_addr;
1276 while (bits >= 8)
1278 if (*mask != *val)
1279 break;
1281 ++mask;
1282 ++val;
1283 bits -= 8;
1286 if (bits < 8)
1288 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1289 /* Match! */
1290 break;
1294 return list[idx].val;
1298 static int
1299 get_label (const struct sockaddr_in6 *in6)
1301 /* XXX What is a good default value? */
1302 return match_prefix (in6, labels, INT_MAX);
1306 static int
1307 get_precedence (const struct sockaddr_in6 *in6)
1309 /* XXX What is a good default value? */
1310 return match_prefix (in6, precedence, 0);
1314 /* Find last bit set in a word. */
1315 static int
1316 fls (uint32_t a)
1318 uint32_t mask;
1319 int n;
1320 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1321 if ((a & mask) != 0)
1322 break;
1323 return n;
1327 static int
1328 rfc3484_sort (const void *p1, const void *p2, void *arg)
1330 const size_t idx1 = *(const size_t *) p1;
1331 const size_t idx2 = *(const size_t *) p2;
1332 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1333 struct sort_result *a1 = &src->results[idx1];
1334 struct sort_result *a2 = &src->results[idx2];
1336 /* Rule 1: Avoid unusable destinations.
1337 We have the got_source_addr flag set if the destination is reachable. */
1338 if (a1->got_source_addr && ! a2->got_source_addr)
1339 return -1;
1340 if (! a1->got_source_addr && a2->got_source_addr)
1341 return 1;
1344 /* Rule 2: Prefer matching scope. Only interesting if both
1345 destination addresses are IPv6. */
1346 int a1_dst_scope
1347 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1349 int a2_dst_scope
1350 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1352 if (a1->got_source_addr)
1354 int a1_src_scope = get_scope (&a1->source_addr);
1355 int a2_src_scope = get_scope (&a2->source_addr);
1357 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1358 return -1;
1359 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1360 return 1;
1364 /* Rule 3: Avoid deprecated addresses. */
1365 if (a1->got_source_addr)
1367 if (!(a1->source_addr_flags & in6ai_deprecated)
1368 && (a2->source_addr_flags & in6ai_deprecated))
1369 return -1;
1370 if ((a1->source_addr_flags & in6ai_deprecated)
1371 && !(a2->source_addr_flags & in6ai_deprecated))
1372 return 1;
1375 /* Rule 4: Prefer home addresses. */
1376 if (a1->got_source_addr)
1378 if (!(a1->source_addr_flags & in6ai_homeaddress)
1379 && (a2->source_addr_flags & in6ai_homeaddress))
1380 return 1;
1381 if ((a1->source_addr_flags & in6ai_homeaddress)
1382 && !(a2->source_addr_flags & in6ai_homeaddress))
1383 return -1;
1386 /* Rule 5: Prefer matching label. */
1387 if (a1->got_source_addr)
1389 int a1_dst_label
1390 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1391 int a1_src_label = get_label (&a1->source_addr);
1393 int a2_dst_label
1394 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1395 int a2_src_label = get_label (&a2->source_addr);
1397 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1398 return -1;
1399 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1400 return 1;
1404 /* Rule 6: Prefer higher precedence. */
1405 int a1_prec
1406 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1407 int a2_prec
1408 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1410 if (a1_prec > a2_prec)
1411 return -1;
1412 if (a1_prec < a2_prec)
1413 return 1;
1416 /* Rule 7: Prefer native transport. */
1417 if (a1->got_source_addr)
1419 /* The same interface index means the same interface which means
1420 there is no difference in transport. This should catch many
1421 (most?) cases. */
1422 if (a1->index != a2->index)
1424 int a1_native = a1->native;
1425 int a2_native = a2->native;
1427 if (a1_native == -1 || a2_native == -1)
1429 uint32_t a1_index;
1430 if (a1_native == -1)
1432 /* If we do not have the information use 'native' as
1433 the default. */
1434 a1_native = 0;
1435 a1_index = a1->index;
1437 else
1438 a1_index = 0xffffffffu;
1440 uint32_t a2_index;
1441 if (a2_native == -1)
1443 /* If we do not have the information use 'native' as
1444 the default. */
1445 a2_native = 0;
1446 a2_index = a2->index;
1448 else
1449 a2_index = 0xffffffffu;
1451 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1453 /* Fill in the results in all the records. */
1454 for (int i = 0; i < src->nresults; ++i)
1455 if (src->results[i].index == a1_index)
1457 assert (src->results[i].native == -1
1458 || src->results[i].native == a1_native);
1459 src->results[i].native = a1_native;
1461 else if (src->results[i].index == a2_index)
1463 assert (src->results[i].native == -1
1464 || src->results[i].native == a2_native);
1465 src->results[i].native = a2_native;
1469 if (a1_native && !a2_native)
1470 return -1;
1471 if (!a1_native && a2_native)
1472 return 1;
1477 /* Rule 8: Prefer smaller scope. */
1478 if (a1_dst_scope < a2_dst_scope)
1479 return -1;
1480 if (a1_dst_scope > a2_dst_scope)
1481 return 1;
1484 /* Rule 9: Use longest matching prefix. */
1485 if (a1->got_source_addr
1486 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1488 int bit1 = 0;
1489 int bit2 = 0;
1491 if (a1->dest_addr->ai_family == PF_INET)
1493 assert (a1->source_addr.sin6_family == PF_INET);
1494 assert (a2->source_addr.sin6_family == PF_INET);
1496 /* Outside of subnets, as defined by the network masks,
1497 common address prefixes for IPv4 addresses make no sense.
1498 So, define a non-zero value only if source and
1499 destination address are on the same subnet. */
1500 struct sockaddr_in *in1_dst
1501 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1502 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1503 struct sockaddr_in *in1_src
1504 = (struct sockaddr_in *) &a1->source_addr;
1505 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1506 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1508 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1509 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1511 struct sockaddr_in *in2_dst
1512 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1513 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1514 struct sockaddr_in *in2_src
1515 = (struct sockaddr_in *) &a2->source_addr;
1516 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1517 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1519 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1520 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1522 else if (a1->dest_addr->ai_family == PF_INET6)
1524 assert (a1->source_addr.sin6_family == PF_INET6);
1525 assert (a2->source_addr.sin6_family == PF_INET6);
1527 struct sockaddr_in6 *in1_dst;
1528 struct sockaddr_in6 *in1_src;
1529 struct sockaddr_in6 *in2_dst;
1530 struct sockaddr_in6 *in2_src;
1532 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1533 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1534 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1535 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1537 int i;
1538 for (i = 0; i < 4; ++i)
1539 if (in1_dst->sin6_addr.s6_addr32[i]
1540 != in1_src->sin6_addr.s6_addr32[i]
1541 || (in2_dst->sin6_addr.s6_addr32[i]
1542 != in2_src->sin6_addr.s6_addr32[i]))
1543 break;
1545 if (i < 4)
1547 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1548 ^ in1_src->sin6_addr.s6_addr32[i]));
1549 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1550 ^ in2_src->sin6_addr.s6_addr32[i]));
1554 if (bit1 > bit2)
1555 return -1;
1556 if (bit1 < bit2)
1557 return 1;
1561 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1562 compare with the value indicating the order in which the entries
1563 have been received from the services. NB: no two entries can have
1564 the same order so the test will never return zero. */
1565 return idx1 < idx2 ? -1 : 1;
1569 static int
1570 in6aicmp (const void *p1, const void *p2)
1572 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1573 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1575 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1579 /* Name of the config file for RFC 3484 sorting (for now). */
1580 #define GAICONF_FNAME "/etc/gai.conf"
1583 /* Non-zero if we are supposed to reload the config file automatically
1584 whenever it changed. */
1585 static int gaiconf_reload_flag;
1587 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1588 static int gaiconf_reload_flag_ever_set;
1590 /* Last modification time. */
1591 static struct timespec gaiconf_mtime;
1594 libc_freeres_fn(fini)
1596 if (labels != default_labels)
1598 const struct prefixentry *old = labels;
1599 labels = default_labels;
1600 free ((void *) old);
1603 if (precedence != default_precedence)
1605 const struct prefixentry *old = precedence;
1606 precedence = default_precedence;
1607 free ((void *) old);
1610 if (scopes != default_scopes)
1612 const struct scopeentry *old = scopes;
1613 scopes = default_scopes;
1614 free ((void *) old);
1619 struct prefixlist
1621 struct prefixentry entry;
1622 struct prefixlist *next;
1626 struct scopelist
1628 struct scopeentry entry;
1629 struct scopelist *next;
1633 static void
1634 free_prefixlist (struct prefixlist *list)
1636 while (list != NULL)
1638 struct prefixlist *oldp = list;
1639 list = list->next;
1640 free (oldp);
1645 static void
1646 free_scopelist (struct scopelist *list)
1648 while (list != NULL)
1650 struct scopelist *oldp = list;
1651 list = list->next;
1652 free (oldp);
1657 static int
1658 prefixcmp (const void *p1, const void *p2)
1660 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1661 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1663 if (e1->bits < e2->bits)
1664 return 1;
1665 if (e1->bits == e2->bits)
1666 return 0;
1667 return -1;
1671 static int
1672 scopecmp (const void *p1, const void *p2)
1674 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1675 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1677 if (e1->netmask > e2->netmask)
1678 return -1;
1679 if (e1->netmask == e2->netmask)
1680 return 0;
1681 return 1;
1685 static void
1686 gaiconf_init (void)
1688 struct prefixlist *labellist = NULL;
1689 size_t nlabellist = 0;
1690 bool labellist_nullbits = false;
1691 struct prefixlist *precedencelist = NULL;
1692 size_t nprecedencelist = 0;
1693 bool precedencelist_nullbits = false;
1694 struct scopelist *scopelist = NULL;
1695 size_t nscopelist = 0;
1696 bool scopelist_nullbits = false;
1698 FILE *fp = fopen (GAICONF_FNAME, "rc");
1699 if (fp != NULL)
1701 struct stat64 st;
1702 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1704 fclose (fp);
1705 goto no_file;
1708 char *line = NULL;
1709 size_t linelen = 0;
1711 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1713 while (!feof_unlocked (fp))
1715 ssize_t n = __getline (&line, &linelen, fp);
1716 if (n <= 0)
1717 break;
1719 /* Handle comments. No escaping possible so this is easy. */
1720 char *cp = strchr (line, '#');
1721 if (cp != NULL)
1722 *cp = '\0';
1724 cp = line;
1725 while (isspace (*cp))
1726 ++cp;
1728 char *cmd = cp;
1729 while (*cp != '\0' && !isspace (*cp))
1730 ++cp;
1731 size_t cmdlen = cp - cmd;
1733 if (*cp != '\0')
1734 *cp++ = '\0';
1735 while (isspace (*cp))
1736 ++cp;
1738 char *val1 = cp;
1739 while (*cp != '\0' && !isspace (*cp))
1740 ++cp;
1741 size_t val1len = cp - cmd;
1743 /* We always need at least two values. */
1744 if (val1len == 0)
1745 continue;
1747 if (*cp != '\0')
1748 *cp++ = '\0';
1749 while (isspace (*cp))
1750 ++cp;
1752 char *val2 = cp;
1753 while (*cp != '\0' && !isspace (*cp))
1754 ++cp;
1756 /* Ignore the rest of the line. */
1757 *cp = '\0';
1759 struct prefixlist **listp;
1760 size_t *lenp;
1761 bool *nullbitsp;
1762 switch (cmdlen)
1764 case 5:
1765 if (strcmp (cmd, "label") == 0)
1767 struct in6_addr prefix;
1768 unsigned long int bits;
1769 unsigned long int val;
1770 char *endp;
1772 listp = &labellist;
1773 lenp = &nlabellist;
1774 nullbitsp = &labellist_nullbits;
1776 new_elem:
1777 bits = 128;
1778 __set_errno (0);
1779 cp = strchr (val1, '/');
1780 if (cp != NULL)
1781 *cp++ = '\0';
1782 if (inet_pton (AF_INET6, val1, &prefix)
1783 && (cp == NULL
1784 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1785 || errno != ERANGE)
1786 && *endp == '\0'
1787 && bits <= 128
1788 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1789 || errno != ERANGE)
1790 && *endp == '\0'
1791 && val <= INT_MAX)
1793 struct prefixlist *newp = malloc (sizeof (*newp));
1794 if (newp == NULL)
1796 free (line);
1797 fclose (fp);
1798 goto no_file;
1801 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1802 newp->entry.bits = bits;
1803 newp->entry.val = val;
1804 newp->next = *listp;
1805 *listp = newp;
1806 ++*lenp;
1807 *nullbitsp |= bits == 0;
1810 break;
1812 case 6:
1813 if (strcmp (cmd, "reload") == 0)
1815 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1816 if (gaiconf_reload_flag)
1817 gaiconf_reload_flag_ever_set = 1;
1819 break;
1821 case 7:
1822 if (strcmp (cmd, "scopev4") == 0)
1824 struct in6_addr prefix;
1825 unsigned long int bits;
1826 unsigned long int val;
1827 char *endp;
1829 bits = 32;
1830 __set_errno (0);
1831 cp = strchr (val1, '/');
1832 if (cp != NULL)
1833 *cp++ = '\0';
1834 if (inet_pton (AF_INET6, val1, &prefix))
1836 bits = 128;
1837 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1838 && (cp == NULL
1839 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1840 || errno != ERANGE)
1841 && *endp == '\0'
1842 && bits >= 96
1843 && bits <= 128
1844 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1845 || errno != ERANGE)
1846 && *endp == '\0'
1847 && val <= INT_MAX)
1849 struct scopelist *newp;
1850 new_scope:
1851 newp = malloc (sizeof (*newp));
1852 if (newp == NULL)
1854 free (line);
1855 fclose (fp);
1856 goto no_file;
1859 newp->entry.netmask = htonl (bits != 96
1860 ? (0xffffffff
1861 << (128 - bits))
1862 : 0);
1863 newp->entry.addr32 = (prefix.s6_addr32[3]
1864 & newp->entry.netmask);
1865 newp->entry.scope = val;
1866 newp->next = scopelist;
1867 scopelist = newp;
1868 ++nscopelist;
1869 scopelist_nullbits |= bits == 96;
1872 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1873 && (cp == NULL
1874 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1875 || errno != ERANGE)
1876 && *endp == '\0'
1877 && bits <= 32
1878 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1879 || errno != ERANGE)
1880 && *endp == '\0'
1881 && val <= INT_MAX)
1883 bits += 96;
1884 goto new_scope;
1887 break;
1889 case 10:
1890 if (strcmp (cmd, "precedence") == 0)
1892 listp = &precedencelist;
1893 lenp = &nprecedencelist;
1894 nullbitsp = &precedencelist_nullbits;
1895 goto new_elem;
1897 break;
1901 free (line);
1903 fclose (fp);
1905 /* Create the array for the labels. */
1906 struct prefixentry *new_labels;
1907 if (nlabellist > 0)
1909 if (!labellist_nullbits)
1910 ++nlabellist;
1911 new_labels = malloc (nlabellist * sizeof (*new_labels));
1912 if (new_labels == NULL)
1913 goto no_file;
1915 int i = nlabellist;
1916 if (!labellist_nullbits)
1918 --i;
1919 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1920 new_labels[i].bits = 0;
1921 new_labels[i].val = 1;
1924 struct prefixlist *l = labellist;
1925 while (i-- > 0)
1927 new_labels[i] = l->entry;
1928 l = l->next;
1930 free_prefixlist (labellist);
1932 /* Sort the entries so that the most specific ones are at
1933 the beginning. */
1934 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1936 else
1937 new_labels = (struct prefixentry *) default_labels;
1939 struct prefixentry *new_precedence;
1940 if (nprecedencelist > 0)
1942 if (!precedencelist_nullbits)
1943 ++nprecedencelist;
1944 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1945 if (new_precedence == NULL)
1947 if (new_labels != default_labels)
1948 free (new_labels);
1949 goto no_file;
1952 int i = nprecedencelist;
1953 if (!precedencelist_nullbits)
1955 --i;
1956 memset (&new_precedence[i].prefix, '\0',
1957 sizeof (struct in6_addr));
1958 new_precedence[i].bits = 0;
1959 new_precedence[i].val = 40;
1962 struct prefixlist *l = precedencelist;
1963 while (i-- > 0)
1965 new_precedence[i] = l->entry;
1966 l = l->next;
1968 free_prefixlist (precedencelist);
1970 /* Sort the entries so that the most specific ones are at
1971 the beginning. */
1972 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1973 prefixcmp);
1975 else
1976 new_precedence = (struct prefixentry *) default_precedence;
1978 struct scopeentry *new_scopes;
1979 if (nscopelist > 0)
1981 if (!scopelist_nullbits)
1982 ++nscopelist;
1983 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1984 if (new_scopes == NULL)
1986 if (new_labels != default_labels)
1987 free (new_labels);
1988 if (new_precedence != default_precedence)
1989 free (new_precedence);
1990 goto no_file;
1993 int i = nscopelist;
1994 if (!scopelist_nullbits)
1996 --i;
1997 new_scopes[i].addr32 = 0;
1998 new_scopes[i].netmask = 0;
1999 new_scopes[i].scope = 14;
2002 struct scopelist *l = scopelist;
2003 while (i-- > 0)
2005 new_scopes[i] = l->entry;
2006 l = l->next;
2008 free_scopelist (scopelist);
2010 /* Sort the entries so that the most specific ones are at
2011 the beginning. */
2012 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2013 scopecmp);
2015 else
2016 new_scopes = (struct scopeentry *) default_scopes;
2018 /* Now we are ready to replace the values. */
2019 const struct prefixentry *old = labels;
2020 labels = new_labels;
2021 if (old != default_labels)
2022 free ((void *) old);
2024 old = precedence;
2025 precedence = new_precedence;
2026 if (old != default_precedence)
2027 free ((void *) old);
2029 const struct scopeentry *oldscope = scopes;
2030 scopes = new_scopes;
2031 if (oldscope != default_scopes)
2032 free ((void *) oldscope);
2034 gaiconf_mtime = st.st_mtim;
2036 else
2038 no_file:
2039 free_prefixlist (labellist);
2040 free_prefixlist (precedencelist);
2041 free_scopelist (scopelist);
2043 /* If we previously read the file but it is gone now, free the
2044 old data and use the builtin one. Leave the reload flag
2045 alone. */
2046 fini ();
2051 static void
2052 gaiconf_reload (void)
2054 struct stat64 st;
2055 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2056 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2057 gaiconf_init ();
2062 getaddrinfo (const char *name, const char *service,
2063 const struct addrinfo *hints, struct addrinfo **pai)
2065 int i = 0, last_i = 0;
2066 int nresults = 0;
2067 struct addrinfo *p = NULL;
2068 struct gaih_service gaih_service, *pservice;
2069 struct addrinfo local_hints;
2071 if (name != NULL && name[0] == '*' && name[1] == 0)
2072 name = NULL;
2074 if (service != NULL && service[0] == '*' && service[1] == 0)
2075 service = NULL;
2077 if (name == NULL && service == NULL)
2078 return EAI_NONAME;
2080 if (hints == NULL)
2081 hints = &default_hints;
2083 if (hints->ai_flags
2084 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2085 #ifdef HAVE_LIBIDN
2086 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2087 |AI_IDN_USE_STD3_ASCII_RULES
2088 #endif
2089 |AI_NUMERICSERV|AI_ALL))
2090 return EAI_BADFLAGS;
2092 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2093 return EAI_BADFLAGS;
2095 struct in6addrinfo *in6ai = NULL;
2096 size_t in6ailen = 0;
2097 bool seen_ipv4 = false;
2098 bool seen_ipv6 = false;
2099 /* We might need information about what interfaces are available.
2100 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2101 cannot cache the results since new interfaces could be added at
2102 any time. */
2103 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2105 if (hints->ai_flags & AI_ADDRCONFIG)
2107 /* Now make a decision on what we return, if anything. */
2108 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2110 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2111 narrow down the search. */
2112 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2114 local_hints = *hints;
2115 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2116 hints = &local_hints;
2119 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2120 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2122 /* We cannot possibly return a valid answer. */
2123 free (in6ai);
2124 return EAI_NONAME;
2128 if (service && service[0])
2130 char *c;
2131 gaih_service.name = service;
2132 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2133 if (*c != '\0')
2135 if (hints->ai_flags & AI_NUMERICSERV)
2137 free (in6ai);
2138 return EAI_NONAME;
2141 gaih_service.num = -1;
2144 pservice = &gaih_service;
2146 else
2147 pservice = NULL;
2149 struct addrinfo **end = &p;
2151 unsigned int naddrs = 0;
2152 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2153 || hints->ai_family == AF_INET6)
2155 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2156 if (last_i != 0)
2158 freeaddrinfo (p);
2159 free (in6ai);
2161 return -(last_i & GAIH_EAI);
2163 while (*end)
2165 end = &((*end)->ai_next);
2166 ++nresults;
2169 else
2171 free (in6ai);
2172 return EAI_FAMILY;
2175 if (naddrs > 1)
2177 /* Read the config file. */
2178 __libc_once_define (static, once);
2179 __typeof (once) old_once = once;
2180 __libc_once (once, gaiconf_init);
2181 /* Sort results according to RFC 3484. */
2182 struct sort_result results[nresults];
2183 size_t order[nresults];
2184 struct addrinfo *q;
2185 struct addrinfo *last = NULL;
2186 char *canonname = NULL;
2188 /* If we have information about deprecated and temporary addresses
2189 sort the array now. */
2190 if (in6ai != NULL)
2191 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2193 int fd = -1;
2194 int af = AF_UNSPEC;
2196 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2198 results[i].dest_addr = q;
2199 results[i].native = -1;
2200 order[i] = i;
2202 /* If we just looked up the address for a different
2203 protocol, reuse the result. */
2204 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2205 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2207 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2208 results[i - 1].source_addr_len);
2209 results[i].source_addr_len = results[i - 1].source_addr_len;
2210 results[i].got_source_addr = results[i - 1].got_source_addr;
2211 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2212 results[i].prefixlen = results[i - 1].prefixlen;
2213 results[i].index = results[i - 1].index;
2215 else
2217 results[i].got_source_addr = false;
2218 results[i].source_addr_flags = 0;
2219 results[i].prefixlen = 0;
2220 results[i].index = 0xffffffffu;
2222 /* We overwrite the type with SOCK_DGRAM since we do not
2223 want connect() to connect to the other side. If we
2224 cannot determine the source address remember this
2225 fact. */
2226 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2228 if (fd != -1)
2229 close_retry:
2230 close_not_cancel_no_status (fd);
2231 af = q->ai_family;
2232 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2234 else
2236 /* Reset the connection. */
2237 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2238 __connect (fd, &sa, sizeof (sa));
2241 socklen_t sl = sizeof (results[i].source_addr);
2242 if (fd != -1
2243 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2244 && __getsockname (fd,
2245 (struct sockaddr *) &results[i].source_addr,
2246 &sl) == 0)
2248 results[i].source_addr_len = sl;
2249 results[i].got_source_addr = true;
2251 if (in6ai != NULL)
2253 /* See whether the source address is on the list of
2254 deprecated or temporary addresses. */
2255 struct in6addrinfo tmp;
2257 if (q->ai_family == AF_INET && af == AF_INET)
2259 struct sockaddr_in *sinp
2260 = (struct sockaddr_in *) &results[i].source_addr;
2261 tmp.addr[0] = 0;
2262 tmp.addr[1] = 0;
2263 tmp.addr[2] = htonl (0xffff);
2264 tmp.addr[3] = sinp->sin_addr.s_addr;
2266 else
2268 struct sockaddr_in6 *sin6p
2269 = (struct sockaddr_in6 *) &results[i].source_addr;
2270 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2273 struct in6addrinfo *found
2274 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2275 in6aicmp);
2276 if (found != NULL)
2278 results[i].source_addr_flags = found->flags;
2279 results[i].prefixlen = found->prefixlen;
2280 results[i].index = found->index;
2284 if (q->ai_family == AF_INET && af == AF_INET6)
2286 /* We have to convert the address. The socket is
2287 IPv6 and the request is for IPv4. */
2288 struct sockaddr_in6 *sin6
2289 = (struct sockaddr_in6 *) &results[i].source_addr;
2290 struct sockaddr_in *sin
2291 = (struct sockaddr_in *) &results[i].source_addr;
2292 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2293 sin->sin_family = AF_INET;
2294 /* We do not have to initialize sin_port since this
2295 fields has the same position and size in the IPv6
2296 structure. */
2297 assert (offsetof (struct sockaddr_in, sin_port)
2298 == offsetof (struct sockaddr_in6, sin6_port));
2299 assert (sizeof (sin->sin_port)
2300 == sizeof (sin6->sin6_port));
2301 memcpy (&sin->sin_addr,
2302 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2303 results[i].source_addr_len = sizeof (struct sockaddr_in);
2306 else if (errno == EAFNOSUPPORT && af == AF_INET6
2307 && q->ai_family == AF_INET)
2308 /* This could mean IPv6 sockets are IPv6-only. */
2309 goto close_retry;
2310 else
2311 /* Just make sure that if we have to process the same
2312 address again we do not copy any memory. */
2313 results[i].source_addr_len = 0;
2316 /* Remember the canonical name. */
2317 if (q->ai_canonname != NULL)
2319 assert (canonname == NULL);
2320 canonname = q->ai_canonname;
2321 q->ai_canonname = NULL;
2325 if (fd != -1)
2326 close_not_cancel_no_status (fd);
2328 /* We got all the source addresses we can get, now sort using
2329 the information. */
2330 struct sort_result_combo src
2331 = { .results = results, .nresults = nresults };
2332 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2334 __libc_lock_define_initialized (static, lock);
2336 __libc_lock_lock (lock);
2337 if (old_once && gaiconf_reload_flag)
2338 gaiconf_reload ();
2339 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2340 __libc_lock_unlock (lock);
2342 else
2343 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2345 /* Queue the results up as they come out of sorting. */
2346 q = p = results[order[0]].dest_addr;
2347 for (i = 1; i < nresults; ++i)
2348 q = q->ai_next = results[order[i]].dest_addr;
2349 q->ai_next = NULL;
2351 /* Fill in the canonical name into the new first entry. */
2352 p->ai_canonname = canonname;
2355 free (in6ai);
2357 if (p)
2359 *pai = p;
2360 return 0;
2363 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2365 libc_hidden_def (getaddrinfo)
2367 static_link_warning (getaddrinfo)
2369 void
2370 freeaddrinfo (struct addrinfo *ai)
2372 struct addrinfo *p;
2374 while (ai != NULL)
2376 p = ai;
2377 ai = ai->ai_next;
2378 free (p->ai_canonname);
2379 free (p);
2382 libc_hidden_def (freeaddrinfo)