Update version.h and include/features.h for 2.19 release
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob8218237af23c4b59282a52a89fcd11bf559b990c
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 struct gaih_service
76 const char *name;
77 int num;
80 struct gaih_servtuple
82 struct gaih_servtuple *next;
83 int socktype;
84 int protocol;
85 int port;
88 static const struct gaih_servtuple nullserv;
91 struct gaih_typeproto
93 int socktype;
94 int protocol;
95 uint8_t protoflag;
96 bool defaultflag;
97 char name[8];
100 /* Values for `protoflag'. */
101 #define GAI_PROTO_NOSERVICE 1
102 #define GAI_PROTO_PROTOANY 2
104 static const struct gaih_typeproto gaih_inet_typeproto[] =
106 { 0, 0, 0, false, "" },
107 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
108 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
109 #if defined SOCK_DCCP && defined IPPROTO_DCCP
110 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
111 #endif
112 #ifdef IPPROTO_UDPLITE
113 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
114 #endif
115 #ifdef IPPROTO_SCTP
116 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
117 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
118 #endif
119 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
120 { 0, 0, 0, false, "" }
123 static const struct addrinfo default_hints =
125 .ai_flags = AI_DEFAULT,
126 .ai_family = PF_UNSPEC,
127 .ai_socktype = 0,
128 .ai_protocol = 0,
129 .ai_addrlen = 0,
130 .ai_addr = NULL,
131 .ai_canonname = NULL,
132 .ai_next = NULL
136 static int
137 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
138 const struct addrinfo *req, struct gaih_servtuple *st)
140 struct servent *s;
141 size_t tmpbuflen = 1024;
142 struct servent ts;
143 char *tmpbuf;
144 int r;
148 tmpbuf = __alloca (tmpbuflen);
150 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
151 &s);
152 if (r != 0 || s == NULL)
154 if (r == ERANGE)
155 tmpbuflen *= 2;
156 else
157 return -EAI_SERVICE;
160 while (r);
162 st->next = NULL;
163 st->socktype = tp->socktype;
164 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
165 ? req->ai_protocol : tp->protocol);
166 st->port = s->s_port;
168 return 0;
171 #define gethosts(_family, _type) \
173 int i; \
174 int herrno; \
175 struct hostent th; \
176 struct hostent *h; \
177 char *localcanon = NULL; \
178 no_data = 0; \
179 while (1) { \
180 rc = 0; \
181 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
182 &rc, &herrno, NULL, &localcanon)); \
183 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
184 break; \
185 if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
186 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
187 alloca_used); \
188 else \
190 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
191 2 * tmpbuflen); \
192 if (newp == NULL) \
194 result = -EAI_MEMORY; \
195 goto free_and_return; \
197 tmpbuf = newp; \
198 malloc_tmpbuf = true; \
199 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 result = -EAI_SYSTEM; \
213 goto free_and_return; \
215 if (herrno == TRY_AGAIN) \
216 no_data = EAI_AGAIN; \
217 else \
218 no_data = herrno == NO_DATA; \
220 else if (h != NULL) \
222 for (i = 0; h->h_addr_list[i]; i++) \
224 if (*pat == NULL) \
226 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
227 (*pat)->scopeid = 0; \
229 uint32_t *addr = (*pat)->addr; \
230 (*pat)->next = NULL; \
231 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
232 if (_family == AF_INET && req->ai_family == AF_INET6) \
234 (*pat)->family = AF_INET6; \
235 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
236 addr[2] = htonl (0xffff); \
237 addr[1] = 0; \
238 addr[0] = 0; \
240 else \
242 (*pat)->family = _family; \
243 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
245 pat = &((*pat)->next); \
248 if (localcanon != NULL && canon == NULL) \
249 canon = strdupa (localcanon); \
251 if (_family == AF_INET6 && i > 0) \
252 got_ipv6 = true; \
257 typedef enum nss_status (*nss_gethostbyname4_r)
258 (const char *name, struct gaih_addrtuple **pat,
259 char *buffer, size_t buflen, int *errnop,
260 int *h_errnop, int32_t *ttlp);
261 typedef enum nss_status (*nss_gethostbyname3_r)
262 (const char *name, int af, struct hostent *host,
263 char *buffer, size_t buflen, int *errnop,
264 int *h_errnop, int32_t *ttlp, char **canonp);
265 typedef enum nss_status (*nss_getcanonname_r)
266 (const char *name, char *buffer, size_t buflen, char **result,
267 int *errnop, int *h_errnop);
268 extern service_user *__nss_hosts_database attribute_hidden;
271 static int
272 gaih_inet (const char *name, const struct gaih_service *service,
273 const struct addrinfo *req, struct addrinfo **pai,
274 unsigned int *naddrs)
276 const struct gaih_typeproto *tp = gaih_inet_typeproto;
277 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
278 struct gaih_addrtuple *at = NULL;
279 int rc;
280 bool got_ipv6 = false;
281 const char *canon = NULL;
282 const char *orig_name = name;
283 size_t alloca_used = 0;
285 if (req->ai_protocol || req->ai_socktype)
287 ++tp;
289 while (tp->name[0]
290 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
291 || (req->ai_protocol != 0
292 && !(tp->protoflag & GAI_PROTO_PROTOANY)
293 && req->ai_protocol != tp->protocol)))
294 ++tp;
296 if (! tp->name[0])
298 if (req->ai_socktype)
299 return -EAI_SOCKTYPE;
300 else
301 return -EAI_SERVICE;
305 int port = 0;
306 if (service != NULL)
308 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
309 return -EAI_SERVICE;
311 if (service->num < 0)
313 if (tp->name[0])
315 st = (struct gaih_servtuple *)
316 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
318 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
319 return rc;
321 else
323 struct gaih_servtuple **pst = &st;
324 for (tp++; tp->name[0]; tp++)
326 struct gaih_servtuple *newp;
328 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
329 continue;
331 if (req->ai_socktype != 0
332 && req->ai_socktype != tp->socktype)
333 continue;
334 if (req->ai_protocol != 0
335 && !(tp->protoflag & GAI_PROTO_PROTOANY)
336 && req->ai_protocol != tp->protocol)
337 continue;
339 newp = (struct gaih_servtuple *)
340 alloca_account (sizeof (struct gaih_servtuple),
341 alloca_used);
343 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
345 if (rc)
346 continue;
347 return rc;
350 *pst = newp;
351 pst = &(newp->next);
353 if (st == (struct gaih_servtuple *) &nullserv)
354 return -EAI_SERVICE;
357 else
359 port = htons (service->num);
360 goto got_port;
363 else
365 got_port:
367 if (req->ai_socktype || req->ai_protocol)
369 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
370 st->next = NULL;
371 st->socktype = tp->socktype;
372 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
373 ? req->ai_protocol : tp->protocol);
374 st->port = port;
376 else
378 /* Neither socket type nor protocol is set. Return all socket types
379 we know about. */
380 struct gaih_servtuple **lastp = &st;
381 for (++tp; tp->name[0]; ++tp)
382 if (tp->defaultflag)
384 struct gaih_servtuple *newp;
386 newp = alloca_account (sizeof (struct gaih_servtuple),
387 alloca_used);
388 newp->next = NULL;
389 newp->socktype = tp->socktype;
390 newp->protocol = tp->protocol;
391 newp->port = port;
393 *lastp = newp;
394 lastp = &newp->next;
399 bool malloc_name = false;
400 bool malloc_addrmem = false;
401 struct gaih_addrtuple *addrmem = NULL;
402 bool malloc_canonbuf = false;
403 char *canonbuf = NULL;
404 bool malloc_tmpbuf = false;
405 char *tmpbuf = NULL;
406 int result = 0;
407 if (name != NULL)
409 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
410 at->family = AF_UNSPEC;
411 at->scopeid = 0;
412 at->next = NULL;
414 #ifdef HAVE_LIBIDN
415 if (req->ai_flags & AI_IDN)
417 int idn_flags = 0;
418 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
419 idn_flags |= IDNA_ALLOW_UNASSIGNED;
420 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
421 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
423 char *p = NULL;
424 rc = __idna_to_ascii_lz (name, &p, idn_flags);
425 if (rc != IDNA_SUCCESS)
427 /* No need to jump to free_and_return here. */
428 if (rc == IDNA_MALLOC_ERROR)
429 return -EAI_MEMORY;
430 if (rc == IDNA_DLOPEN_ERROR)
431 return -EAI_SYSTEM;
432 return -EAI_IDN_ENCODE;
434 /* In case the output string is the same as the input string
435 no new string has been allocated. */
436 if (p != name)
438 name = p;
439 malloc_name = true;
442 #endif
444 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
446 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
447 at->family = AF_INET;
448 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
450 at->addr[3] = at->addr[0];
451 at->addr[2] = htonl (0xffff);
452 at->addr[1] = 0;
453 at->addr[0] = 0;
454 at->family = AF_INET6;
456 else
458 result = -EAI_ADDRFAMILY;
459 goto free_and_return;
462 if (req->ai_flags & AI_CANONNAME)
463 canon = name;
465 else if (at->family == AF_UNSPEC)
467 char *scope_delim = strchr (name, SCOPE_DELIMITER);
468 int e;
471 bool malloc_namebuf = false;
472 char *namebuf = (char *) name;
474 if (__builtin_expect (scope_delim != NULL, 0))
476 if (malloc_name)
477 *scope_delim = '\0';
478 else
480 if (__libc_use_alloca (alloca_used
481 + scope_delim - name + 1))
483 namebuf = alloca_account (scope_delim - name + 1,
484 alloca_used);
485 *((char *) __mempcpy (namebuf, name,
486 scope_delim - name)) = '\0';
488 else
490 namebuf = strndup (name, scope_delim - name);
491 if (namebuf == NULL)
493 assert (!malloc_name);
494 return -EAI_MEMORY;
496 malloc_namebuf = true;
501 e = inet_pton (AF_INET6, namebuf, at->addr);
503 if (malloc_namebuf)
504 free (namebuf);
505 else if (scope_delim != NULL && malloc_name)
506 /* Undo what we did above. */
507 *scope_delim = SCOPE_DELIMITER;
509 if (e > 0)
511 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
512 at->family = AF_INET6;
513 else if (req->ai_family == AF_INET
514 && IN6_IS_ADDR_V4MAPPED (at->addr))
516 at->addr[0] = at->addr[3];
517 at->family = AF_INET;
519 else
521 result = -EAI_ADDRFAMILY;
522 goto free_and_return;
525 if (scope_delim != NULL)
527 int try_numericscope = 0;
528 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
529 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
531 at->scopeid = if_nametoindex (scope_delim + 1);
532 if (at->scopeid == 0)
533 try_numericscope = 1;
535 else
536 try_numericscope = 1;
538 if (try_numericscope != 0)
540 char *end;
541 assert (sizeof (uint32_t) <= sizeof (unsigned long));
542 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
543 10);
544 if (*end != '\0')
546 result = -EAI_NONAME;
547 goto free_and_return;
552 if (req->ai_flags & AI_CANONNAME)
553 canon = name;
557 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
559 struct gaih_addrtuple **pat = &at;
560 int no_data = 0;
561 int no_inet6_data = 0;
562 service_user *nip;
563 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
564 enum nss_status status = NSS_STATUS_UNAVAIL;
565 int no_more;
566 int old_res_options;
568 /* If we do not have to look for IPv6 addresses or the canonical
569 name, use the simple, old functions, which do not support
570 IPv6 scope ids, nor retrieving the canonical name. */
571 if (req->ai_family == AF_INET
572 && (req->ai_flags & AI_CANONNAME) == 0)
574 /* Allocate additional room for struct host_data. */
575 size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
576 + 16 * sizeof(char));
577 assert (tmpbuf == NULL);
578 tmpbuf = alloca_account (tmpbuflen, alloca_used);
579 int rc;
580 struct hostent th;
581 struct hostent *h;
582 int herrno;
584 while (1)
586 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
587 tmpbuflen, &h, &herrno);
588 if (rc != ERANGE || herrno != NETDB_INTERNAL)
589 break;
591 if (!malloc_tmpbuf
592 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
593 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
594 2 * tmpbuflen,
595 alloca_used);
596 else
598 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
599 2 * tmpbuflen);
600 if (newp == NULL)
602 result = -EAI_MEMORY;
603 goto free_and_return;
605 tmpbuf = newp;
606 malloc_tmpbuf = true;
607 tmpbuflen = 2 * tmpbuflen;
611 if (rc == 0)
613 if (h != NULL)
615 int i;
616 /* We found data, count the number of addresses. */
617 for (i = 0; h->h_addr_list[i]; ++i)
619 if (i > 0 && *pat != NULL)
620 --i;
622 if (__libc_use_alloca (alloca_used
623 + i * sizeof (struct gaih_addrtuple)))
624 addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
625 alloca_used);
626 else
628 addrmem = malloc (i
629 * sizeof (struct gaih_addrtuple));
630 if (addrmem == NULL)
632 result = -EAI_MEMORY;
633 goto free_and_return;
635 malloc_addrmem = true;
638 /* Now convert it into the list. */
639 struct gaih_addrtuple *addrfree = addrmem;
640 for (i = 0; h->h_addr_list[i]; ++i)
642 if (*pat == NULL)
644 *pat = addrfree++;
645 (*pat)->scopeid = 0;
647 (*pat)->next = NULL;
648 (*pat)->family = AF_INET;
649 memcpy ((*pat)->addr, h->h_addr_list[i],
650 h->h_length);
651 pat = &((*pat)->next);
655 else
657 if (herrno == NETDB_INTERNAL)
659 __set_h_errno (herrno);
660 result = -EAI_SYSTEM;
662 else if (herrno == TRY_AGAIN)
663 result = -EAI_AGAIN;
664 else
665 /* We made requests but they turned out no data.
666 The name is known, though. */
667 result = -EAI_NODATA;
669 goto free_and_return;
672 goto process_list;
675 #ifdef USE_NSCD
676 if (__nss_not_use_nscd_hosts > 0
677 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
678 __nss_not_use_nscd_hosts = 0;
680 if (!__nss_not_use_nscd_hosts
681 && !__nss_database_custom[NSS_DBSIDX_hosts])
683 /* Try to use nscd. */
684 struct nscd_ai_result *air = NULL;
685 int herrno;
686 int err = __nscd_getai (name, &air, &herrno);
687 if (air != NULL)
689 /* Transform into gaih_addrtuple list. */
690 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
691 char *addrs = air->addrs;
693 if (__libc_use_alloca (alloca_used
694 + air->naddrs * sizeof (struct gaih_addrtuple)))
695 addrmem = alloca_account (air->naddrs
696 * sizeof (struct gaih_addrtuple),
697 alloca_used);
698 else
700 addrmem = malloc (air->naddrs
701 * sizeof (struct gaih_addrtuple));
702 if (addrmem == NULL)
704 result = -EAI_MEMORY;
705 goto free_and_return;
707 malloc_addrmem = true;
710 struct gaih_addrtuple *addrfree = addrmem;
711 for (int i = 0; i < air->naddrs; ++i)
713 socklen_t size = (air->family[i] == AF_INET
714 ? INADDRSZ : IN6ADDRSZ);
715 if (*pat == NULL)
717 *pat = addrfree++;
718 (*pat)->scopeid = 0;
720 uint32_t *pataddr = (*pat)->addr;
721 (*pat)->next = NULL;
722 if (added_canon || air->canon == NULL)
723 (*pat)->name = NULL;
724 else if (canonbuf == NULL)
726 size_t canonlen = strlen (air->canon) + 1;
727 if ((req->ai_flags & AI_CANONIDN) != 0
728 && __libc_use_alloca (alloca_used + canonlen))
729 canonbuf = alloca_account (canonlen, alloca_used);
730 else
732 canonbuf = malloc (canonlen);
733 if (canonbuf == NULL)
735 result = -EAI_MEMORY;
736 goto free_and_return;
738 malloc_canonbuf = true;
740 canon = (*pat)->name = memcpy (canonbuf, air->canon,
741 canonlen);
744 if (air->family[i] == AF_INET
745 && req->ai_family == AF_INET6
746 && (req->ai_flags & AI_V4MAPPED))
748 (*pat)->family = AF_INET6;
749 pataddr[3] = *(uint32_t *) addrs;
750 pataddr[2] = htonl (0xffff);
751 pataddr[1] = 0;
752 pataddr[0] = 0;
753 pat = &((*pat)->next);
754 added_canon = true;
756 else if (req->ai_family == AF_UNSPEC
757 || air->family[i] == req->ai_family)
759 (*pat)->family = air->family[i];
760 memcpy (pataddr, addrs, size);
761 pat = &((*pat)->next);
762 added_canon = true;
763 if (air->family[i] == AF_INET6)
764 got_ipv6 = true;
766 addrs += size;
769 free (air);
771 if (at->family == AF_UNSPEC)
773 result = -EAI_NONAME;
774 goto free_and_return;
777 goto process_list;
779 else if (err == 0)
780 /* The database contains a negative entry. */
781 goto free_and_return;
782 else if (__nss_not_use_nscd_hosts == 0)
784 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
785 result = -EAI_MEMORY;
786 else if (herrno == TRY_AGAIN)
787 result = -EAI_AGAIN;
788 else
789 result = -EAI_SYSTEM;
791 goto free_and_return;
794 #endif
796 if (__nss_hosts_database == NULL)
797 no_more = __nss_database_lookup ("hosts", NULL,
798 "dns [!UNAVAIL=return] files",
799 &__nss_hosts_database);
800 else
801 no_more = 0;
802 nip = __nss_hosts_database;
804 /* Initialize configurations. */
805 if (__glibc_unlikely (!_res_hconf.initialized))
806 _res_hconf_init ();
807 if (__res_maybe_init (&_res, 0) == -1)
808 no_more = 1;
810 /* If we are looking for both IPv4 and IPv6 address we don't
811 want the lookup functions to automatically promote IPv4
812 addresses to IPv6 addresses. Currently this is decided
813 by setting the RES_USE_INET6 bit in _res.options. */
814 old_res_options = _res.options;
815 _res.options &= ~RES_USE_INET6;
817 size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
818 malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
819 assert (tmpbuf == NULL);
820 if (!malloc_tmpbuf)
821 tmpbuf = alloca_account (tmpbuflen, alloca_used);
822 else
824 tmpbuf = malloc (tmpbuflen);
825 if (tmpbuf == NULL)
827 _res.options |= old_res_options & RES_USE_INET6;
828 result = -EAI_MEMORY;
829 goto free_and_return;
833 while (!no_more)
835 no_data = 0;
836 nss_gethostbyname4_r fct4 = NULL;
838 /* gethostbyname4_r sends out parallel A and AAAA queries and
839 is thus only suitable for PF_UNSPEC. */
840 if (req->ai_family == PF_UNSPEC)
841 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
843 if (fct4 != NULL)
845 int herrno;
847 while (1)
849 rc = 0;
850 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
851 tmpbuflen, &rc, &herrno,
852 NULL));
853 if (status == NSS_STATUS_SUCCESS)
854 break;
855 if (status != NSS_STATUS_TRYAGAIN
856 || rc != ERANGE || herrno != NETDB_INTERNAL)
858 if (status == NSS_STATUS_TRYAGAIN
859 && herrno == TRY_AGAIN)
860 no_data = EAI_AGAIN;
861 else
862 no_data = herrno == NO_DATA;
863 break;
866 if (!malloc_tmpbuf
867 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
868 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
869 2 * tmpbuflen,
870 alloca_used);
871 else
873 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
874 2 * tmpbuflen);
875 if (newp == NULL)
877 _res.options |= old_res_options & RES_USE_INET6;
878 result = -EAI_MEMORY;
879 goto free_and_return;
881 tmpbuf = newp;
882 malloc_tmpbuf = true;
883 tmpbuflen = 2 * tmpbuflen;
887 if (status == NSS_STATUS_SUCCESS)
889 assert (!no_data);
890 no_data = 1;
892 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
893 canon = (*pat)->name;
895 while (*pat != NULL)
897 if ((*pat)->family == AF_INET
898 && req->ai_family == AF_INET6
899 && (req->ai_flags & AI_V4MAPPED) != 0)
901 uint32_t *pataddr = (*pat)->addr;
902 (*pat)->family = AF_INET6;
903 pataddr[3] = pataddr[0];
904 pataddr[2] = htonl (0xffff);
905 pataddr[1] = 0;
906 pataddr[0] = 0;
907 pat = &((*pat)->next);
908 no_data = 0;
910 else if (req->ai_family == AF_UNSPEC
911 || (*pat)->family == req->ai_family)
913 pat = &((*pat)->next);
915 no_data = 0;
916 if (req->ai_family == AF_INET6)
917 got_ipv6 = true;
919 else
920 *pat = ((*pat)->next);
924 no_inet6_data = no_data;
926 else
928 nss_gethostbyname3_r fct = NULL;
929 if (req->ai_flags & AI_CANONNAME)
930 /* No need to use this function if we do not look for
931 the canonical name. The function does not exist in
932 all NSS modules and therefore the lookup would
933 often fail. */
934 fct = __nss_lookup_function (nip, "gethostbyname3_r");
935 if (fct == NULL)
936 /* We are cheating here. The gethostbyname2_r
937 function does not have the same interface as
938 gethostbyname3_r but the extra arguments the
939 latter takes are added at the end. So the
940 gethostbyname2_r code will just ignore them. */
941 fct = __nss_lookup_function (nip, "gethostbyname2_r");
943 if (fct != NULL)
945 if (req->ai_family == AF_INET6
946 || req->ai_family == AF_UNSPEC)
948 gethosts (AF_INET6, struct in6_addr);
949 no_inet6_data = no_data;
950 inet6_status = status;
952 if (req->ai_family == AF_INET
953 || req->ai_family == AF_UNSPEC
954 || (req->ai_family == AF_INET6
955 && (req->ai_flags & AI_V4MAPPED)
956 /* Avoid generating the mapped addresses if we
957 know we are not going to need them. */
958 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
960 gethosts (AF_INET, struct in_addr);
962 if (req->ai_family == AF_INET)
964 no_inet6_data = no_data;
965 inet6_status = status;
969 /* If we found one address for AF_INET or AF_INET6,
970 don't continue the search. */
971 if (inet6_status == NSS_STATUS_SUCCESS
972 || status == NSS_STATUS_SUCCESS)
974 if ((req->ai_flags & AI_CANONNAME) != 0
975 && canon == NULL)
977 /* If we need the canonical name, get it
978 from the same service as the result. */
979 nss_getcanonname_r cfct;
980 int herrno;
982 cfct = __nss_lookup_function (nip,
983 "getcanonname_r");
984 if (cfct != NULL)
986 const size_t max_fqdn_len = 256;
987 if ((req->ai_flags & AI_CANONIDN) != 0
988 && __libc_use_alloca (alloca_used
989 + max_fqdn_len))
990 canonbuf = alloca_account (max_fqdn_len,
991 alloca_used);
992 else
994 canonbuf = malloc (max_fqdn_len);
995 if (canonbuf == NULL)
997 _res.options
998 |= old_res_options & RES_USE_INET6;
999 result = -EAI_MEMORY;
1000 goto free_and_return;
1002 malloc_canonbuf = true;
1004 char *s;
1006 if (DL_CALL_FCT (cfct, (at->name ?: name,
1007 canonbuf,
1008 max_fqdn_len,
1009 &s, &rc, &herrno))
1010 == NSS_STATUS_SUCCESS)
1011 canon = s;
1012 else
1014 /* If the canonical name cannot be
1015 determined, use the passed in
1016 string. */
1017 if (malloc_canonbuf)
1019 free (canonbuf);
1020 malloc_canonbuf = false;
1022 canon = name;
1026 status = NSS_STATUS_SUCCESS;
1028 else
1030 /* We can have different states for AF_INET and
1031 AF_INET6. Try to find a useful one for both. */
1032 if (inet6_status == NSS_STATUS_TRYAGAIN)
1033 status = NSS_STATUS_TRYAGAIN;
1034 else if (status == NSS_STATUS_UNAVAIL
1035 && inet6_status != NSS_STATUS_UNAVAIL)
1036 status = inet6_status;
1039 else
1041 status = NSS_STATUS_UNAVAIL;
1042 /* Could not load any of the lookup functions. Indicate
1043 an internal error if the failure was due to a system
1044 error other than the file not being found. We use the
1045 errno from the last failed callback. */
1046 if (errno != 0 && errno != ENOENT)
1047 __set_h_errno (NETDB_INTERNAL);
1051 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1052 break;
1054 if (nip->next == NULL)
1055 no_more = -1;
1056 else
1057 nip = nip->next;
1060 _res.options |= old_res_options & RES_USE_INET6;
1062 if (h_errno == NETDB_INTERNAL)
1064 result = -EAI_SYSTEM;
1065 goto free_and_return;
1068 if (no_data != 0 && no_inet6_data != 0)
1070 /* If both requests timed out report this. */
1071 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1072 result = -EAI_AGAIN;
1073 else
1074 /* We made requests but they turned out no data. The name
1075 is known, though. */
1076 result = -EAI_NODATA;
1078 goto free_and_return;
1082 process_list:
1083 if (at->family == AF_UNSPEC)
1085 result = -EAI_NONAME;
1086 goto free_and_return;
1089 else
1091 struct gaih_addrtuple *atr;
1092 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1093 memset (at, '\0', sizeof (struct gaih_addrtuple));
1095 if (req->ai_family == AF_UNSPEC)
1097 at->next = __alloca (sizeof (struct gaih_addrtuple));
1098 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1101 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1103 at->family = AF_INET6;
1104 if ((req->ai_flags & AI_PASSIVE) == 0)
1105 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1106 atr = at->next;
1109 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1111 atr->family = AF_INET;
1112 if ((req->ai_flags & AI_PASSIVE) == 0)
1113 atr->addr[0] = htonl (INADDR_LOOPBACK);
1118 struct gaih_servtuple *st2;
1119 struct gaih_addrtuple *at2 = at;
1120 size_t socklen;
1121 sa_family_t family;
1124 buffer is the size of an unformatted IPv6 address in printable format.
1126 while (at2 != NULL)
1128 /* Only the first entry gets the canonical name. */
1129 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1131 if (canon == NULL)
1132 /* If the canonical name cannot be determined, use
1133 the passed in string. */
1134 canon = orig_name;
1136 #ifdef HAVE_LIBIDN
1137 if (req->ai_flags & AI_CANONIDN)
1139 int idn_flags = 0;
1140 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1141 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1142 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1143 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1145 char *out;
1146 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1147 if (rc != IDNA_SUCCESS)
1149 if (rc == IDNA_MALLOC_ERROR)
1150 result = -EAI_MEMORY;
1151 else if (rc == IDNA_DLOPEN_ERROR)
1152 result = -EAI_SYSTEM;
1153 else
1154 result = -EAI_IDN_ENCODE;
1155 goto free_and_return;
1157 /* In case the output string is the same as the input
1158 string no new string has been allocated and we
1159 make a copy. */
1160 if (out == canon)
1161 goto make_copy;
1162 canon = out;
1164 else
1165 #endif
1167 #ifdef HAVE_LIBIDN
1168 make_copy:
1169 #endif
1170 if (malloc_canonbuf)
1171 /* We already allocated the string using malloc. */
1172 malloc_canonbuf = false;
1173 else
1175 canon = strdup (canon);
1176 if (canon == NULL)
1178 result = -EAI_MEMORY;
1179 goto free_and_return;
1185 family = at2->family;
1186 if (family == AF_INET6)
1188 socklen = sizeof (struct sockaddr_in6);
1190 /* If we looked up IPv4 mapped address discard them here if
1191 the caller isn't interested in all address and we have
1192 found at least one IPv6 address. */
1193 if (got_ipv6
1194 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1195 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1196 goto ignore;
1198 else
1199 socklen = sizeof (struct sockaddr_in);
1201 for (st2 = st; st2 != NULL; st2 = st2->next)
1203 struct addrinfo *ai;
1204 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1205 if (ai == NULL)
1207 free ((char *) canon);
1208 result = -EAI_MEMORY;
1209 goto free_and_return;
1212 ai->ai_flags = req->ai_flags;
1213 ai->ai_family = family;
1214 ai->ai_socktype = st2->socktype;
1215 ai->ai_protocol = st2->protocol;
1216 ai->ai_addrlen = socklen;
1217 ai->ai_addr = (void *) (ai + 1);
1219 /* We only add the canonical name once. */
1220 ai->ai_canonname = (char *) canon;
1221 canon = NULL;
1223 #ifdef _HAVE_SA_LEN
1224 ai->ai_addr->sa_len = socklen;
1225 #endif /* _HAVE_SA_LEN */
1226 ai->ai_addr->sa_family = family;
1228 /* In case of an allocation error the list must be NULL
1229 terminated. */
1230 ai->ai_next = NULL;
1232 if (family == AF_INET6)
1234 struct sockaddr_in6 *sin6p =
1235 (struct sockaddr_in6 *) ai->ai_addr;
1237 sin6p->sin6_port = st2->port;
1238 sin6p->sin6_flowinfo = 0;
1239 memcpy (&sin6p->sin6_addr,
1240 at2->addr, sizeof (struct in6_addr));
1241 sin6p->sin6_scope_id = at2->scopeid;
1243 else
1245 struct sockaddr_in *sinp =
1246 (struct sockaddr_in *) ai->ai_addr;
1247 sinp->sin_port = st2->port;
1248 memcpy (&sinp->sin_addr,
1249 at2->addr, sizeof (struct in_addr));
1250 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1253 pai = &(ai->ai_next);
1256 ++*naddrs;
1258 ignore:
1259 at2 = at2->next;
1263 free_and_return:
1264 if (malloc_name)
1265 free ((char *) name);
1266 if (malloc_addrmem)
1267 free (addrmem);
1268 if (malloc_canonbuf)
1269 free (canonbuf);
1270 if (malloc_tmpbuf)
1271 free (tmpbuf);
1273 return result;
1277 struct sort_result
1279 struct addrinfo *dest_addr;
1280 /* Using sockaddr_storage is for now overkill. We only support IPv4
1281 and IPv6 so far. If this changes at some point we can adjust the
1282 type here. */
1283 struct sockaddr_in6 source_addr;
1284 uint8_t source_addr_len;
1285 bool got_source_addr;
1286 uint8_t source_addr_flags;
1287 uint8_t prefixlen;
1288 uint32_t index;
1289 int32_t native;
1292 struct sort_result_combo
1294 struct sort_result *results;
1295 int nresults;
1299 #if __BYTE_ORDER == __BIG_ENDIAN
1300 # define htonl_c(n) n
1301 #else
1302 # define htonl_c(n) __bswap_constant_32 (n)
1303 #endif
1305 static const struct scopeentry
1307 union
1309 char addr[4];
1310 uint32_t addr32;
1312 uint32_t netmask;
1313 int32_t scope;
1314 } default_scopes[] =
1316 /* Link-local addresses: scope 2. */
1317 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1318 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1319 /* Default: scope 14. */
1320 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1323 /* The label table. */
1324 static const struct scopeentry *scopes;
1327 static int
1328 get_scope (const struct sockaddr_in6 *in6)
1330 int scope;
1331 if (in6->sin6_family == PF_INET6)
1333 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1335 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1336 /* RFC 4291 2.5.3 says that the loopback address is to be
1337 treated like a link-local address. */
1338 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1339 scope = 2;
1340 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1341 scope = 5;
1342 else
1343 /* XXX Is this the correct default behavior? */
1344 scope = 14;
1346 else
1347 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1349 else if (in6->sin6_family == PF_INET)
1351 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1353 size_t cnt = 0;
1354 while (1)
1356 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1357 == scopes[cnt].addr32)
1358 return scopes[cnt].scope;
1360 ++cnt;
1362 /* NOTREACHED */
1364 else
1365 /* XXX What is a good default? */
1366 scope = 15;
1368 return scope;
1372 struct prefixentry
1374 struct in6_addr prefix;
1375 unsigned int bits;
1376 int val;
1380 /* The label table. */
1381 static const struct prefixentry *labels;
1383 /* Default labels. */
1384 static const struct prefixentry default_labels[] =
1386 /* See RFC 3484 for the details. */
1387 { { .__in6_u
1388 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1390 }, 128, 0 },
1391 { { .__in6_u
1392 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1394 }, 16, 2 },
1395 { { .__in6_u
1396 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1398 }, 96, 3 },
1399 { { .__in6_u
1400 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1402 }, 96, 4 },
1403 /* The next two entries differ from RFC 3484. We need to treat
1404 IPv6 site-local addresses special because they are never NATed,
1405 unlike site-locale IPv4 addresses. If this would not happen, on
1406 machines which have only IPv4 and IPv6 site-local addresses, the
1407 sorting would prefer the IPv6 site-local addresses, causing
1408 unnecessary delays when trying to connect to a global IPv6 address
1409 through a site-local IPv6 address. */
1410 { { .__in6_u
1411 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1413 }, 10, 5 },
1414 { { .__in6_u
1415 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1417 }, 7, 6 },
1418 /* Additional rule for Teredo tunnels. */
1419 { { .__in6_u
1420 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1422 }, 32, 7 },
1423 { { .__in6_u
1424 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1426 }, 0, 1 }
1430 /* The precedence table. */
1431 static const struct prefixentry *precedence;
1433 /* The default precedences. */
1434 static const struct prefixentry default_precedence[] =
1436 /* See RFC 3484 for the details. */
1437 { { .__in6_u
1438 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1440 }, 128, 50 },
1441 { { .__in6_u
1442 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1444 }, 16, 30 },
1445 { { .__in6_u
1446 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1448 }, 96, 20 },
1449 { { .__in6_u
1450 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1452 }, 96, 10 },
1453 { { .__in6_u
1454 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1456 }, 0, 40 }
1460 static int
1461 match_prefix (const struct sockaddr_in6 *in6,
1462 const struct prefixentry *list, int default_val)
1464 int idx;
1465 struct sockaddr_in6 in6_mem;
1467 if (in6->sin6_family == PF_INET)
1469 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1471 /* Construct a V4-to-6 mapped address. */
1472 in6_mem.sin6_family = PF_INET6;
1473 in6_mem.sin6_port = in->sin_port;
1474 in6_mem.sin6_flowinfo = 0;
1475 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1476 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1477 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1478 in6_mem.sin6_scope_id = 0;
1480 in6 = &in6_mem;
1482 else if (in6->sin6_family != PF_INET6)
1483 return default_val;
1485 for (idx = 0; ; ++idx)
1487 unsigned int bits = list[idx].bits;
1488 const uint8_t *mask = list[idx].prefix.s6_addr;
1489 const uint8_t *val = in6->sin6_addr.s6_addr;
1491 while (bits >= 8)
1493 if (*mask != *val)
1494 break;
1496 ++mask;
1497 ++val;
1498 bits -= 8;
1501 if (bits < 8)
1503 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1504 /* Match! */
1505 break;
1509 return list[idx].val;
1513 static int
1514 get_label (const struct sockaddr_in6 *in6)
1516 /* XXX What is a good default value? */
1517 return match_prefix (in6, labels, INT_MAX);
1521 static int
1522 get_precedence (const struct sockaddr_in6 *in6)
1524 /* XXX What is a good default value? */
1525 return match_prefix (in6, precedence, 0);
1529 /* Find last bit set in a word. */
1530 static int
1531 fls (uint32_t a)
1533 uint32_t mask;
1534 int n;
1535 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1536 if ((a & mask) != 0)
1537 break;
1538 return n;
1542 static int
1543 rfc3484_sort (const void *p1, const void *p2, void *arg)
1545 const size_t idx1 = *(const size_t *) p1;
1546 const size_t idx2 = *(const size_t *) p2;
1547 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1548 struct sort_result *a1 = &src->results[idx1];
1549 struct sort_result *a2 = &src->results[idx2];
1551 /* Rule 1: Avoid unusable destinations.
1552 We have the got_source_addr flag set if the destination is reachable. */
1553 if (a1->got_source_addr && ! a2->got_source_addr)
1554 return -1;
1555 if (! a1->got_source_addr && a2->got_source_addr)
1556 return 1;
1559 /* Rule 2: Prefer matching scope. Only interesting if both
1560 destination addresses are IPv6. */
1561 int a1_dst_scope
1562 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1564 int a2_dst_scope
1565 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1567 if (a1->got_source_addr)
1569 int a1_src_scope = get_scope (&a1->source_addr);
1570 int a2_src_scope = get_scope (&a2->source_addr);
1572 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1573 return -1;
1574 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1575 return 1;
1579 /* Rule 3: Avoid deprecated addresses. */
1580 if (a1->got_source_addr)
1582 if (!(a1->source_addr_flags & in6ai_deprecated)
1583 && (a2->source_addr_flags & in6ai_deprecated))
1584 return -1;
1585 if ((a1->source_addr_flags & in6ai_deprecated)
1586 && !(a2->source_addr_flags & in6ai_deprecated))
1587 return 1;
1590 /* Rule 4: Prefer home addresses. */
1591 if (a1->got_source_addr)
1593 if (!(a1->source_addr_flags & in6ai_homeaddress)
1594 && (a2->source_addr_flags & in6ai_homeaddress))
1595 return 1;
1596 if ((a1->source_addr_flags & in6ai_homeaddress)
1597 && !(a2->source_addr_flags & in6ai_homeaddress))
1598 return -1;
1601 /* Rule 5: Prefer matching label. */
1602 if (a1->got_source_addr)
1604 int a1_dst_label
1605 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1606 int a1_src_label = get_label (&a1->source_addr);
1608 int a2_dst_label
1609 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1610 int a2_src_label = get_label (&a2->source_addr);
1612 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1613 return -1;
1614 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1615 return 1;
1619 /* Rule 6: Prefer higher precedence. */
1620 int a1_prec
1621 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1622 int a2_prec
1623 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1625 if (a1_prec > a2_prec)
1626 return -1;
1627 if (a1_prec < a2_prec)
1628 return 1;
1631 /* Rule 7: Prefer native transport. */
1632 if (a1->got_source_addr)
1634 /* The same interface index means the same interface which means
1635 there is no difference in transport. This should catch many
1636 (most?) cases. */
1637 if (a1->index != a2->index)
1639 int a1_native = a1->native;
1640 int a2_native = a2->native;
1642 if (a1_native == -1 || a2_native == -1)
1644 uint32_t a1_index;
1645 if (a1_native == -1)
1647 /* If we do not have the information use 'native' as
1648 the default. */
1649 a1_native = 0;
1650 a1_index = a1->index;
1652 else
1653 a1_index = 0xffffffffu;
1655 uint32_t a2_index;
1656 if (a2_native == -1)
1658 /* If we do not have the information use 'native' as
1659 the default. */
1660 a2_native = 0;
1661 a2_index = a2->index;
1663 else
1664 a2_index = 0xffffffffu;
1666 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1668 /* Fill in the results in all the records. */
1669 for (int i = 0; i < src->nresults; ++i)
1670 if (a1_index != -1 && src->results[i].index == a1_index)
1672 assert (src->results[i].native == -1
1673 || src->results[i].native == a1_native);
1674 src->results[i].native = a1_native;
1676 else if (a2_index != -1 && src->results[i].index == a2_index)
1678 assert (src->results[i].native == -1
1679 || src->results[i].native == a2_native);
1680 src->results[i].native = a2_native;
1684 if (a1_native && !a2_native)
1685 return -1;
1686 if (!a1_native && a2_native)
1687 return 1;
1692 /* Rule 8: Prefer smaller scope. */
1693 if (a1_dst_scope < a2_dst_scope)
1694 return -1;
1695 if (a1_dst_scope > a2_dst_scope)
1696 return 1;
1699 /* Rule 9: Use longest matching prefix. */
1700 if (a1->got_source_addr
1701 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1703 int bit1 = 0;
1704 int bit2 = 0;
1706 if (a1->dest_addr->ai_family == PF_INET)
1708 assert (a1->source_addr.sin6_family == PF_INET);
1709 assert (a2->source_addr.sin6_family == PF_INET);
1711 /* Outside of subnets, as defined by the network masks,
1712 common address prefixes for IPv4 addresses make no sense.
1713 So, define a non-zero value only if source and
1714 destination address are on the same subnet. */
1715 struct sockaddr_in *in1_dst
1716 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1717 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1718 struct sockaddr_in *in1_src
1719 = (struct sockaddr_in *) &a1->source_addr;
1720 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1721 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1723 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1724 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1726 struct sockaddr_in *in2_dst
1727 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1728 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1729 struct sockaddr_in *in2_src
1730 = (struct sockaddr_in *) &a2->source_addr;
1731 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1732 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1734 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1735 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1737 else if (a1->dest_addr->ai_family == PF_INET6)
1739 assert (a1->source_addr.sin6_family == PF_INET6);
1740 assert (a2->source_addr.sin6_family == PF_INET6);
1742 struct sockaddr_in6 *in1_dst;
1743 struct sockaddr_in6 *in1_src;
1744 struct sockaddr_in6 *in2_dst;
1745 struct sockaddr_in6 *in2_src;
1747 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1748 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1749 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1750 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1752 int i;
1753 for (i = 0; i < 4; ++i)
1754 if (in1_dst->sin6_addr.s6_addr32[i]
1755 != in1_src->sin6_addr.s6_addr32[i]
1756 || (in2_dst->sin6_addr.s6_addr32[i]
1757 != in2_src->sin6_addr.s6_addr32[i]))
1758 break;
1760 if (i < 4)
1762 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1763 ^ in1_src->sin6_addr.s6_addr32[i]));
1764 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1765 ^ in2_src->sin6_addr.s6_addr32[i]));
1769 if (bit1 > bit2)
1770 return -1;
1771 if (bit1 < bit2)
1772 return 1;
1776 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1777 compare with the value indicating the order in which the entries
1778 have been received from the services. NB: no two entries can have
1779 the same order so the test will never return zero. */
1780 return idx1 < idx2 ? -1 : 1;
1784 static int
1785 in6aicmp (const void *p1, const void *p2)
1787 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1788 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1790 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1794 /* Name of the config file for RFC 3484 sorting (for now). */
1795 #define GAICONF_FNAME "/etc/gai.conf"
1798 /* Non-zero if we are supposed to reload the config file automatically
1799 whenever it changed. */
1800 static int gaiconf_reload_flag;
1802 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1803 static int gaiconf_reload_flag_ever_set;
1805 /* Last modification time. */
1806 #ifdef _STATBUF_ST_NSEC
1808 static struct timespec gaiconf_mtime;
1810 static inline void
1811 save_gaiconf_mtime (const struct stat64 *st)
1813 gaiconf_mtime = st->st_mtim;
1816 static inline bool
1817 check_gaiconf_mtime (const struct stat64 *st)
1819 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1820 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1823 #else
1825 static time_t gaiconf_mtime;
1827 static inline void
1828 save_gaiconf_mtime (const struct stat64 *st)
1830 gaiconf_mtime = st->st_mtime;
1833 static inline bool
1834 check_gaiconf_mtime (const struct stat64 *st)
1836 return st->st_mtime == gaiconf_mtime;
1839 #endif
1842 libc_freeres_fn(fini)
1844 if (labels != default_labels)
1846 const struct prefixentry *old = labels;
1847 labels = default_labels;
1848 free ((void *) old);
1851 if (precedence != default_precedence)
1853 const struct prefixentry *old = precedence;
1854 precedence = default_precedence;
1855 free ((void *) old);
1858 if (scopes != default_scopes)
1860 const struct scopeentry *old = scopes;
1861 scopes = default_scopes;
1862 free ((void *) old);
1867 struct prefixlist
1869 struct prefixentry entry;
1870 struct prefixlist *next;
1874 struct scopelist
1876 struct scopeentry entry;
1877 struct scopelist *next;
1881 static void
1882 free_prefixlist (struct prefixlist *list)
1884 while (list != NULL)
1886 struct prefixlist *oldp = list;
1887 list = list->next;
1888 free (oldp);
1893 static void
1894 free_scopelist (struct scopelist *list)
1896 while (list != NULL)
1898 struct scopelist *oldp = list;
1899 list = list->next;
1900 free (oldp);
1905 static int
1906 prefixcmp (const void *p1, const void *p2)
1908 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1909 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1911 if (e1->bits < e2->bits)
1912 return 1;
1913 if (e1->bits == e2->bits)
1914 return 0;
1915 return -1;
1919 static int
1920 scopecmp (const void *p1, const void *p2)
1922 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1923 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1925 if (e1->netmask > e2->netmask)
1926 return -1;
1927 if (e1->netmask == e2->netmask)
1928 return 0;
1929 return 1;
1933 static void
1934 gaiconf_init (void)
1936 struct prefixlist *labellist = NULL;
1937 size_t nlabellist = 0;
1938 bool labellist_nullbits = false;
1939 struct prefixlist *precedencelist = NULL;
1940 size_t nprecedencelist = 0;
1941 bool precedencelist_nullbits = false;
1942 struct scopelist *scopelist = NULL;
1943 size_t nscopelist = 0;
1944 bool scopelist_nullbits = false;
1946 FILE *fp = fopen (GAICONF_FNAME, "rce");
1947 if (fp != NULL)
1949 struct stat64 st;
1950 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1952 fclose (fp);
1953 goto no_file;
1956 char *line = NULL;
1957 size_t linelen = 0;
1959 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1961 while (!feof_unlocked (fp))
1963 ssize_t n = __getline (&line, &linelen, fp);
1964 if (n <= 0)
1965 break;
1967 /* Handle comments. No escaping possible so this is easy. */
1968 char *cp = strchr (line, '#');
1969 if (cp != NULL)
1970 *cp = '\0';
1972 cp = line;
1973 while (isspace (*cp))
1974 ++cp;
1976 char *cmd = cp;
1977 while (*cp != '\0' && !isspace (*cp))
1978 ++cp;
1979 size_t cmdlen = cp - cmd;
1981 if (*cp != '\0')
1982 *cp++ = '\0';
1983 while (isspace (*cp))
1984 ++cp;
1986 char *val1 = cp;
1987 while (*cp != '\0' && !isspace (*cp))
1988 ++cp;
1989 size_t val1len = cp - cmd;
1991 /* We always need at least two values. */
1992 if (val1len == 0)
1993 continue;
1995 if (*cp != '\0')
1996 *cp++ = '\0';
1997 while (isspace (*cp))
1998 ++cp;
2000 char *val2 = cp;
2001 while (*cp != '\0' && !isspace (*cp))
2002 ++cp;
2004 /* Ignore the rest of the line. */
2005 *cp = '\0';
2007 struct prefixlist **listp;
2008 size_t *lenp;
2009 bool *nullbitsp;
2010 switch (cmdlen)
2012 case 5:
2013 if (strcmp (cmd, "label") == 0)
2015 struct in6_addr prefix;
2016 unsigned long int bits;
2017 unsigned long int val;
2018 char *endp;
2020 listp = &labellist;
2021 lenp = &nlabellist;
2022 nullbitsp = &labellist_nullbits;
2024 new_elem:
2025 bits = 128;
2026 __set_errno (0);
2027 cp = strchr (val1, '/');
2028 if (cp != NULL)
2029 *cp++ = '\0';
2030 if (inet_pton (AF_INET6, val1, &prefix)
2031 && (cp == NULL
2032 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2033 || errno != ERANGE)
2034 && *endp == '\0'
2035 && bits <= 128
2036 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2037 || errno != ERANGE)
2038 && *endp == '\0'
2039 && val <= INT_MAX)
2041 struct prefixlist *newp = malloc (sizeof (*newp));
2042 if (newp == NULL)
2044 free (line);
2045 fclose (fp);
2046 goto no_file;
2049 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2050 newp->entry.bits = bits;
2051 newp->entry.val = val;
2052 newp->next = *listp;
2053 *listp = newp;
2054 ++*lenp;
2055 *nullbitsp |= bits == 0;
2058 break;
2060 case 6:
2061 if (strcmp (cmd, "reload") == 0)
2063 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2064 if (gaiconf_reload_flag)
2065 gaiconf_reload_flag_ever_set = 1;
2067 break;
2069 case 7:
2070 if (strcmp (cmd, "scopev4") == 0)
2072 struct in6_addr prefix;
2073 unsigned long int bits;
2074 unsigned long int val;
2075 char *endp;
2077 bits = 32;
2078 __set_errno (0);
2079 cp = strchr (val1, '/');
2080 if (cp != NULL)
2081 *cp++ = '\0';
2082 if (inet_pton (AF_INET6, val1, &prefix))
2084 bits = 128;
2085 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2086 && (cp == NULL
2087 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2088 || errno != ERANGE)
2089 && *endp == '\0'
2090 && bits >= 96
2091 && bits <= 128
2092 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2093 || errno != ERANGE)
2094 && *endp == '\0'
2095 && val <= INT_MAX)
2097 struct scopelist *newp;
2098 new_scope:
2099 newp = malloc (sizeof (*newp));
2100 if (newp == NULL)
2102 free (line);
2103 fclose (fp);
2104 goto no_file;
2107 newp->entry.netmask = htonl (bits != 96
2108 ? (0xffffffff
2109 << (128 - bits))
2110 : 0);
2111 newp->entry.addr32 = (prefix.s6_addr32[3]
2112 & newp->entry.netmask);
2113 newp->entry.scope = val;
2114 newp->next = scopelist;
2115 scopelist = newp;
2116 ++nscopelist;
2117 scopelist_nullbits |= bits == 96;
2120 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2121 && (cp == NULL
2122 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2123 || errno != ERANGE)
2124 && *endp == '\0'
2125 && bits <= 32
2126 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2127 || errno != ERANGE)
2128 && *endp == '\0'
2129 && val <= INT_MAX)
2131 bits += 96;
2132 goto new_scope;
2135 break;
2137 case 10:
2138 if (strcmp (cmd, "precedence") == 0)
2140 listp = &precedencelist;
2141 lenp = &nprecedencelist;
2142 nullbitsp = &precedencelist_nullbits;
2143 goto new_elem;
2145 break;
2149 free (line);
2151 fclose (fp);
2153 /* Create the array for the labels. */
2154 struct prefixentry *new_labels;
2155 if (nlabellist > 0)
2157 if (!labellist_nullbits)
2158 ++nlabellist;
2159 new_labels = malloc (nlabellist * sizeof (*new_labels));
2160 if (new_labels == NULL)
2161 goto no_file;
2163 int i = nlabellist;
2164 if (!labellist_nullbits)
2166 --i;
2167 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2168 new_labels[i].bits = 0;
2169 new_labels[i].val = 1;
2172 struct prefixlist *l = labellist;
2173 while (i-- > 0)
2175 new_labels[i] = l->entry;
2176 l = l->next;
2178 free_prefixlist (labellist);
2180 /* Sort the entries so that the most specific ones are at
2181 the beginning. */
2182 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2184 else
2185 new_labels = (struct prefixentry *) default_labels;
2187 struct prefixentry *new_precedence;
2188 if (nprecedencelist > 0)
2190 if (!precedencelist_nullbits)
2191 ++nprecedencelist;
2192 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2193 if (new_precedence == NULL)
2195 if (new_labels != default_labels)
2196 free (new_labels);
2197 goto no_file;
2200 int i = nprecedencelist;
2201 if (!precedencelist_nullbits)
2203 --i;
2204 memset (&new_precedence[i].prefix, '\0',
2205 sizeof (struct in6_addr));
2206 new_precedence[i].bits = 0;
2207 new_precedence[i].val = 40;
2210 struct prefixlist *l = precedencelist;
2211 while (i-- > 0)
2213 new_precedence[i] = l->entry;
2214 l = l->next;
2216 free_prefixlist (precedencelist);
2218 /* Sort the entries so that the most specific ones are at
2219 the beginning. */
2220 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2221 prefixcmp);
2223 else
2224 new_precedence = (struct prefixentry *) default_precedence;
2226 struct scopeentry *new_scopes;
2227 if (nscopelist > 0)
2229 if (!scopelist_nullbits)
2230 ++nscopelist;
2231 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2232 if (new_scopes == NULL)
2234 if (new_labels != default_labels)
2235 free (new_labels);
2236 if (new_precedence != default_precedence)
2237 free (new_precedence);
2238 goto no_file;
2241 int i = nscopelist;
2242 if (!scopelist_nullbits)
2244 --i;
2245 new_scopes[i].addr32 = 0;
2246 new_scopes[i].netmask = 0;
2247 new_scopes[i].scope = 14;
2250 struct scopelist *l = scopelist;
2251 while (i-- > 0)
2253 new_scopes[i] = l->entry;
2254 l = l->next;
2256 free_scopelist (scopelist);
2258 /* Sort the entries so that the most specific ones are at
2259 the beginning. */
2260 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2261 scopecmp);
2263 else
2264 new_scopes = (struct scopeentry *) default_scopes;
2266 /* Now we are ready to replace the values. */
2267 const struct prefixentry *old = labels;
2268 labels = new_labels;
2269 if (old != default_labels)
2270 free ((void *) old);
2272 old = precedence;
2273 precedence = new_precedence;
2274 if (old != default_precedence)
2275 free ((void *) old);
2277 const struct scopeentry *oldscope = scopes;
2278 scopes = new_scopes;
2279 if (oldscope != default_scopes)
2280 free ((void *) oldscope);
2282 save_gaiconf_mtime (&st);
2284 else
2286 no_file:
2287 free_prefixlist (labellist);
2288 free_prefixlist (precedencelist);
2289 free_scopelist (scopelist);
2291 /* If we previously read the file but it is gone now, free the
2292 old data and use the builtin one. Leave the reload flag
2293 alone. */
2294 fini ();
2299 static void
2300 gaiconf_reload (void)
2302 struct stat64 st;
2303 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2304 || !check_gaiconf_mtime (&st))
2305 gaiconf_init ();
2310 getaddrinfo (const char *name, const char *service,
2311 const struct addrinfo *hints, struct addrinfo **pai)
2313 int i = 0, last_i = 0;
2314 int nresults = 0;
2315 struct addrinfo *p = NULL;
2316 struct gaih_service gaih_service, *pservice;
2317 struct addrinfo local_hints;
2319 if (name != NULL && name[0] == '*' && name[1] == 0)
2320 name = NULL;
2322 if (service != NULL && service[0] == '*' && service[1] == 0)
2323 service = NULL;
2325 if (name == NULL && service == NULL)
2326 return EAI_NONAME;
2328 if (hints == NULL)
2329 hints = &default_hints;
2331 if (hints->ai_flags
2332 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2333 #ifdef HAVE_LIBIDN
2334 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2335 |AI_IDN_USE_STD3_ASCII_RULES
2336 #endif
2337 |AI_NUMERICSERV|AI_ALL))
2338 return EAI_BADFLAGS;
2340 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2341 return EAI_BADFLAGS;
2343 struct in6addrinfo *in6ai = NULL;
2344 size_t in6ailen = 0;
2345 bool seen_ipv4 = false;
2346 bool seen_ipv6 = false;
2347 bool check_pf_called = false;
2349 if (hints->ai_flags & AI_ADDRCONFIG)
2351 /* We might need information about what interfaces are available.
2352 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2353 cannot cache the results since new interfaces could be added at
2354 any time. */
2355 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2356 check_pf_called = true;
2358 /* Now make a decision on what we return, if anything. */
2359 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2361 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2362 narrow down the search. */
2363 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2365 local_hints = *hints;
2366 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2367 hints = &local_hints;
2370 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2371 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2373 /* We cannot possibly return a valid answer. */
2374 __free_in6ai (in6ai);
2375 return EAI_NONAME;
2379 if (service && service[0])
2381 char *c;
2382 gaih_service.name = service;
2383 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2384 if (*c != '\0')
2386 if (hints->ai_flags & AI_NUMERICSERV)
2388 __free_in6ai (in6ai);
2389 return EAI_NONAME;
2392 gaih_service.num = -1;
2395 pservice = &gaih_service;
2397 else
2398 pservice = NULL;
2400 struct addrinfo **end = &p;
2402 unsigned int naddrs = 0;
2403 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2404 || hints->ai_family == AF_INET6)
2406 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2407 if (last_i != 0)
2409 freeaddrinfo (p);
2410 __free_in6ai (in6ai);
2412 return -last_i;
2414 while (*end)
2416 end = &((*end)->ai_next);
2417 ++nresults;
2420 else
2422 __free_in6ai (in6ai);
2423 return EAI_FAMILY;
2426 if (naddrs > 1)
2428 /* Read the config file. */
2429 __libc_once_define (static, once);
2430 __typeof (once) old_once = once;
2431 __libc_once (once, gaiconf_init);
2432 /* Sort results according to RFC 3484. */
2433 struct sort_result *results;
2434 size_t *order;
2435 struct addrinfo *q;
2436 struct addrinfo *last = NULL;
2437 char *canonname = NULL;
2438 bool malloc_results;
2439 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2441 malloc_results
2442 = !__libc_use_alloca (alloc_size);
2443 if (malloc_results)
2445 results = malloc (alloc_size);
2446 if (results == NULL)
2448 __free_in6ai (in6ai);
2449 return EAI_MEMORY;
2452 else
2453 results = alloca (alloc_size);
2454 order = (size_t *) (results + nresults);
2456 /* Now we definitely need the interface information. */
2457 if (! check_pf_called)
2458 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2460 /* If we have information about deprecated and temporary addresses
2461 sort the array now. */
2462 if (in6ai != NULL)
2463 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2465 int fd = -1;
2466 int af = AF_UNSPEC;
2468 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2470 results[i].dest_addr = q;
2471 results[i].native = -1;
2472 order[i] = i;
2474 /* If we just looked up the address for a different
2475 protocol, reuse the result. */
2476 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2477 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2479 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2480 results[i - 1].source_addr_len);
2481 results[i].source_addr_len = results[i - 1].source_addr_len;
2482 results[i].got_source_addr = results[i - 1].got_source_addr;
2483 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2484 results[i].prefixlen = results[i - 1].prefixlen;
2485 results[i].index = results[i - 1].index;
2487 else
2489 results[i].got_source_addr = false;
2490 results[i].source_addr_flags = 0;
2491 results[i].prefixlen = 0;
2492 results[i].index = 0xffffffffu;
2494 /* We overwrite the type with SOCK_DGRAM since we do not
2495 want connect() to connect to the other side. If we
2496 cannot determine the source address remember this
2497 fact. */
2498 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2500 if (fd != -1)
2501 close_retry:
2502 close_not_cancel_no_status (fd);
2503 af = q->ai_family;
2504 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2506 else
2508 /* Reset the connection. */
2509 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2510 __connect (fd, &sa, sizeof (sa));
2513 socklen_t sl = sizeof (results[i].source_addr);
2514 if (fd != -1
2515 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2516 && __getsockname (fd,
2517 (struct sockaddr *) &results[i].source_addr,
2518 &sl) == 0)
2520 results[i].source_addr_len = sl;
2521 results[i].got_source_addr = true;
2523 if (in6ai != NULL)
2525 /* See whether the source address is on the list of
2526 deprecated or temporary addresses. */
2527 struct in6addrinfo tmp;
2529 if (q->ai_family == AF_INET && af == AF_INET)
2531 struct sockaddr_in *sinp
2532 = (struct sockaddr_in *) &results[i].source_addr;
2533 tmp.addr[0] = 0;
2534 tmp.addr[1] = 0;
2535 tmp.addr[2] = htonl (0xffff);
2536 /* Special case for lo interface, the source address
2537 being possibly different than the interface
2538 address. */
2539 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2540 == 0x7f000000)
2541 tmp.addr[3] = htonl(0x7f000001);
2542 else
2543 tmp.addr[3] = sinp->sin_addr.s_addr;
2545 else
2547 struct sockaddr_in6 *sin6p
2548 = (struct sockaddr_in6 *) &results[i].source_addr;
2549 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2552 struct in6addrinfo *found
2553 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2554 in6aicmp);
2555 if (found != NULL)
2557 results[i].source_addr_flags = found->flags;
2558 results[i].prefixlen = found->prefixlen;
2559 results[i].index = found->index;
2563 if (q->ai_family == AF_INET && af == AF_INET6)
2565 /* We have to convert the address. The socket is
2566 IPv6 and the request is for IPv4. */
2567 struct sockaddr_in6 *sin6
2568 = (struct sockaddr_in6 *) &results[i].source_addr;
2569 struct sockaddr_in *sin
2570 = (struct sockaddr_in *) &results[i].source_addr;
2571 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2572 sin->sin_family = AF_INET;
2573 /* We do not have to initialize sin_port since this
2574 fields has the same position and size in the IPv6
2575 structure. */
2576 assert (offsetof (struct sockaddr_in, sin_port)
2577 == offsetof (struct sockaddr_in6, sin6_port));
2578 assert (sizeof (sin->sin_port)
2579 == sizeof (sin6->sin6_port));
2580 memcpy (&sin->sin_addr,
2581 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2582 results[i].source_addr_len = sizeof (struct sockaddr_in);
2585 else if (errno == EAFNOSUPPORT && af == AF_INET6
2586 && q->ai_family == AF_INET)
2587 /* This could mean IPv6 sockets are IPv6-only. */
2588 goto close_retry;
2589 else
2590 /* Just make sure that if we have to process the same
2591 address again we do not copy any memory. */
2592 results[i].source_addr_len = 0;
2595 /* Remember the canonical name. */
2596 if (q->ai_canonname != NULL)
2598 assert (canonname == NULL);
2599 canonname = q->ai_canonname;
2600 q->ai_canonname = NULL;
2604 if (fd != -1)
2605 close_not_cancel_no_status (fd);
2607 /* We got all the source addresses we can get, now sort using
2608 the information. */
2609 struct sort_result_combo src
2610 = { .results = results, .nresults = nresults };
2611 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2613 __libc_lock_define_initialized (static, lock);
2615 __libc_lock_lock (lock);
2616 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2617 gaiconf_reload ();
2618 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2619 __libc_lock_unlock (lock);
2621 else
2622 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2624 /* Queue the results up as they come out of sorting. */
2625 q = p = results[order[0]].dest_addr;
2626 for (i = 1; i < nresults; ++i)
2627 q = q->ai_next = results[order[i]].dest_addr;
2628 q->ai_next = NULL;
2630 /* Fill in the canonical name into the new first entry. */
2631 p->ai_canonname = canonname;
2633 if (malloc_results)
2634 free (results);
2637 __free_in6ai (in6ai);
2639 if (p)
2641 *pai = p;
2642 return 0;
2645 return last_i ? -last_i : EAI_NONAME;
2647 libc_hidden_def (getaddrinfo)
2649 nss_interface_function (getaddrinfo)
2651 void
2652 freeaddrinfo (struct addrinfo *ai)
2654 struct addrinfo *p;
2656 while (ai != NULL)
2658 p = ai;
2659 ai = ai->ai_next;
2660 free (p->ai_canonname);
2661 free (p);
2664 libc_hidden_def (freeaddrinfo)