NPTL: Move fork state variables to initializer files.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob31bb7e66dcbe1868b8e5e34185e048fe5bde15ab
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 (__glibc_unlikely (scope_delim != NULL))
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);
716 if (!((air->family[i] == AF_INET
717 && req->ai_family == AF_INET6
718 && (req->ai_flags & AI_V4MAPPED) != 0)
719 || req->ai_family == AF_UNSPEC
720 || air->family[i] == req->ai_family))
722 /* Skip over non-matching result. */
723 addrs += size;
724 continue;
727 if (*pat == NULL)
729 *pat = addrfree++;
730 (*pat)->scopeid = 0;
732 uint32_t *pataddr = (*pat)->addr;
733 (*pat)->next = NULL;
734 if (added_canon || air->canon == NULL)
735 (*pat)->name = NULL;
736 else if (canonbuf == NULL)
738 size_t canonlen = strlen (air->canon) + 1;
739 if ((req->ai_flags & AI_CANONIDN) != 0
740 && __libc_use_alloca (alloca_used + canonlen))
741 canonbuf = alloca_account (canonlen, alloca_used);
742 else
744 canonbuf = malloc (canonlen);
745 if (canonbuf == NULL)
747 result = -EAI_MEMORY;
748 goto free_and_return;
750 malloc_canonbuf = true;
752 canon = (*pat)->name = memcpy (canonbuf, air->canon,
753 canonlen);
756 if (air->family[i] == AF_INET
757 && req->ai_family == AF_INET6
758 && (req->ai_flags & AI_V4MAPPED))
760 (*pat)->family = AF_INET6;
761 pataddr[3] = *(uint32_t *) addrs;
762 pataddr[2] = htonl (0xffff);
763 pataddr[1] = 0;
764 pataddr[0] = 0;
765 pat = &((*pat)->next);
766 added_canon = true;
768 else if (req->ai_family == AF_UNSPEC
769 || air->family[i] == req->ai_family)
771 (*pat)->family = air->family[i];
772 memcpy (pataddr, addrs, size);
773 pat = &((*pat)->next);
774 added_canon = true;
775 if (air->family[i] == AF_INET6)
776 got_ipv6 = true;
778 addrs += size;
781 free (air);
783 if (at->family == AF_UNSPEC)
785 result = -EAI_NONAME;
786 goto free_and_return;
789 goto process_list;
791 else if (err == 0)
792 /* The database contains a negative entry. */
793 goto free_and_return;
794 else if (__nss_not_use_nscd_hosts == 0)
796 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
797 result = -EAI_MEMORY;
798 else if (herrno == TRY_AGAIN)
799 result = -EAI_AGAIN;
800 else
801 result = -EAI_SYSTEM;
803 goto free_and_return;
806 #endif
808 if (__nss_hosts_database == NULL)
809 no_more = __nss_database_lookup ("hosts", NULL,
810 "dns [!UNAVAIL=return] files",
811 &__nss_hosts_database);
812 else
813 no_more = 0;
814 nip = __nss_hosts_database;
816 /* Initialize configurations. */
817 if (__glibc_unlikely (!_res_hconf.initialized))
818 _res_hconf_init ();
819 if (__res_maybe_init (&_res, 0) == -1)
820 no_more = 1;
822 /* If we are looking for both IPv4 and IPv6 address we don't
823 want the lookup functions to automatically promote IPv4
824 addresses to IPv6 addresses. Currently this is decided
825 by setting the RES_USE_INET6 bit in _res.options. */
826 old_res_options = _res.options;
827 _res.options &= ~RES_USE_INET6;
829 size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
830 malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
831 assert (tmpbuf == NULL);
832 if (!malloc_tmpbuf)
833 tmpbuf = alloca_account (tmpbuflen, alloca_used);
834 else
836 tmpbuf = malloc (tmpbuflen);
837 if (tmpbuf == NULL)
839 _res.options |= old_res_options & RES_USE_INET6;
840 result = -EAI_MEMORY;
841 goto free_and_return;
845 while (!no_more)
847 no_data = 0;
848 nss_gethostbyname4_r fct4 = NULL;
850 /* gethostbyname4_r sends out parallel A and AAAA queries and
851 is thus only suitable for PF_UNSPEC. */
852 if (req->ai_family == PF_UNSPEC)
853 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
855 if (fct4 != NULL)
857 int herrno;
859 while (1)
861 rc = 0;
862 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
863 tmpbuflen, &rc, &herrno,
864 NULL));
865 if (status == NSS_STATUS_SUCCESS)
866 break;
867 if (status != NSS_STATUS_TRYAGAIN
868 || rc != ERANGE || herrno != NETDB_INTERNAL)
870 if (herrno == TRY_AGAIN)
871 no_data = EAI_AGAIN;
872 else
873 no_data = herrno == NO_DATA;
874 break;
877 if (!malloc_tmpbuf
878 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
879 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
880 2 * tmpbuflen,
881 alloca_used);
882 else
884 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
885 2 * tmpbuflen);
886 if (newp == NULL)
888 _res.options |= old_res_options & RES_USE_INET6;
889 result = -EAI_MEMORY;
890 goto free_and_return;
892 tmpbuf = newp;
893 malloc_tmpbuf = true;
894 tmpbuflen = 2 * tmpbuflen;
898 if (status == NSS_STATUS_SUCCESS)
900 assert (!no_data);
901 no_data = 1;
903 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
904 canon = (*pat)->name;
906 while (*pat != NULL)
908 if ((*pat)->family == AF_INET
909 && req->ai_family == AF_INET6
910 && (req->ai_flags & AI_V4MAPPED) != 0)
912 uint32_t *pataddr = (*pat)->addr;
913 (*pat)->family = AF_INET6;
914 pataddr[3] = pataddr[0];
915 pataddr[2] = htonl (0xffff);
916 pataddr[1] = 0;
917 pataddr[0] = 0;
918 pat = &((*pat)->next);
919 no_data = 0;
921 else if (req->ai_family == AF_UNSPEC
922 || (*pat)->family == req->ai_family)
924 pat = &((*pat)->next);
926 no_data = 0;
927 if (req->ai_family == AF_INET6)
928 got_ipv6 = true;
930 else
931 *pat = ((*pat)->next);
935 no_inet6_data = no_data;
937 else
939 nss_gethostbyname3_r fct = NULL;
940 if (req->ai_flags & AI_CANONNAME)
941 /* No need to use this function if we do not look for
942 the canonical name. The function does not exist in
943 all NSS modules and therefore the lookup would
944 often fail. */
945 fct = __nss_lookup_function (nip, "gethostbyname3_r");
946 if (fct == NULL)
947 /* We are cheating here. The gethostbyname2_r
948 function does not have the same interface as
949 gethostbyname3_r but the extra arguments the
950 latter takes are added at the end. So the
951 gethostbyname2_r code will just ignore them. */
952 fct = __nss_lookup_function (nip, "gethostbyname2_r");
954 if (fct != NULL)
956 if (req->ai_family == AF_INET6
957 || req->ai_family == AF_UNSPEC)
959 gethosts (AF_INET6, struct in6_addr);
960 no_inet6_data = no_data;
961 inet6_status = status;
963 if (req->ai_family == AF_INET
964 || req->ai_family == AF_UNSPEC
965 || (req->ai_family == AF_INET6
966 && (req->ai_flags & AI_V4MAPPED)
967 /* Avoid generating the mapped addresses if we
968 know we are not going to need them. */
969 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
971 gethosts (AF_INET, struct in_addr);
973 if (req->ai_family == AF_INET)
975 no_inet6_data = no_data;
976 inet6_status = status;
980 /* If we found one address for AF_INET or AF_INET6,
981 don't continue the search. */
982 if (inet6_status == NSS_STATUS_SUCCESS
983 || status == NSS_STATUS_SUCCESS)
985 if ((req->ai_flags & AI_CANONNAME) != 0
986 && canon == NULL)
988 /* If we need the canonical name, get it
989 from the same service as the result. */
990 nss_getcanonname_r cfct;
991 int herrno;
993 cfct = __nss_lookup_function (nip,
994 "getcanonname_r");
995 if (cfct != NULL)
997 const size_t max_fqdn_len = 256;
998 if ((req->ai_flags & AI_CANONIDN) != 0
999 && __libc_use_alloca (alloca_used
1000 + max_fqdn_len))
1001 canonbuf = alloca_account (max_fqdn_len,
1002 alloca_used);
1003 else
1005 canonbuf = malloc (max_fqdn_len);
1006 if (canonbuf == NULL)
1008 _res.options
1009 |= old_res_options & RES_USE_INET6;
1010 result = -EAI_MEMORY;
1011 goto free_and_return;
1013 malloc_canonbuf = true;
1015 char *s;
1017 if (DL_CALL_FCT (cfct, (at->name ?: name,
1018 canonbuf,
1019 max_fqdn_len,
1020 &s, &rc, &herrno))
1021 == NSS_STATUS_SUCCESS)
1022 canon = s;
1023 else
1025 /* If the canonical name cannot be
1026 determined, use the passed in
1027 string. */
1028 if (malloc_canonbuf)
1030 free (canonbuf);
1031 malloc_canonbuf = false;
1033 canon = name;
1037 status = NSS_STATUS_SUCCESS;
1039 else
1041 /* We can have different states for AF_INET and
1042 AF_INET6. Try to find a useful one for both. */
1043 if (inet6_status == NSS_STATUS_TRYAGAIN)
1044 status = NSS_STATUS_TRYAGAIN;
1045 else if (status == NSS_STATUS_UNAVAIL
1046 && inet6_status != NSS_STATUS_UNAVAIL)
1047 status = inet6_status;
1050 else
1052 status = NSS_STATUS_UNAVAIL;
1053 /* Could not load any of the lookup functions. Indicate
1054 an internal error if the failure was due to a system
1055 error other than the file not being found. We use the
1056 errno from the last failed callback. */
1057 if (errno != 0 && errno != ENOENT)
1058 __set_h_errno (NETDB_INTERNAL);
1062 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1063 break;
1065 if (nip->next == NULL)
1066 no_more = -1;
1067 else
1068 nip = nip->next;
1071 _res.options |= old_res_options & RES_USE_INET6;
1073 if (h_errno == NETDB_INTERNAL)
1075 result = -EAI_SYSTEM;
1076 goto free_and_return;
1079 if (no_data != 0 && no_inet6_data != 0)
1081 /* If both requests timed out report this. */
1082 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1083 result = -EAI_AGAIN;
1084 else
1085 /* We made requests but they turned out no data. The name
1086 is known, though. */
1087 result = -EAI_NODATA;
1089 goto free_and_return;
1093 process_list:
1094 if (at->family == AF_UNSPEC)
1096 result = -EAI_NONAME;
1097 goto free_and_return;
1100 else
1102 struct gaih_addrtuple *atr;
1103 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1104 memset (at, '\0', sizeof (struct gaih_addrtuple));
1106 if (req->ai_family == AF_UNSPEC)
1108 at->next = __alloca (sizeof (struct gaih_addrtuple));
1109 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1112 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1114 at->family = AF_INET6;
1115 if ((req->ai_flags & AI_PASSIVE) == 0)
1116 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1117 atr = at->next;
1120 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1122 atr->family = AF_INET;
1123 if ((req->ai_flags & AI_PASSIVE) == 0)
1124 atr->addr[0] = htonl (INADDR_LOOPBACK);
1129 struct gaih_servtuple *st2;
1130 struct gaih_addrtuple *at2 = at;
1131 size_t socklen;
1132 sa_family_t family;
1135 buffer is the size of an unformatted IPv6 address in printable format.
1137 while (at2 != NULL)
1139 /* Only the first entry gets the canonical name. */
1140 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1142 if (canon == NULL)
1143 /* If the canonical name cannot be determined, use
1144 the passed in string. */
1145 canon = orig_name;
1147 #ifdef HAVE_LIBIDN
1148 if (req->ai_flags & AI_CANONIDN)
1150 int idn_flags = 0;
1151 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1152 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1153 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1154 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1156 char *out;
1157 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1158 if (rc != IDNA_SUCCESS)
1160 if (rc == IDNA_MALLOC_ERROR)
1161 result = -EAI_MEMORY;
1162 else if (rc == IDNA_DLOPEN_ERROR)
1163 result = -EAI_SYSTEM;
1164 else
1165 result = -EAI_IDN_ENCODE;
1166 goto free_and_return;
1168 /* In case the output string is the same as the input
1169 string no new string has been allocated and we
1170 make a copy. */
1171 if (out == canon)
1172 goto make_copy;
1173 canon = out;
1175 else
1176 #endif
1178 #ifdef HAVE_LIBIDN
1179 make_copy:
1180 #endif
1181 if (malloc_canonbuf)
1182 /* We already allocated the string using malloc. */
1183 malloc_canonbuf = false;
1184 else
1186 canon = strdup (canon);
1187 if (canon == NULL)
1189 result = -EAI_MEMORY;
1190 goto free_and_return;
1196 family = at2->family;
1197 if (family == AF_INET6)
1199 socklen = sizeof (struct sockaddr_in6);
1201 /* If we looked up IPv4 mapped address discard them here if
1202 the caller isn't interested in all address and we have
1203 found at least one IPv6 address. */
1204 if (got_ipv6
1205 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1206 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1207 goto ignore;
1209 else
1210 socklen = sizeof (struct sockaddr_in);
1212 for (st2 = st; st2 != NULL; st2 = st2->next)
1214 struct addrinfo *ai;
1215 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1216 if (ai == NULL)
1218 free ((char *) canon);
1219 result = -EAI_MEMORY;
1220 goto free_and_return;
1223 ai->ai_flags = req->ai_flags;
1224 ai->ai_family = family;
1225 ai->ai_socktype = st2->socktype;
1226 ai->ai_protocol = st2->protocol;
1227 ai->ai_addrlen = socklen;
1228 ai->ai_addr = (void *) (ai + 1);
1230 /* We only add the canonical name once. */
1231 ai->ai_canonname = (char *) canon;
1232 canon = NULL;
1234 #ifdef _HAVE_SA_LEN
1235 ai->ai_addr->sa_len = socklen;
1236 #endif /* _HAVE_SA_LEN */
1237 ai->ai_addr->sa_family = family;
1239 /* In case of an allocation error the list must be NULL
1240 terminated. */
1241 ai->ai_next = NULL;
1243 if (family == AF_INET6)
1245 struct sockaddr_in6 *sin6p =
1246 (struct sockaddr_in6 *) ai->ai_addr;
1248 sin6p->sin6_port = st2->port;
1249 sin6p->sin6_flowinfo = 0;
1250 memcpy (&sin6p->sin6_addr,
1251 at2->addr, sizeof (struct in6_addr));
1252 sin6p->sin6_scope_id = at2->scopeid;
1254 else
1256 struct sockaddr_in *sinp =
1257 (struct sockaddr_in *) ai->ai_addr;
1258 sinp->sin_port = st2->port;
1259 memcpy (&sinp->sin_addr,
1260 at2->addr, sizeof (struct in_addr));
1261 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1264 pai = &(ai->ai_next);
1267 ++*naddrs;
1269 ignore:
1270 at2 = at2->next;
1274 free_and_return:
1275 if (malloc_name)
1276 free ((char *) name);
1277 if (malloc_addrmem)
1278 free (addrmem);
1279 if (malloc_canonbuf)
1280 free (canonbuf);
1281 if (malloc_tmpbuf)
1282 free (tmpbuf);
1284 return result;
1288 struct sort_result
1290 struct addrinfo *dest_addr;
1291 /* Using sockaddr_storage is for now overkill. We only support IPv4
1292 and IPv6 so far. If this changes at some point we can adjust the
1293 type here. */
1294 struct sockaddr_in6 source_addr;
1295 uint8_t source_addr_len;
1296 bool got_source_addr;
1297 uint8_t source_addr_flags;
1298 uint8_t prefixlen;
1299 uint32_t index;
1300 int32_t native;
1303 struct sort_result_combo
1305 struct sort_result *results;
1306 int nresults;
1310 #if __BYTE_ORDER == __BIG_ENDIAN
1311 # define htonl_c(n) n
1312 #else
1313 # define htonl_c(n) __bswap_constant_32 (n)
1314 #endif
1316 static const struct scopeentry
1318 union
1320 char addr[4];
1321 uint32_t addr32;
1323 uint32_t netmask;
1324 int32_t scope;
1325 } default_scopes[] =
1327 /* Link-local addresses: scope 2. */
1328 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1329 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1330 /* Default: scope 14. */
1331 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1334 /* The label table. */
1335 static const struct scopeentry *scopes;
1338 static int
1339 get_scope (const struct sockaddr_in6 *in6)
1341 int scope;
1342 if (in6->sin6_family == PF_INET6)
1344 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1346 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1347 /* RFC 4291 2.5.3 says that the loopback address is to be
1348 treated like a link-local address. */
1349 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1350 scope = 2;
1351 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1352 scope = 5;
1353 else
1354 /* XXX Is this the correct default behavior? */
1355 scope = 14;
1357 else
1358 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1360 else if (in6->sin6_family == PF_INET)
1362 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1364 size_t cnt = 0;
1365 while (1)
1367 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1368 == scopes[cnt].addr32)
1369 return scopes[cnt].scope;
1371 ++cnt;
1373 /* NOTREACHED */
1375 else
1376 /* XXX What is a good default? */
1377 scope = 15;
1379 return scope;
1383 struct prefixentry
1385 struct in6_addr prefix;
1386 unsigned int bits;
1387 int val;
1391 /* The label table. */
1392 static const struct prefixentry *labels;
1394 /* Default labels. */
1395 static const struct prefixentry default_labels[] =
1397 /* See RFC 3484 for the details. */
1398 { { .__in6_u
1399 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1401 }, 128, 0 },
1402 { { .__in6_u
1403 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1405 }, 16, 2 },
1406 { { .__in6_u
1407 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1409 }, 96, 3 },
1410 { { .__in6_u
1411 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1413 }, 96, 4 },
1414 /* The next two entries differ from RFC 3484. We need to treat
1415 IPv6 site-local addresses special because they are never NATed,
1416 unlike site-locale IPv4 addresses. If this would not happen, on
1417 machines which have only IPv4 and IPv6 site-local addresses, the
1418 sorting would prefer the IPv6 site-local addresses, causing
1419 unnecessary delays when trying to connect to a global IPv6 address
1420 through a site-local IPv6 address. */
1421 { { .__in6_u
1422 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1424 }, 10, 5 },
1425 { { .__in6_u
1426 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1428 }, 7, 6 },
1429 /* Additional rule for Teredo tunnels. */
1430 { { .__in6_u
1431 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1433 }, 32, 7 },
1434 { { .__in6_u
1435 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1437 }, 0, 1 }
1441 /* The precedence table. */
1442 static const struct prefixentry *precedence;
1444 /* The default precedences. */
1445 static const struct prefixentry default_precedence[] =
1447 /* See RFC 3484 for the details. */
1448 { { .__in6_u
1449 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1451 }, 128, 50 },
1452 { { .__in6_u
1453 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1455 }, 16, 30 },
1456 { { .__in6_u
1457 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1459 }, 96, 20 },
1460 { { .__in6_u
1461 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1463 }, 96, 10 },
1464 { { .__in6_u
1465 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1467 }, 0, 40 }
1471 static int
1472 match_prefix (const struct sockaddr_in6 *in6,
1473 const struct prefixentry *list, int default_val)
1475 int idx;
1476 struct sockaddr_in6 in6_mem;
1478 if (in6->sin6_family == PF_INET)
1480 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1482 /* Construct a V4-to-6 mapped address. */
1483 in6_mem.sin6_family = PF_INET6;
1484 in6_mem.sin6_port = in->sin_port;
1485 in6_mem.sin6_flowinfo = 0;
1486 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1487 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1488 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1489 in6_mem.sin6_scope_id = 0;
1491 in6 = &in6_mem;
1493 else if (in6->sin6_family != PF_INET6)
1494 return default_val;
1496 for (idx = 0; ; ++idx)
1498 unsigned int bits = list[idx].bits;
1499 const uint8_t *mask = list[idx].prefix.s6_addr;
1500 const uint8_t *val = in6->sin6_addr.s6_addr;
1502 while (bits >= 8)
1504 if (*mask != *val)
1505 break;
1507 ++mask;
1508 ++val;
1509 bits -= 8;
1512 if (bits < 8)
1514 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1515 /* Match! */
1516 break;
1520 return list[idx].val;
1524 static int
1525 get_label (const struct sockaddr_in6 *in6)
1527 /* XXX What is a good default value? */
1528 return match_prefix (in6, labels, INT_MAX);
1532 static int
1533 get_precedence (const struct sockaddr_in6 *in6)
1535 /* XXX What is a good default value? */
1536 return match_prefix (in6, precedence, 0);
1540 /* Find last bit set in a word. */
1541 static int
1542 fls (uint32_t a)
1544 uint32_t mask;
1545 int n;
1546 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1547 if ((a & mask) != 0)
1548 break;
1549 return n;
1553 static int
1554 rfc3484_sort (const void *p1, const void *p2, void *arg)
1556 const size_t idx1 = *(const size_t *) p1;
1557 const size_t idx2 = *(const size_t *) p2;
1558 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1559 struct sort_result *a1 = &src->results[idx1];
1560 struct sort_result *a2 = &src->results[idx2];
1562 /* Rule 1: Avoid unusable destinations.
1563 We have the got_source_addr flag set if the destination is reachable. */
1564 if (a1->got_source_addr && ! a2->got_source_addr)
1565 return -1;
1566 if (! a1->got_source_addr && a2->got_source_addr)
1567 return 1;
1570 /* Rule 2: Prefer matching scope. Only interesting if both
1571 destination addresses are IPv6. */
1572 int a1_dst_scope
1573 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1575 int a2_dst_scope
1576 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1578 if (a1->got_source_addr)
1580 int a1_src_scope = get_scope (&a1->source_addr);
1581 int a2_src_scope = get_scope (&a2->source_addr);
1583 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1584 return -1;
1585 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1586 return 1;
1590 /* Rule 3: Avoid deprecated addresses. */
1591 if (a1->got_source_addr)
1593 if (!(a1->source_addr_flags & in6ai_deprecated)
1594 && (a2->source_addr_flags & in6ai_deprecated))
1595 return -1;
1596 if ((a1->source_addr_flags & in6ai_deprecated)
1597 && !(a2->source_addr_flags & in6ai_deprecated))
1598 return 1;
1601 /* Rule 4: Prefer home addresses. */
1602 if (a1->got_source_addr)
1604 if (!(a1->source_addr_flags & in6ai_homeaddress)
1605 && (a2->source_addr_flags & in6ai_homeaddress))
1606 return 1;
1607 if ((a1->source_addr_flags & in6ai_homeaddress)
1608 && !(a2->source_addr_flags & in6ai_homeaddress))
1609 return -1;
1612 /* Rule 5: Prefer matching label. */
1613 if (a1->got_source_addr)
1615 int a1_dst_label
1616 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1617 int a1_src_label = get_label (&a1->source_addr);
1619 int a2_dst_label
1620 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1621 int a2_src_label = get_label (&a2->source_addr);
1623 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1624 return -1;
1625 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1626 return 1;
1630 /* Rule 6: Prefer higher precedence. */
1631 int a1_prec
1632 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1633 int a2_prec
1634 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1636 if (a1_prec > a2_prec)
1637 return -1;
1638 if (a1_prec < a2_prec)
1639 return 1;
1642 /* Rule 7: Prefer native transport. */
1643 if (a1->got_source_addr)
1645 /* The same interface index means the same interface which means
1646 there is no difference in transport. This should catch many
1647 (most?) cases. */
1648 if (a1->index != a2->index)
1650 int a1_native = a1->native;
1651 int a2_native = a2->native;
1653 if (a1_native == -1 || a2_native == -1)
1655 uint32_t a1_index;
1656 if (a1_native == -1)
1658 /* If we do not have the information use 'native' as
1659 the default. */
1660 a1_native = 0;
1661 a1_index = a1->index;
1663 else
1664 a1_index = 0xffffffffu;
1666 uint32_t a2_index;
1667 if (a2_native == -1)
1669 /* If we do not have the information use 'native' as
1670 the default. */
1671 a2_native = 0;
1672 a2_index = a2->index;
1674 else
1675 a2_index = 0xffffffffu;
1677 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1679 /* Fill in the results in all the records. */
1680 for (int i = 0; i < src->nresults; ++i)
1681 if (a1_index != -1 && src->results[i].index == a1_index)
1683 assert (src->results[i].native == -1
1684 || src->results[i].native == a1_native);
1685 src->results[i].native = a1_native;
1687 else if (a2_index != -1 && src->results[i].index == a2_index)
1689 assert (src->results[i].native == -1
1690 || src->results[i].native == a2_native);
1691 src->results[i].native = a2_native;
1695 if (a1_native && !a2_native)
1696 return -1;
1697 if (!a1_native && a2_native)
1698 return 1;
1703 /* Rule 8: Prefer smaller scope. */
1704 if (a1_dst_scope < a2_dst_scope)
1705 return -1;
1706 if (a1_dst_scope > a2_dst_scope)
1707 return 1;
1710 /* Rule 9: Use longest matching prefix. */
1711 if (a1->got_source_addr
1712 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1714 int bit1 = 0;
1715 int bit2 = 0;
1717 if (a1->dest_addr->ai_family == PF_INET)
1719 assert (a1->source_addr.sin6_family == PF_INET);
1720 assert (a2->source_addr.sin6_family == PF_INET);
1722 /* Outside of subnets, as defined by the network masks,
1723 common address prefixes for IPv4 addresses make no sense.
1724 So, define a non-zero value only if source and
1725 destination address are on the same subnet. */
1726 struct sockaddr_in *in1_dst
1727 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1728 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1729 struct sockaddr_in *in1_src
1730 = (struct sockaddr_in *) &a1->source_addr;
1731 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1732 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1734 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1735 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1737 struct sockaddr_in *in2_dst
1738 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1739 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1740 struct sockaddr_in *in2_src
1741 = (struct sockaddr_in *) &a2->source_addr;
1742 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1743 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1745 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1746 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1748 else if (a1->dest_addr->ai_family == PF_INET6)
1750 assert (a1->source_addr.sin6_family == PF_INET6);
1751 assert (a2->source_addr.sin6_family == PF_INET6);
1753 struct sockaddr_in6 *in1_dst;
1754 struct sockaddr_in6 *in1_src;
1755 struct sockaddr_in6 *in2_dst;
1756 struct sockaddr_in6 *in2_src;
1758 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1759 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1760 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1761 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1763 int i;
1764 for (i = 0; i < 4; ++i)
1765 if (in1_dst->sin6_addr.s6_addr32[i]
1766 != in1_src->sin6_addr.s6_addr32[i]
1767 || (in2_dst->sin6_addr.s6_addr32[i]
1768 != in2_src->sin6_addr.s6_addr32[i]))
1769 break;
1771 if (i < 4)
1773 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1774 ^ in1_src->sin6_addr.s6_addr32[i]));
1775 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1776 ^ in2_src->sin6_addr.s6_addr32[i]));
1780 if (bit1 > bit2)
1781 return -1;
1782 if (bit1 < bit2)
1783 return 1;
1787 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1788 compare with the value indicating the order in which the entries
1789 have been received from the services. NB: no two entries can have
1790 the same order so the test will never return zero. */
1791 return idx1 < idx2 ? -1 : 1;
1795 static int
1796 in6aicmp (const void *p1, const void *p2)
1798 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1799 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1801 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1805 /* Name of the config file for RFC 3484 sorting (for now). */
1806 #define GAICONF_FNAME "/etc/gai.conf"
1809 /* Non-zero if we are supposed to reload the config file automatically
1810 whenever it changed. */
1811 static int gaiconf_reload_flag;
1813 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1814 static int gaiconf_reload_flag_ever_set;
1816 /* Last modification time. */
1817 #ifdef _STATBUF_ST_NSEC
1819 static struct timespec gaiconf_mtime;
1821 static inline void
1822 save_gaiconf_mtime (const struct stat64 *st)
1824 gaiconf_mtime = st->st_mtim;
1827 static inline bool
1828 check_gaiconf_mtime (const struct stat64 *st)
1830 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1831 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1834 #else
1836 static time_t gaiconf_mtime;
1838 static inline void
1839 save_gaiconf_mtime (const struct stat64 *st)
1841 gaiconf_mtime = st->st_mtime;
1844 static inline bool
1845 check_gaiconf_mtime (const struct stat64 *st)
1847 return st->st_mtime == gaiconf_mtime;
1850 #endif
1853 libc_freeres_fn(fini)
1855 if (labels != default_labels)
1857 const struct prefixentry *old = labels;
1858 labels = default_labels;
1859 free ((void *) old);
1862 if (precedence != default_precedence)
1864 const struct prefixentry *old = precedence;
1865 precedence = default_precedence;
1866 free ((void *) old);
1869 if (scopes != default_scopes)
1871 const struct scopeentry *old = scopes;
1872 scopes = default_scopes;
1873 free ((void *) old);
1878 struct prefixlist
1880 struct prefixentry entry;
1881 struct prefixlist *next;
1885 struct scopelist
1887 struct scopeentry entry;
1888 struct scopelist *next;
1892 static void
1893 free_prefixlist (struct prefixlist *list)
1895 while (list != NULL)
1897 struct prefixlist *oldp = list;
1898 list = list->next;
1899 free (oldp);
1904 static void
1905 free_scopelist (struct scopelist *list)
1907 while (list != NULL)
1909 struct scopelist *oldp = list;
1910 list = list->next;
1911 free (oldp);
1916 static int
1917 prefixcmp (const void *p1, const void *p2)
1919 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1920 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1922 if (e1->bits < e2->bits)
1923 return 1;
1924 if (e1->bits == e2->bits)
1925 return 0;
1926 return -1;
1930 static int
1931 scopecmp (const void *p1, const void *p2)
1933 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1934 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1936 if (e1->netmask > e2->netmask)
1937 return -1;
1938 if (e1->netmask == e2->netmask)
1939 return 0;
1940 return 1;
1944 static void
1945 gaiconf_init (void)
1947 struct prefixlist *labellist = NULL;
1948 size_t nlabellist = 0;
1949 bool labellist_nullbits = false;
1950 struct prefixlist *precedencelist = NULL;
1951 size_t nprecedencelist = 0;
1952 bool precedencelist_nullbits = false;
1953 struct scopelist *scopelist = NULL;
1954 size_t nscopelist = 0;
1955 bool scopelist_nullbits = false;
1957 FILE *fp = fopen (GAICONF_FNAME, "rce");
1958 if (fp != NULL)
1960 struct stat64 st;
1961 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1963 fclose (fp);
1964 goto no_file;
1967 char *line = NULL;
1968 size_t linelen = 0;
1970 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1972 while (!feof_unlocked (fp))
1974 ssize_t n = __getline (&line, &linelen, fp);
1975 if (n <= 0)
1976 break;
1978 /* Handle comments. No escaping possible so this is easy. */
1979 char *cp = strchr (line, '#');
1980 if (cp != NULL)
1981 *cp = '\0';
1983 cp = line;
1984 while (isspace (*cp))
1985 ++cp;
1987 char *cmd = cp;
1988 while (*cp != '\0' && !isspace (*cp))
1989 ++cp;
1990 size_t cmdlen = cp - cmd;
1992 if (*cp != '\0')
1993 *cp++ = '\0';
1994 while (isspace (*cp))
1995 ++cp;
1997 char *val1 = cp;
1998 while (*cp != '\0' && !isspace (*cp))
1999 ++cp;
2000 size_t val1len = cp - cmd;
2002 /* We always need at least two values. */
2003 if (val1len == 0)
2004 continue;
2006 if (*cp != '\0')
2007 *cp++ = '\0';
2008 while (isspace (*cp))
2009 ++cp;
2011 char *val2 = cp;
2012 while (*cp != '\0' && !isspace (*cp))
2013 ++cp;
2015 /* Ignore the rest of the line. */
2016 *cp = '\0';
2018 struct prefixlist **listp;
2019 size_t *lenp;
2020 bool *nullbitsp;
2021 switch (cmdlen)
2023 case 5:
2024 if (strcmp (cmd, "label") == 0)
2026 struct in6_addr prefix;
2027 unsigned long int bits;
2028 unsigned long int val;
2029 char *endp;
2031 listp = &labellist;
2032 lenp = &nlabellist;
2033 nullbitsp = &labellist_nullbits;
2035 new_elem:
2036 bits = 128;
2037 __set_errno (0);
2038 cp = strchr (val1, '/');
2039 if (cp != NULL)
2040 *cp++ = '\0';
2041 if (inet_pton (AF_INET6, val1, &prefix)
2042 && (cp == NULL
2043 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2044 || errno != ERANGE)
2045 && *endp == '\0'
2046 && bits <= 128
2047 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2048 || errno != ERANGE)
2049 && *endp == '\0'
2050 && val <= INT_MAX)
2052 struct prefixlist *newp = malloc (sizeof (*newp));
2053 if (newp == NULL)
2055 free (line);
2056 fclose (fp);
2057 goto no_file;
2060 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2061 newp->entry.bits = bits;
2062 newp->entry.val = val;
2063 newp->next = *listp;
2064 *listp = newp;
2065 ++*lenp;
2066 *nullbitsp |= bits == 0;
2069 break;
2071 case 6:
2072 if (strcmp (cmd, "reload") == 0)
2074 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2075 if (gaiconf_reload_flag)
2076 gaiconf_reload_flag_ever_set = 1;
2078 break;
2080 case 7:
2081 if (strcmp (cmd, "scopev4") == 0)
2083 struct in6_addr prefix;
2084 unsigned long int bits;
2085 unsigned long int val;
2086 char *endp;
2088 bits = 32;
2089 __set_errno (0);
2090 cp = strchr (val1, '/');
2091 if (cp != NULL)
2092 *cp++ = '\0';
2093 if (inet_pton (AF_INET6, val1, &prefix))
2095 bits = 128;
2096 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2097 && (cp == NULL
2098 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2099 || errno != ERANGE)
2100 && *endp == '\0'
2101 && bits >= 96
2102 && bits <= 128
2103 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2104 || errno != ERANGE)
2105 && *endp == '\0'
2106 && val <= INT_MAX)
2108 struct scopelist *newp;
2109 new_scope:
2110 newp = malloc (sizeof (*newp));
2111 if (newp == NULL)
2113 free (line);
2114 fclose (fp);
2115 goto no_file;
2118 newp->entry.netmask = htonl (bits != 96
2119 ? (0xffffffff
2120 << (128 - bits))
2121 : 0);
2122 newp->entry.addr32 = (prefix.s6_addr32[3]
2123 & newp->entry.netmask);
2124 newp->entry.scope = val;
2125 newp->next = scopelist;
2126 scopelist = newp;
2127 ++nscopelist;
2128 scopelist_nullbits |= bits == 96;
2131 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2132 && (cp == NULL
2133 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2134 || errno != ERANGE)
2135 && *endp == '\0'
2136 && bits <= 32
2137 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2138 || errno != ERANGE)
2139 && *endp == '\0'
2140 && val <= INT_MAX)
2142 bits += 96;
2143 goto new_scope;
2146 break;
2148 case 10:
2149 if (strcmp (cmd, "precedence") == 0)
2151 listp = &precedencelist;
2152 lenp = &nprecedencelist;
2153 nullbitsp = &precedencelist_nullbits;
2154 goto new_elem;
2156 break;
2160 free (line);
2162 fclose (fp);
2164 /* Create the array for the labels. */
2165 struct prefixentry *new_labels;
2166 if (nlabellist > 0)
2168 if (!labellist_nullbits)
2169 ++nlabellist;
2170 new_labels = malloc (nlabellist * sizeof (*new_labels));
2171 if (new_labels == NULL)
2172 goto no_file;
2174 int i = nlabellist;
2175 if (!labellist_nullbits)
2177 --i;
2178 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2179 new_labels[i].bits = 0;
2180 new_labels[i].val = 1;
2183 struct prefixlist *l = labellist;
2184 while (i-- > 0)
2186 new_labels[i] = l->entry;
2187 l = l->next;
2189 free_prefixlist (labellist);
2191 /* Sort the entries so that the most specific ones are at
2192 the beginning. */
2193 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2195 else
2196 new_labels = (struct prefixentry *) default_labels;
2198 struct prefixentry *new_precedence;
2199 if (nprecedencelist > 0)
2201 if (!precedencelist_nullbits)
2202 ++nprecedencelist;
2203 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2204 if (new_precedence == NULL)
2206 if (new_labels != default_labels)
2207 free (new_labels);
2208 goto no_file;
2211 int i = nprecedencelist;
2212 if (!precedencelist_nullbits)
2214 --i;
2215 memset (&new_precedence[i].prefix, '\0',
2216 sizeof (struct in6_addr));
2217 new_precedence[i].bits = 0;
2218 new_precedence[i].val = 40;
2221 struct prefixlist *l = precedencelist;
2222 while (i-- > 0)
2224 new_precedence[i] = l->entry;
2225 l = l->next;
2227 free_prefixlist (precedencelist);
2229 /* Sort the entries so that the most specific ones are at
2230 the beginning. */
2231 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2232 prefixcmp);
2234 else
2235 new_precedence = (struct prefixentry *) default_precedence;
2237 struct scopeentry *new_scopes;
2238 if (nscopelist > 0)
2240 if (!scopelist_nullbits)
2241 ++nscopelist;
2242 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2243 if (new_scopes == NULL)
2245 if (new_labels != default_labels)
2246 free (new_labels);
2247 if (new_precedence != default_precedence)
2248 free (new_precedence);
2249 goto no_file;
2252 int i = nscopelist;
2253 if (!scopelist_nullbits)
2255 --i;
2256 new_scopes[i].addr32 = 0;
2257 new_scopes[i].netmask = 0;
2258 new_scopes[i].scope = 14;
2261 struct scopelist *l = scopelist;
2262 while (i-- > 0)
2264 new_scopes[i] = l->entry;
2265 l = l->next;
2267 free_scopelist (scopelist);
2269 /* Sort the entries so that the most specific ones are at
2270 the beginning. */
2271 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2272 scopecmp);
2274 else
2275 new_scopes = (struct scopeentry *) default_scopes;
2277 /* Now we are ready to replace the values. */
2278 const struct prefixentry *old = labels;
2279 labels = new_labels;
2280 if (old != default_labels)
2281 free ((void *) old);
2283 old = precedence;
2284 precedence = new_precedence;
2285 if (old != default_precedence)
2286 free ((void *) old);
2288 const struct scopeentry *oldscope = scopes;
2289 scopes = new_scopes;
2290 if (oldscope != default_scopes)
2291 free ((void *) oldscope);
2293 save_gaiconf_mtime (&st);
2295 else
2297 no_file:
2298 free_prefixlist (labellist);
2299 free_prefixlist (precedencelist);
2300 free_scopelist (scopelist);
2302 /* If we previously read the file but it is gone now, free the
2303 old data and use the builtin one. Leave the reload flag
2304 alone. */
2305 fini ();
2310 static void
2311 gaiconf_reload (void)
2313 struct stat64 st;
2314 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2315 || !check_gaiconf_mtime (&st))
2316 gaiconf_init ();
2321 getaddrinfo (const char *name, const char *service,
2322 const struct addrinfo *hints, struct addrinfo **pai)
2324 int i = 0, last_i = 0;
2325 int nresults = 0;
2326 struct addrinfo *p = NULL;
2327 struct gaih_service gaih_service, *pservice;
2328 struct addrinfo local_hints;
2330 if (name != NULL && name[0] == '*' && name[1] == 0)
2331 name = NULL;
2333 if (service != NULL && service[0] == '*' && service[1] == 0)
2334 service = NULL;
2336 if (name == NULL && service == NULL)
2337 return EAI_NONAME;
2339 if (hints == NULL)
2340 hints = &default_hints;
2342 if (hints->ai_flags
2343 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2344 #ifdef HAVE_LIBIDN
2345 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2346 |AI_IDN_USE_STD3_ASCII_RULES
2347 #endif
2348 |AI_NUMERICSERV|AI_ALL))
2349 return EAI_BADFLAGS;
2351 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2352 return EAI_BADFLAGS;
2354 struct in6addrinfo *in6ai = NULL;
2355 size_t in6ailen = 0;
2356 bool seen_ipv4 = false;
2357 bool seen_ipv6 = false;
2358 bool check_pf_called = false;
2360 if (hints->ai_flags & AI_ADDRCONFIG)
2362 /* We might need information about what interfaces are available.
2363 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2364 cannot cache the results since new interfaces could be added at
2365 any time. */
2366 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2367 check_pf_called = true;
2369 /* Now make a decision on what we return, if anything. */
2370 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2372 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2373 narrow down the search. */
2374 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2376 local_hints = *hints;
2377 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2378 hints = &local_hints;
2381 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2382 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2384 /* We cannot possibly return a valid answer. */
2385 __free_in6ai (in6ai);
2386 return EAI_NONAME;
2390 if (service && service[0])
2392 char *c;
2393 gaih_service.name = service;
2394 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2395 if (*c != '\0')
2397 if (hints->ai_flags & AI_NUMERICSERV)
2399 __free_in6ai (in6ai);
2400 return EAI_NONAME;
2403 gaih_service.num = -1;
2406 pservice = &gaih_service;
2408 else
2409 pservice = NULL;
2411 struct addrinfo **end = &p;
2413 unsigned int naddrs = 0;
2414 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2415 || hints->ai_family == AF_INET6)
2417 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2418 if (last_i != 0)
2420 freeaddrinfo (p);
2421 __free_in6ai (in6ai);
2423 return -last_i;
2425 while (*end)
2427 end = &((*end)->ai_next);
2428 ++nresults;
2431 else
2433 __free_in6ai (in6ai);
2434 return EAI_FAMILY;
2437 if (naddrs > 1)
2439 /* Read the config file. */
2440 __libc_once_define (static, once);
2441 __typeof (once) old_once = once;
2442 __libc_once (once, gaiconf_init);
2443 /* Sort results according to RFC 3484. */
2444 struct sort_result *results;
2445 size_t *order;
2446 struct addrinfo *q;
2447 struct addrinfo *last = NULL;
2448 char *canonname = NULL;
2449 bool malloc_results;
2450 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2452 malloc_results
2453 = !__libc_use_alloca (alloc_size);
2454 if (malloc_results)
2456 results = malloc (alloc_size);
2457 if (results == NULL)
2459 __free_in6ai (in6ai);
2460 return EAI_MEMORY;
2463 else
2464 results = alloca (alloc_size);
2465 order = (size_t *) (results + nresults);
2467 /* Now we definitely need the interface information. */
2468 if (! check_pf_called)
2469 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2471 /* If we have information about deprecated and temporary addresses
2472 sort the array now. */
2473 if (in6ai != NULL)
2474 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2476 int fd = -1;
2477 int af = AF_UNSPEC;
2479 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2481 results[i].dest_addr = q;
2482 results[i].native = -1;
2483 order[i] = i;
2485 /* If we just looked up the address for a different
2486 protocol, reuse the result. */
2487 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2488 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2490 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2491 results[i - 1].source_addr_len);
2492 results[i].source_addr_len = results[i - 1].source_addr_len;
2493 results[i].got_source_addr = results[i - 1].got_source_addr;
2494 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2495 results[i].prefixlen = results[i - 1].prefixlen;
2496 results[i].index = results[i - 1].index;
2498 else
2500 results[i].got_source_addr = false;
2501 results[i].source_addr_flags = 0;
2502 results[i].prefixlen = 0;
2503 results[i].index = 0xffffffffu;
2505 /* We overwrite the type with SOCK_DGRAM since we do not
2506 want connect() to connect to the other side. If we
2507 cannot determine the source address remember this
2508 fact. */
2509 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2511 if (fd != -1)
2512 close_retry:
2513 close_not_cancel_no_status (fd);
2514 af = q->ai_family;
2515 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2517 else
2519 /* Reset the connection. */
2520 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2521 __connect (fd, &sa, sizeof (sa));
2524 socklen_t sl = sizeof (results[i].source_addr);
2525 if (fd != -1
2526 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2527 && __getsockname (fd,
2528 (struct sockaddr *) &results[i].source_addr,
2529 &sl) == 0)
2531 results[i].source_addr_len = sl;
2532 results[i].got_source_addr = true;
2534 if (in6ai != NULL)
2536 /* See whether the source address is on the list of
2537 deprecated or temporary addresses. */
2538 struct in6addrinfo tmp;
2540 if (q->ai_family == AF_INET && af == AF_INET)
2542 struct sockaddr_in *sinp
2543 = (struct sockaddr_in *) &results[i].source_addr;
2544 tmp.addr[0] = 0;
2545 tmp.addr[1] = 0;
2546 tmp.addr[2] = htonl (0xffff);
2547 /* Special case for lo interface, the source address
2548 being possibly different than the interface
2549 address. */
2550 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2551 == 0x7f000000)
2552 tmp.addr[3] = htonl(0x7f000001);
2553 else
2554 tmp.addr[3] = sinp->sin_addr.s_addr;
2556 else
2558 struct sockaddr_in6 *sin6p
2559 = (struct sockaddr_in6 *) &results[i].source_addr;
2560 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2563 struct in6addrinfo *found
2564 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2565 in6aicmp);
2566 if (found != NULL)
2568 results[i].source_addr_flags = found->flags;
2569 results[i].prefixlen = found->prefixlen;
2570 results[i].index = found->index;
2574 if (q->ai_family == AF_INET && af == AF_INET6)
2576 /* We have to convert the address. The socket is
2577 IPv6 and the request is for IPv4. */
2578 struct sockaddr_in6 *sin6
2579 = (struct sockaddr_in6 *) &results[i].source_addr;
2580 struct sockaddr_in *sin
2581 = (struct sockaddr_in *) &results[i].source_addr;
2582 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2583 sin->sin_family = AF_INET;
2584 /* We do not have to initialize sin_port since this
2585 fields has the same position and size in the IPv6
2586 structure. */
2587 assert (offsetof (struct sockaddr_in, sin_port)
2588 == offsetof (struct sockaddr_in6, sin6_port));
2589 assert (sizeof (sin->sin_port)
2590 == sizeof (sin6->sin6_port));
2591 memcpy (&sin->sin_addr,
2592 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2593 results[i].source_addr_len = sizeof (struct sockaddr_in);
2596 else if (errno == EAFNOSUPPORT && af == AF_INET6
2597 && q->ai_family == AF_INET)
2598 /* This could mean IPv6 sockets are IPv6-only. */
2599 goto close_retry;
2600 else
2601 /* Just make sure that if we have to process the same
2602 address again we do not copy any memory. */
2603 results[i].source_addr_len = 0;
2606 /* Remember the canonical name. */
2607 if (q->ai_canonname != NULL)
2609 assert (canonname == NULL);
2610 canonname = q->ai_canonname;
2611 q->ai_canonname = NULL;
2615 if (fd != -1)
2616 close_not_cancel_no_status (fd);
2618 /* We got all the source addresses we can get, now sort using
2619 the information. */
2620 struct sort_result_combo src
2621 = { .results = results, .nresults = nresults };
2622 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2624 __libc_lock_define_initialized (static, lock);
2626 __libc_lock_lock (lock);
2627 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2628 gaiconf_reload ();
2629 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2630 __libc_lock_unlock (lock);
2632 else
2633 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2635 /* Queue the results up as they come out of sorting. */
2636 q = p = results[order[0]].dest_addr;
2637 for (i = 1; i < nresults; ++i)
2638 q = q->ai_next = results[order[i]].dest_addr;
2639 q->ai_next = NULL;
2641 /* Fill in the canonical name into the new first entry. */
2642 p->ai_canonname = canonname;
2644 if (malloc_results)
2645 free (results);
2648 __free_in6ai (in6ai);
2650 if (p)
2652 *pai = p;
2653 return 0;
2656 return last_i ? -last_i : EAI_NONAME;
2658 libc_hidden_def (getaddrinfo)
2660 nss_interface_function (getaddrinfo)
2662 void
2663 freeaddrinfo (struct addrinfo *ai)
2665 struct addrinfo *p;
2667 while (ai != NULL)
2669 p = ai;
2670 ai = ai->ai_next;
2671 free (p->ai_canonname);
2672 free (p);
2675 libc_hidden_def (freeaddrinfo)