Don't use gethostbyaddr to determine canonical name
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob0f4b88514f64bb6de3a6343d324bd6ac4218b664
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 <stdint.h>
51 #include <arpa/inet.h>
52 #include <net/if.h>
53 #include <netinet/in.h>
54 #include <sys/socket.h>
55 #include <sys/stat.h>
56 #include <sys/types.h>
57 #include <sys/un.h>
58 #include <sys/utsname.h>
59 #include <unistd.h>
60 #include <nsswitch.h>
61 #include <bits/libc-lock.h>
62 #include <not-cancel.h>
63 #include <nscd/nscd-client.h>
64 #include <nscd/nscd_proto.h>
65 #include <resolv/res_hconf.h>
67 #ifdef HAVE_LIBIDN
68 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
69 extern int __idna_to_unicode_lzlz (const char *input, char **output,
70 int flags);
71 # include <libidn/idna.h>
72 #endif
74 #define GAIH_OKIFUNSPEC 0x0100
75 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
77 #ifndef UNIX_PATH_MAX
78 # define UNIX_PATH_MAX 108
79 #endif
81 struct gaih_service
83 const char *name;
84 int num;
87 struct gaih_servtuple
89 struct gaih_servtuple *next;
90 int socktype;
91 int protocol;
92 int port;
95 static const struct gaih_servtuple nullserv;
98 struct gaih_typeproto
100 int socktype;
101 int protocol;
102 uint8_t protoflag;
103 bool defaultflag;
104 char name[8];
107 /* Values for `protoflag'. */
108 #define GAI_PROTO_NOSERVICE 1
109 #define GAI_PROTO_PROTOANY 2
111 static const struct gaih_typeproto gaih_inet_typeproto[] =
113 { 0, 0, 0, false, "" },
114 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
115 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
116 #if defined SOCK_DCCP && defined IPPROTO_DCCP
117 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
118 #endif
119 #ifdef IPPROTO_UDPLITE
120 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
121 #endif
122 #ifdef IPPROTO_SCTP
123 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
124 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
125 #endif
126 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
127 { 0, 0, 0, false, "" }
130 struct gaih
132 int family;
133 int (*gaih)(const char *name, const struct gaih_service *service,
134 const struct addrinfo *req, struct addrinfo **pai,
135 unsigned int *naddrs);
138 static const struct addrinfo default_hints =
140 .ai_flags = AI_DEFAULT,
141 .ai_family = PF_UNSPEC,
142 .ai_socktype = 0,
143 .ai_protocol = 0,
144 .ai_addrlen = 0,
145 .ai_addr = NULL,
146 .ai_canonname = NULL,
147 .ai_next = NULL
151 static int
152 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
153 const struct addrinfo *req, struct gaih_servtuple *st)
155 struct servent *s;
156 size_t tmpbuflen = 1024;
157 struct servent ts;
158 char *tmpbuf;
159 int r;
163 tmpbuf = __alloca (tmpbuflen);
165 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
166 &s);
167 if (r != 0 || s == NULL)
169 if (r == ERANGE)
170 tmpbuflen *= 2;
171 else
172 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
175 while (r);
177 st->next = NULL;
178 st->socktype = tp->socktype;
179 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
180 ? req->ai_protocol : tp->protocol);
181 st->port = s->s_port;
183 return 0;
186 #define gethosts(_family, _type) \
188 int i; \
189 int herrno; \
190 struct hostent th; \
191 struct hostent *h; \
192 char *localcanon = NULL; \
193 no_data = 0; \
194 while (1) { \
195 rc = 0; \
196 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
197 &rc, &herrno, NULL, &localcanon)); \
198 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
199 break; \
200 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
202 if (status == NSS_STATUS_SUCCESS && rc == 0) \
203 h = &th; \
204 else \
205 h = NULL; \
206 if (rc != 0) \
208 if (herrno == NETDB_INTERNAL) \
210 __set_h_errno (herrno); \
211 _res.options |= old_res_options & RES_USE_INET6; \
212 return -EAI_SYSTEM; \
214 if (herrno == TRY_AGAIN) \
215 no_data = EAI_AGAIN; \
216 else \
217 no_data = herrno == NO_DATA; \
219 else if (h != NULL) \
221 for (i = 0; h->h_addr_list[i]; i++) \
223 if (*pat == NULL) \
225 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
226 (*pat)->scopeid = 0; \
228 uint32_t *addr = (*pat)->addr; \
229 (*pat)->next = NULL; \
230 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
231 if (_family == AF_INET && req->ai_family == AF_INET6) \
233 (*pat)->family = AF_INET6; \
234 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
235 addr[2] = htonl (0xffff); \
236 addr[1] = 0; \
237 addr[0] = 0; \
239 else \
241 (*pat)->family = _family; \
242 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
244 pat = &((*pat)->next); \
247 if (localcanon != NULL && canon == NULL) \
248 canon = strdupa (localcanon); \
250 if (_family == AF_INET6 && i > 0) \
251 got_ipv6 = true; \
256 typedef enum nss_status (*nss_gethostbyname4_r)
257 (const char *name, struct gaih_addrtuple **pat,
258 char *buffer, size_t buflen, int *errnop,
259 int *h_errnop, int32_t *ttlp);
260 typedef enum nss_status (*nss_gethostbyname3_r)
261 (const char *name, int af, struct hostent *host,
262 char *buffer, size_t buflen, int *errnop,
263 int *h_errnop, int32_t *ttlp, char **canonp);
264 typedef enum nss_status (*nss_getcanonname_r)
265 (const char *name, char *buffer, size_t buflen, char **result,
266 int *errnop, int *h_errnop);
267 extern service_user *__nss_hosts_database attribute_hidden;
270 static int
271 gaih_inet (const char *name, const struct gaih_service *service,
272 const struct addrinfo *req, struct addrinfo **pai,
273 unsigned int *naddrs)
275 const struct gaih_typeproto *tp = gaih_inet_typeproto;
276 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
277 struct gaih_addrtuple *at = NULL;
278 int rc;
279 bool got_ipv6 = false;
280 const char *canon = NULL;
281 const char *orig_name = name;
282 size_t alloca_used = 0;
284 if (req->ai_protocol || req->ai_socktype)
286 ++tp;
288 while (tp->name[0]
289 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
290 || (req->ai_protocol != 0
291 && !(tp->protoflag & GAI_PROTO_PROTOANY)
292 && req->ai_protocol != tp->protocol)))
293 ++tp;
295 if (! tp->name[0])
297 if (req->ai_socktype)
298 return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
299 else
300 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
304 int port = 0;
305 if (service != NULL)
307 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
308 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
310 if (service->num < 0)
312 if (tp->name[0])
314 st = (struct gaih_servtuple *)
315 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
317 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
318 return rc;
320 else
322 struct gaih_servtuple **pst = &st;
323 for (tp++; tp->name[0]; tp++)
325 struct gaih_servtuple *newp;
327 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
328 continue;
330 if (req->ai_socktype != 0
331 && req->ai_socktype != tp->socktype)
332 continue;
333 if (req->ai_protocol != 0
334 && !(tp->protoflag & GAI_PROTO_PROTOANY)
335 && req->ai_protocol != tp->protocol)
336 continue;
338 newp = (struct gaih_servtuple *)
339 alloca_account (sizeof (struct gaih_servtuple),
340 alloca_used);
342 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
344 if (rc & GAIH_OKIFUNSPEC)
345 continue;
346 return rc;
349 *pst = newp;
350 pst = &(newp->next);
352 if (st == (struct gaih_servtuple *) &nullserv)
353 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
356 else
358 port = htons (service->num);
359 goto got_port;
362 else
364 got_port:
366 if (req->ai_socktype || req->ai_protocol)
368 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
369 st->next = NULL;
370 st->socktype = tp->socktype;
371 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
372 ? req->ai_protocol : tp->protocol);
373 st->port = port;
375 else
377 /* Neither socket type nor protocol is set. Return all socket types
378 we know about. */
379 struct gaih_servtuple **lastp = &st;
380 for (++tp; tp->name[0]; ++tp)
381 if (tp->defaultflag)
383 struct gaih_servtuple *newp;
385 newp = alloca_account (sizeof (struct gaih_servtuple),
386 alloca_used);
387 newp->next = NULL;
388 newp->socktype = tp->socktype;
389 newp->protocol = tp->protocol;
390 newp->port = port;
392 *lastp = newp;
393 lastp = &newp->next;
398 bool malloc_name = false;
399 bool malloc_addrmem = false;
400 struct gaih_addrtuple *addrmem = NULL;
401 bool malloc_canonbuf = false;
402 char *canonbuf = NULL;
403 bool malloc_tmpbuf = false;
404 char *tmpbuf = NULL;
405 int result = 0;
406 if (name != NULL)
408 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
409 at->family = AF_UNSPEC;
410 at->scopeid = 0;
411 at->next = NULL;
413 #ifdef HAVE_LIBIDN
414 if (req->ai_flags & AI_IDN)
416 int idn_flags = 0;
417 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
418 idn_flags |= IDNA_ALLOW_UNASSIGNED;
419 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
420 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
422 char *p = NULL;
423 rc = __idna_to_ascii_lz (name, &p, idn_flags);
424 if (rc != IDNA_SUCCESS)
426 /* No need to jump to free_and_return here. */
427 if (rc == IDNA_MALLOC_ERROR)
428 return -EAI_MEMORY;
429 if (rc == IDNA_DLOPEN_ERROR)
430 return -EAI_SYSTEM;
431 return -EAI_IDN_ENCODE;
433 /* In case the output string is the same as the input string
434 no new string has been allocated. */
435 if (p != name)
437 name = p;
438 malloc_name = true;
441 #endif
443 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
445 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
446 at->family = AF_INET;
447 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
449 at->addr[3] = at->addr[0];
450 at->addr[2] = htonl (0xffff);
451 at->addr[1] = 0;
452 at->addr[0] = 0;
453 at->family = AF_INET6;
455 else
457 result = -EAI_ADDRFAMILY;
458 goto free_and_return;
461 if (req->ai_flags & AI_CANONNAME)
462 canon = name;
464 else if (at->family == AF_UNSPEC)
466 char *scope_delim = strchr (name, SCOPE_DELIMITER);
467 int e;
470 bool malloc_namebuf = false;
471 char *namebuf = (char *) name;
473 if (__builtin_expect (scope_delim != NULL, 0))
475 if (malloc_name)
476 *scope_delim = '\0';
477 else
479 if (__libc_use_alloca (alloca_used
480 + scope_delim - name + 1))
482 namebuf = alloca_account (scope_delim - name + 1,
483 alloca_used);
484 *((char *) __mempcpy (namebuf, name,
485 scope_delim - name)) = '\0';
487 else
489 namebuf = strndup (name, scope_delim - name);
490 if (namebuf == NULL)
492 assert (!malloc_name);
493 return -EAI_MEMORY;
495 malloc_namebuf = true;
500 e = inet_pton (AF_INET6, namebuf, at->addr);
502 if (malloc_namebuf)
503 free (namebuf);
504 else if (scope_delim != NULL && malloc_name)
505 /* Undo what we did above. */
506 *scope_delim = SCOPE_DELIMITER;
508 if (e > 0)
510 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
511 at->family = AF_INET6;
512 else if (req->ai_family == AF_INET
513 && IN6_IS_ADDR_V4MAPPED (at->addr))
515 at->addr[0] = at->addr[3];
516 at->family = AF_INET;
518 else
520 result = -EAI_ADDRFAMILY;
521 goto free_and_return;
524 if (scope_delim != NULL)
526 int try_numericscope = 0;
527 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
528 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
530 at->scopeid = if_nametoindex (scope_delim + 1);
531 if (at->scopeid == 0)
532 try_numericscope = 1;
534 else
535 try_numericscope = 1;
537 if (try_numericscope != 0)
539 char *end;
540 assert (sizeof (uint32_t) <= sizeof (unsigned long));
541 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
542 10);
543 if (*end != '\0')
545 result = GAIH_OKIFUNSPEC | -EAI_NONAME;
546 goto free_and_return;
551 if (req->ai_flags & AI_CANONNAME)
552 canon = name;
556 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
558 struct gaih_addrtuple **pat = &at;
559 int no_data = 0;
560 int no_inet6_data = 0;
561 service_user *nip;
562 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
563 enum nss_status status = NSS_STATUS_UNAVAIL;
564 int no_more;
565 int old_res_options;
567 /* If we do not have to look for IPv6 addresses or the canonical
568 name, use the simple, old functions, which do not support
569 IPv6 scope ids, nor retrieving the canonical name. */
570 if (req->ai_family == AF_INET
571 && (req->ai_flags & AI_CANONNAME) == 0)
573 /* Allocate additional room for struct host_data. */
574 size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
575 + 16 * sizeof(char));
576 assert (tmpbuf == NULL);
577 tmpbuf = alloca_account (tmpbuflen, alloca_used);
578 int rc;
579 struct hostent th;
580 struct hostent *h;
581 int herrno;
583 while (1)
585 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
586 tmpbuflen, &h, &herrno);
587 if (rc != ERANGE || herrno != NETDB_INTERNAL)
588 break;
590 if (!malloc_tmpbuf
591 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
592 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
593 2 * tmpbuflen,
594 alloca_used);
595 else
597 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
598 2 * tmpbuflen);
599 if (newp == NULL)
601 result = -EAI_MEMORY;
602 goto free_and_return;
604 tmpbuf = newp;
605 malloc_tmpbuf = true;
606 tmpbuflen = 2 * tmpbuflen;
610 if (rc == 0)
612 if (h != NULL)
614 int i;
615 /* We found data, count the number of addresses. */
616 for (i = 0; h->h_addr_list[i]; ++i)
618 if (i > 0 && *pat != NULL)
619 --i;
621 if (__libc_use_alloca (alloca_used
622 + i * sizeof (struct gaih_addrtuple)))
623 addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
624 alloca_used);
625 else
627 addrmem = malloc (i
628 * sizeof (struct gaih_addrtuple));
629 if (addrmem == NULL)
631 result = -EAI_MEMORY;
632 goto free_and_return;
634 malloc_addrmem = true;
637 /* Now convert it into the list. */
638 struct gaih_addrtuple *addrfree = addrmem;
639 for (i = 0; h->h_addr_list[i]; ++i)
641 if (*pat == NULL)
643 *pat = addrfree++;
644 (*pat)->scopeid = 0;
646 (*pat)->next = NULL;
647 (*pat)->family = AF_INET;
648 memcpy ((*pat)->addr, h->h_addr_list[i],
649 h->h_length);
650 pat = &((*pat)->next);
654 else
656 if (herrno == NETDB_INTERNAL)
658 __set_h_errno (herrno);
659 result = -EAI_SYSTEM;
661 else if (herrno == TRY_AGAIN)
662 result = -EAI_AGAIN;
663 else
664 /* We made requests but they turned out no data.
665 The name is known, though. */
666 result = GAIH_OKIFUNSPEC | -EAI_NODATA;
668 goto free_and_return;
671 goto process_list;
674 #ifdef USE_NSCD
675 if (__nss_not_use_nscd_hosts > 0
676 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
677 __nss_not_use_nscd_hosts = 0;
679 if (!__nss_not_use_nscd_hosts
680 && !__nss_database_custom[NSS_DBSIDX_hosts])
682 /* Try to use nscd. */
683 struct nscd_ai_result *air = NULL;
684 int herrno;
685 int err = __nscd_getai (name, &air, &herrno);
686 if (air != NULL)
688 /* Transform into gaih_addrtuple list. */
689 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
690 char *addrs = air->addrs;
692 if (__libc_use_alloca (alloca_used
693 + air->naddrs * sizeof (struct gaih_addrtuple)))
694 addrmem = alloca_account (air->naddrs
695 * sizeof (struct gaih_addrtuple),
696 alloca_used);
697 else
699 addrmem = malloc (air->naddrs
700 * sizeof (struct gaih_addrtuple));
701 if (addrmem == NULL)
703 result = -EAI_MEMORY;
704 goto free_and_return;
706 malloc_addrmem = true;
709 struct gaih_addrtuple *addrfree = addrmem;
710 for (int i = 0; i < air->naddrs; ++i)
712 socklen_t size = (air->family[i] == AF_INET
713 ? INADDRSZ : IN6ADDRSZ);
714 if (*pat == NULL)
716 *pat = addrfree++;
717 (*pat)->scopeid = 0;
719 uint32_t *pataddr = (*pat)->addr;
720 (*pat)->next = NULL;
721 if (added_canon || air->canon == NULL)
722 (*pat)->name = NULL;
723 else if (canonbuf == NULL)
725 size_t canonlen = strlen (air->canon) + 1;
726 if ((req->ai_flags & AI_CANONIDN) != 0
727 && __libc_use_alloca (alloca_used + canonlen))
728 canonbuf = alloca_account (canonlen, alloca_used);
729 else
731 canonbuf = malloc (canonlen);
732 if (canonbuf == NULL)
734 result = -EAI_MEMORY;
735 goto free_and_return;
737 malloc_canonbuf = true;
739 canon = (*pat)->name = memcpy (canonbuf, air->canon,
740 canonlen);
743 if (air->family[i] == AF_INET
744 && req->ai_family == AF_INET6
745 && (req->ai_flags & AI_V4MAPPED))
747 (*pat)->family = AF_INET6;
748 pataddr[3] = *(uint32_t *) addrs;
749 pataddr[2] = htonl (0xffff);
750 pataddr[1] = 0;
751 pataddr[0] = 0;
752 pat = &((*pat)->next);
753 added_canon = true;
755 else if (req->ai_family == AF_UNSPEC
756 || air->family[i] == req->ai_family)
758 (*pat)->family = air->family[i];
759 memcpy (pataddr, addrs, size);
760 pat = &((*pat)->next);
761 added_canon = true;
762 if (air->family[i] == AF_INET6)
763 got_ipv6 = true;
765 addrs += size;
768 free (air);
770 if (at->family == AF_UNSPEC)
772 result = GAIH_OKIFUNSPEC | -EAI_NONAME;
773 goto free_and_return;
776 goto process_list;
778 else if (err == 0)
779 /* The database contains a negative entry. */
780 goto free_and_return;
781 else if (__nss_not_use_nscd_hosts == 0)
783 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
784 result = -EAI_MEMORY;
785 else if (herrno == TRY_AGAIN)
786 result = -EAI_AGAIN;
787 else
788 result = -EAI_SYSTEM;
790 goto free_and_return;
793 #endif
795 if (__nss_hosts_database == NULL)
796 no_more = __nss_database_lookup ("hosts", NULL,
797 "dns [!UNAVAIL=return] files",
798 &__nss_hosts_database);
799 else
800 no_more = 0;
801 nip = __nss_hosts_database;
803 /* Initialize configurations. */
804 if (__glibc_unlikely (!_res_hconf.initialized))
805 _res_hconf_init ();
806 if (__res_maybe_init (&_res, 0) == -1)
807 no_more = 1;
809 /* If we are looking for both IPv4 and IPv6 address we don't
810 want the lookup functions to automatically promote IPv4
811 addresses to IPv6 addresses. Currently this is decided
812 by setting the RES_USE_INET6 bit in _res.options. */
813 old_res_options = _res.options;
814 _res.options &= ~RES_USE_INET6;
816 size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
817 malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
818 assert (tmpbuf == NULL);
819 if (!malloc_tmpbuf)
820 tmpbuf = alloca_account (tmpbuflen, alloca_used);
821 else
823 tmpbuf = malloc (tmpbuflen);
824 if (tmpbuf == NULL)
826 _res.options |= old_res_options & RES_USE_INET6;
827 result = -EAI_MEMORY;
828 goto free_and_return;
832 while (!no_more)
834 no_data = 0;
835 nss_gethostbyname4_r fct4 = NULL;
837 /* gethostbyname4_r sends out parallel A and AAAA queries and
838 is thus only suitable for PF_UNSPEC. */
839 if (req->ai_family == PF_UNSPEC)
840 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
842 if (fct4 != NULL)
844 int herrno;
846 while (1)
848 rc = 0;
849 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
850 tmpbuflen, &rc, &herrno,
851 NULL));
852 if (status == NSS_STATUS_SUCCESS)
853 break;
854 if (status != NSS_STATUS_TRYAGAIN
855 || rc != ERANGE || herrno != NETDB_INTERNAL)
857 if (status == NSS_STATUS_TRYAGAIN
858 && herrno == TRY_AGAIN)
859 no_data = EAI_AGAIN;
860 else
861 no_data = herrno == NO_DATA;
862 break;
865 if (!malloc_tmpbuf
866 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
867 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
868 2 * tmpbuflen,
869 alloca_used);
870 else
872 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
873 2 * tmpbuflen);
874 if (newp == NULL)
876 _res.options |= old_res_options & RES_USE_INET6;
877 result = -EAI_MEMORY;
878 goto free_and_return;
880 tmpbuf = newp;
881 malloc_tmpbuf = true;
882 tmpbuflen = 2 * tmpbuflen;
886 if (status == NSS_STATUS_SUCCESS)
888 assert (!no_data);
889 no_data = 1;
891 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
892 canon = (*pat)->name;
894 while (*pat != NULL)
896 if ((*pat)->family == AF_INET
897 && req->ai_family == AF_INET6
898 && (req->ai_flags & AI_V4MAPPED) != 0)
900 uint32_t *pataddr = (*pat)->addr;
901 (*pat)->family = AF_INET6;
902 pataddr[3] = pataddr[0];
903 pataddr[2] = htonl (0xffff);
904 pataddr[1] = 0;
905 pataddr[0] = 0;
906 pat = &((*pat)->next);
907 no_data = 0;
909 else if (req->ai_family == AF_UNSPEC
910 || (*pat)->family == req->ai_family)
912 pat = &((*pat)->next);
914 no_data = 0;
915 if (req->ai_family == AF_INET6)
916 got_ipv6 = true;
918 else
919 *pat = ((*pat)->next);
923 no_inet6_data = no_data;
925 else
927 nss_gethostbyname3_r fct = NULL;
928 if (req->ai_flags & AI_CANONNAME)
929 /* No need to use this function if we do not look for
930 the canonical name. The function does not exist in
931 all NSS modules and therefore the lookup would
932 often fail. */
933 fct = __nss_lookup_function (nip, "gethostbyname3_r");
934 if (fct == NULL)
935 /* We are cheating here. The gethostbyname2_r
936 function does not have the same interface as
937 gethostbyname3_r but the extra arguments the
938 latter takes are added at the end. So the
939 gethostbyname2_r code will just ignore them. */
940 fct = __nss_lookup_function (nip, "gethostbyname2_r");
942 if (fct != NULL)
944 if (req->ai_family == AF_INET6
945 || req->ai_family == AF_UNSPEC)
947 gethosts (AF_INET6, struct in6_addr);
948 no_inet6_data = no_data;
949 inet6_status = status;
951 if (req->ai_family == AF_INET
952 || req->ai_family == AF_UNSPEC
953 || (req->ai_family == AF_INET6
954 && (req->ai_flags & AI_V4MAPPED)
955 /* Avoid generating the mapped addresses if we
956 know we are not going to need them. */
957 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
959 gethosts (AF_INET, struct in_addr);
961 if (req->ai_family == AF_INET)
963 no_inet6_data = no_data;
964 inet6_status = status;
968 /* If we found one address for AF_INET or AF_INET6,
969 don't continue the search. */
970 if (inet6_status == NSS_STATUS_SUCCESS
971 || status == NSS_STATUS_SUCCESS)
973 if ((req->ai_flags & AI_CANONNAME) != 0
974 && canon == NULL)
976 /* If we need the canonical name, get it
977 from the same service as the result. */
978 nss_getcanonname_r cfct;
979 int herrno;
981 cfct = __nss_lookup_function (nip,
982 "getcanonname_r");
983 if (cfct != NULL)
985 const size_t max_fqdn_len = 256;
986 if ((req->ai_flags & AI_CANONIDN) != 0
987 && __libc_use_alloca (alloca_used
988 + max_fqdn_len))
989 canonbuf = alloca_account (max_fqdn_len,
990 alloca_used);
991 else
993 canonbuf = malloc (max_fqdn_len);
994 if (canonbuf == NULL)
996 _res.options
997 |= old_res_options & RES_USE_INET6;
998 result = -EAI_MEMORY;
999 goto free_and_return;
1001 malloc_canonbuf = true;
1003 char *s;
1005 if (DL_CALL_FCT (cfct, (at->name ?: name,
1006 canonbuf,
1007 max_fqdn_len,
1008 &s, &rc, &herrno))
1009 == NSS_STATUS_SUCCESS)
1010 canon = s;
1011 else
1013 /* If the canonical name cannot be
1014 determined, use the passed in
1015 string. */
1016 if (malloc_canonbuf)
1018 free (canonbuf);
1019 malloc_canonbuf = false;
1021 canon = name;
1025 status = NSS_STATUS_SUCCESS;
1027 else
1029 /* We can have different states for AF_INET and
1030 AF_INET6. Try to find a useful one for both. */
1031 if (inet6_status == NSS_STATUS_TRYAGAIN)
1032 status = NSS_STATUS_TRYAGAIN;
1033 else if (status == NSS_STATUS_UNAVAIL
1034 && inet6_status != NSS_STATUS_UNAVAIL)
1035 status = inet6_status;
1038 else
1040 status = NSS_STATUS_UNAVAIL;
1041 /* Could not load any of the lookup functions. Indicate
1042 an internal error if the failure was due to a system
1043 error other than the file not being found. We use the
1044 errno from the last failed callback. */
1045 if (errno != 0 && errno != ENOENT)
1046 __set_h_errno (NETDB_INTERNAL);
1050 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1051 break;
1053 if (nip->next == NULL)
1054 no_more = -1;
1055 else
1056 nip = nip->next;
1059 _res.options |= old_res_options & RES_USE_INET6;
1061 if (h_errno == NETDB_INTERNAL)
1063 result = GAIH_OKIFUNSPEC | -EAI_SYSTEM;
1064 goto free_and_return;
1067 if (no_data != 0 && no_inet6_data != 0)
1069 /* If both requests timed out report this. */
1070 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1071 result = -EAI_AGAIN;
1072 else
1073 /* We made requests but they turned out no data. The name
1074 is known, though. */
1075 result = GAIH_OKIFUNSPEC | -EAI_NODATA;
1077 goto free_and_return;
1081 process_list:
1082 if (at->family == AF_UNSPEC)
1084 result = GAIH_OKIFUNSPEC | -EAI_NONAME;
1085 goto free_and_return;
1088 else
1090 struct gaih_addrtuple *atr;
1091 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1092 memset (at, '\0', sizeof (struct gaih_addrtuple));
1094 if (req->ai_family == AF_UNSPEC)
1096 at->next = __alloca (sizeof (struct gaih_addrtuple));
1097 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1100 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1102 at->family = AF_INET6;
1103 if ((req->ai_flags & AI_PASSIVE) == 0)
1104 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1105 atr = at->next;
1108 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1110 atr->family = AF_INET;
1111 if ((req->ai_flags & AI_PASSIVE) == 0)
1112 atr->addr[0] = htonl (INADDR_LOOPBACK);
1117 struct gaih_servtuple *st2;
1118 struct gaih_addrtuple *at2 = at;
1119 size_t socklen;
1120 sa_family_t family;
1123 buffer is the size of an unformatted IPv6 address in printable format.
1125 while (at2 != NULL)
1127 /* Only the first entry gets the canonical name. */
1128 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1130 if (canon == NULL)
1131 /* If the canonical name cannot be determined, use
1132 the passed in string. */
1133 canon = orig_name;
1135 #ifdef HAVE_LIBIDN
1136 if (req->ai_flags & AI_CANONIDN)
1138 int idn_flags = 0;
1139 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1140 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1141 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1142 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1144 char *out;
1145 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1146 if (rc != IDNA_SUCCESS)
1148 if (rc == IDNA_MALLOC_ERROR)
1149 result = -EAI_MEMORY;
1150 else if (rc == IDNA_DLOPEN_ERROR)
1151 result = -EAI_SYSTEM;
1152 else
1153 result = -EAI_IDN_ENCODE;
1154 goto free_and_return;
1156 /* In case the output string is the same as the input
1157 string no new string has been allocated and we
1158 make a copy. */
1159 if (out == canon)
1160 goto make_copy;
1161 canon = out;
1163 else
1164 #endif
1166 #ifdef HAVE_LIBIDN
1167 make_copy:
1168 #endif
1169 if (malloc_canonbuf)
1170 /* We already allocated the string using malloc. */
1171 malloc_canonbuf = false;
1172 else
1174 canon = strdup (canon);
1175 if (canon == NULL)
1177 result = -EAI_MEMORY;
1178 goto free_and_return;
1184 family = at2->family;
1185 if (family == AF_INET6)
1187 socklen = sizeof (struct sockaddr_in6);
1189 /* If we looked up IPv4 mapped address discard them here if
1190 the caller isn't interested in all address and we have
1191 found at least one IPv6 address. */
1192 if (got_ipv6
1193 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1194 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1195 goto ignore;
1197 else
1198 socklen = sizeof (struct sockaddr_in);
1200 for (st2 = st; st2 != NULL; st2 = st2->next)
1202 struct addrinfo *ai;
1203 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1204 if (ai == NULL)
1206 free ((char *) canon);
1207 result = -EAI_MEMORY;
1208 goto free_and_return;
1211 ai->ai_flags = req->ai_flags;
1212 ai->ai_family = family;
1213 ai->ai_socktype = st2->socktype;
1214 ai->ai_protocol = st2->protocol;
1215 ai->ai_addrlen = socklen;
1216 ai->ai_addr = (void *) (ai + 1);
1218 /* We only add the canonical name once. */
1219 ai->ai_canonname = (char *) canon;
1220 canon = NULL;
1222 #ifdef _HAVE_SA_LEN
1223 ai->ai_addr->sa_len = socklen;
1224 #endif /* _HAVE_SA_LEN */
1225 ai->ai_addr->sa_family = family;
1227 /* In case of an allocation error the list must be NULL
1228 terminated. */
1229 ai->ai_next = NULL;
1231 if (family == AF_INET6)
1233 struct sockaddr_in6 *sin6p =
1234 (struct sockaddr_in6 *) ai->ai_addr;
1236 sin6p->sin6_port = st2->port;
1237 sin6p->sin6_flowinfo = 0;
1238 memcpy (&sin6p->sin6_addr,
1239 at2->addr, sizeof (struct in6_addr));
1240 sin6p->sin6_scope_id = at2->scopeid;
1242 else
1244 struct sockaddr_in *sinp =
1245 (struct sockaddr_in *) ai->ai_addr;
1246 sinp->sin_port = st2->port;
1247 memcpy (&sinp->sin_addr,
1248 at2->addr, sizeof (struct in_addr));
1249 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1252 pai = &(ai->ai_next);
1255 ++*naddrs;
1257 ignore:
1258 at2 = at2->next;
1262 free_and_return:
1263 if (malloc_name)
1264 free ((char *) name);
1265 if (malloc_addrmem)
1266 free (addrmem);
1267 if (malloc_canonbuf)
1268 free (canonbuf);
1269 if (malloc_tmpbuf)
1270 free (tmpbuf);
1272 return result;
1276 struct sort_result
1278 struct addrinfo *dest_addr;
1279 /* Using sockaddr_storage is for now overkill. We only support IPv4
1280 and IPv6 so far. If this changes at some point we can adjust the
1281 type here. */
1282 struct sockaddr_in6 source_addr;
1283 uint8_t source_addr_len;
1284 bool got_source_addr;
1285 uint8_t source_addr_flags;
1286 uint8_t prefixlen;
1287 uint32_t index;
1288 int32_t native;
1291 struct sort_result_combo
1293 struct sort_result *results;
1294 int nresults;
1298 #if __BYTE_ORDER == __BIG_ENDIAN
1299 # define htonl_c(n) n
1300 #else
1301 # define htonl_c(n) __bswap_constant_32 (n)
1302 #endif
1304 static const struct scopeentry
1306 union
1308 char addr[4];
1309 uint32_t addr32;
1311 uint32_t netmask;
1312 int32_t scope;
1313 } default_scopes[] =
1315 /* Link-local addresses: scope 2. */
1316 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1317 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1318 /* Default: scope 14. */
1319 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1322 /* The label table. */
1323 static const struct scopeentry *scopes;
1326 static int
1327 get_scope (const struct sockaddr_in6 *in6)
1329 int scope;
1330 if (in6->sin6_family == PF_INET6)
1332 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1334 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1335 /* RFC 4291 2.5.3 says that the loopback address is to be
1336 treated like a link-local address. */
1337 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1338 scope = 2;
1339 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1340 scope = 5;
1341 else
1342 /* XXX Is this the correct default behavior? */
1343 scope = 14;
1345 else
1346 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1348 else if (in6->sin6_family == PF_INET)
1350 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1352 size_t cnt = 0;
1353 while (1)
1355 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1356 == scopes[cnt].addr32)
1357 return scopes[cnt].scope;
1359 ++cnt;
1361 /* NOTREACHED */
1363 else
1364 /* XXX What is a good default? */
1365 scope = 15;
1367 return scope;
1371 struct prefixentry
1373 struct in6_addr prefix;
1374 unsigned int bits;
1375 int val;
1379 /* The label table. */
1380 static const struct prefixentry *labels;
1382 /* Default labels. */
1383 static const struct prefixentry default_labels[] =
1385 /* See RFC 3484 for the details. */
1386 { { .__in6_u
1387 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1389 }, 128, 0 },
1390 { { .__in6_u
1391 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1393 }, 16, 2 },
1394 { { .__in6_u
1395 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1397 }, 96, 3 },
1398 { { .__in6_u
1399 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1401 }, 96, 4 },
1402 /* The next two entries differ from RFC 3484. We need to treat
1403 IPv6 site-local addresses special because they are never NATed,
1404 unlike site-locale IPv4 addresses. If this would not happen, on
1405 machines which have only IPv4 and IPv6 site-local addresses, the
1406 sorting would prefer the IPv6 site-local addresses, causing
1407 unnecessary delays when trying to connect to a global IPv6 address
1408 through a site-local IPv6 address. */
1409 { { .__in6_u
1410 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1412 }, 10, 5 },
1413 { { .__in6_u
1414 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1416 }, 7, 6 },
1417 /* Additional rule for Teredo tunnels. */
1418 { { .__in6_u
1419 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1421 }, 32, 7 },
1422 { { .__in6_u
1423 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1425 }, 0, 1 }
1429 /* The precedence table. */
1430 static const struct prefixentry *precedence;
1432 /* The default precedences. */
1433 static const struct prefixentry default_precedence[] =
1435 /* See RFC 3484 for the details. */
1436 { { .__in6_u
1437 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1439 }, 128, 50 },
1440 { { .__in6_u
1441 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1443 }, 16, 30 },
1444 { { .__in6_u
1445 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1447 }, 96, 20 },
1448 { { .__in6_u
1449 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1451 }, 96, 10 },
1452 { { .__in6_u
1453 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1455 }, 0, 40 }
1459 static int
1460 match_prefix (const struct sockaddr_in6 *in6,
1461 const struct prefixentry *list, int default_val)
1463 int idx;
1464 struct sockaddr_in6 in6_mem;
1466 if (in6->sin6_family == PF_INET)
1468 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1470 /* Construct a V4-to-6 mapped address. */
1471 in6_mem.sin6_family = PF_INET6;
1472 in6_mem.sin6_port = in->sin_port;
1473 in6_mem.sin6_flowinfo = 0;
1474 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1475 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1476 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1477 in6_mem.sin6_scope_id = 0;
1479 in6 = &in6_mem;
1481 else if (in6->sin6_family != PF_INET6)
1482 return default_val;
1484 for (idx = 0; ; ++idx)
1486 unsigned int bits = list[idx].bits;
1487 const uint8_t *mask = list[idx].prefix.s6_addr;
1488 const uint8_t *val = in6->sin6_addr.s6_addr;
1490 while (bits >= 8)
1492 if (*mask != *val)
1493 break;
1495 ++mask;
1496 ++val;
1497 bits -= 8;
1500 if (bits < 8)
1502 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1503 /* Match! */
1504 break;
1508 return list[idx].val;
1512 static int
1513 get_label (const struct sockaddr_in6 *in6)
1515 /* XXX What is a good default value? */
1516 return match_prefix (in6, labels, INT_MAX);
1520 static int
1521 get_precedence (const struct sockaddr_in6 *in6)
1523 /* XXX What is a good default value? */
1524 return match_prefix (in6, precedence, 0);
1528 /* Find last bit set in a word. */
1529 static int
1530 fls (uint32_t a)
1532 uint32_t mask;
1533 int n;
1534 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1535 if ((a & mask) != 0)
1536 break;
1537 return n;
1541 static int
1542 rfc3484_sort (const void *p1, const void *p2, void *arg)
1544 const size_t idx1 = *(const size_t *) p1;
1545 const size_t idx2 = *(const size_t *) p2;
1546 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1547 struct sort_result *a1 = &src->results[idx1];
1548 struct sort_result *a2 = &src->results[idx2];
1550 /* Rule 1: Avoid unusable destinations.
1551 We have the got_source_addr flag set if the destination is reachable. */
1552 if (a1->got_source_addr && ! a2->got_source_addr)
1553 return -1;
1554 if (! a1->got_source_addr && a2->got_source_addr)
1555 return 1;
1558 /* Rule 2: Prefer matching scope. Only interesting if both
1559 destination addresses are IPv6. */
1560 int a1_dst_scope
1561 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1563 int a2_dst_scope
1564 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1566 if (a1->got_source_addr)
1568 int a1_src_scope = get_scope (&a1->source_addr);
1569 int a2_src_scope = get_scope (&a2->source_addr);
1571 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1572 return -1;
1573 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1574 return 1;
1578 /* Rule 3: Avoid deprecated addresses. */
1579 if (a1->got_source_addr)
1581 if (!(a1->source_addr_flags & in6ai_deprecated)
1582 && (a2->source_addr_flags & in6ai_deprecated))
1583 return -1;
1584 if ((a1->source_addr_flags & in6ai_deprecated)
1585 && !(a2->source_addr_flags & in6ai_deprecated))
1586 return 1;
1589 /* Rule 4: Prefer home addresses. */
1590 if (a1->got_source_addr)
1592 if (!(a1->source_addr_flags & in6ai_homeaddress)
1593 && (a2->source_addr_flags & in6ai_homeaddress))
1594 return 1;
1595 if ((a1->source_addr_flags & in6ai_homeaddress)
1596 && !(a2->source_addr_flags & in6ai_homeaddress))
1597 return -1;
1600 /* Rule 5: Prefer matching label. */
1601 if (a1->got_source_addr)
1603 int a1_dst_label
1604 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1605 int a1_src_label = get_label (&a1->source_addr);
1607 int a2_dst_label
1608 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1609 int a2_src_label = get_label (&a2->source_addr);
1611 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1612 return -1;
1613 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1614 return 1;
1618 /* Rule 6: Prefer higher precedence. */
1619 int a1_prec
1620 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1621 int a2_prec
1622 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1624 if (a1_prec > a2_prec)
1625 return -1;
1626 if (a1_prec < a2_prec)
1627 return 1;
1630 /* Rule 7: Prefer native transport. */
1631 if (a1->got_source_addr)
1633 /* The same interface index means the same interface which means
1634 there is no difference in transport. This should catch many
1635 (most?) cases. */
1636 if (a1->index != a2->index)
1638 int a1_native = a1->native;
1639 int a2_native = a2->native;
1641 if (a1_native == -1 || a2_native == -1)
1643 uint32_t a1_index;
1644 if (a1_native == -1)
1646 /* If we do not have the information use 'native' as
1647 the default. */
1648 a1_native = 0;
1649 a1_index = a1->index;
1651 else
1652 a1_index = 0xffffffffu;
1654 uint32_t a2_index;
1655 if (a2_native == -1)
1657 /* If we do not have the information use 'native' as
1658 the default. */
1659 a2_native = 0;
1660 a2_index = a2->index;
1662 else
1663 a2_index = 0xffffffffu;
1665 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1667 /* Fill in the results in all the records. */
1668 for (int i = 0; i < src->nresults; ++i)
1669 if (src->results[i].index == a1_index)
1671 assert (src->results[i].native == -1
1672 || src->results[i].native == a1_native);
1673 src->results[i].native = a1_native;
1675 else if (src->results[i].index == a2_index)
1677 assert (src->results[i].native == -1
1678 || src->results[i].native == a2_native);
1679 src->results[i].native = a2_native;
1683 if (a1_native && !a2_native)
1684 return -1;
1685 if (!a1_native && a2_native)
1686 return 1;
1691 /* Rule 8: Prefer smaller scope. */
1692 if (a1_dst_scope < a2_dst_scope)
1693 return -1;
1694 if (a1_dst_scope > a2_dst_scope)
1695 return 1;
1698 /* Rule 9: Use longest matching prefix. */
1699 if (a1->got_source_addr
1700 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1702 int bit1 = 0;
1703 int bit2 = 0;
1705 if (a1->dest_addr->ai_family == PF_INET)
1707 assert (a1->source_addr.sin6_family == PF_INET);
1708 assert (a2->source_addr.sin6_family == PF_INET);
1710 /* Outside of subnets, as defined by the network masks,
1711 common address prefixes for IPv4 addresses make no sense.
1712 So, define a non-zero value only if source and
1713 destination address are on the same subnet. */
1714 struct sockaddr_in *in1_dst
1715 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1716 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1717 struct sockaddr_in *in1_src
1718 = (struct sockaddr_in *) &a1->source_addr;
1719 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1720 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1722 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1723 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1725 struct sockaddr_in *in2_dst
1726 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1727 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1728 struct sockaddr_in *in2_src
1729 = (struct sockaddr_in *) &a2->source_addr;
1730 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1731 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1733 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1734 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1736 else if (a1->dest_addr->ai_family == PF_INET6)
1738 assert (a1->source_addr.sin6_family == PF_INET6);
1739 assert (a2->source_addr.sin6_family == PF_INET6);
1741 struct sockaddr_in6 *in1_dst;
1742 struct sockaddr_in6 *in1_src;
1743 struct sockaddr_in6 *in2_dst;
1744 struct sockaddr_in6 *in2_src;
1746 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1747 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1748 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1749 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1751 int i;
1752 for (i = 0; i < 4; ++i)
1753 if (in1_dst->sin6_addr.s6_addr32[i]
1754 != in1_src->sin6_addr.s6_addr32[i]
1755 || (in2_dst->sin6_addr.s6_addr32[i]
1756 != in2_src->sin6_addr.s6_addr32[i]))
1757 break;
1759 if (i < 4)
1761 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1762 ^ in1_src->sin6_addr.s6_addr32[i]));
1763 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1764 ^ in2_src->sin6_addr.s6_addr32[i]));
1768 if (bit1 > bit2)
1769 return -1;
1770 if (bit1 < bit2)
1771 return 1;
1775 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1776 compare with the value indicating the order in which the entries
1777 have been received from the services. NB: no two entries can have
1778 the same order so the test will never return zero. */
1779 return idx1 < idx2 ? -1 : 1;
1783 static int
1784 in6aicmp (const void *p1, const void *p2)
1786 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1787 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1789 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1793 /* Name of the config file for RFC 3484 sorting (for now). */
1794 #define GAICONF_FNAME "/etc/gai.conf"
1797 /* Non-zero if we are supposed to reload the config file automatically
1798 whenever it changed. */
1799 static int gaiconf_reload_flag;
1801 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1802 static int gaiconf_reload_flag_ever_set;
1804 /* Last modification time. */
1805 #ifdef _STATBUF_ST_NSEC
1807 static struct timespec gaiconf_mtime;
1809 static inline void
1810 save_gaiconf_mtime (const struct stat64 *st)
1812 gaiconf_mtime = st->st_mtim;
1815 static inline bool
1816 check_gaiconf_mtime (const struct stat64 *st)
1818 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1819 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1822 #else
1824 static time_t gaiconf_mtime;
1826 static inline void
1827 save_gaiconf_mtime (const struct stat64 *st)
1829 gaiconf_mtime = st->st_mtime;
1832 static inline bool
1833 check_gaiconf_mtime (const struct stat64 *st)
1835 return st->st_mtime == gaiconf_mtime;
1838 #endif
1841 libc_freeres_fn(fini)
1843 if (labels != default_labels)
1845 const struct prefixentry *old = labels;
1846 labels = default_labels;
1847 free ((void *) old);
1850 if (precedence != default_precedence)
1852 const struct prefixentry *old = precedence;
1853 precedence = default_precedence;
1854 free ((void *) old);
1857 if (scopes != default_scopes)
1859 const struct scopeentry *old = scopes;
1860 scopes = default_scopes;
1861 free ((void *) old);
1866 struct prefixlist
1868 struct prefixentry entry;
1869 struct prefixlist *next;
1873 struct scopelist
1875 struct scopeentry entry;
1876 struct scopelist *next;
1880 static void
1881 free_prefixlist (struct prefixlist *list)
1883 while (list != NULL)
1885 struct prefixlist *oldp = list;
1886 list = list->next;
1887 free (oldp);
1892 static void
1893 free_scopelist (struct scopelist *list)
1895 while (list != NULL)
1897 struct scopelist *oldp = list;
1898 list = list->next;
1899 free (oldp);
1904 static int
1905 prefixcmp (const void *p1, const void *p2)
1907 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1908 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1910 if (e1->bits < e2->bits)
1911 return 1;
1912 if (e1->bits == e2->bits)
1913 return 0;
1914 return -1;
1918 static int
1919 scopecmp (const void *p1, const void *p2)
1921 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1922 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1924 if (e1->netmask > e2->netmask)
1925 return -1;
1926 if (e1->netmask == e2->netmask)
1927 return 0;
1928 return 1;
1932 static void
1933 gaiconf_init (void)
1935 struct prefixlist *labellist = NULL;
1936 size_t nlabellist = 0;
1937 bool labellist_nullbits = false;
1938 struct prefixlist *precedencelist = NULL;
1939 size_t nprecedencelist = 0;
1940 bool precedencelist_nullbits = false;
1941 struct scopelist *scopelist = NULL;
1942 size_t nscopelist = 0;
1943 bool scopelist_nullbits = false;
1945 FILE *fp = fopen (GAICONF_FNAME, "rce");
1946 if (fp != NULL)
1948 struct stat64 st;
1949 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1951 fclose (fp);
1952 goto no_file;
1955 char *line = NULL;
1956 size_t linelen = 0;
1958 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1960 while (!feof_unlocked (fp))
1962 ssize_t n = __getline (&line, &linelen, fp);
1963 if (n <= 0)
1964 break;
1966 /* Handle comments. No escaping possible so this is easy. */
1967 char *cp = strchr (line, '#');
1968 if (cp != NULL)
1969 *cp = '\0';
1971 cp = line;
1972 while (isspace (*cp))
1973 ++cp;
1975 char *cmd = cp;
1976 while (*cp != '\0' && !isspace (*cp))
1977 ++cp;
1978 size_t cmdlen = cp - cmd;
1980 if (*cp != '\0')
1981 *cp++ = '\0';
1982 while (isspace (*cp))
1983 ++cp;
1985 char *val1 = cp;
1986 while (*cp != '\0' && !isspace (*cp))
1987 ++cp;
1988 size_t val1len = cp - cmd;
1990 /* We always need at least two values. */
1991 if (val1len == 0)
1992 continue;
1994 if (*cp != '\0')
1995 *cp++ = '\0';
1996 while (isspace (*cp))
1997 ++cp;
1999 char *val2 = cp;
2000 while (*cp != '\0' && !isspace (*cp))
2001 ++cp;
2003 /* Ignore the rest of the line. */
2004 *cp = '\0';
2006 struct prefixlist **listp;
2007 size_t *lenp;
2008 bool *nullbitsp;
2009 switch (cmdlen)
2011 case 5:
2012 if (strcmp (cmd, "label") == 0)
2014 struct in6_addr prefix;
2015 unsigned long int bits;
2016 unsigned long int val;
2017 char *endp;
2019 listp = &labellist;
2020 lenp = &nlabellist;
2021 nullbitsp = &labellist_nullbits;
2023 new_elem:
2024 bits = 128;
2025 __set_errno (0);
2026 cp = strchr (val1, '/');
2027 if (cp != NULL)
2028 *cp++ = '\0';
2029 if (inet_pton (AF_INET6, val1, &prefix)
2030 && (cp == NULL
2031 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2032 || errno != ERANGE)
2033 && *endp == '\0'
2034 && bits <= 128
2035 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2036 || errno != ERANGE)
2037 && *endp == '\0'
2038 && val <= INT_MAX)
2040 struct prefixlist *newp = malloc (sizeof (*newp));
2041 if (newp == NULL)
2043 free (line);
2044 fclose (fp);
2045 goto no_file;
2048 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2049 newp->entry.bits = bits;
2050 newp->entry.val = val;
2051 newp->next = *listp;
2052 *listp = newp;
2053 ++*lenp;
2054 *nullbitsp |= bits == 0;
2057 break;
2059 case 6:
2060 if (strcmp (cmd, "reload") == 0)
2062 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2063 if (gaiconf_reload_flag)
2064 gaiconf_reload_flag_ever_set = 1;
2066 break;
2068 case 7:
2069 if (strcmp (cmd, "scopev4") == 0)
2071 struct in6_addr prefix;
2072 unsigned long int bits;
2073 unsigned long int val;
2074 char *endp;
2076 bits = 32;
2077 __set_errno (0);
2078 cp = strchr (val1, '/');
2079 if (cp != NULL)
2080 *cp++ = '\0';
2081 if (inet_pton (AF_INET6, val1, &prefix))
2083 bits = 128;
2084 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2085 && (cp == NULL
2086 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2087 || errno != ERANGE)
2088 && *endp == '\0'
2089 && bits >= 96
2090 && bits <= 128
2091 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2092 || errno != ERANGE)
2093 && *endp == '\0'
2094 && val <= INT_MAX)
2096 struct scopelist *newp;
2097 new_scope:
2098 newp = malloc (sizeof (*newp));
2099 if (newp == NULL)
2101 free (line);
2102 fclose (fp);
2103 goto no_file;
2106 newp->entry.netmask = htonl (bits != 96
2107 ? (0xffffffff
2108 << (128 - bits))
2109 : 0);
2110 newp->entry.addr32 = (prefix.s6_addr32[3]
2111 & newp->entry.netmask);
2112 newp->entry.scope = val;
2113 newp->next = scopelist;
2114 scopelist = newp;
2115 ++nscopelist;
2116 scopelist_nullbits |= bits == 96;
2119 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2120 && (cp == NULL
2121 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2122 || errno != ERANGE)
2123 && *endp == '\0'
2124 && bits <= 32
2125 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2126 || errno != ERANGE)
2127 && *endp == '\0'
2128 && val <= INT_MAX)
2130 bits += 96;
2131 goto new_scope;
2134 break;
2136 case 10:
2137 if (strcmp (cmd, "precedence") == 0)
2139 listp = &precedencelist;
2140 lenp = &nprecedencelist;
2141 nullbitsp = &precedencelist_nullbits;
2142 goto new_elem;
2144 break;
2148 free (line);
2150 fclose (fp);
2152 /* Create the array for the labels. */
2153 struct prefixentry *new_labels;
2154 if (nlabellist > 0)
2156 if (!labellist_nullbits)
2157 ++nlabellist;
2158 new_labels = malloc (nlabellist * sizeof (*new_labels));
2159 if (new_labels == NULL)
2160 goto no_file;
2162 int i = nlabellist;
2163 if (!labellist_nullbits)
2165 --i;
2166 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2167 new_labels[i].bits = 0;
2168 new_labels[i].val = 1;
2171 struct prefixlist *l = labellist;
2172 while (i-- > 0)
2174 new_labels[i] = l->entry;
2175 l = l->next;
2177 free_prefixlist (labellist);
2179 /* Sort the entries so that the most specific ones are at
2180 the beginning. */
2181 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2183 else
2184 new_labels = (struct prefixentry *) default_labels;
2186 struct prefixentry *new_precedence;
2187 if (nprecedencelist > 0)
2189 if (!precedencelist_nullbits)
2190 ++nprecedencelist;
2191 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2192 if (new_precedence == NULL)
2194 if (new_labels != default_labels)
2195 free (new_labels);
2196 goto no_file;
2199 int i = nprecedencelist;
2200 if (!precedencelist_nullbits)
2202 --i;
2203 memset (&new_precedence[i].prefix, '\0',
2204 sizeof (struct in6_addr));
2205 new_precedence[i].bits = 0;
2206 new_precedence[i].val = 40;
2209 struct prefixlist *l = precedencelist;
2210 while (i-- > 0)
2212 new_precedence[i] = l->entry;
2213 l = l->next;
2215 free_prefixlist (precedencelist);
2217 /* Sort the entries so that the most specific ones are at
2218 the beginning. */
2219 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2220 prefixcmp);
2222 else
2223 new_precedence = (struct prefixentry *) default_precedence;
2225 struct scopeentry *new_scopes;
2226 if (nscopelist > 0)
2228 if (!scopelist_nullbits)
2229 ++nscopelist;
2230 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2231 if (new_scopes == NULL)
2233 if (new_labels != default_labels)
2234 free (new_labels);
2235 if (new_precedence != default_precedence)
2236 free (new_precedence);
2237 goto no_file;
2240 int i = nscopelist;
2241 if (!scopelist_nullbits)
2243 --i;
2244 new_scopes[i].addr32 = 0;
2245 new_scopes[i].netmask = 0;
2246 new_scopes[i].scope = 14;
2249 struct scopelist *l = scopelist;
2250 while (i-- > 0)
2252 new_scopes[i] = l->entry;
2253 l = l->next;
2255 free_scopelist (scopelist);
2257 /* Sort the entries so that the most specific ones are at
2258 the beginning. */
2259 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2260 scopecmp);
2262 else
2263 new_scopes = (struct scopeentry *) default_scopes;
2265 /* Now we are ready to replace the values. */
2266 const struct prefixentry *old = labels;
2267 labels = new_labels;
2268 if (old != default_labels)
2269 free ((void *) old);
2271 old = precedence;
2272 precedence = new_precedence;
2273 if (old != default_precedence)
2274 free ((void *) old);
2276 const struct scopeentry *oldscope = scopes;
2277 scopes = new_scopes;
2278 if (oldscope != default_scopes)
2279 free ((void *) oldscope);
2281 save_gaiconf_mtime (&st);
2283 else
2285 no_file:
2286 free_prefixlist (labellist);
2287 free_prefixlist (precedencelist);
2288 free_scopelist (scopelist);
2290 /* If we previously read the file but it is gone now, free the
2291 old data and use the builtin one. Leave the reload flag
2292 alone. */
2293 fini ();
2298 static void
2299 gaiconf_reload (void)
2301 struct stat64 st;
2302 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2303 || !check_gaiconf_mtime (&st))
2304 gaiconf_init ();
2309 getaddrinfo (const char *name, const char *service,
2310 const struct addrinfo *hints, struct addrinfo **pai)
2312 int i = 0, last_i = 0;
2313 int nresults = 0;
2314 struct addrinfo *p = NULL;
2315 struct gaih_service gaih_service, *pservice;
2316 struct addrinfo local_hints;
2318 if (name != NULL && name[0] == '*' && name[1] == 0)
2319 name = NULL;
2321 if (service != NULL && service[0] == '*' && service[1] == 0)
2322 service = NULL;
2324 if (name == NULL && service == NULL)
2325 return EAI_NONAME;
2327 if (hints == NULL)
2328 hints = &default_hints;
2330 if (hints->ai_flags
2331 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2332 #ifdef HAVE_LIBIDN
2333 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2334 |AI_IDN_USE_STD3_ASCII_RULES
2335 #endif
2336 |AI_NUMERICSERV|AI_ALL))
2337 return EAI_BADFLAGS;
2339 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2340 return EAI_BADFLAGS;
2342 struct in6addrinfo *in6ai = NULL;
2343 size_t in6ailen = 0;
2344 bool seen_ipv4 = false;
2345 bool seen_ipv6 = false;
2346 bool check_pf_called = false;
2348 if (hints->ai_flags & AI_ADDRCONFIG)
2350 /* We might need information about what interfaces are available.
2351 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2352 cannot cache the results since new interfaces could be added at
2353 any time. */
2354 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2355 check_pf_called = true;
2357 /* Now make a decision on what we return, if anything. */
2358 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2360 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2361 narrow down the search. */
2362 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2364 local_hints = *hints;
2365 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2366 hints = &local_hints;
2369 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2370 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2372 /* We cannot possibly return a valid answer. */
2373 __free_in6ai (in6ai);
2374 return EAI_NONAME;
2378 if (service && service[0])
2380 char *c;
2381 gaih_service.name = service;
2382 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2383 if (*c != '\0')
2385 if (hints->ai_flags & AI_NUMERICSERV)
2387 __free_in6ai (in6ai);
2388 return EAI_NONAME;
2391 gaih_service.num = -1;
2394 pservice = &gaih_service;
2396 else
2397 pservice = NULL;
2399 struct addrinfo **end = &p;
2401 unsigned int naddrs = 0;
2402 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2403 || hints->ai_family == AF_INET6)
2405 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2406 if (last_i != 0)
2408 freeaddrinfo (p);
2409 __free_in6ai (in6ai);
2411 return -(last_i & GAIH_EAI);
2413 while (*end)
2415 end = &((*end)->ai_next);
2416 ++nresults;
2419 else
2421 __free_in6ai (in6ai);
2422 return EAI_FAMILY;
2425 if (naddrs > 1)
2427 /* Read the config file. */
2428 __libc_once_define (static, once);
2429 __typeof (once) old_once = once;
2430 __libc_once (once, gaiconf_init);
2431 /* Sort results according to RFC 3484. */
2432 struct sort_result *results;
2433 size_t *order;
2434 struct addrinfo *q;
2435 struct addrinfo *last = NULL;
2436 char *canonname = NULL;
2437 bool malloc_results;
2438 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2440 malloc_results
2441 = !__libc_use_alloca (alloc_size);
2442 if (malloc_results)
2444 results = malloc (alloc_size);
2445 if (results == NULL)
2447 __free_in6ai (in6ai);
2448 return EAI_MEMORY;
2451 else
2452 results = alloca (alloc_size);
2453 order = (size_t *) (results + nresults);
2455 /* Now we definitely need the interface information. */
2456 if (! check_pf_called)
2457 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2459 /* If we have information about deprecated and temporary addresses
2460 sort the array now. */
2461 if (in6ai != NULL)
2462 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2464 int fd = -1;
2465 int af = AF_UNSPEC;
2467 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2469 results[i].dest_addr = q;
2470 results[i].native = -1;
2471 order[i] = i;
2473 /* If we just looked up the address for a different
2474 protocol, reuse the result. */
2475 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2476 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2478 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2479 results[i - 1].source_addr_len);
2480 results[i].source_addr_len = results[i - 1].source_addr_len;
2481 results[i].got_source_addr = results[i - 1].got_source_addr;
2482 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2483 results[i].prefixlen = results[i - 1].prefixlen;
2484 results[i].index = results[i - 1].index;
2486 else
2488 results[i].got_source_addr = false;
2489 results[i].source_addr_flags = 0;
2490 results[i].prefixlen = 0;
2491 results[i].index = 0xffffffffu;
2493 /* We overwrite the type with SOCK_DGRAM since we do not
2494 want connect() to connect to the other side. If we
2495 cannot determine the source address remember this
2496 fact. */
2497 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2499 if (fd != -1)
2500 close_retry:
2501 close_not_cancel_no_status (fd);
2502 af = q->ai_family;
2503 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2505 else
2507 /* Reset the connection. */
2508 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2509 __connect (fd, &sa, sizeof (sa));
2512 socklen_t sl = sizeof (results[i].source_addr);
2513 if (fd != -1
2514 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2515 && __getsockname (fd,
2516 (struct sockaddr *) &results[i].source_addr,
2517 &sl) == 0)
2519 results[i].source_addr_len = sl;
2520 results[i].got_source_addr = true;
2522 if (in6ai != NULL)
2524 /* See whether the source address is on the list of
2525 deprecated or temporary addresses. */
2526 struct in6addrinfo tmp;
2528 if (q->ai_family == AF_INET && af == AF_INET)
2530 struct sockaddr_in *sinp
2531 = (struct sockaddr_in *) &results[i].source_addr;
2532 tmp.addr[0] = 0;
2533 tmp.addr[1] = 0;
2534 tmp.addr[2] = htonl (0xffff);
2535 tmp.addr[3] = sinp->sin_addr.s_addr;
2537 else
2539 struct sockaddr_in6 *sin6p
2540 = (struct sockaddr_in6 *) &results[i].source_addr;
2541 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2544 struct in6addrinfo *found
2545 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2546 in6aicmp);
2547 if (found != NULL)
2549 results[i].source_addr_flags = found->flags;
2550 results[i].prefixlen = found->prefixlen;
2551 results[i].index = found->index;
2555 if (q->ai_family == AF_INET && af == AF_INET6)
2557 /* We have to convert the address. The socket is
2558 IPv6 and the request is for IPv4. */
2559 struct sockaddr_in6 *sin6
2560 = (struct sockaddr_in6 *) &results[i].source_addr;
2561 struct sockaddr_in *sin
2562 = (struct sockaddr_in *) &results[i].source_addr;
2563 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2564 sin->sin_family = AF_INET;
2565 /* We do not have to initialize sin_port since this
2566 fields has the same position and size in the IPv6
2567 structure. */
2568 assert (offsetof (struct sockaddr_in, sin_port)
2569 == offsetof (struct sockaddr_in6, sin6_port));
2570 assert (sizeof (sin->sin_port)
2571 == sizeof (sin6->sin6_port));
2572 memcpy (&sin->sin_addr,
2573 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2574 results[i].source_addr_len = sizeof (struct sockaddr_in);
2577 else if (errno == EAFNOSUPPORT && af == AF_INET6
2578 && q->ai_family == AF_INET)
2579 /* This could mean IPv6 sockets are IPv6-only. */
2580 goto close_retry;
2581 else
2582 /* Just make sure that if we have to process the same
2583 address again we do not copy any memory. */
2584 results[i].source_addr_len = 0;
2587 /* Remember the canonical name. */
2588 if (q->ai_canonname != NULL)
2590 assert (canonname == NULL);
2591 canonname = q->ai_canonname;
2592 q->ai_canonname = NULL;
2596 if (fd != -1)
2597 close_not_cancel_no_status (fd);
2599 /* We got all the source addresses we can get, now sort using
2600 the information. */
2601 struct sort_result_combo src
2602 = { .results = results, .nresults = nresults };
2603 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2605 __libc_lock_define_initialized (static, lock);
2607 __libc_lock_lock (lock);
2608 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2609 gaiconf_reload ();
2610 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2611 __libc_lock_unlock (lock);
2613 else
2614 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2616 /* Queue the results up as they come out of sorting. */
2617 q = p = results[order[0]].dest_addr;
2618 for (i = 1; i < nresults; ++i)
2619 q = q->ai_next = results[order[i]].dest_addr;
2620 q->ai_next = NULL;
2622 /* Fill in the canonical name into the new first entry. */
2623 p->ai_canonname = canonname;
2625 if (malloc_results)
2626 free (results);
2629 __free_in6ai (in6ai);
2631 if (p)
2633 *pai = p;
2634 return 0;
2637 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2639 libc_hidden_def (getaddrinfo)
2641 nss_interface_function (getaddrinfo)
2643 void
2644 freeaddrinfo (struct addrinfo *ai)
2646 struct addrinfo *p;
2648 while (ai != NULL)
2650 p = ai;
2651 ai = ai->ai_next;
2652 free (p->ai_canonname);
2653 free (p);
2656 libc_hidden_def (freeaddrinfo)