Move bits/types.h into posix/bits.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob43eb31365ed10059bb6e1147af197ed54550e6c5
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
28 way or form.
29 1. All terms of the all other applicable copyrights and licenses must be
30 followed.
31 2. Redistributions of source code must retain the authors' copyright
32 notice(s), this list of conditions, and the following disclaimer.
33 3. Redistributions in binary form must reproduce the authors' copyright
34 notice(s), this list of conditions, and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36 4. [The copyright holder has authorized the removal of this clause.]
37 5. Neither the name(s) of the author(s) nor the names of its contributors
38 may be used to endorse or promote products derived from this software
39 without specific prior written permission.
41 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
42 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
45 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 If these license terms cause you a real problem, contact the author. */
54 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
56 #include <assert.h>
57 #include <ctype.h>
58 #include <errno.h>
59 #include <ifaddrs.h>
60 #include <netdb.h>
61 #include <nss.h>
62 #include <resolv/resolv-internal.h>
63 #include <stdbool.h>
64 #include <stdio.h>
65 #include <stdio_ext.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <stdint.h>
69 #include <arpa/inet.h>
70 #include <net/if.h>
71 #include <netinet/in.h>
72 #include <sys/socket.h>
73 #include <sys/stat.h>
74 #include <sys/types.h>
75 #include <sys/un.h>
76 #include <sys/utsname.h>
77 #include <unistd.h>
78 #include <nsswitch.h>
79 #include <libc-lock.h>
80 #include <not-cancel.h>
81 #include <nscd/nscd-client.h>
82 #include <nscd/nscd_proto.h>
83 #include <resolv/res_hconf.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
87 #ifdef HAVE_LIBIDN
88 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
89 extern int __idna_to_unicode_lzlz (const char *input, char **output,
90 int flags);
91 # include <libidn/idna.h>
92 #endif
94 struct gaih_service
96 const char *name;
97 int num;
100 struct gaih_servtuple
102 struct gaih_servtuple *next;
103 int socktype;
104 int protocol;
105 int port;
108 static const struct gaih_servtuple nullserv;
111 struct gaih_typeproto
113 int socktype;
114 int protocol;
115 uint8_t protoflag;
116 bool defaultflag;
117 char name[8];
120 /* Values for `protoflag'. */
121 #define GAI_PROTO_NOSERVICE 1
122 #define GAI_PROTO_PROTOANY 2
124 static const struct gaih_typeproto gaih_inet_typeproto[] =
126 { 0, 0, 0, false, "" },
127 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
128 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
129 #if defined SOCK_DCCP && defined IPPROTO_DCCP
130 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
131 #endif
132 #ifdef IPPROTO_UDPLITE
133 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
134 #endif
135 #ifdef IPPROTO_SCTP
136 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
137 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
138 #endif
139 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
140 { 0, 0, 0, false, "" }
143 static const struct addrinfo default_hints =
145 .ai_flags = AI_DEFAULT,
146 .ai_family = PF_UNSPEC,
147 .ai_socktype = 0,
148 .ai_protocol = 0,
149 .ai_addrlen = 0,
150 .ai_addr = NULL,
151 .ai_canonname = NULL,
152 .ai_next = NULL
156 static int
157 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
158 const struct addrinfo *req, struct gaih_servtuple *st,
159 struct scratch_buffer *tmpbuf)
161 struct servent *s;
162 struct servent ts;
163 int r;
167 r = __getservbyname_r (servicename, tp->name, &ts,
168 tmpbuf->data, tmpbuf->length, &s);
169 if (r != 0 || s == NULL)
171 if (r == ERANGE)
173 if (!scratch_buffer_grow (tmpbuf))
174 return -EAI_MEMORY;
176 else
177 return -EAI_SERVICE;
180 while (r);
182 st->next = NULL;
183 st->socktype = tp->socktype;
184 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
185 ? req->ai_protocol : tp->protocol);
186 st->port = s->s_port;
188 return 0;
191 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
192 h_name is not copied, and the struct hostent object must not be
193 deallocated prematurely. *RESULT must be NULL or a pointer to an
194 object allocated using malloc, which is freed. */
195 static bool
196 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
197 int family,
198 struct hostent *h,
199 struct gaih_addrtuple **result)
201 free (*result);
202 *result = NULL;
204 /* Count the number of addresses in h->h_addr_list. */
205 size_t count = 0;
206 for (char **p = h->h_addr_list; *p != NULL; ++p)
207 ++count;
209 /* Report no data if no addresses are available, or if the incoming
210 address size is larger than what we can store. */
211 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
212 return true;
214 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
215 if (array == NULL)
216 return false;
218 for (size_t i = 0; i < count; ++i)
220 if (family == AF_INET && req->ai_family == AF_INET6)
222 /* Perform address mapping. */
223 array[i].family = AF_INET6;
224 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
225 array[i].addr[2] = htonl (0xffff);
227 else
229 array[i].family = family;
230 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
232 array[i].next = array + i + 1;
234 array[0].name = h->h_name;
235 array[count - 1].next = NULL;
237 *result = array;
238 return true;
241 #define gethosts(_family, _type) \
243 int herrno; \
244 struct hostent th; \
245 struct hostent *h; \
246 char *localcanon = NULL; \
247 no_data = 0; \
248 while (1) { \
249 rc = 0; \
250 status = DL_CALL_FCT (fct, (name, _family, &th, \
251 tmpbuf->data, tmpbuf->length, \
252 &rc, &herrno, NULL, &localcanon)); \
253 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
254 break; \
255 if (!scratch_buffer_grow (tmpbuf)) \
257 result = -EAI_MEMORY; \
258 goto free_and_return; \
261 if (status == NSS_STATUS_SUCCESS && rc == 0) \
262 h = &th; \
263 else \
264 h = NULL; \
265 if (rc != 0) \
267 if (herrno == NETDB_INTERNAL) \
269 __set_h_errno (herrno); \
270 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
271 result = -EAI_SYSTEM; \
272 goto free_and_return; \
274 if (herrno == TRY_AGAIN) \
275 no_data = EAI_AGAIN; \
276 else \
277 no_data = herrno == NO_DATA; \
279 else if (h != NULL) \
281 /* Make sure that addrmem can be freed. */ \
282 if (!malloc_addrmem) \
283 addrmem = NULL; \
284 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
286 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
287 result = -EAI_SYSTEM; \
288 goto free_and_return; \
290 *pat = addrmem; \
291 /* The conversion uses malloc unconditionally. */ \
292 malloc_addrmem = true; \
294 if (localcanon != NULL && canon == NULL) \
295 canon = strdupa (localcanon); \
297 if (_family == AF_INET6 && *pat != NULL) \
298 got_ipv6 = true; \
303 typedef enum nss_status (*nss_gethostbyname4_r)
304 (const char *name, struct gaih_addrtuple **pat,
305 char *buffer, size_t buflen, int *errnop,
306 int *h_errnop, int32_t *ttlp);
307 typedef enum nss_status (*nss_gethostbyname3_r)
308 (const char *name, int af, struct hostent *host,
309 char *buffer, size_t buflen, int *errnop,
310 int *h_errnop, int32_t *ttlp, char **canonp);
311 typedef enum nss_status (*nss_getcanonname_r)
312 (const char *name, char *buffer, size_t buflen, char **result,
313 int *errnop, int *h_errnop);
314 extern service_user *__nss_hosts_database attribute_hidden;
317 static int
318 gaih_inet (const char *name, const struct gaih_service *service,
319 const struct addrinfo *req, struct addrinfo **pai,
320 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
322 const struct gaih_typeproto *tp = gaih_inet_typeproto;
323 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
324 struct gaih_addrtuple *at = NULL;
325 int rc;
326 bool got_ipv6 = false;
327 const char *canon = NULL;
328 const char *orig_name = name;
330 /* Reserve stack memory for the scratch buffer in the getaddrinfo
331 function. */
332 size_t alloca_used = sizeof (struct scratch_buffer);
334 if (req->ai_protocol || req->ai_socktype)
336 ++tp;
338 while (tp->name[0]
339 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
340 || (req->ai_protocol != 0
341 && !(tp->protoflag & GAI_PROTO_PROTOANY)
342 && req->ai_protocol != tp->protocol)))
343 ++tp;
345 if (! tp->name[0])
347 if (req->ai_socktype)
348 return -EAI_SOCKTYPE;
349 else
350 return -EAI_SERVICE;
354 int port = 0;
355 if (service != NULL)
357 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
358 return -EAI_SERVICE;
360 if (service->num < 0)
362 if (tp->name[0])
364 st = (struct gaih_servtuple *)
365 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
367 if ((rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf)))
368 return rc;
370 else
372 struct gaih_servtuple **pst = &st;
373 for (tp++; tp->name[0]; tp++)
375 struct gaih_servtuple *newp;
377 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
378 continue;
380 if (req->ai_socktype != 0
381 && req->ai_socktype != tp->socktype)
382 continue;
383 if (req->ai_protocol != 0
384 && !(tp->protoflag & GAI_PROTO_PROTOANY)
385 && req->ai_protocol != tp->protocol)
386 continue;
388 newp = (struct gaih_servtuple *)
389 alloca_account (sizeof (struct gaih_servtuple),
390 alloca_used);
392 if ((rc = gaih_inet_serv (service->name,
393 tp, req, newp, tmpbuf)))
395 if (rc)
396 continue;
397 return rc;
400 *pst = newp;
401 pst = &(newp->next);
403 if (st == (struct gaih_servtuple *) &nullserv)
404 return -EAI_SERVICE;
407 else
409 port = htons (service->num);
410 goto got_port;
413 else
415 got_port:
417 if (req->ai_socktype || req->ai_protocol)
419 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
420 st->next = NULL;
421 st->socktype = tp->socktype;
422 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
423 ? req->ai_protocol : tp->protocol);
424 st->port = port;
426 else
428 /* Neither socket type nor protocol is set. Return all socket types
429 we know about. */
430 struct gaih_servtuple **lastp = &st;
431 for (++tp; tp->name[0]; ++tp)
432 if (tp->defaultflag)
434 struct gaih_servtuple *newp;
436 newp = alloca_account (sizeof (struct gaih_servtuple),
437 alloca_used);
438 newp->next = NULL;
439 newp->socktype = tp->socktype;
440 newp->protocol = tp->protocol;
441 newp->port = port;
443 *lastp = newp;
444 lastp = &newp->next;
449 bool malloc_name = false;
450 bool malloc_addrmem = false;
451 struct gaih_addrtuple *addrmem = NULL;
452 bool malloc_canonbuf = false;
453 char *canonbuf = NULL;
454 int result = 0;
456 if (name != NULL)
458 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
459 at->family = AF_UNSPEC;
460 at->scopeid = 0;
461 at->next = NULL;
463 #ifdef HAVE_LIBIDN
464 if (req->ai_flags & AI_IDN)
466 int idn_flags = 0;
467 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
468 idn_flags |= IDNA_ALLOW_UNASSIGNED;
469 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
470 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
472 char *p = NULL;
473 rc = __idna_to_ascii_lz (name, &p, idn_flags);
474 if (rc != IDNA_SUCCESS)
476 /* No need to jump to free_and_return here. */
477 if (rc == IDNA_MALLOC_ERROR)
478 return -EAI_MEMORY;
479 if (rc == IDNA_DLOPEN_ERROR)
480 return -EAI_SYSTEM;
481 return -EAI_IDN_ENCODE;
483 /* In case the output string is the same as the input string
484 no new string has been allocated. */
485 if (p != name)
487 name = p;
488 malloc_name = true;
491 #endif
493 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
495 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
496 at->family = AF_INET;
497 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
499 at->addr[3] = at->addr[0];
500 at->addr[2] = htonl (0xffff);
501 at->addr[1] = 0;
502 at->addr[0] = 0;
503 at->family = AF_INET6;
505 else
507 result = -EAI_ADDRFAMILY;
508 goto free_and_return;
511 if (req->ai_flags & AI_CANONNAME)
512 canon = name;
514 else if (at->family == AF_UNSPEC)
516 char *scope_delim = strchr (name, SCOPE_DELIMITER);
517 int e;
520 bool malloc_namebuf = false;
521 char *namebuf = (char *) name;
523 if (__glibc_unlikely (scope_delim != NULL))
525 if (malloc_name)
526 *scope_delim = '\0';
527 else
529 if (__libc_use_alloca (alloca_used
530 + scope_delim - name + 1))
532 namebuf = alloca_account (scope_delim - name + 1,
533 alloca_used);
534 *((char *) __mempcpy (namebuf, name,
535 scope_delim - name)) = '\0';
537 else
539 namebuf = strndup (name, scope_delim - name);
540 if (namebuf == NULL)
542 assert (!malloc_name);
543 return -EAI_MEMORY;
545 malloc_namebuf = true;
550 e = inet_pton (AF_INET6, namebuf, at->addr);
552 if (malloc_namebuf)
553 free (namebuf);
554 else if (scope_delim != NULL && malloc_name)
555 /* Undo what we did above. */
556 *scope_delim = SCOPE_DELIMITER;
558 if (e > 0)
560 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
561 at->family = AF_INET6;
562 else if (req->ai_family == AF_INET
563 && IN6_IS_ADDR_V4MAPPED (at->addr))
565 at->addr[0] = at->addr[3];
566 at->family = AF_INET;
568 else
570 result = -EAI_ADDRFAMILY;
571 goto free_and_return;
574 if (scope_delim != NULL
575 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
576 scope_delim + 1,
577 &at->scopeid) != 0)
579 result = -EAI_NONAME;
580 goto free_and_return;
583 if (req->ai_flags & AI_CANONNAME)
584 canon = name;
588 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
590 struct gaih_addrtuple **pat = &at;
591 int no_data = 0;
592 int no_inet6_data = 0;
593 service_user *nip;
594 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
595 enum nss_status status = NSS_STATUS_UNAVAIL;
596 int no_more;
597 int old_res_options;
599 /* If we do not have to look for IPv6 addresses or the canonical
600 name, use the simple, old functions, which do not support
601 IPv6 scope ids, nor retrieving the canonical name. */
602 if (req->ai_family == AF_INET
603 && (req->ai_flags & AI_CANONNAME) == 0)
605 int rc;
606 struct hostent th;
607 struct hostent *h;
608 int herrno;
610 while (1)
612 rc = __gethostbyname2_r (name, AF_INET, &th,
613 tmpbuf->data, tmpbuf->length,
614 &h, &herrno);
615 if (rc != ERANGE || herrno != NETDB_INTERNAL)
616 break;
617 if (!scratch_buffer_grow (tmpbuf))
619 result = -EAI_MEMORY;
620 goto free_and_return;
624 if (rc == 0)
626 if (h != NULL)
628 /* We found data, convert it. */
629 if (!convert_hostent_to_gaih_addrtuple
630 (req, AF_INET, h, &addrmem))
632 result = -EAI_MEMORY;
633 goto free_and_return;
635 *pat = addrmem;
636 /* The conversion uses malloc unconditionally. */
637 malloc_addrmem = true;
640 else
642 if (herrno == NETDB_INTERNAL)
644 __set_h_errno (herrno);
645 result = -EAI_SYSTEM;
647 else if (herrno == TRY_AGAIN)
648 result = -EAI_AGAIN;
649 else
650 /* We made requests but they turned out no data.
651 The name is known, though. */
652 result = -EAI_NODATA;
654 goto free_and_return;
657 goto process_list;
660 #ifdef USE_NSCD
661 if (__nss_not_use_nscd_hosts > 0
662 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
663 __nss_not_use_nscd_hosts = 0;
665 if (!__nss_not_use_nscd_hosts
666 && !__nss_database_custom[NSS_DBSIDX_hosts])
668 /* Try to use nscd. */
669 struct nscd_ai_result *air = NULL;
670 int herrno;
671 int err = __nscd_getai (name, &air, &herrno);
672 if (air != NULL)
674 /* Transform into gaih_addrtuple list. */
675 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
676 char *addrs = air->addrs;
678 if (__libc_use_alloca (alloca_used
679 + air->naddrs * sizeof (struct gaih_addrtuple)))
680 addrmem = alloca_account (air->naddrs
681 * sizeof (struct gaih_addrtuple),
682 alloca_used);
683 else
685 addrmem = malloc (air->naddrs
686 * sizeof (struct gaih_addrtuple));
687 if (addrmem == NULL)
689 result = -EAI_MEMORY;
690 goto free_and_return;
692 malloc_addrmem = true;
695 struct gaih_addrtuple *addrfree = addrmem;
696 for (int i = 0; i < air->naddrs; ++i)
698 socklen_t size = (air->family[i] == AF_INET
699 ? INADDRSZ : IN6ADDRSZ);
701 if (!((air->family[i] == AF_INET
702 && req->ai_family == AF_INET6
703 && (req->ai_flags & AI_V4MAPPED) != 0)
704 || req->ai_family == AF_UNSPEC
705 || air->family[i] == req->ai_family))
707 /* Skip over non-matching result. */
708 addrs += size;
709 continue;
712 if (*pat == NULL)
714 *pat = addrfree++;
715 (*pat)->scopeid = 0;
717 uint32_t *pataddr = (*pat)->addr;
718 (*pat)->next = NULL;
719 if (added_canon || air->canon == NULL)
720 (*pat)->name = NULL;
721 else if (canonbuf == NULL)
723 size_t canonlen = strlen (air->canon) + 1;
724 if ((req->ai_flags & AI_CANONIDN) != 0
725 && __libc_use_alloca (alloca_used + canonlen))
726 canonbuf = alloca_account (canonlen, alloca_used);
727 else
729 canonbuf = malloc (canonlen);
730 if (canonbuf == NULL)
732 result = -EAI_MEMORY;
733 goto free_and_return;
735 malloc_canonbuf = true;
737 canon = (*pat)->name = memcpy (canonbuf, air->canon,
738 canonlen);
741 if (air->family[i] == AF_INET
742 && req->ai_family == AF_INET6
743 && (req->ai_flags & AI_V4MAPPED))
745 (*pat)->family = AF_INET6;
746 pataddr[3] = *(uint32_t *) addrs;
747 pataddr[2] = htonl (0xffff);
748 pataddr[1] = 0;
749 pataddr[0] = 0;
750 pat = &((*pat)->next);
751 added_canon = true;
753 else if (req->ai_family == AF_UNSPEC
754 || air->family[i] == req->ai_family)
756 (*pat)->family = air->family[i];
757 memcpy (pataddr, addrs, size);
758 pat = &((*pat)->next);
759 added_canon = true;
760 if (air->family[i] == AF_INET6)
761 got_ipv6 = true;
763 addrs += size;
766 free (air);
768 if (at->family == AF_UNSPEC)
770 result = -EAI_NONAME;
771 goto free_and_return;
774 goto process_list;
776 else if (err == 0)
777 /* The database contains a negative entry. */
778 goto free_and_return;
779 else if (__nss_not_use_nscd_hosts == 0)
781 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
782 result = -EAI_MEMORY;
783 else if (herrno == TRY_AGAIN)
784 result = -EAI_AGAIN;
785 else
786 result = -EAI_SYSTEM;
788 goto free_and_return;
791 #endif
793 if (__nss_hosts_database == NULL)
794 no_more = __nss_database_lookup ("hosts", NULL,
795 "dns [!UNAVAIL=return] files",
796 &__nss_hosts_database);
797 else
798 no_more = 0;
799 nip = __nss_hosts_database;
801 /* Initialize configurations. */
802 _res_hconf_init ();
803 if (__res_maybe_init (&_res, 0) == -1)
804 no_more = 1;
806 /* If we are looking for both IPv4 and IPv6 address we don't
807 want the lookup functions to automatically promote IPv4
808 addresses to IPv6 addresses. Currently this is decided
809 by setting the RES_USE_INET6 bit in _res.options. */
810 old_res_options = _res.options;
811 _res.options &= ~DEPRECATED_RES_USE_INET6;
813 while (!no_more)
815 no_data = 0;
816 nss_gethostbyname4_r fct4 = NULL;
818 /* gethostbyname4_r sends out parallel A and AAAA queries and
819 is thus only suitable for PF_UNSPEC. */
820 if (req->ai_family == PF_UNSPEC)
821 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
823 if (fct4 != NULL)
825 int herrno;
827 while (1)
829 rc = 0;
830 status = DL_CALL_FCT (fct4, (name, pat,
831 tmpbuf->data, tmpbuf->length,
832 &rc, &herrno,
833 NULL));
834 if (status == NSS_STATUS_SUCCESS)
835 break;
836 if (status != NSS_STATUS_TRYAGAIN
837 || rc != ERANGE || herrno != NETDB_INTERNAL)
839 if (herrno == TRY_AGAIN)
840 no_data = EAI_AGAIN;
841 else
842 no_data = herrno == NO_DATA;
843 break;
846 if (!scratch_buffer_grow (tmpbuf))
848 _res.options
849 |= old_res_options & DEPRECATED_RES_USE_INET6;
850 result = -EAI_MEMORY;
851 goto free_and_return;
855 if (status == NSS_STATUS_SUCCESS)
857 assert (!no_data);
858 no_data = 1;
860 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
861 canon = (*pat)->name;
863 while (*pat != NULL)
865 if ((*pat)->family == AF_INET
866 && req->ai_family == AF_INET6
867 && (req->ai_flags & AI_V4MAPPED) != 0)
869 uint32_t *pataddr = (*pat)->addr;
870 (*pat)->family = AF_INET6;
871 pataddr[3] = pataddr[0];
872 pataddr[2] = htonl (0xffff);
873 pataddr[1] = 0;
874 pataddr[0] = 0;
875 pat = &((*pat)->next);
876 no_data = 0;
878 else if (req->ai_family == AF_UNSPEC
879 || (*pat)->family == req->ai_family)
881 pat = &((*pat)->next);
883 no_data = 0;
884 if (req->ai_family == AF_INET6)
885 got_ipv6 = true;
887 else
888 *pat = ((*pat)->next);
892 no_inet6_data = no_data;
894 else
896 nss_gethostbyname3_r fct = NULL;
897 if (req->ai_flags & AI_CANONNAME)
898 /* No need to use this function if we do not look for
899 the canonical name. The function does not exist in
900 all NSS modules and therefore the lookup would
901 often fail. */
902 fct = __nss_lookup_function (nip, "gethostbyname3_r");
903 if (fct == NULL)
904 /* We are cheating here. The gethostbyname2_r
905 function does not have the same interface as
906 gethostbyname3_r but the extra arguments the
907 latter takes are added at the end. So the
908 gethostbyname2_r code will just ignore them. */
909 fct = __nss_lookup_function (nip, "gethostbyname2_r");
911 if (fct != NULL)
913 if (req->ai_family == AF_INET6
914 || req->ai_family == AF_UNSPEC)
916 gethosts (AF_INET6, struct in6_addr);
917 no_inet6_data = no_data;
918 inet6_status = status;
920 if (req->ai_family == AF_INET
921 || req->ai_family == AF_UNSPEC
922 || (req->ai_family == AF_INET6
923 && (req->ai_flags & AI_V4MAPPED)
924 /* Avoid generating the mapped addresses if we
925 know we are not going to need them. */
926 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
928 gethosts (AF_INET, struct in_addr);
930 if (req->ai_family == AF_INET)
932 no_inet6_data = no_data;
933 inet6_status = status;
937 /* If we found one address for AF_INET or AF_INET6,
938 don't continue the search. */
939 if (inet6_status == NSS_STATUS_SUCCESS
940 || status == NSS_STATUS_SUCCESS)
942 if ((req->ai_flags & AI_CANONNAME) != 0
943 && canon == NULL)
945 /* If we need the canonical name, get it
946 from the same service as the result. */
947 nss_getcanonname_r cfct;
948 int herrno;
950 cfct = __nss_lookup_function (nip,
951 "getcanonname_r");
952 if (cfct != NULL)
954 const size_t max_fqdn_len = 256;
955 if ((req->ai_flags & AI_CANONIDN) != 0
956 && __libc_use_alloca (alloca_used
957 + max_fqdn_len))
958 canonbuf = alloca_account (max_fqdn_len,
959 alloca_used);
960 else
962 canonbuf = malloc (max_fqdn_len);
963 if (canonbuf == NULL)
965 _res.options
966 |= old_res_options
967 & DEPRECATED_RES_USE_INET6;
968 result = -EAI_MEMORY;
969 goto free_and_return;
971 malloc_canonbuf = true;
973 char *s;
975 if (DL_CALL_FCT (cfct, (at->name ?: name,
976 canonbuf,
977 max_fqdn_len,
978 &s, &rc, &herrno))
979 == NSS_STATUS_SUCCESS)
980 canon = s;
981 else
983 /* If the canonical name cannot be
984 determined, use the passed in
985 string. */
986 if (malloc_canonbuf)
988 free (canonbuf);
989 malloc_canonbuf = false;
991 canon = name;
995 status = NSS_STATUS_SUCCESS;
997 else
999 /* We can have different states for AF_INET and
1000 AF_INET6. Try to find a useful one for both. */
1001 if (inet6_status == NSS_STATUS_TRYAGAIN)
1002 status = NSS_STATUS_TRYAGAIN;
1003 else if (status == NSS_STATUS_UNAVAIL
1004 && inet6_status != NSS_STATUS_UNAVAIL)
1005 status = inet6_status;
1008 else
1010 status = NSS_STATUS_UNAVAIL;
1011 /* Could not load any of the lookup functions. Indicate
1012 an internal error if the failure was due to a system
1013 error other than the file not being found. We use the
1014 errno from the last failed callback. */
1015 if (errno != 0 && errno != ENOENT)
1016 __set_h_errno (NETDB_INTERNAL);
1020 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1021 break;
1023 if (nip->next == NULL)
1024 no_more = -1;
1025 else
1026 nip = nip->next;
1029 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6;
1031 if (h_errno == NETDB_INTERNAL)
1033 result = -EAI_SYSTEM;
1034 goto free_and_return;
1037 if (no_data != 0 && no_inet6_data != 0)
1039 /* If both requests timed out report this. */
1040 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1041 result = -EAI_AGAIN;
1042 else
1043 /* We made requests but they turned out no data. The name
1044 is known, though. */
1045 result = -EAI_NODATA;
1047 goto free_and_return;
1051 process_list:
1052 if (at->family == AF_UNSPEC)
1054 result = -EAI_NONAME;
1055 goto free_and_return;
1058 else
1060 struct gaih_addrtuple *atr;
1061 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1062 memset (at, '\0', sizeof (struct gaih_addrtuple));
1064 if (req->ai_family == AF_UNSPEC)
1066 at->next = __alloca (sizeof (struct gaih_addrtuple));
1067 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1070 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1072 at->family = AF_INET6;
1073 if ((req->ai_flags & AI_PASSIVE) == 0)
1074 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1075 atr = at->next;
1078 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1080 atr->family = AF_INET;
1081 if ((req->ai_flags & AI_PASSIVE) == 0)
1082 atr->addr[0] = htonl (INADDR_LOOPBACK);
1087 struct gaih_servtuple *st2;
1088 struct gaih_addrtuple *at2 = at;
1089 size_t socklen;
1090 sa_family_t family;
1093 buffer is the size of an unformatted IPv6 address in printable format.
1095 while (at2 != NULL)
1097 /* Only the first entry gets the canonical name. */
1098 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1100 if (canon == NULL)
1101 /* If the canonical name cannot be determined, use
1102 the passed in string. */
1103 canon = orig_name;
1105 #ifdef HAVE_LIBIDN
1106 if (req->ai_flags & AI_CANONIDN)
1108 int idn_flags = 0;
1109 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1110 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1111 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1112 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1114 char *out;
1115 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1116 if (rc != IDNA_SUCCESS)
1118 if (rc == IDNA_MALLOC_ERROR)
1119 result = -EAI_MEMORY;
1120 else if (rc == IDNA_DLOPEN_ERROR)
1121 result = -EAI_SYSTEM;
1122 else
1123 result = -EAI_IDN_ENCODE;
1124 goto free_and_return;
1126 /* In case the output string is the same as the input
1127 string no new string has been allocated and we
1128 make a copy. */
1129 if (out == canon)
1130 goto make_copy;
1131 canon = out;
1133 else
1134 #endif
1136 #ifdef HAVE_LIBIDN
1137 make_copy:
1138 #endif
1139 if (malloc_canonbuf)
1140 /* We already allocated the string using malloc. */
1141 malloc_canonbuf = false;
1142 else
1144 canon = strdup (canon);
1145 if (canon == NULL)
1147 result = -EAI_MEMORY;
1148 goto free_and_return;
1154 family = at2->family;
1155 if (family == AF_INET6)
1157 socklen = sizeof (struct sockaddr_in6);
1159 /* If we looked up IPv4 mapped address discard them here if
1160 the caller isn't interested in all address and we have
1161 found at least one IPv6 address. */
1162 if (got_ipv6
1163 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1164 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1165 goto ignore;
1167 else
1168 socklen = sizeof (struct sockaddr_in);
1170 for (st2 = st; st2 != NULL; st2 = st2->next)
1172 struct addrinfo *ai;
1173 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1174 if (ai == NULL)
1176 free ((char *) canon);
1177 result = -EAI_MEMORY;
1178 goto free_and_return;
1181 ai->ai_flags = req->ai_flags;
1182 ai->ai_family = family;
1183 ai->ai_socktype = st2->socktype;
1184 ai->ai_protocol = st2->protocol;
1185 ai->ai_addrlen = socklen;
1186 ai->ai_addr = (void *) (ai + 1);
1188 /* We only add the canonical name once. */
1189 ai->ai_canonname = (char *) canon;
1190 canon = NULL;
1192 #ifdef _HAVE_SA_LEN
1193 ai->ai_addr->sa_len = socklen;
1194 #endif /* _HAVE_SA_LEN */
1195 ai->ai_addr->sa_family = family;
1197 /* In case of an allocation error the list must be NULL
1198 terminated. */
1199 ai->ai_next = NULL;
1201 if (family == AF_INET6)
1203 struct sockaddr_in6 *sin6p =
1204 (struct sockaddr_in6 *) ai->ai_addr;
1206 sin6p->sin6_port = st2->port;
1207 sin6p->sin6_flowinfo = 0;
1208 memcpy (&sin6p->sin6_addr,
1209 at2->addr, sizeof (struct in6_addr));
1210 sin6p->sin6_scope_id = at2->scopeid;
1212 else
1214 struct sockaddr_in *sinp =
1215 (struct sockaddr_in *) ai->ai_addr;
1216 sinp->sin_port = st2->port;
1217 memcpy (&sinp->sin_addr,
1218 at2->addr, sizeof (struct in_addr));
1219 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1222 pai = &(ai->ai_next);
1225 ++*naddrs;
1227 ignore:
1228 at2 = at2->next;
1232 free_and_return:
1233 if (malloc_name)
1234 free ((char *) name);
1235 if (malloc_addrmem)
1236 free (addrmem);
1237 if (malloc_canonbuf)
1238 free (canonbuf);
1240 return result;
1244 struct sort_result
1246 struct addrinfo *dest_addr;
1247 /* Using sockaddr_storage is for now overkill. We only support IPv4
1248 and IPv6 so far. If this changes at some point we can adjust the
1249 type here. */
1250 struct sockaddr_in6 source_addr;
1251 uint8_t source_addr_len;
1252 bool got_source_addr;
1253 uint8_t source_addr_flags;
1254 uint8_t prefixlen;
1255 uint32_t index;
1256 int32_t native;
1259 struct sort_result_combo
1261 struct sort_result *results;
1262 int nresults;
1266 #if __BYTE_ORDER == __BIG_ENDIAN
1267 # define htonl_c(n) n
1268 #else
1269 # define htonl_c(n) __bswap_constant_32 (n)
1270 #endif
1272 static const struct scopeentry
1274 union
1276 char addr[4];
1277 uint32_t addr32;
1279 uint32_t netmask;
1280 int32_t scope;
1281 } default_scopes[] =
1283 /* Link-local addresses: scope 2. */
1284 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1285 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1286 /* Default: scope 14. */
1287 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1290 /* The label table. */
1291 static const struct scopeentry *scopes;
1294 static int
1295 get_scope (const struct sockaddr_in6 *in6)
1297 int scope;
1298 if (in6->sin6_family == PF_INET6)
1300 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1302 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1303 /* RFC 4291 2.5.3 says that the loopback address is to be
1304 treated like a link-local address. */
1305 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1306 scope = 2;
1307 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1308 scope = 5;
1309 else
1310 /* XXX Is this the correct default behavior? */
1311 scope = 14;
1313 else
1314 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1316 else if (in6->sin6_family == PF_INET)
1318 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1320 size_t cnt = 0;
1321 while (1)
1323 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1324 == scopes[cnt].addr32)
1325 return scopes[cnt].scope;
1327 ++cnt;
1329 /* NOTREACHED */
1331 else
1332 /* XXX What is a good default? */
1333 scope = 15;
1335 return scope;
1339 struct prefixentry
1341 struct in6_addr prefix;
1342 unsigned int bits;
1343 int val;
1347 /* The label table. */
1348 static const struct prefixentry *labels;
1350 /* Default labels. */
1351 static const struct prefixentry default_labels[] =
1353 /* See RFC 3484 for the details. */
1354 { { .__in6_u
1355 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1357 }, 128, 0 },
1358 { { .__in6_u
1359 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1361 }, 16, 2 },
1362 { { .__in6_u
1363 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1365 }, 96, 3 },
1366 { { .__in6_u
1367 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1369 }, 96, 4 },
1370 /* The next two entries differ from RFC 3484. We need to treat
1371 IPv6 site-local addresses special because they are never NATed,
1372 unlike site-locale IPv4 addresses. If this would not happen, on
1373 machines which have only IPv4 and IPv6 site-local addresses, the
1374 sorting would prefer the IPv6 site-local addresses, causing
1375 unnecessary delays when trying to connect to a global IPv6 address
1376 through a site-local IPv6 address. */
1377 { { .__in6_u
1378 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1380 }, 10, 5 },
1381 { { .__in6_u
1382 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1384 }, 7, 6 },
1385 /* Additional rule for Teredo tunnels. */
1386 { { .__in6_u
1387 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1389 }, 32, 7 },
1390 { { .__in6_u
1391 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1393 }, 0, 1 }
1397 /* The precedence table. */
1398 static const struct prefixentry *precedence;
1400 /* The default precedences. */
1401 static const struct prefixentry default_precedence[] =
1403 /* See RFC 3484 for the details. */
1404 { { .__in6_u
1405 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1407 }, 128, 50 },
1408 { { .__in6_u
1409 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1411 }, 16, 30 },
1412 { { .__in6_u
1413 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1415 }, 96, 20 },
1416 { { .__in6_u
1417 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1418 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1419 }, 96, 10 },
1420 { { .__in6_u
1421 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1423 }, 0, 40 }
1427 static int
1428 match_prefix (const struct sockaddr_in6 *in6,
1429 const struct prefixentry *list, int default_val)
1431 int idx;
1432 struct sockaddr_in6 in6_mem;
1434 if (in6->sin6_family == PF_INET)
1436 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1438 /* Construct a V4-to-6 mapped address. */
1439 in6_mem.sin6_family = PF_INET6;
1440 in6_mem.sin6_port = in->sin_port;
1441 in6_mem.sin6_flowinfo = 0;
1442 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1443 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1444 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1445 in6_mem.sin6_scope_id = 0;
1447 in6 = &in6_mem;
1449 else if (in6->sin6_family != PF_INET6)
1450 return default_val;
1452 for (idx = 0; ; ++idx)
1454 unsigned int bits = list[idx].bits;
1455 const uint8_t *mask = list[idx].prefix.s6_addr;
1456 const uint8_t *val = in6->sin6_addr.s6_addr;
1458 while (bits >= 8)
1460 if (*mask != *val)
1461 break;
1463 ++mask;
1464 ++val;
1465 bits -= 8;
1468 if (bits < 8)
1470 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1471 /* Match! */
1472 break;
1476 return list[idx].val;
1480 static int
1481 get_label (const struct sockaddr_in6 *in6)
1483 /* XXX What is a good default value? */
1484 return match_prefix (in6, labels, INT_MAX);
1488 static int
1489 get_precedence (const struct sockaddr_in6 *in6)
1491 /* XXX What is a good default value? */
1492 return match_prefix (in6, precedence, 0);
1496 /* Find last bit set in a word. */
1497 static int
1498 fls (uint32_t a)
1500 uint32_t mask;
1501 int n;
1502 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1503 if ((a & mask) != 0)
1504 break;
1505 return n;
1509 static int
1510 rfc3484_sort (const void *p1, const void *p2, void *arg)
1512 const size_t idx1 = *(const size_t *) p1;
1513 const size_t idx2 = *(const size_t *) p2;
1514 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1515 struct sort_result *a1 = &src->results[idx1];
1516 struct sort_result *a2 = &src->results[idx2];
1518 /* Rule 1: Avoid unusable destinations.
1519 We have the got_source_addr flag set if the destination is reachable. */
1520 if (a1->got_source_addr && ! a2->got_source_addr)
1521 return -1;
1522 if (! a1->got_source_addr && a2->got_source_addr)
1523 return 1;
1526 /* Rule 2: Prefer matching scope. Only interesting if both
1527 destination addresses are IPv6. */
1528 int a1_dst_scope
1529 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1531 int a2_dst_scope
1532 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1534 if (a1->got_source_addr)
1536 int a1_src_scope = get_scope (&a1->source_addr);
1537 int a2_src_scope = get_scope (&a2->source_addr);
1539 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1540 return -1;
1541 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1542 return 1;
1546 /* Rule 3: Avoid deprecated addresses. */
1547 if (a1->got_source_addr)
1549 if (!(a1->source_addr_flags & in6ai_deprecated)
1550 && (a2->source_addr_flags & in6ai_deprecated))
1551 return -1;
1552 if ((a1->source_addr_flags & in6ai_deprecated)
1553 && !(a2->source_addr_flags & in6ai_deprecated))
1554 return 1;
1557 /* Rule 4: Prefer home addresses. */
1558 if (a1->got_source_addr)
1560 if (!(a1->source_addr_flags & in6ai_homeaddress)
1561 && (a2->source_addr_flags & in6ai_homeaddress))
1562 return 1;
1563 if ((a1->source_addr_flags & in6ai_homeaddress)
1564 && !(a2->source_addr_flags & in6ai_homeaddress))
1565 return -1;
1568 /* Rule 5: Prefer matching label. */
1569 if (a1->got_source_addr)
1571 int a1_dst_label
1572 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1573 int a1_src_label = get_label (&a1->source_addr);
1575 int a2_dst_label
1576 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1577 int a2_src_label = get_label (&a2->source_addr);
1579 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1580 return -1;
1581 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1582 return 1;
1586 /* Rule 6: Prefer higher precedence. */
1587 int a1_prec
1588 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1589 int a2_prec
1590 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1592 if (a1_prec > a2_prec)
1593 return -1;
1594 if (a1_prec < a2_prec)
1595 return 1;
1598 /* Rule 7: Prefer native transport. */
1599 if (a1->got_source_addr)
1601 /* The same interface index means the same interface which means
1602 there is no difference in transport. This should catch many
1603 (most?) cases. */
1604 if (a1->index != a2->index)
1606 int a1_native = a1->native;
1607 int a2_native = a2->native;
1609 if (a1_native == -1 || a2_native == -1)
1611 uint32_t a1_index;
1612 if (a1_native == -1)
1614 /* If we do not have the information use 'native' as
1615 the default. */
1616 a1_native = 0;
1617 a1_index = a1->index;
1619 else
1620 a1_index = 0xffffffffu;
1622 uint32_t a2_index;
1623 if (a2_native == -1)
1625 /* If we do not have the information use 'native' as
1626 the default. */
1627 a2_native = 0;
1628 a2_index = a2->index;
1630 else
1631 a2_index = 0xffffffffu;
1633 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1635 /* Fill in the results in all the records. */
1636 for (int i = 0; i < src->nresults; ++i)
1637 if (a1_index != -1 && src->results[i].index == a1_index)
1639 assert (src->results[i].native == -1
1640 || src->results[i].native == a1_native);
1641 src->results[i].native = a1_native;
1643 else if (a2_index != -1 && src->results[i].index == a2_index)
1645 assert (src->results[i].native == -1
1646 || src->results[i].native == a2_native);
1647 src->results[i].native = a2_native;
1651 if (a1_native && !a2_native)
1652 return -1;
1653 if (!a1_native && a2_native)
1654 return 1;
1659 /* Rule 8: Prefer smaller scope. */
1660 if (a1_dst_scope < a2_dst_scope)
1661 return -1;
1662 if (a1_dst_scope > a2_dst_scope)
1663 return 1;
1666 /* Rule 9: Use longest matching prefix. */
1667 if (a1->got_source_addr
1668 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1670 int bit1 = 0;
1671 int bit2 = 0;
1673 if (a1->dest_addr->ai_family == PF_INET)
1675 assert (a1->source_addr.sin6_family == PF_INET);
1676 assert (a2->source_addr.sin6_family == PF_INET);
1678 /* Outside of subnets, as defined by the network masks,
1679 common address prefixes for IPv4 addresses make no sense.
1680 So, define a non-zero value only if source and
1681 destination address are on the same subnet. */
1682 struct sockaddr_in *in1_dst
1683 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1684 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1685 struct sockaddr_in *in1_src
1686 = (struct sockaddr_in *) &a1->source_addr;
1687 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1688 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1690 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1691 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1693 struct sockaddr_in *in2_dst
1694 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1695 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1696 struct sockaddr_in *in2_src
1697 = (struct sockaddr_in *) &a2->source_addr;
1698 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1699 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1701 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1702 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1704 else if (a1->dest_addr->ai_family == PF_INET6)
1706 assert (a1->source_addr.sin6_family == PF_INET6);
1707 assert (a2->source_addr.sin6_family == PF_INET6);
1709 struct sockaddr_in6 *in1_dst;
1710 struct sockaddr_in6 *in1_src;
1711 struct sockaddr_in6 *in2_dst;
1712 struct sockaddr_in6 *in2_src;
1714 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1715 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1716 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1717 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1719 int i;
1720 for (i = 0; i < 4; ++i)
1721 if (in1_dst->sin6_addr.s6_addr32[i]
1722 != in1_src->sin6_addr.s6_addr32[i]
1723 || (in2_dst->sin6_addr.s6_addr32[i]
1724 != in2_src->sin6_addr.s6_addr32[i]))
1725 break;
1727 if (i < 4)
1729 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1730 ^ in1_src->sin6_addr.s6_addr32[i]));
1731 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1732 ^ in2_src->sin6_addr.s6_addr32[i]));
1736 if (bit1 > bit2)
1737 return -1;
1738 if (bit1 < bit2)
1739 return 1;
1743 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1744 compare with the value indicating the order in which the entries
1745 have been received from the services. NB: no two entries can have
1746 the same order so the test will never return zero. */
1747 return idx1 < idx2 ? -1 : 1;
1751 static int
1752 in6aicmp (const void *p1, const void *p2)
1754 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1755 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1757 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1761 /* Name of the config file for RFC 3484 sorting (for now). */
1762 #define GAICONF_FNAME "/etc/gai.conf"
1765 /* Non-zero if we are supposed to reload the config file automatically
1766 whenever it changed. */
1767 static int gaiconf_reload_flag;
1769 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1770 static int gaiconf_reload_flag_ever_set;
1772 /* Last modification time. */
1773 #ifdef _STATBUF_ST_NSEC
1775 static struct timespec gaiconf_mtime;
1777 static inline void
1778 save_gaiconf_mtime (const struct stat64 *st)
1780 gaiconf_mtime = st->st_mtim;
1783 static inline bool
1784 check_gaiconf_mtime (const struct stat64 *st)
1786 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1787 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1790 #else
1792 static time_t gaiconf_mtime;
1794 static inline void
1795 save_gaiconf_mtime (const struct stat64 *st)
1797 gaiconf_mtime = st->st_mtime;
1800 static inline bool
1801 check_gaiconf_mtime (const struct stat64 *st)
1803 return st->st_mtime == gaiconf_mtime;
1806 #endif
1809 libc_freeres_fn(fini)
1811 if (labels != default_labels)
1813 const struct prefixentry *old = labels;
1814 labels = default_labels;
1815 free ((void *) old);
1818 if (precedence != default_precedence)
1820 const struct prefixentry *old = precedence;
1821 precedence = default_precedence;
1822 free ((void *) old);
1825 if (scopes != default_scopes)
1827 const struct scopeentry *old = scopes;
1828 scopes = default_scopes;
1829 free ((void *) old);
1834 struct prefixlist
1836 struct prefixentry entry;
1837 struct prefixlist *next;
1841 struct scopelist
1843 struct scopeentry entry;
1844 struct scopelist *next;
1848 static void
1849 free_prefixlist (struct prefixlist *list)
1851 while (list != NULL)
1853 struct prefixlist *oldp = list;
1854 list = list->next;
1855 free (oldp);
1860 static void
1861 free_scopelist (struct scopelist *list)
1863 while (list != NULL)
1865 struct scopelist *oldp = list;
1866 list = list->next;
1867 free (oldp);
1872 static int
1873 prefixcmp (const void *p1, const void *p2)
1875 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1876 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1878 if (e1->bits < e2->bits)
1879 return 1;
1880 if (e1->bits == e2->bits)
1881 return 0;
1882 return -1;
1886 static int
1887 scopecmp (const void *p1, const void *p2)
1889 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1890 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1892 if (e1->netmask > e2->netmask)
1893 return -1;
1894 if (e1->netmask == e2->netmask)
1895 return 0;
1896 return 1;
1900 static void
1901 gaiconf_init (void)
1903 struct prefixlist *labellist = NULL;
1904 size_t nlabellist = 0;
1905 bool labellist_nullbits = false;
1906 struct prefixlist *precedencelist = NULL;
1907 size_t nprecedencelist = 0;
1908 bool precedencelist_nullbits = false;
1909 struct scopelist *scopelist = NULL;
1910 size_t nscopelist = 0;
1911 bool scopelist_nullbits = false;
1913 FILE *fp = fopen (GAICONF_FNAME, "rce");
1914 if (fp != NULL)
1916 struct stat64 st;
1917 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1919 fclose (fp);
1920 goto no_file;
1923 char *line = NULL;
1924 size_t linelen = 0;
1926 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1928 while (!feof_unlocked (fp))
1930 ssize_t n = __getline (&line, &linelen, fp);
1931 if (n <= 0)
1932 break;
1934 /* Handle comments. No escaping possible so this is easy. */
1935 char *cp = strchr (line, '#');
1936 if (cp != NULL)
1937 *cp = '\0';
1939 cp = line;
1940 while (isspace (*cp))
1941 ++cp;
1943 char *cmd = cp;
1944 while (*cp != '\0' && !isspace (*cp))
1945 ++cp;
1946 size_t cmdlen = cp - cmd;
1948 if (*cp != '\0')
1949 *cp++ = '\0';
1950 while (isspace (*cp))
1951 ++cp;
1953 char *val1 = cp;
1954 while (*cp != '\0' && !isspace (*cp))
1955 ++cp;
1956 size_t val1len = cp - cmd;
1958 /* We always need at least two values. */
1959 if (val1len == 0)
1960 continue;
1962 if (*cp != '\0')
1963 *cp++ = '\0';
1964 while (isspace (*cp))
1965 ++cp;
1967 char *val2 = cp;
1968 while (*cp != '\0' && !isspace (*cp))
1969 ++cp;
1971 /* Ignore the rest of the line. */
1972 *cp = '\0';
1974 struct prefixlist **listp;
1975 size_t *lenp;
1976 bool *nullbitsp;
1977 switch (cmdlen)
1979 case 5:
1980 if (strcmp (cmd, "label") == 0)
1982 struct in6_addr prefix;
1983 unsigned long int bits;
1984 unsigned long int val;
1985 char *endp;
1987 listp = &labellist;
1988 lenp = &nlabellist;
1989 nullbitsp = &labellist_nullbits;
1991 new_elem:
1992 bits = 128;
1993 __set_errno (0);
1994 cp = strchr (val1, '/');
1995 if (cp != NULL)
1996 *cp++ = '\0';
1997 if (inet_pton (AF_INET6, val1, &prefix)
1998 && (cp == NULL
1999 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2000 || errno != ERANGE)
2001 && *endp == '\0'
2002 && bits <= 128
2003 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2004 || errno != ERANGE)
2005 && *endp == '\0'
2006 && val <= INT_MAX)
2008 struct prefixlist *newp = malloc (sizeof (*newp));
2009 if (newp == NULL)
2011 free (line);
2012 fclose (fp);
2013 goto no_file;
2016 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2017 newp->entry.bits = bits;
2018 newp->entry.val = val;
2019 newp->next = *listp;
2020 *listp = newp;
2021 ++*lenp;
2022 *nullbitsp |= bits == 0;
2025 break;
2027 case 6:
2028 if (strcmp (cmd, "reload") == 0)
2030 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2031 if (gaiconf_reload_flag)
2032 gaiconf_reload_flag_ever_set = 1;
2034 break;
2036 case 7:
2037 if (strcmp (cmd, "scopev4") == 0)
2039 struct in6_addr prefix;
2040 unsigned long int bits;
2041 unsigned long int val;
2042 char *endp;
2044 bits = 32;
2045 __set_errno (0);
2046 cp = strchr (val1, '/');
2047 if (cp != NULL)
2048 *cp++ = '\0';
2049 if (inet_pton (AF_INET6, val1, &prefix))
2051 bits = 128;
2052 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2053 && (cp == NULL
2054 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2055 || errno != ERANGE)
2056 && *endp == '\0'
2057 && bits >= 96
2058 && bits <= 128
2059 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2060 || errno != ERANGE)
2061 && *endp == '\0'
2062 && val <= INT_MAX)
2064 struct scopelist *newp;
2065 new_scope:
2066 newp = malloc (sizeof (*newp));
2067 if (newp == NULL)
2069 free (line);
2070 fclose (fp);
2071 goto no_file;
2074 newp->entry.netmask = htonl (bits != 96
2075 ? (0xffffffff
2076 << (128 - bits))
2077 : 0);
2078 newp->entry.addr32 = (prefix.s6_addr32[3]
2079 & newp->entry.netmask);
2080 newp->entry.scope = val;
2081 newp->next = scopelist;
2082 scopelist = newp;
2083 ++nscopelist;
2084 scopelist_nullbits |= bits == 96;
2087 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2088 && (cp == NULL
2089 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2090 || errno != ERANGE)
2091 && *endp == '\0'
2092 && bits <= 32
2093 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2094 || errno != ERANGE)
2095 && *endp == '\0'
2096 && val <= INT_MAX)
2098 bits += 96;
2099 goto new_scope;
2102 break;
2104 case 10:
2105 if (strcmp (cmd, "precedence") == 0)
2107 listp = &precedencelist;
2108 lenp = &nprecedencelist;
2109 nullbitsp = &precedencelist_nullbits;
2110 goto new_elem;
2112 break;
2116 free (line);
2118 fclose (fp);
2120 /* Create the array for the labels. */
2121 struct prefixentry *new_labels;
2122 if (nlabellist > 0)
2124 if (!labellist_nullbits)
2125 ++nlabellist;
2126 new_labels = malloc (nlabellist * sizeof (*new_labels));
2127 if (new_labels == NULL)
2128 goto no_file;
2130 int i = nlabellist;
2131 if (!labellist_nullbits)
2133 --i;
2134 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2135 new_labels[i].bits = 0;
2136 new_labels[i].val = 1;
2139 struct prefixlist *l = labellist;
2140 while (i-- > 0)
2142 new_labels[i] = l->entry;
2143 l = l->next;
2145 free_prefixlist (labellist);
2147 /* Sort the entries so that the most specific ones are at
2148 the beginning. */
2149 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2151 else
2152 new_labels = (struct prefixentry *) default_labels;
2154 struct prefixentry *new_precedence;
2155 if (nprecedencelist > 0)
2157 if (!precedencelist_nullbits)
2158 ++nprecedencelist;
2159 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2160 if (new_precedence == NULL)
2162 if (new_labels != default_labels)
2163 free (new_labels);
2164 goto no_file;
2167 int i = nprecedencelist;
2168 if (!precedencelist_nullbits)
2170 --i;
2171 memset (&new_precedence[i].prefix, '\0',
2172 sizeof (struct in6_addr));
2173 new_precedence[i].bits = 0;
2174 new_precedence[i].val = 40;
2177 struct prefixlist *l = precedencelist;
2178 while (i-- > 0)
2180 new_precedence[i] = l->entry;
2181 l = l->next;
2183 free_prefixlist (precedencelist);
2185 /* Sort the entries so that the most specific ones are at
2186 the beginning. */
2187 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2188 prefixcmp);
2190 else
2191 new_precedence = (struct prefixentry *) default_precedence;
2193 struct scopeentry *new_scopes;
2194 if (nscopelist > 0)
2196 if (!scopelist_nullbits)
2197 ++nscopelist;
2198 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2199 if (new_scopes == NULL)
2201 if (new_labels != default_labels)
2202 free (new_labels);
2203 if (new_precedence != default_precedence)
2204 free (new_precedence);
2205 goto no_file;
2208 int i = nscopelist;
2209 if (!scopelist_nullbits)
2211 --i;
2212 new_scopes[i].addr32 = 0;
2213 new_scopes[i].netmask = 0;
2214 new_scopes[i].scope = 14;
2217 struct scopelist *l = scopelist;
2218 while (i-- > 0)
2220 new_scopes[i] = l->entry;
2221 l = l->next;
2223 free_scopelist (scopelist);
2225 /* Sort the entries so that the most specific ones are at
2226 the beginning. */
2227 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2228 scopecmp);
2230 else
2231 new_scopes = (struct scopeentry *) default_scopes;
2233 /* Now we are ready to replace the values. */
2234 const struct prefixentry *old = labels;
2235 labels = new_labels;
2236 if (old != default_labels)
2237 free ((void *) old);
2239 old = precedence;
2240 precedence = new_precedence;
2241 if (old != default_precedence)
2242 free ((void *) old);
2244 const struct scopeentry *oldscope = scopes;
2245 scopes = new_scopes;
2246 if (oldscope != default_scopes)
2247 free ((void *) oldscope);
2249 save_gaiconf_mtime (&st);
2251 else
2253 no_file:
2254 free_prefixlist (labellist);
2255 free_prefixlist (precedencelist);
2256 free_scopelist (scopelist);
2258 /* If we previously read the file but it is gone now, free the
2259 old data and use the builtin one. Leave the reload flag
2260 alone. */
2261 fini ();
2266 static void
2267 gaiconf_reload (void)
2269 struct stat64 st;
2270 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2271 || !check_gaiconf_mtime (&st))
2272 gaiconf_init ();
2277 getaddrinfo (const char *name, const char *service,
2278 const struct addrinfo *hints, struct addrinfo **pai)
2280 int i = 0, last_i = 0;
2281 int nresults = 0;
2282 struct addrinfo *p = NULL;
2283 struct gaih_service gaih_service, *pservice;
2284 struct addrinfo local_hints;
2286 if (name != NULL && name[0] == '*' && name[1] == 0)
2287 name = NULL;
2289 if (service != NULL && service[0] == '*' && service[1] == 0)
2290 service = NULL;
2292 if (name == NULL && service == NULL)
2293 return EAI_NONAME;
2295 if (hints == NULL)
2296 hints = &default_hints;
2298 if (hints->ai_flags
2299 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2300 #ifdef HAVE_LIBIDN
2301 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2302 |AI_IDN_USE_STD3_ASCII_RULES
2303 #endif
2304 |AI_NUMERICSERV|AI_ALL))
2305 return EAI_BADFLAGS;
2307 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2308 return EAI_BADFLAGS;
2310 struct in6addrinfo *in6ai = NULL;
2311 size_t in6ailen = 0;
2312 bool seen_ipv4 = false;
2313 bool seen_ipv6 = false;
2314 bool check_pf_called = false;
2316 if (hints->ai_flags & AI_ADDRCONFIG)
2318 /* We might need information about what interfaces are available.
2319 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2320 cannot cache the results since new interfaces could be added at
2321 any time. */
2322 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2323 check_pf_called = true;
2325 /* Now make a decision on what we return, if anything. */
2326 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2328 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2329 narrow down the search. */
2330 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2332 local_hints = *hints;
2333 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2334 hints = &local_hints;
2337 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2338 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2340 /* We cannot possibly return a valid answer. */
2341 __free_in6ai (in6ai);
2342 return EAI_NONAME;
2346 if (service && service[0])
2348 char *c;
2349 gaih_service.name = service;
2350 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2351 if (*c != '\0')
2353 if (hints->ai_flags & AI_NUMERICSERV)
2355 __free_in6ai (in6ai);
2356 return EAI_NONAME;
2359 gaih_service.num = -1;
2362 pservice = &gaih_service;
2364 else
2365 pservice = NULL;
2367 struct addrinfo **end = &p;
2369 unsigned int naddrs = 0;
2370 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2371 || hints->ai_family == AF_INET6)
2373 struct scratch_buffer tmpbuf;
2374 scratch_buffer_init (&tmpbuf);
2375 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2376 scratch_buffer_free (&tmpbuf);
2378 if (last_i != 0)
2380 freeaddrinfo (p);
2381 __free_in6ai (in6ai);
2383 return -last_i;
2385 while (*end)
2387 end = &((*end)->ai_next);
2388 ++nresults;
2391 else
2393 __free_in6ai (in6ai);
2394 return EAI_FAMILY;
2397 if (naddrs > 1)
2399 /* Read the config file. */
2400 __libc_once_define (static, once);
2401 __typeof (once) old_once = once;
2402 __libc_once (once, gaiconf_init);
2403 /* Sort results according to RFC 3484. */
2404 struct sort_result *results;
2405 size_t *order;
2406 struct addrinfo *q;
2407 struct addrinfo *last = NULL;
2408 char *canonname = NULL;
2409 bool malloc_results;
2410 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2412 malloc_results
2413 = !__libc_use_alloca (alloc_size);
2414 if (malloc_results)
2416 results = malloc (alloc_size);
2417 if (results == NULL)
2419 __free_in6ai (in6ai);
2420 return EAI_MEMORY;
2423 else
2424 results = alloca (alloc_size);
2425 order = (size_t *) (results + nresults);
2427 /* Now we definitely need the interface information. */
2428 if (! check_pf_called)
2429 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2431 /* If we have information about deprecated and temporary addresses
2432 sort the array now. */
2433 if (in6ai != NULL)
2434 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2436 int fd = -1;
2437 int af = AF_UNSPEC;
2439 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2441 results[i].dest_addr = q;
2442 results[i].native = -1;
2443 order[i] = i;
2445 /* If we just looked up the address for a different
2446 protocol, reuse the result. */
2447 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2448 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2450 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2451 results[i - 1].source_addr_len);
2452 results[i].source_addr_len = results[i - 1].source_addr_len;
2453 results[i].got_source_addr = results[i - 1].got_source_addr;
2454 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2455 results[i].prefixlen = results[i - 1].prefixlen;
2456 results[i].index = results[i - 1].index;
2458 else
2460 results[i].got_source_addr = false;
2461 results[i].source_addr_flags = 0;
2462 results[i].prefixlen = 0;
2463 results[i].index = 0xffffffffu;
2465 /* We overwrite the type with SOCK_DGRAM since we do not
2466 want connect() to connect to the other side. If we
2467 cannot determine the source address remember this
2468 fact. */
2469 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2471 if (fd != -1)
2472 close_retry:
2473 close_not_cancel_no_status (fd);
2474 af = q->ai_family;
2475 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2477 else
2479 /* Reset the connection. */
2480 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2481 __connect (fd, &sa, sizeof (sa));
2484 socklen_t sl = sizeof (results[i].source_addr);
2485 if (fd != -1
2486 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2487 && __getsockname (fd,
2488 (struct sockaddr *) &results[i].source_addr,
2489 &sl) == 0)
2491 results[i].source_addr_len = sl;
2492 results[i].got_source_addr = true;
2494 if (in6ai != NULL)
2496 /* See whether the source address is on the list of
2497 deprecated or temporary addresses. */
2498 struct in6addrinfo tmp;
2500 if (q->ai_family == AF_INET && af == AF_INET)
2502 struct sockaddr_in *sinp
2503 = (struct sockaddr_in *) &results[i].source_addr;
2504 tmp.addr[0] = 0;
2505 tmp.addr[1] = 0;
2506 tmp.addr[2] = htonl (0xffff);
2507 /* Special case for lo interface, the source address
2508 being possibly different than the interface
2509 address. */
2510 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2511 == 0x7f000000)
2512 tmp.addr[3] = htonl(0x7f000001);
2513 else
2514 tmp.addr[3] = sinp->sin_addr.s_addr;
2516 else
2518 struct sockaddr_in6 *sin6p
2519 = (struct sockaddr_in6 *) &results[i].source_addr;
2520 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2523 struct in6addrinfo *found
2524 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2525 in6aicmp);
2526 if (found != NULL)
2528 results[i].source_addr_flags = found->flags;
2529 results[i].prefixlen = found->prefixlen;
2530 results[i].index = found->index;
2534 if (q->ai_family == AF_INET && af == AF_INET6)
2536 /* We have to convert the address. The socket is
2537 IPv6 and the request is for IPv4. */
2538 struct sockaddr_in6 *sin6
2539 = (struct sockaddr_in6 *) &results[i].source_addr;
2540 struct sockaddr_in *sin
2541 = (struct sockaddr_in *) &results[i].source_addr;
2542 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2543 sin->sin_family = AF_INET;
2544 /* We do not have to initialize sin_port since this
2545 fields has the same position and size in the IPv6
2546 structure. */
2547 assert (offsetof (struct sockaddr_in, sin_port)
2548 == offsetof (struct sockaddr_in6, sin6_port));
2549 assert (sizeof (sin->sin_port)
2550 == sizeof (sin6->sin6_port));
2551 memcpy (&sin->sin_addr,
2552 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2553 results[i].source_addr_len = sizeof (struct sockaddr_in);
2556 else if (errno == EAFNOSUPPORT && af == AF_INET6
2557 && q->ai_family == AF_INET)
2558 /* This could mean IPv6 sockets are IPv6-only. */
2559 goto close_retry;
2560 else
2561 /* Just make sure that if we have to process the same
2562 address again we do not copy any memory. */
2563 results[i].source_addr_len = 0;
2566 /* Remember the canonical name. */
2567 if (q->ai_canonname != NULL)
2569 assert (canonname == NULL);
2570 canonname = q->ai_canonname;
2571 q->ai_canonname = NULL;
2575 if (fd != -1)
2576 close_not_cancel_no_status (fd);
2578 /* We got all the source addresses we can get, now sort using
2579 the information. */
2580 struct sort_result_combo src
2581 = { .results = results, .nresults = nresults };
2582 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2584 __libc_lock_define_initialized (static, lock);
2586 __libc_lock_lock (lock);
2587 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2588 gaiconf_reload ();
2589 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2590 __libc_lock_unlock (lock);
2592 else
2593 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2595 /* Queue the results up as they come out of sorting. */
2596 q = p = results[order[0]].dest_addr;
2597 for (i = 1; i < nresults; ++i)
2598 q = q->ai_next = results[order[i]].dest_addr;
2599 q->ai_next = NULL;
2601 /* Fill in the canonical name into the new first entry. */
2602 p->ai_canonname = canonname;
2604 if (malloc_results)
2605 free (results);
2608 __free_in6ai (in6ai);
2610 if (p)
2612 *pai = p;
2613 return 0;
2616 return last_i ? -last_i : EAI_NONAME;
2618 libc_hidden_def (getaddrinfo)
2620 nss_interface_function (getaddrinfo)
2622 void
2623 freeaddrinfo (struct addrinfo *ai)
2625 struct addrinfo *p;
2627 while (ai != NULL)
2629 p = ai;
2630 ai = ai->ai_next;
2631 free (p->ai_canonname);
2632 free (p);
2635 libc_hidden_def (freeaddrinfo)