Fix use of half-initialized result in getaddrinfo when using nscd (bug 16743)
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob3385bed3332252046746fb5a84f3dce12e2bfaf4
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 if (!((air->family[i] == AF_INET
714 && req->ai_family == AF_INET6
715 && (req->ai_flags & AI_V4MAPPED) != 0)
716 || req->ai_family == AF_UNSPEC
717 || air->family[i] == req->ai_family))
718 /* Skip over non-matching result. */
719 continue;
721 socklen_t size = (air->family[i] == AF_INET
722 ? INADDRSZ : IN6ADDRSZ);
723 if (*pat == NULL)
725 *pat = addrfree++;
726 (*pat)->scopeid = 0;
728 uint32_t *pataddr = (*pat)->addr;
729 (*pat)->next = NULL;
730 if (added_canon || air->canon == NULL)
731 (*pat)->name = NULL;
732 else if (canonbuf == NULL)
734 size_t canonlen = strlen (air->canon) + 1;
735 if ((req->ai_flags & AI_CANONIDN) != 0
736 && __libc_use_alloca (alloca_used + canonlen))
737 canonbuf = alloca_account (canonlen, alloca_used);
738 else
740 canonbuf = malloc (canonlen);
741 if (canonbuf == NULL)
743 result = -EAI_MEMORY;
744 goto free_and_return;
746 malloc_canonbuf = true;
748 canon = (*pat)->name = memcpy (canonbuf, air->canon,
749 canonlen);
752 if (air->family[i] == AF_INET
753 && req->ai_family == AF_INET6
754 && (req->ai_flags & AI_V4MAPPED))
756 (*pat)->family = AF_INET6;
757 pataddr[3] = *(uint32_t *) addrs;
758 pataddr[2] = htonl (0xffff);
759 pataddr[1] = 0;
760 pataddr[0] = 0;
761 pat = &((*pat)->next);
762 added_canon = true;
764 else if (req->ai_family == AF_UNSPEC
765 || air->family[i] == req->ai_family)
767 (*pat)->family = air->family[i];
768 memcpy (pataddr, addrs, size);
769 pat = &((*pat)->next);
770 added_canon = true;
771 if (air->family[i] == AF_INET6)
772 got_ipv6 = true;
774 addrs += size;
777 free (air);
779 if (at->family == AF_UNSPEC)
781 result = -EAI_NONAME;
782 goto free_and_return;
785 goto process_list;
787 else if (err == 0)
788 /* The database contains a negative entry. */
789 goto free_and_return;
790 else if (__nss_not_use_nscd_hosts == 0)
792 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
793 result = -EAI_MEMORY;
794 else if (herrno == TRY_AGAIN)
795 result = -EAI_AGAIN;
796 else
797 result = -EAI_SYSTEM;
799 goto free_and_return;
802 #endif
804 if (__nss_hosts_database == NULL)
805 no_more = __nss_database_lookup ("hosts", NULL,
806 "dns [!UNAVAIL=return] files",
807 &__nss_hosts_database);
808 else
809 no_more = 0;
810 nip = __nss_hosts_database;
812 /* Initialize configurations. */
813 if (__glibc_unlikely (!_res_hconf.initialized))
814 _res_hconf_init ();
815 if (__res_maybe_init (&_res, 0) == -1)
816 no_more = 1;
818 /* If we are looking for both IPv4 and IPv6 address we don't
819 want the lookup functions to automatically promote IPv4
820 addresses to IPv6 addresses. Currently this is decided
821 by setting the RES_USE_INET6 bit in _res.options. */
822 old_res_options = _res.options;
823 _res.options &= ~RES_USE_INET6;
825 size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
826 malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
827 assert (tmpbuf == NULL);
828 if (!malloc_tmpbuf)
829 tmpbuf = alloca_account (tmpbuflen, alloca_used);
830 else
832 tmpbuf = malloc (tmpbuflen);
833 if (tmpbuf == NULL)
835 _res.options |= old_res_options & RES_USE_INET6;
836 result = -EAI_MEMORY;
837 goto free_and_return;
841 while (!no_more)
843 no_data = 0;
844 nss_gethostbyname4_r fct4 = NULL;
846 /* gethostbyname4_r sends out parallel A and AAAA queries and
847 is thus only suitable for PF_UNSPEC. */
848 if (req->ai_family == PF_UNSPEC)
849 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
851 if (fct4 != NULL)
853 int herrno;
855 while (1)
857 rc = 0;
858 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
859 tmpbuflen, &rc, &herrno,
860 NULL));
861 if (status == NSS_STATUS_SUCCESS)
862 break;
863 if (status != NSS_STATUS_TRYAGAIN
864 || rc != ERANGE || herrno != NETDB_INTERNAL)
866 if (status == NSS_STATUS_TRYAGAIN
867 && herrno == TRY_AGAIN)
868 no_data = EAI_AGAIN;
869 else
870 no_data = herrno == NO_DATA;
871 break;
874 if (!malloc_tmpbuf
875 && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
876 tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
877 2 * tmpbuflen,
878 alloca_used);
879 else
881 char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
882 2 * tmpbuflen);
883 if (newp == NULL)
885 _res.options |= old_res_options & RES_USE_INET6;
886 result = -EAI_MEMORY;
887 goto free_and_return;
889 tmpbuf = newp;
890 malloc_tmpbuf = true;
891 tmpbuflen = 2 * tmpbuflen;
895 if (status == NSS_STATUS_SUCCESS)
897 assert (!no_data);
898 no_data = 1;
900 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
901 canon = (*pat)->name;
903 while (*pat != NULL)
905 if ((*pat)->family == AF_INET
906 && req->ai_family == AF_INET6
907 && (req->ai_flags & AI_V4MAPPED) != 0)
909 uint32_t *pataddr = (*pat)->addr;
910 (*pat)->family = AF_INET6;
911 pataddr[3] = pataddr[0];
912 pataddr[2] = htonl (0xffff);
913 pataddr[1] = 0;
914 pataddr[0] = 0;
915 pat = &((*pat)->next);
916 no_data = 0;
918 else if (req->ai_family == AF_UNSPEC
919 || (*pat)->family == req->ai_family)
921 pat = &((*pat)->next);
923 no_data = 0;
924 if (req->ai_family == AF_INET6)
925 got_ipv6 = true;
927 else
928 *pat = ((*pat)->next);
932 no_inet6_data = no_data;
934 else
936 nss_gethostbyname3_r fct = NULL;
937 if (req->ai_flags & AI_CANONNAME)
938 /* No need to use this function if we do not look for
939 the canonical name. The function does not exist in
940 all NSS modules and therefore the lookup would
941 often fail. */
942 fct = __nss_lookup_function (nip, "gethostbyname3_r");
943 if (fct == NULL)
944 /* We are cheating here. The gethostbyname2_r
945 function does not have the same interface as
946 gethostbyname3_r but the extra arguments the
947 latter takes are added at the end. So the
948 gethostbyname2_r code will just ignore them. */
949 fct = __nss_lookup_function (nip, "gethostbyname2_r");
951 if (fct != NULL)
953 if (req->ai_family == AF_INET6
954 || req->ai_family == AF_UNSPEC)
956 gethosts (AF_INET6, struct in6_addr);
957 no_inet6_data = no_data;
958 inet6_status = status;
960 if (req->ai_family == AF_INET
961 || req->ai_family == AF_UNSPEC
962 || (req->ai_family == AF_INET6
963 && (req->ai_flags & AI_V4MAPPED)
964 /* Avoid generating the mapped addresses if we
965 know we are not going to need them. */
966 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
968 gethosts (AF_INET, struct in_addr);
970 if (req->ai_family == AF_INET)
972 no_inet6_data = no_data;
973 inet6_status = status;
977 /* If we found one address for AF_INET or AF_INET6,
978 don't continue the search. */
979 if (inet6_status == NSS_STATUS_SUCCESS
980 || status == NSS_STATUS_SUCCESS)
982 if ((req->ai_flags & AI_CANONNAME) != 0
983 && canon == NULL)
985 /* If we need the canonical name, get it
986 from the same service as the result. */
987 nss_getcanonname_r cfct;
988 int herrno;
990 cfct = __nss_lookup_function (nip,
991 "getcanonname_r");
992 if (cfct != NULL)
994 const size_t max_fqdn_len = 256;
995 if ((req->ai_flags & AI_CANONIDN) != 0
996 && __libc_use_alloca (alloca_used
997 + max_fqdn_len))
998 canonbuf = alloca_account (max_fqdn_len,
999 alloca_used);
1000 else
1002 canonbuf = malloc (max_fqdn_len);
1003 if (canonbuf == NULL)
1005 _res.options
1006 |= old_res_options & RES_USE_INET6;
1007 result = -EAI_MEMORY;
1008 goto free_and_return;
1010 malloc_canonbuf = true;
1012 char *s;
1014 if (DL_CALL_FCT (cfct, (at->name ?: name,
1015 canonbuf,
1016 max_fqdn_len,
1017 &s, &rc, &herrno))
1018 == NSS_STATUS_SUCCESS)
1019 canon = s;
1020 else
1022 /* If the canonical name cannot be
1023 determined, use the passed in
1024 string. */
1025 if (malloc_canonbuf)
1027 free (canonbuf);
1028 malloc_canonbuf = false;
1030 canon = name;
1034 status = NSS_STATUS_SUCCESS;
1036 else
1038 /* We can have different states for AF_INET and
1039 AF_INET6. Try to find a useful one for both. */
1040 if (inet6_status == NSS_STATUS_TRYAGAIN)
1041 status = NSS_STATUS_TRYAGAIN;
1042 else if (status == NSS_STATUS_UNAVAIL
1043 && inet6_status != NSS_STATUS_UNAVAIL)
1044 status = inet6_status;
1047 else
1049 status = NSS_STATUS_UNAVAIL;
1050 /* Could not load any of the lookup functions. Indicate
1051 an internal error if the failure was due to a system
1052 error other than the file not being found. We use the
1053 errno from the last failed callback. */
1054 if (errno != 0 && errno != ENOENT)
1055 __set_h_errno (NETDB_INTERNAL);
1059 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1060 break;
1062 if (nip->next == NULL)
1063 no_more = -1;
1064 else
1065 nip = nip->next;
1068 _res.options |= old_res_options & RES_USE_INET6;
1070 if (h_errno == NETDB_INTERNAL)
1072 result = -EAI_SYSTEM;
1073 goto free_and_return;
1076 if (no_data != 0 && no_inet6_data != 0)
1078 /* If both requests timed out report this. */
1079 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1080 result = -EAI_AGAIN;
1081 else
1082 /* We made requests but they turned out no data. The name
1083 is known, though. */
1084 result = -EAI_NODATA;
1086 goto free_and_return;
1090 process_list:
1091 if (at->family == AF_UNSPEC)
1093 result = -EAI_NONAME;
1094 goto free_and_return;
1097 else
1099 struct gaih_addrtuple *atr;
1100 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1101 memset (at, '\0', sizeof (struct gaih_addrtuple));
1103 if (req->ai_family == AF_UNSPEC)
1105 at->next = __alloca (sizeof (struct gaih_addrtuple));
1106 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1109 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1111 at->family = AF_INET6;
1112 if ((req->ai_flags & AI_PASSIVE) == 0)
1113 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1114 atr = at->next;
1117 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1119 atr->family = AF_INET;
1120 if ((req->ai_flags & AI_PASSIVE) == 0)
1121 atr->addr[0] = htonl (INADDR_LOOPBACK);
1126 struct gaih_servtuple *st2;
1127 struct gaih_addrtuple *at2 = at;
1128 size_t socklen;
1129 sa_family_t family;
1132 buffer is the size of an unformatted IPv6 address in printable format.
1134 while (at2 != NULL)
1136 /* Only the first entry gets the canonical name. */
1137 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1139 if (canon == NULL)
1140 /* If the canonical name cannot be determined, use
1141 the passed in string. */
1142 canon = orig_name;
1144 #ifdef HAVE_LIBIDN
1145 if (req->ai_flags & AI_CANONIDN)
1147 int idn_flags = 0;
1148 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1149 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1150 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1151 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1153 char *out;
1154 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1155 if (rc != IDNA_SUCCESS)
1157 if (rc == IDNA_MALLOC_ERROR)
1158 result = -EAI_MEMORY;
1159 else if (rc == IDNA_DLOPEN_ERROR)
1160 result = -EAI_SYSTEM;
1161 else
1162 result = -EAI_IDN_ENCODE;
1163 goto free_and_return;
1165 /* In case the output string is the same as the input
1166 string no new string has been allocated and we
1167 make a copy. */
1168 if (out == canon)
1169 goto make_copy;
1170 canon = out;
1172 else
1173 #endif
1175 #ifdef HAVE_LIBIDN
1176 make_copy:
1177 #endif
1178 if (malloc_canonbuf)
1179 /* We already allocated the string using malloc. */
1180 malloc_canonbuf = false;
1181 else
1183 canon = strdup (canon);
1184 if (canon == NULL)
1186 result = -EAI_MEMORY;
1187 goto free_and_return;
1193 family = at2->family;
1194 if (family == AF_INET6)
1196 socklen = sizeof (struct sockaddr_in6);
1198 /* If we looked up IPv4 mapped address discard them here if
1199 the caller isn't interested in all address and we have
1200 found at least one IPv6 address. */
1201 if (got_ipv6
1202 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1203 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1204 goto ignore;
1206 else
1207 socklen = sizeof (struct sockaddr_in);
1209 for (st2 = st; st2 != NULL; st2 = st2->next)
1211 struct addrinfo *ai;
1212 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1213 if (ai == NULL)
1215 free ((char *) canon);
1216 result = -EAI_MEMORY;
1217 goto free_and_return;
1220 ai->ai_flags = req->ai_flags;
1221 ai->ai_family = family;
1222 ai->ai_socktype = st2->socktype;
1223 ai->ai_protocol = st2->protocol;
1224 ai->ai_addrlen = socklen;
1225 ai->ai_addr = (void *) (ai + 1);
1227 /* We only add the canonical name once. */
1228 ai->ai_canonname = (char *) canon;
1229 canon = NULL;
1231 #ifdef _HAVE_SA_LEN
1232 ai->ai_addr->sa_len = socklen;
1233 #endif /* _HAVE_SA_LEN */
1234 ai->ai_addr->sa_family = family;
1236 /* In case of an allocation error the list must be NULL
1237 terminated. */
1238 ai->ai_next = NULL;
1240 if (family == AF_INET6)
1242 struct sockaddr_in6 *sin6p =
1243 (struct sockaddr_in6 *) ai->ai_addr;
1245 sin6p->sin6_port = st2->port;
1246 sin6p->sin6_flowinfo = 0;
1247 memcpy (&sin6p->sin6_addr,
1248 at2->addr, sizeof (struct in6_addr));
1249 sin6p->sin6_scope_id = at2->scopeid;
1251 else
1253 struct sockaddr_in *sinp =
1254 (struct sockaddr_in *) ai->ai_addr;
1255 sinp->sin_port = st2->port;
1256 memcpy (&sinp->sin_addr,
1257 at2->addr, sizeof (struct in_addr));
1258 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1261 pai = &(ai->ai_next);
1264 ++*naddrs;
1266 ignore:
1267 at2 = at2->next;
1271 free_and_return:
1272 if (malloc_name)
1273 free ((char *) name);
1274 if (malloc_addrmem)
1275 free (addrmem);
1276 if (malloc_canonbuf)
1277 free (canonbuf);
1278 if (malloc_tmpbuf)
1279 free (tmpbuf);
1281 return result;
1285 struct sort_result
1287 struct addrinfo *dest_addr;
1288 /* Using sockaddr_storage is for now overkill. We only support IPv4
1289 and IPv6 so far. If this changes at some point we can adjust the
1290 type here. */
1291 struct sockaddr_in6 source_addr;
1292 uint8_t source_addr_len;
1293 bool got_source_addr;
1294 uint8_t source_addr_flags;
1295 uint8_t prefixlen;
1296 uint32_t index;
1297 int32_t native;
1300 struct sort_result_combo
1302 struct sort_result *results;
1303 int nresults;
1307 #if __BYTE_ORDER == __BIG_ENDIAN
1308 # define htonl_c(n) n
1309 #else
1310 # define htonl_c(n) __bswap_constant_32 (n)
1311 #endif
1313 static const struct scopeentry
1315 union
1317 char addr[4];
1318 uint32_t addr32;
1320 uint32_t netmask;
1321 int32_t scope;
1322 } default_scopes[] =
1324 /* Link-local addresses: scope 2. */
1325 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1326 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1327 /* Default: scope 14. */
1328 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1331 /* The label table. */
1332 static const struct scopeentry *scopes;
1335 static int
1336 get_scope (const struct sockaddr_in6 *in6)
1338 int scope;
1339 if (in6->sin6_family == PF_INET6)
1341 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1343 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1344 /* RFC 4291 2.5.3 says that the loopback address is to be
1345 treated like a link-local address. */
1346 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1347 scope = 2;
1348 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1349 scope = 5;
1350 else
1351 /* XXX Is this the correct default behavior? */
1352 scope = 14;
1354 else
1355 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1357 else if (in6->sin6_family == PF_INET)
1359 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1361 size_t cnt = 0;
1362 while (1)
1364 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1365 == scopes[cnt].addr32)
1366 return scopes[cnt].scope;
1368 ++cnt;
1370 /* NOTREACHED */
1372 else
1373 /* XXX What is a good default? */
1374 scope = 15;
1376 return scope;
1380 struct prefixentry
1382 struct in6_addr prefix;
1383 unsigned int bits;
1384 int val;
1388 /* The label table. */
1389 static const struct prefixentry *labels;
1391 /* Default labels. */
1392 static const struct prefixentry default_labels[] =
1394 /* See RFC 3484 for the details. */
1395 { { .__in6_u
1396 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1398 }, 128, 0 },
1399 { { .__in6_u
1400 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1402 }, 16, 2 },
1403 { { .__in6_u
1404 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1406 }, 96, 3 },
1407 { { .__in6_u
1408 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1409 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1410 }, 96, 4 },
1411 /* The next two entries differ from RFC 3484. We need to treat
1412 IPv6 site-local addresses special because they are never NATed,
1413 unlike site-locale IPv4 addresses. If this would not happen, on
1414 machines which have only IPv4 and IPv6 site-local addresses, the
1415 sorting would prefer the IPv6 site-local addresses, causing
1416 unnecessary delays when trying to connect to a global IPv6 address
1417 through a site-local IPv6 address. */
1418 { { .__in6_u
1419 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1421 }, 10, 5 },
1422 { { .__in6_u
1423 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1425 }, 7, 6 },
1426 /* Additional rule for Teredo tunnels. */
1427 { { .__in6_u
1428 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1430 }, 32, 7 },
1431 { { .__in6_u
1432 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1434 }, 0, 1 }
1438 /* The precedence table. */
1439 static const struct prefixentry *precedence;
1441 /* The default precedences. */
1442 static const struct prefixentry default_precedence[] =
1444 /* See RFC 3484 for the details. */
1445 { { .__in6_u
1446 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1448 }, 128, 50 },
1449 { { .__in6_u
1450 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1452 }, 16, 30 },
1453 { { .__in6_u
1454 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1456 }, 96, 20 },
1457 { { .__in6_u
1458 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1460 }, 96, 10 },
1461 { { .__in6_u
1462 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1464 }, 0, 40 }
1468 static int
1469 match_prefix (const struct sockaddr_in6 *in6,
1470 const struct prefixentry *list, int default_val)
1472 int idx;
1473 struct sockaddr_in6 in6_mem;
1475 if (in6->sin6_family == PF_INET)
1477 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1479 /* Construct a V4-to-6 mapped address. */
1480 in6_mem.sin6_family = PF_INET6;
1481 in6_mem.sin6_port = in->sin_port;
1482 in6_mem.sin6_flowinfo = 0;
1483 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1484 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1485 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1486 in6_mem.sin6_scope_id = 0;
1488 in6 = &in6_mem;
1490 else if (in6->sin6_family != PF_INET6)
1491 return default_val;
1493 for (idx = 0; ; ++idx)
1495 unsigned int bits = list[idx].bits;
1496 const uint8_t *mask = list[idx].prefix.s6_addr;
1497 const uint8_t *val = in6->sin6_addr.s6_addr;
1499 while (bits >= 8)
1501 if (*mask != *val)
1502 break;
1504 ++mask;
1505 ++val;
1506 bits -= 8;
1509 if (bits < 8)
1511 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1512 /* Match! */
1513 break;
1517 return list[idx].val;
1521 static int
1522 get_label (const struct sockaddr_in6 *in6)
1524 /* XXX What is a good default value? */
1525 return match_prefix (in6, labels, INT_MAX);
1529 static int
1530 get_precedence (const struct sockaddr_in6 *in6)
1532 /* XXX What is a good default value? */
1533 return match_prefix (in6, precedence, 0);
1537 /* Find last bit set in a word. */
1538 static int
1539 fls (uint32_t a)
1541 uint32_t mask;
1542 int n;
1543 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1544 if ((a & mask) != 0)
1545 break;
1546 return n;
1550 static int
1551 rfc3484_sort (const void *p1, const void *p2, void *arg)
1553 const size_t idx1 = *(const size_t *) p1;
1554 const size_t idx2 = *(const size_t *) p2;
1555 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1556 struct sort_result *a1 = &src->results[idx1];
1557 struct sort_result *a2 = &src->results[idx2];
1559 /* Rule 1: Avoid unusable destinations.
1560 We have the got_source_addr flag set if the destination is reachable. */
1561 if (a1->got_source_addr && ! a2->got_source_addr)
1562 return -1;
1563 if (! a1->got_source_addr && a2->got_source_addr)
1564 return 1;
1567 /* Rule 2: Prefer matching scope. Only interesting if both
1568 destination addresses are IPv6. */
1569 int a1_dst_scope
1570 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1572 int a2_dst_scope
1573 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1575 if (a1->got_source_addr)
1577 int a1_src_scope = get_scope (&a1->source_addr);
1578 int a2_src_scope = get_scope (&a2->source_addr);
1580 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1581 return -1;
1582 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1583 return 1;
1587 /* Rule 3: Avoid deprecated addresses. */
1588 if (a1->got_source_addr)
1590 if (!(a1->source_addr_flags & in6ai_deprecated)
1591 && (a2->source_addr_flags & in6ai_deprecated))
1592 return -1;
1593 if ((a1->source_addr_flags & in6ai_deprecated)
1594 && !(a2->source_addr_flags & in6ai_deprecated))
1595 return 1;
1598 /* Rule 4: Prefer home addresses. */
1599 if (a1->got_source_addr)
1601 if (!(a1->source_addr_flags & in6ai_homeaddress)
1602 && (a2->source_addr_flags & in6ai_homeaddress))
1603 return 1;
1604 if ((a1->source_addr_flags & in6ai_homeaddress)
1605 && !(a2->source_addr_flags & in6ai_homeaddress))
1606 return -1;
1609 /* Rule 5: Prefer matching label. */
1610 if (a1->got_source_addr)
1612 int a1_dst_label
1613 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1614 int a1_src_label = get_label (&a1->source_addr);
1616 int a2_dst_label
1617 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1618 int a2_src_label = get_label (&a2->source_addr);
1620 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1621 return -1;
1622 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1623 return 1;
1627 /* Rule 6: Prefer higher precedence. */
1628 int a1_prec
1629 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1630 int a2_prec
1631 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1633 if (a1_prec > a2_prec)
1634 return -1;
1635 if (a1_prec < a2_prec)
1636 return 1;
1639 /* Rule 7: Prefer native transport. */
1640 if (a1->got_source_addr)
1642 /* The same interface index means the same interface which means
1643 there is no difference in transport. This should catch many
1644 (most?) cases. */
1645 if (a1->index != a2->index)
1647 int a1_native = a1->native;
1648 int a2_native = a2->native;
1650 if (a1_native == -1 || a2_native == -1)
1652 uint32_t a1_index;
1653 if (a1_native == -1)
1655 /* If we do not have the information use 'native' as
1656 the default. */
1657 a1_native = 0;
1658 a1_index = a1->index;
1660 else
1661 a1_index = 0xffffffffu;
1663 uint32_t a2_index;
1664 if (a2_native == -1)
1666 /* If we do not have the information use 'native' as
1667 the default. */
1668 a2_native = 0;
1669 a2_index = a2->index;
1671 else
1672 a2_index = 0xffffffffu;
1674 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1676 /* Fill in the results in all the records. */
1677 for (int i = 0; i < src->nresults; ++i)
1678 if (a1_index != -1 && src->results[i].index == a1_index)
1680 assert (src->results[i].native == -1
1681 || src->results[i].native == a1_native);
1682 src->results[i].native = a1_native;
1684 else if (a2_index != -1 && src->results[i].index == a2_index)
1686 assert (src->results[i].native == -1
1687 || src->results[i].native == a2_native);
1688 src->results[i].native = a2_native;
1692 if (a1_native && !a2_native)
1693 return -1;
1694 if (!a1_native && a2_native)
1695 return 1;
1700 /* Rule 8: Prefer smaller scope. */
1701 if (a1_dst_scope < a2_dst_scope)
1702 return -1;
1703 if (a1_dst_scope > a2_dst_scope)
1704 return 1;
1707 /* Rule 9: Use longest matching prefix. */
1708 if (a1->got_source_addr
1709 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1711 int bit1 = 0;
1712 int bit2 = 0;
1714 if (a1->dest_addr->ai_family == PF_INET)
1716 assert (a1->source_addr.sin6_family == PF_INET);
1717 assert (a2->source_addr.sin6_family == PF_INET);
1719 /* Outside of subnets, as defined by the network masks,
1720 common address prefixes for IPv4 addresses make no sense.
1721 So, define a non-zero value only if source and
1722 destination address are on the same subnet. */
1723 struct sockaddr_in *in1_dst
1724 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1725 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1726 struct sockaddr_in *in1_src
1727 = (struct sockaddr_in *) &a1->source_addr;
1728 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1729 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1731 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1732 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1734 struct sockaddr_in *in2_dst
1735 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1736 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1737 struct sockaddr_in *in2_src
1738 = (struct sockaddr_in *) &a2->source_addr;
1739 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1740 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1742 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1743 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1745 else if (a1->dest_addr->ai_family == PF_INET6)
1747 assert (a1->source_addr.sin6_family == PF_INET6);
1748 assert (a2->source_addr.sin6_family == PF_INET6);
1750 struct sockaddr_in6 *in1_dst;
1751 struct sockaddr_in6 *in1_src;
1752 struct sockaddr_in6 *in2_dst;
1753 struct sockaddr_in6 *in2_src;
1755 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1756 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1757 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1758 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1760 int i;
1761 for (i = 0; i < 4; ++i)
1762 if (in1_dst->sin6_addr.s6_addr32[i]
1763 != in1_src->sin6_addr.s6_addr32[i]
1764 || (in2_dst->sin6_addr.s6_addr32[i]
1765 != in2_src->sin6_addr.s6_addr32[i]))
1766 break;
1768 if (i < 4)
1770 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1771 ^ in1_src->sin6_addr.s6_addr32[i]));
1772 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1773 ^ in2_src->sin6_addr.s6_addr32[i]));
1777 if (bit1 > bit2)
1778 return -1;
1779 if (bit1 < bit2)
1780 return 1;
1784 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1785 compare with the value indicating the order in which the entries
1786 have been received from the services. NB: no two entries can have
1787 the same order so the test will never return zero. */
1788 return idx1 < idx2 ? -1 : 1;
1792 static int
1793 in6aicmp (const void *p1, const void *p2)
1795 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1796 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1798 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1802 /* Name of the config file for RFC 3484 sorting (for now). */
1803 #define GAICONF_FNAME "/etc/gai.conf"
1806 /* Non-zero if we are supposed to reload the config file automatically
1807 whenever it changed. */
1808 static int gaiconf_reload_flag;
1810 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1811 static int gaiconf_reload_flag_ever_set;
1813 /* Last modification time. */
1814 #ifdef _STATBUF_ST_NSEC
1816 static struct timespec gaiconf_mtime;
1818 static inline void
1819 save_gaiconf_mtime (const struct stat64 *st)
1821 gaiconf_mtime = st->st_mtim;
1824 static inline bool
1825 check_gaiconf_mtime (const struct stat64 *st)
1827 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1828 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1831 #else
1833 static time_t gaiconf_mtime;
1835 static inline void
1836 save_gaiconf_mtime (const struct stat64 *st)
1838 gaiconf_mtime = st->st_mtime;
1841 static inline bool
1842 check_gaiconf_mtime (const struct stat64 *st)
1844 return st->st_mtime == gaiconf_mtime;
1847 #endif
1850 libc_freeres_fn(fini)
1852 if (labels != default_labels)
1854 const struct prefixentry *old = labels;
1855 labels = default_labels;
1856 free ((void *) old);
1859 if (precedence != default_precedence)
1861 const struct prefixentry *old = precedence;
1862 precedence = default_precedence;
1863 free ((void *) old);
1866 if (scopes != default_scopes)
1868 const struct scopeentry *old = scopes;
1869 scopes = default_scopes;
1870 free ((void *) old);
1875 struct prefixlist
1877 struct prefixentry entry;
1878 struct prefixlist *next;
1882 struct scopelist
1884 struct scopeentry entry;
1885 struct scopelist *next;
1889 static void
1890 free_prefixlist (struct prefixlist *list)
1892 while (list != NULL)
1894 struct prefixlist *oldp = list;
1895 list = list->next;
1896 free (oldp);
1901 static void
1902 free_scopelist (struct scopelist *list)
1904 while (list != NULL)
1906 struct scopelist *oldp = list;
1907 list = list->next;
1908 free (oldp);
1913 static int
1914 prefixcmp (const void *p1, const void *p2)
1916 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1917 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1919 if (e1->bits < e2->bits)
1920 return 1;
1921 if (e1->bits == e2->bits)
1922 return 0;
1923 return -1;
1927 static int
1928 scopecmp (const void *p1, const void *p2)
1930 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1931 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1933 if (e1->netmask > e2->netmask)
1934 return -1;
1935 if (e1->netmask == e2->netmask)
1936 return 0;
1937 return 1;
1941 static void
1942 gaiconf_init (void)
1944 struct prefixlist *labellist = NULL;
1945 size_t nlabellist = 0;
1946 bool labellist_nullbits = false;
1947 struct prefixlist *precedencelist = NULL;
1948 size_t nprecedencelist = 0;
1949 bool precedencelist_nullbits = false;
1950 struct scopelist *scopelist = NULL;
1951 size_t nscopelist = 0;
1952 bool scopelist_nullbits = false;
1954 FILE *fp = fopen (GAICONF_FNAME, "rce");
1955 if (fp != NULL)
1957 struct stat64 st;
1958 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1960 fclose (fp);
1961 goto no_file;
1964 char *line = NULL;
1965 size_t linelen = 0;
1967 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1969 while (!feof_unlocked (fp))
1971 ssize_t n = __getline (&line, &linelen, fp);
1972 if (n <= 0)
1973 break;
1975 /* Handle comments. No escaping possible so this is easy. */
1976 char *cp = strchr (line, '#');
1977 if (cp != NULL)
1978 *cp = '\0';
1980 cp = line;
1981 while (isspace (*cp))
1982 ++cp;
1984 char *cmd = cp;
1985 while (*cp != '\0' && !isspace (*cp))
1986 ++cp;
1987 size_t cmdlen = cp - cmd;
1989 if (*cp != '\0')
1990 *cp++ = '\0';
1991 while (isspace (*cp))
1992 ++cp;
1994 char *val1 = cp;
1995 while (*cp != '\0' && !isspace (*cp))
1996 ++cp;
1997 size_t val1len = cp - cmd;
1999 /* We always need at least two values. */
2000 if (val1len == 0)
2001 continue;
2003 if (*cp != '\0')
2004 *cp++ = '\0';
2005 while (isspace (*cp))
2006 ++cp;
2008 char *val2 = cp;
2009 while (*cp != '\0' && !isspace (*cp))
2010 ++cp;
2012 /* Ignore the rest of the line. */
2013 *cp = '\0';
2015 struct prefixlist **listp;
2016 size_t *lenp;
2017 bool *nullbitsp;
2018 switch (cmdlen)
2020 case 5:
2021 if (strcmp (cmd, "label") == 0)
2023 struct in6_addr prefix;
2024 unsigned long int bits;
2025 unsigned long int val;
2026 char *endp;
2028 listp = &labellist;
2029 lenp = &nlabellist;
2030 nullbitsp = &labellist_nullbits;
2032 new_elem:
2033 bits = 128;
2034 __set_errno (0);
2035 cp = strchr (val1, '/');
2036 if (cp != NULL)
2037 *cp++ = '\0';
2038 if (inet_pton (AF_INET6, val1, &prefix)
2039 && (cp == NULL
2040 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2041 || errno != ERANGE)
2042 && *endp == '\0'
2043 && bits <= 128
2044 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2045 || errno != ERANGE)
2046 && *endp == '\0'
2047 && val <= INT_MAX)
2049 struct prefixlist *newp = malloc (sizeof (*newp));
2050 if (newp == NULL)
2052 free (line);
2053 fclose (fp);
2054 goto no_file;
2057 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2058 newp->entry.bits = bits;
2059 newp->entry.val = val;
2060 newp->next = *listp;
2061 *listp = newp;
2062 ++*lenp;
2063 *nullbitsp |= bits == 0;
2066 break;
2068 case 6:
2069 if (strcmp (cmd, "reload") == 0)
2071 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2072 if (gaiconf_reload_flag)
2073 gaiconf_reload_flag_ever_set = 1;
2075 break;
2077 case 7:
2078 if (strcmp (cmd, "scopev4") == 0)
2080 struct in6_addr prefix;
2081 unsigned long int bits;
2082 unsigned long int val;
2083 char *endp;
2085 bits = 32;
2086 __set_errno (0);
2087 cp = strchr (val1, '/');
2088 if (cp != NULL)
2089 *cp++ = '\0';
2090 if (inet_pton (AF_INET6, val1, &prefix))
2092 bits = 128;
2093 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2094 && (cp == NULL
2095 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2096 || errno != ERANGE)
2097 && *endp == '\0'
2098 && bits >= 96
2099 && bits <= 128
2100 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2101 || errno != ERANGE)
2102 && *endp == '\0'
2103 && val <= INT_MAX)
2105 struct scopelist *newp;
2106 new_scope:
2107 newp = malloc (sizeof (*newp));
2108 if (newp == NULL)
2110 free (line);
2111 fclose (fp);
2112 goto no_file;
2115 newp->entry.netmask = htonl (bits != 96
2116 ? (0xffffffff
2117 << (128 - bits))
2118 : 0);
2119 newp->entry.addr32 = (prefix.s6_addr32[3]
2120 & newp->entry.netmask);
2121 newp->entry.scope = val;
2122 newp->next = scopelist;
2123 scopelist = newp;
2124 ++nscopelist;
2125 scopelist_nullbits |= bits == 96;
2128 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2129 && (cp == NULL
2130 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2131 || errno != ERANGE)
2132 && *endp == '\0'
2133 && bits <= 32
2134 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2135 || errno != ERANGE)
2136 && *endp == '\0'
2137 && val <= INT_MAX)
2139 bits += 96;
2140 goto new_scope;
2143 break;
2145 case 10:
2146 if (strcmp (cmd, "precedence") == 0)
2148 listp = &precedencelist;
2149 lenp = &nprecedencelist;
2150 nullbitsp = &precedencelist_nullbits;
2151 goto new_elem;
2153 break;
2157 free (line);
2159 fclose (fp);
2161 /* Create the array for the labels. */
2162 struct prefixentry *new_labels;
2163 if (nlabellist > 0)
2165 if (!labellist_nullbits)
2166 ++nlabellist;
2167 new_labels = malloc (nlabellist * sizeof (*new_labels));
2168 if (new_labels == NULL)
2169 goto no_file;
2171 int i = nlabellist;
2172 if (!labellist_nullbits)
2174 --i;
2175 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2176 new_labels[i].bits = 0;
2177 new_labels[i].val = 1;
2180 struct prefixlist *l = labellist;
2181 while (i-- > 0)
2183 new_labels[i] = l->entry;
2184 l = l->next;
2186 free_prefixlist (labellist);
2188 /* Sort the entries so that the most specific ones are at
2189 the beginning. */
2190 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2192 else
2193 new_labels = (struct prefixentry *) default_labels;
2195 struct prefixentry *new_precedence;
2196 if (nprecedencelist > 0)
2198 if (!precedencelist_nullbits)
2199 ++nprecedencelist;
2200 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2201 if (new_precedence == NULL)
2203 if (new_labels != default_labels)
2204 free (new_labels);
2205 goto no_file;
2208 int i = nprecedencelist;
2209 if (!precedencelist_nullbits)
2211 --i;
2212 memset (&new_precedence[i].prefix, '\0',
2213 sizeof (struct in6_addr));
2214 new_precedence[i].bits = 0;
2215 new_precedence[i].val = 40;
2218 struct prefixlist *l = precedencelist;
2219 while (i-- > 0)
2221 new_precedence[i] = l->entry;
2222 l = l->next;
2224 free_prefixlist (precedencelist);
2226 /* Sort the entries so that the most specific ones are at
2227 the beginning. */
2228 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2229 prefixcmp);
2231 else
2232 new_precedence = (struct prefixentry *) default_precedence;
2234 struct scopeentry *new_scopes;
2235 if (nscopelist > 0)
2237 if (!scopelist_nullbits)
2238 ++nscopelist;
2239 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2240 if (new_scopes == NULL)
2242 if (new_labels != default_labels)
2243 free (new_labels);
2244 if (new_precedence != default_precedence)
2245 free (new_precedence);
2246 goto no_file;
2249 int i = nscopelist;
2250 if (!scopelist_nullbits)
2252 --i;
2253 new_scopes[i].addr32 = 0;
2254 new_scopes[i].netmask = 0;
2255 new_scopes[i].scope = 14;
2258 struct scopelist *l = scopelist;
2259 while (i-- > 0)
2261 new_scopes[i] = l->entry;
2262 l = l->next;
2264 free_scopelist (scopelist);
2266 /* Sort the entries so that the most specific ones are at
2267 the beginning. */
2268 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2269 scopecmp);
2271 else
2272 new_scopes = (struct scopeentry *) default_scopes;
2274 /* Now we are ready to replace the values. */
2275 const struct prefixentry *old = labels;
2276 labels = new_labels;
2277 if (old != default_labels)
2278 free ((void *) old);
2280 old = precedence;
2281 precedence = new_precedence;
2282 if (old != default_precedence)
2283 free ((void *) old);
2285 const struct scopeentry *oldscope = scopes;
2286 scopes = new_scopes;
2287 if (oldscope != default_scopes)
2288 free ((void *) oldscope);
2290 save_gaiconf_mtime (&st);
2292 else
2294 no_file:
2295 free_prefixlist (labellist);
2296 free_prefixlist (precedencelist);
2297 free_scopelist (scopelist);
2299 /* If we previously read the file but it is gone now, free the
2300 old data and use the builtin one. Leave the reload flag
2301 alone. */
2302 fini ();
2307 static void
2308 gaiconf_reload (void)
2310 struct stat64 st;
2311 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2312 || !check_gaiconf_mtime (&st))
2313 gaiconf_init ();
2318 getaddrinfo (const char *name, const char *service,
2319 const struct addrinfo *hints, struct addrinfo **pai)
2321 int i = 0, last_i = 0;
2322 int nresults = 0;
2323 struct addrinfo *p = NULL;
2324 struct gaih_service gaih_service, *pservice;
2325 struct addrinfo local_hints;
2327 if (name != NULL && name[0] == '*' && name[1] == 0)
2328 name = NULL;
2330 if (service != NULL && service[0] == '*' && service[1] == 0)
2331 service = NULL;
2333 if (name == NULL && service == NULL)
2334 return EAI_NONAME;
2336 if (hints == NULL)
2337 hints = &default_hints;
2339 if (hints->ai_flags
2340 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2341 #ifdef HAVE_LIBIDN
2342 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2343 |AI_IDN_USE_STD3_ASCII_RULES
2344 #endif
2345 |AI_NUMERICSERV|AI_ALL))
2346 return EAI_BADFLAGS;
2348 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2349 return EAI_BADFLAGS;
2351 struct in6addrinfo *in6ai = NULL;
2352 size_t in6ailen = 0;
2353 bool seen_ipv4 = false;
2354 bool seen_ipv6 = false;
2355 bool check_pf_called = false;
2357 if (hints->ai_flags & AI_ADDRCONFIG)
2359 /* We might need information about what interfaces are available.
2360 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2361 cannot cache the results since new interfaces could be added at
2362 any time. */
2363 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2364 check_pf_called = true;
2366 /* Now make a decision on what we return, if anything. */
2367 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2369 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2370 narrow down the search. */
2371 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2373 local_hints = *hints;
2374 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2375 hints = &local_hints;
2378 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2379 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2381 /* We cannot possibly return a valid answer. */
2382 __free_in6ai (in6ai);
2383 return EAI_NONAME;
2387 if (service && service[0])
2389 char *c;
2390 gaih_service.name = service;
2391 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2392 if (*c != '\0')
2394 if (hints->ai_flags & AI_NUMERICSERV)
2396 __free_in6ai (in6ai);
2397 return EAI_NONAME;
2400 gaih_service.num = -1;
2403 pservice = &gaih_service;
2405 else
2406 pservice = NULL;
2408 struct addrinfo **end = &p;
2410 unsigned int naddrs = 0;
2411 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2412 || hints->ai_family == AF_INET6)
2414 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2415 if (last_i != 0)
2417 freeaddrinfo (p);
2418 __free_in6ai (in6ai);
2420 return -last_i;
2422 while (*end)
2424 end = &((*end)->ai_next);
2425 ++nresults;
2428 else
2430 __free_in6ai (in6ai);
2431 return EAI_FAMILY;
2434 if (naddrs > 1)
2436 /* Read the config file. */
2437 __libc_once_define (static, once);
2438 __typeof (once) old_once = once;
2439 __libc_once (once, gaiconf_init);
2440 /* Sort results according to RFC 3484. */
2441 struct sort_result *results;
2442 size_t *order;
2443 struct addrinfo *q;
2444 struct addrinfo *last = NULL;
2445 char *canonname = NULL;
2446 bool malloc_results;
2447 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2449 malloc_results
2450 = !__libc_use_alloca (alloc_size);
2451 if (malloc_results)
2453 results = malloc (alloc_size);
2454 if (results == NULL)
2456 __free_in6ai (in6ai);
2457 return EAI_MEMORY;
2460 else
2461 results = alloca (alloc_size);
2462 order = (size_t *) (results + nresults);
2464 /* Now we definitely need the interface information. */
2465 if (! check_pf_called)
2466 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2468 /* If we have information about deprecated and temporary addresses
2469 sort the array now. */
2470 if (in6ai != NULL)
2471 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2473 int fd = -1;
2474 int af = AF_UNSPEC;
2476 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2478 results[i].dest_addr = q;
2479 results[i].native = -1;
2480 order[i] = i;
2482 /* If we just looked up the address for a different
2483 protocol, reuse the result. */
2484 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2485 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2487 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2488 results[i - 1].source_addr_len);
2489 results[i].source_addr_len = results[i - 1].source_addr_len;
2490 results[i].got_source_addr = results[i - 1].got_source_addr;
2491 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2492 results[i].prefixlen = results[i - 1].prefixlen;
2493 results[i].index = results[i - 1].index;
2495 else
2497 results[i].got_source_addr = false;
2498 results[i].source_addr_flags = 0;
2499 results[i].prefixlen = 0;
2500 results[i].index = 0xffffffffu;
2502 /* We overwrite the type with SOCK_DGRAM since we do not
2503 want connect() to connect to the other side. If we
2504 cannot determine the source address remember this
2505 fact. */
2506 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2508 if (fd != -1)
2509 close_retry:
2510 close_not_cancel_no_status (fd);
2511 af = q->ai_family;
2512 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2514 else
2516 /* Reset the connection. */
2517 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2518 __connect (fd, &sa, sizeof (sa));
2521 socklen_t sl = sizeof (results[i].source_addr);
2522 if (fd != -1
2523 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2524 && __getsockname (fd,
2525 (struct sockaddr *) &results[i].source_addr,
2526 &sl) == 0)
2528 results[i].source_addr_len = sl;
2529 results[i].got_source_addr = true;
2531 if (in6ai != NULL)
2533 /* See whether the source address is on the list of
2534 deprecated or temporary addresses. */
2535 struct in6addrinfo tmp;
2537 if (q->ai_family == AF_INET && af == AF_INET)
2539 struct sockaddr_in *sinp
2540 = (struct sockaddr_in *) &results[i].source_addr;
2541 tmp.addr[0] = 0;
2542 tmp.addr[1] = 0;
2543 tmp.addr[2] = htonl (0xffff);
2544 /* Special case for lo interface, the source address
2545 being possibly different than the interface
2546 address. */
2547 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2548 == 0x7f000000)
2549 tmp.addr[3] = htonl(0x7f000001);
2550 else
2551 tmp.addr[3] = sinp->sin_addr.s_addr;
2553 else
2555 struct sockaddr_in6 *sin6p
2556 = (struct sockaddr_in6 *) &results[i].source_addr;
2557 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2560 struct in6addrinfo *found
2561 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2562 in6aicmp);
2563 if (found != NULL)
2565 results[i].source_addr_flags = found->flags;
2566 results[i].prefixlen = found->prefixlen;
2567 results[i].index = found->index;
2571 if (q->ai_family == AF_INET && af == AF_INET6)
2573 /* We have to convert the address. The socket is
2574 IPv6 and the request is for IPv4. */
2575 struct sockaddr_in6 *sin6
2576 = (struct sockaddr_in6 *) &results[i].source_addr;
2577 struct sockaddr_in *sin
2578 = (struct sockaddr_in *) &results[i].source_addr;
2579 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2580 sin->sin_family = AF_INET;
2581 /* We do not have to initialize sin_port since this
2582 fields has the same position and size in the IPv6
2583 structure. */
2584 assert (offsetof (struct sockaddr_in, sin_port)
2585 == offsetof (struct sockaddr_in6, sin6_port));
2586 assert (sizeof (sin->sin_port)
2587 == sizeof (sin6->sin6_port));
2588 memcpy (&sin->sin_addr,
2589 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2590 results[i].source_addr_len = sizeof (struct sockaddr_in);
2593 else if (errno == EAFNOSUPPORT && af == AF_INET6
2594 && q->ai_family == AF_INET)
2595 /* This could mean IPv6 sockets are IPv6-only. */
2596 goto close_retry;
2597 else
2598 /* Just make sure that if we have to process the same
2599 address again we do not copy any memory. */
2600 results[i].source_addr_len = 0;
2603 /* Remember the canonical name. */
2604 if (q->ai_canonname != NULL)
2606 assert (canonname == NULL);
2607 canonname = q->ai_canonname;
2608 q->ai_canonname = NULL;
2612 if (fd != -1)
2613 close_not_cancel_no_status (fd);
2615 /* We got all the source addresses we can get, now sort using
2616 the information. */
2617 struct sort_result_combo src
2618 = { .results = results, .nresults = nresults };
2619 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2621 __libc_lock_define_initialized (static, lock);
2623 __libc_lock_lock (lock);
2624 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2625 gaiconf_reload ();
2626 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2627 __libc_lock_unlock (lock);
2629 else
2630 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2632 /* Queue the results up as they come out of sorting. */
2633 q = p = results[order[0]].dest_addr;
2634 for (i = 1; i < nresults; ++i)
2635 q = q->ai_next = results[order[i]].dest_addr;
2636 q->ai_next = NULL;
2638 /* Fill in the canonical name into the new first entry. */
2639 p->ai_canonname = canonname;
2641 if (malloc_results)
2642 free (results);
2645 __free_in6ai (in6ai);
2647 if (p)
2649 *pai = p;
2650 return 0;
2653 return last_i ? -last_i : EAI_NONAME;
2655 libc_hidden_def (getaddrinfo)
2657 nss_interface_function (getaddrinfo)
2659 void
2660 freeaddrinfo (struct addrinfo *ai)
2662 struct addrinfo *p;
2664 while (ai != NULL)
2666 p = ai;
2667 ai = ai->ai_next;
2668 free (p->ai_canonname);
2669 free (p);
2672 libc_hidden_def (freeaddrinfo)