Revert exp reimplementation (causes test failures).
[glibc.git] / sysdeps / posix / getaddrinfo.c
blobc58d54dff508d2edb2cd23e1a8d7653743c4d0a1
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 <resolv/resolv_context.h>
64 #include <resolv/res_use_inet6.h>
65 #include <stdbool.h>
66 #include <stdio.h>
67 #include <stdio_ext.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <stdint.h>
71 #include <arpa/inet.h>
72 #include <net/if.h>
73 #include <netinet/in.h>
74 #include <sys/socket.h>
75 #include <sys/stat.h>
76 #include <sys/types.h>
77 #include <sys/un.h>
78 #include <sys/utsname.h>
79 #include <unistd.h>
80 #include <nsswitch.h>
81 #include <libc-lock.h>
82 #include <not-cancel.h>
83 #include <nscd/nscd-client.h>
84 #include <nscd/nscd_proto.h>
85 #include <scratch_buffer.h>
86 #include <inet/net-internal.h>
88 #ifdef HAVE_LIBIDN
89 # include <idna.h>
90 #endif
92 struct gaih_service
94 const char *name;
95 int num;
98 struct gaih_servtuple
100 struct gaih_servtuple *next;
101 int socktype;
102 int protocol;
103 int port;
106 static const struct gaih_servtuple nullserv;
109 struct gaih_typeproto
111 int socktype;
112 int protocol;
113 uint8_t protoflag;
114 bool defaultflag;
115 char name[8];
118 /* Values for `protoflag'. */
119 #define GAI_PROTO_NOSERVICE 1
120 #define GAI_PROTO_PROTOANY 2
122 static const struct gaih_typeproto gaih_inet_typeproto[] =
124 { 0, 0, 0, false, "" },
125 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
126 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
127 #if defined SOCK_DCCP && defined IPPROTO_DCCP
128 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
129 #endif
130 #ifdef IPPROTO_UDPLITE
131 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
132 #endif
133 #ifdef IPPROTO_SCTP
134 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
135 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
136 #endif
137 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
138 { 0, 0, 0, false, "" }
141 static const struct addrinfo default_hints =
143 .ai_flags = AI_DEFAULT,
144 .ai_family = PF_UNSPEC,
145 .ai_socktype = 0,
146 .ai_protocol = 0,
147 .ai_addrlen = 0,
148 .ai_addr = NULL,
149 .ai_canonname = NULL,
150 .ai_next = NULL
154 static int
155 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
156 const struct addrinfo *req, struct gaih_servtuple *st,
157 struct scratch_buffer *tmpbuf)
159 struct servent *s;
160 struct servent ts;
161 int r;
165 r = __getservbyname_r (servicename, tp->name, &ts,
166 tmpbuf->data, tmpbuf->length, &s);
167 if (r != 0 || s == NULL)
169 if (r == ERANGE)
171 if (!scratch_buffer_grow (tmpbuf))
172 return -EAI_MEMORY;
174 else
175 return -EAI_SERVICE;
178 while (r);
180 st->next = NULL;
181 st->socktype = tp->socktype;
182 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
183 ? req->ai_protocol : tp->protocol);
184 st->port = s->s_port;
186 return 0;
189 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
190 h_name is not copied, and the struct hostent object must not be
191 deallocated prematurely. *RESULT must be NULL or a pointer to a
192 linked-list. The new addresses are appended at the end. */
193 static bool
194 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
195 int family,
196 struct hostent *h,
197 struct gaih_addrtuple **result)
199 while (*result)
200 result = &(*result)->next;
202 /* Count the number of addresses in h->h_addr_list. */
203 size_t count = 0;
204 for (char **p = h->h_addr_list; *p != NULL; ++p)
205 ++count;
207 /* Report no data if no addresses are available, or if the incoming
208 address size is larger than what we can store. */
209 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
210 return true;
212 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
213 if (array == NULL)
214 return false;
216 for (size_t i = 0; i < count; ++i)
218 if (family == AF_INET && req->ai_family == AF_INET6)
220 /* Perform address mapping. */
221 array[i].family = AF_INET6;
222 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
223 array[i].addr[2] = htonl (0xffff);
225 else
227 array[i].family = family;
228 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
230 array[i].next = array + i + 1;
232 array[0].name = h->h_name;
233 array[count - 1].next = NULL;
235 *result = array;
236 return true;
239 #define gethosts(_family, _type) \
241 struct hostent th; \
242 char *localcanon = NULL; \
243 no_data = 0; \
244 while (1) \
246 status = DL_CALL_FCT (fct, (name, _family, &th, \
247 tmpbuf->data, tmpbuf->length, \
248 &errno, &h_errno, NULL, &localcanon)); \
249 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
250 || errno != ERANGE) \
251 break; \
252 if (!scratch_buffer_grow (tmpbuf)) \
254 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
255 __resolv_context_put (res_ctx); \
256 result = -EAI_MEMORY; \
257 goto free_and_return; \
260 if (status == NSS_STATUS_NOTFOUND \
261 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
263 if (h_errno == NETDB_INTERNAL) \
265 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
266 __resolv_context_put (res_ctx); \
267 result = -EAI_SYSTEM; \
268 goto free_and_return; \
270 if (h_errno == TRY_AGAIN) \
271 no_data = EAI_AGAIN; \
272 else \
273 no_data = h_errno == NO_DATA; \
275 else if (status == NSS_STATUS_SUCCESS) \
277 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
279 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
280 __resolv_context_put (res_ctx); \
281 result = -EAI_SYSTEM; \
282 goto free_and_return; \
284 *pat = addrmem; \
286 if (localcanon != NULL && canon == NULL) \
288 canonbuf = __strdup (localcanon); \
289 if (canonbuf == NULL) \
291 result = -EAI_SYSTEM; \
292 goto free_and_return; \
294 canon = canonbuf; \
296 if (_family == AF_INET6 && *pat != NULL) \
297 got_ipv6 = true; \
302 typedef enum nss_status (*nss_gethostbyname4_r)
303 (const char *name, struct gaih_addrtuple **pat,
304 char *buffer, size_t buflen, int *errnop,
305 int *h_errnop, int32_t *ttlp);
306 typedef enum nss_status (*nss_gethostbyname3_r)
307 (const char *name, int af, struct hostent *host,
308 char *buffer, size_t buflen, int *errnop,
309 int *h_errnop, int32_t *ttlp, char **canonp);
310 typedef enum nss_status (*nss_getcanonname_r)
311 (const char *name, char *buffer, size_t buflen, char **result,
312 int *errnop, int *h_errnop);
314 /* This function is called if a canonical name is requested, but if
315 the service function did not provide it. It tries to obtain the
316 name using getcanonname_r from the same service NIP. If the name
317 cannot be canonicalized, return a copy of NAME. Return NULL on
318 memory allocation failure. The returned string is allocated on the
319 heap; the caller has to free it. */
320 static char *
321 getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name)
323 nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r");
324 char *s = (char *) name;
325 if (cfct != NULL)
327 char buf[256];
328 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
329 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
330 /* If the canonical name cannot be determined, use the passed
331 string. */
332 s = (char *) name;
334 return __strdup (name);
337 static int
338 gaih_inet (const char *name, const struct gaih_service *service,
339 const struct addrinfo *req, struct addrinfo **pai,
340 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
342 const struct gaih_typeproto *tp = gaih_inet_typeproto;
343 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
344 struct gaih_addrtuple *at = NULL;
345 bool got_ipv6 = false;
346 const char *canon = NULL;
347 const char *orig_name = name;
349 /* Reserve stack memory for the scratch buffer in the getaddrinfo
350 function. */
351 size_t alloca_used = sizeof (struct scratch_buffer);
353 if (req->ai_protocol || req->ai_socktype)
355 ++tp;
357 while (tp->name[0]
358 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
359 || (req->ai_protocol != 0
360 && !(tp->protoflag & GAI_PROTO_PROTOANY)
361 && req->ai_protocol != tp->protocol)))
362 ++tp;
364 if (! tp->name[0])
366 if (req->ai_socktype)
367 return -EAI_SOCKTYPE;
368 else
369 return -EAI_SERVICE;
373 int port = 0;
374 if (service != NULL)
376 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
377 return -EAI_SERVICE;
379 if (service->num < 0)
381 if (tp->name[0])
383 st = (struct gaih_servtuple *)
384 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
386 int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
387 if (__glibc_unlikely (rc != 0))
388 return rc;
390 else
392 struct gaih_servtuple **pst = &st;
393 for (tp++; tp->name[0]; tp++)
395 struct gaih_servtuple *newp;
397 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
398 continue;
400 if (req->ai_socktype != 0
401 && req->ai_socktype != tp->socktype)
402 continue;
403 if (req->ai_protocol != 0
404 && !(tp->protoflag & GAI_PROTO_PROTOANY)
405 && req->ai_protocol != tp->protocol)
406 continue;
408 newp = (struct gaih_servtuple *)
409 alloca_account (sizeof (struct gaih_servtuple),
410 alloca_used);
412 if (gaih_inet_serv (service->name,
413 tp, req, newp, tmpbuf) != 0)
414 continue;
416 *pst = newp;
417 pst = &(newp->next);
419 if (st == (struct gaih_servtuple *) &nullserv)
420 return -EAI_SERVICE;
423 else
425 port = htons (service->num);
426 goto got_port;
429 else
431 got_port:
433 if (req->ai_socktype || req->ai_protocol)
435 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
436 st->next = NULL;
437 st->socktype = tp->socktype;
438 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
439 ? req->ai_protocol : tp->protocol);
440 st->port = port;
442 else
444 /* Neither socket type nor protocol is set. Return all socket types
445 we know about. */
446 struct gaih_servtuple **lastp = &st;
447 for (++tp; tp->name[0]; ++tp)
448 if (tp->defaultflag)
450 struct gaih_servtuple *newp;
452 newp = alloca_account (sizeof (struct gaih_servtuple),
453 alloca_used);
454 newp->next = NULL;
455 newp->socktype = tp->socktype;
456 newp->protocol = tp->protocol;
457 newp->port = port;
459 *lastp = newp;
460 lastp = &newp->next;
465 bool malloc_name = false;
466 struct gaih_addrtuple *addrmem = NULL;
467 char *canonbuf = NULL;
468 int result = 0;
470 if (name != NULL)
472 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
473 at->family = AF_UNSPEC;
474 at->scopeid = 0;
475 at->next = NULL;
477 #ifdef HAVE_LIBIDN
478 if (req->ai_flags & AI_IDN)
480 int idn_flags = 0;
481 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
482 idn_flags |= IDNA_ALLOW_UNASSIGNED;
483 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
484 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
486 char *p = NULL;
487 int rc = __idna_to_ascii_lz (name, &p, idn_flags);
488 if (rc != IDNA_SUCCESS)
490 /* No need to jump to free_and_return here. */
491 if (rc == IDNA_MALLOC_ERROR)
492 return -EAI_MEMORY;
493 if (rc == IDNA_DLOPEN_ERROR)
494 return -EAI_SYSTEM;
495 return -EAI_IDN_ENCODE;
497 /* In case the output string is the same as the input string
498 no new string has been allocated. */
499 if (p != name)
501 name = p;
502 malloc_name = true;
505 #endif
507 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
509 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
510 at->family = AF_INET;
511 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
513 at->addr[3] = at->addr[0];
514 at->addr[2] = htonl (0xffff);
515 at->addr[1] = 0;
516 at->addr[0] = 0;
517 at->family = AF_INET6;
519 else
521 result = -EAI_ADDRFAMILY;
522 goto free_and_return;
525 if (req->ai_flags & AI_CANONNAME)
526 canon = name;
528 else if (at->family == AF_UNSPEC)
530 char *scope_delim = strchr (name, SCOPE_DELIMITER);
531 int e;
532 if (scope_delim == NULL)
533 e = inet_pton (AF_INET6, name, at->addr);
534 else
535 e = __inet_pton_length (AF_INET6, name, scope_delim - name,
536 at->addr);
537 if (e > 0)
539 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
540 at->family = AF_INET6;
541 else if (req->ai_family == AF_INET
542 && IN6_IS_ADDR_V4MAPPED (at->addr))
544 at->addr[0] = at->addr[3];
545 at->family = AF_INET;
547 else
549 result = -EAI_ADDRFAMILY;
550 goto free_and_return;
553 if (scope_delim != NULL
554 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
555 scope_delim + 1,
556 &at->scopeid) != 0)
558 result = -EAI_NONAME;
559 goto free_and_return;
562 if (req->ai_flags & AI_CANONNAME)
563 canon = name;
567 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
569 struct gaih_addrtuple **pat = &at;
570 int no_data = 0;
571 int no_inet6_data = 0;
572 service_user *nip;
573 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
574 enum nss_status status = NSS_STATUS_UNAVAIL;
575 int no_more;
576 struct resolv_context *res_ctx = NULL;
577 bool res_enable_inet6 = false;
579 /* If we do not have to look for IPv6 addresses or the canonical
580 name, use the simple, old functions, which do not support
581 IPv6 scope ids, nor retrieving the canonical name. */
582 if (req->ai_family == AF_INET
583 && (req->ai_flags & AI_CANONNAME) == 0)
585 int rc;
586 struct hostent th;
587 struct hostent *h;
589 while (1)
591 rc = __gethostbyname2_r (name, AF_INET, &th,
592 tmpbuf->data, tmpbuf->length,
593 &h, &h_errno);
594 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
595 break;
596 if (!scratch_buffer_grow (tmpbuf))
598 result = -EAI_MEMORY;
599 goto free_and_return;
603 if (rc == 0)
605 if (h != NULL)
607 /* We found data, convert it. */
608 if (!convert_hostent_to_gaih_addrtuple
609 (req, AF_INET, h, &addrmem))
611 result = -EAI_MEMORY;
612 goto free_and_return;
614 *pat = addrmem;
616 else
618 if (h_errno == NO_DATA)
619 result = -EAI_NODATA;
620 else
621 result = -EAI_NONAME;
622 goto free_and_return;
625 else
627 if (h_errno == NETDB_INTERNAL)
628 result = -EAI_SYSTEM;
629 else if (h_errno == TRY_AGAIN)
630 result = -EAI_AGAIN;
631 else
632 /* We made requests but they turned out no data.
633 The name is known, though. */
634 result = -EAI_NODATA;
636 goto free_and_return;
639 goto process_list;
642 #ifdef USE_NSCD
643 if (__nss_not_use_nscd_hosts > 0
644 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
645 __nss_not_use_nscd_hosts = 0;
647 if (!__nss_not_use_nscd_hosts
648 && !__nss_database_custom[NSS_DBSIDX_hosts])
650 /* Try to use nscd. */
651 struct nscd_ai_result *air = NULL;
652 int err = __nscd_getai (name, &air, &h_errno);
653 if (air != NULL)
655 /* Transform into gaih_addrtuple list. */
656 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
657 char *addrs = air->addrs;
659 addrmem = calloc (air->naddrs, sizeof (*addrmem));
660 if (addrmem == NULL)
662 result = -EAI_MEMORY;
663 goto free_and_return;
666 struct gaih_addrtuple *addrfree = addrmem;
667 for (int i = 0; i < air->naddrs; ++i)
669 socklen_t size = (air->family[i] == AF_INET
670 ? INADDRSZ : IN6ADDRSZ);
672 if (!((air->family[i] == AF_INET
673 && req->ai_family == AF_INET6
674 && (req->ai_flags & AI_V4MAPPED) != 0)
675 || req->ai_family == AF_UNSPEC
676 || air->family[i] == req->ai_family))
678 /* Skip over non-matching result. */
679 addrs += size;
680 continue;
683 if (*pat == NULL)
685 *pat = addrfree++;
686 (*pat)->scopeid = 0;
688 uint32_t *pataddr = (*pat)->addr;
689 (*pat)->next = NULL;
690 if (added_canon || air->canon == NULL)
691 (*pat)->name = NULL;
692 else if (canonbuf == NULL)
694 canonbuf = __strdup (air->canon);
695 if (canonbuf == NULL)
697 result = -EAI_MEMORY;
698 goto free_and_return;
700 canon = (*pat)->name = canonbuf;
703 if (air->family[i] == AF_INET
704 && req->ai_family == AF_INET6
705 && (req->ai_flags & AI_V4MAPPED))
707 (*pat)->family = AF_INET6;
708 pataddr[3] = *(uint32_t *) addrs;
709 pataddr[2] = htonl (0xffff);
710 pataddr[1] = 0;
711 pataddr[0] = 0;
712 pat = &((*pat)->next);
713 added_canon = true;
715 else if (req->ai_family == AF_UNSPEC
716 || air->family[i] == req->ai_family)
718 (*pat)->family = air->family[i];
719 memcpy (pataddr, addrs, size);
720 pat = &((*pat)->next);
721 added_canon = true;
722 if (air->family[i] == AF_INET6)
723 got_ipv6 = true;
725 addrs += size;
728 free (air);
730 if (at->family == AF_UNSPEC)
732 result = -EAI_NONAME;
733 goto free_and_return;
736 goto process_list;
738 else if (err == 0)
739 /* The database contains a negative entry. */
740 goto free_and_return;
741 else if (__nss_not_use_nscd_hosts == 0)
743 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
744 result = -EAI_MEMORY;
745 else if (h_errno == TRY_AGAIN)
746 result = -EAI_AGAIN;
747 else
748 result = -EAI_SYSTEM;
750 goto free_and_return;
753 #endif
755 if (__nss_hosts_database == NULL)
756 no_more = __nss_database_lookup ("hosts", NULL,
757 "dns [!UNAVAIL=return] files",
758 &__nss_hosts_database);
759 else
760 no_more = 0;
761 nip = __nss_hosts_database;
763 /* If we are looking for both IPv4 and IPv6 address we don't
764 want the lookup functions to automatically promote IPv4
765 addresses to IPv6 addresses, so we use the no_inet6
766 function variant. */
767 res_ctx = __resolv_context_get ();
768 res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx);
769 if (res_ctx == NULL)
770 no_more = 1;
772 while (!no_more)
774 no_data = 0;
775 nss_gethostbyname4_r fct4 = NULL;
777 /* gethostbyname4_r sends out parallel A and AAAA queries and
778 is thus only suitable for PF_UNSPEC. */
779 if (req->ai_family == PF_UNSPEC)
780 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
782 if (fct4 != NULL)
784 while (1)
786 status = DL_CALL_FCT (fct4, (name, pat,
787 tmpbuf->data, tmpbuf->length,
788 &errno, &h_errno,
789 NULL));
790 if (status == NSS_STATUS_SUCCESS)
791 break;
792 if (status != NSS_STATUS_TRYAGAIN
793 || errno != ERANGE || h_errno != NETDB_INTERNAL)
795 if (h_errno == TRY_AGAIN)
796 no_data = EAI_AGAIN;
797 else
798 no_data = h_errno == NO_DATA;
799 break;
802 if (!scratch_buffer_grow (tmpbuf))
804 __resolv_context_enable_inet6
805 (res_ctx, res_enable_inet6);
806 __resolv_context_put (res_ctx);
807 result = -EAI_MEMORY;
808 goto free_and_return;
812 if (status == NSS_STATUS_SUCCESS)
814 assert (!no_data);
815 no_data = 1;
817 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
818 canon = (*pat)->name;
820 while (*pat != NULL)
822 if ((*pat)->family == AF_INET
823 && req->ai_family == AF_INET6
824 && (req->ai_flags & AI_V4MAPPED) != 0)
826 uint32_t *pataddr = (*pat)->addr;
827 (*pat)->family = AF_INET6;
828 pataddr[3] = pataddr[0];
829 pataddr[2] = htonl (0xffff);
830 pataddr[1] = 0;
831 pataddr[0] = 0;
832 pat = &((*pat)->next);
833 no_data = 0;
835 else if (req->ai_family == AF_UNSPEC
836 || (*pat)->family == req->ai_family)
838 pat = &((*pat)->next);
840 no_data = 0;
841 if (req->ai_family == AF_INET6)
842 got_ipv6 = true;
844 else
845 *pat = ((*pat)->next);
849 no_inet6_data = no_data;
851 else
853 nss_gethostbyname3_r fct = NULL;
854 if (req->ai_flags & AI_CANONNAME)
855 /* No need to use this function if we do not look for
856 the canonical name. The function does not exist in
857 all NSS modules and therefore the lookup would
858 often fail. */
859 fct = __nss_lookup_function (nip, "gethostbyname3_r");
860 if (fct == NULL)
861 /* We are cheating here. The gethostbyname2_r
862 function does not have the same interface as
863 gethostbyname3_r but the extra arguments the
864 latter takes are added at the end. So the
865 gethostbyname2_r code will just ignore them. */
866 fct = __nss_lookup_function (nip, "gethostbyname2_r");
868 if (fct != NULL)
870 if (req->ai_family == AF_INET6
871 || req->ai_family == AF_UNSPEC)
873 gethosts (AF_INET6, struct in6_addr);
874 no_inet6_data = no_data;
875 inet6_status = status;
877 if (req->ai_family == AF_INET
878 || req->ai_family == AF_UNSPEC
879 || (req->ai_family == AF_INET6
880 && (req->ai_flags & AI_V4MAPPED)
881 /* Avoid generating the mapped addresses if we
882 know we are not going to need them. */
883 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
885 gethosts (AF_INET, struct in_addr);
887 if (req->ai_family == AF_INET)
889 no_inet6_data = no_data;
890 inet6_status = status;
894 /* If we found one address for AF_INET or AF_INET6,
895 don't continue the search. */
896 if (inet6_status == NSS_STATUS_SUCCESS
897 || status == NSS_STATUS_SUCCESS)
899 if ((req->ai_flags & AI_CANONNAME) != 0
900 && canon == NULL)
902 canonbuf = getcanonname (nip, at, name);
903 if (canonbuf == NULL)
905 __resolv_context_enable_inet6
906 (res_ctx, res_enable_inet6);
907 __resolv_context_put (res_ctx);
908 result = -EAI_MEMORY;
909 goto free_and_return;
911 canon = canonbuf;
913 status = NSS_STATUS_SUCCESS;
915 else
917 /* We can have different states for AF_INET and
918 AF_INET6. Try to find a useful one for both. */
919 if (inet6_status == NSS_STATUS_TRYAGAIN)
920 status = NSS_STATUS_TRYAGAIN;
921 else if (status == NSS_STATUS_UNAVAIL
922 && inet6_status != NSS_STATUS_UNAVAIL)
923 status = inet6_status;
926 else
928 /* Could not locate any of the lookup functions.
929 The NSS lookup code does not consistently set
930 errno, so we need to supply our own error
931 code here. The root cause could either be a
932 resource allocation failure, or a missing
933 service function in the DSO (so it should not
934 be listed in /etc/nsswitch.conf). Assume the
935 former, and return EBUSY. */
936 status = NSS_STATUS_UNAVAIL;
937 __set_h_errno (NETDB_INTERNAL);
938 __set_errno (EBUSY);
942 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
943 break;
945 if (nip->next == NULL)
946 no_more = -1;
947 else
948 nip = nip->next;
951 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6);
952 __resolv_context_put (res_ctx);
954 /* If we have a failure which sets errno, report it using
955 EAI_SYSTEM. */
956 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
957 && h_errno == NETDB_INTERNAL)
959 result = -EAI_SYSTEM;
960 goto free_and_return;
963 if (no_data != 0 && no_inet6_data != 0)
965 /* If both requests timed out report this. */
966 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
967 result = -EAI_AGAIN;
968 else
969 /* We made requests but they turned out no data. The name
970 is known, though. */
971 result = -EAI_NODATA;
973 goto free_and_return;
977 process_list:
978 if (at->family == AF_UNSPEC)
980 result = -EAI_NONAME;
981 goto free_and_return;
984 else
986 struct gaih_addrtuple *atr;
987 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
988 memset (at, '\0', sizeof (struct gaih_addrtuple));
990 if (req->ai_family == AF_UNSPEC)
992 at->next = __alloca (sizeof (struct gaih_addrtuple));
993 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
996 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
998 at->family = AF_INET6;
999 if ((req->ai_flags & AI_PASSIVE) == 0)
1000 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1001 atr = at->next;
1004 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1006 atr->family = AF_INET;
1007 if ((req->ai_flags & AI_PASSIVE) == 0)
1008 atr->addr[0] = htonl (INADDR_LOOPBACK);
1013 struct gaih_servtuple *st2;
1014 struct gaih_addrtuple *at2 = at;
1015 size_t socklen;
1016 sa_family_t family;
1019 buffer is the size of an unformatted IPv6 address in printable format.
1021 while (at2 != NULL)
1023 /* Only the first entry gets the canonical name. */
1024 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1026 if (canon == NULL)
1027 /* If the canonical name cannot be determined, use
1028 the passed in string. */
1029 canon = orig_name;
1031 #ifdef HAVE_LIBIDN
1032 if (req->ai_flags & AI_CANONIDN)
1034 int idn_flags = 0;
1035 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1036 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1037 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1038 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1040 char *out;
1041 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1042 if (rc != IDNA_SUCCESS)
1044 if (rc == IDNA_MALLOC_ERROR)
1045 result = -EAI_MEMORY;
1046 else if (rc == IDNA_DLOPEN_ERROR)
1047 result = -EAI_SYSTEM;
1048 else
1049 result = -EAI_IDN_ENCODE;
1050 goto free_and_return;
1052 /* In case the output string is the same as the input
1053 string no new string has been allocated and we
1054 make a copy. */
1055 if (out == canon)
1056 goto make_copy;
1057 canon = out;
1059 else
1060 #endif
1062 #ifdef HAVE_LIBIDN
1063 make_copy:
1064 #endif
1065 if (canonbuf != NULL)
1066 /* We already allocated the string using malloc, but
1067 the buffer is now owned by canon. */
1068 canonbuf = NULL;
1069 else
1071 canon = __strdup (canon);
1072 if (canon == NULL)
1074 result = -EAI_MEMORY;
1075 goto free_and_return;
1081 family = at2->family;
1082 if (family == AF_INET6)
1084 socklen = sizeof (struct sockaddr_in6);
1086 /* If we looked up IPv4 mapped address discard them here if
1087 the caller isn't interested in all address and we have
1088 found at least one IPv6 address. */
1089 if (got_ipv6
1090 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1091 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1092 goto ignore;
1094 else
1095 socklen = sizeof (struct sockaddr_in);
1097 for (st2 = st; st2 != NULL; st2 = st2->next)
1099 struct addrinfo *ai;
1100 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1101 if (ai == NULL)
1103 free ((char *) canon);
1104 result = -EAI_MEMORY;
1105 goto free_and_return;
1108 ai->ai_flags = req->ai_flags;
1109 ai->ai_family = family;
1110 ai->ai_socktype = st2->socktype;
1111 ai->ai_protocol = st2->protocol;
1112 ai->ai_addrlen = socklen;
1113 ai->ai_addr = (void *) (ai + 1);
1115 /* We only add the canonical name once. */
1116 ai->ai_canonname = (char *) canon;
1117 canon = NULL;
1119 #ifdef _HAVE_SA_LEN
1120 ai->ai_addr->sa_len = socklen;
1121 #endif /* _HAVE_SA_LEN */
1122 ai->ai_addr->sa_family = family;
1124 /* In case of an allocation error the list must be NULL
1125 terminated. */
1126 ai->ai_next = NULL;
1128 if (family == AF_INET6)
1130 struct sockaddr_in6 *sin6p =
1131 (struct sockaddr_in6 *) ai->ai_addr;
1133 sin6p->sin6_port = st2->port;
1134 sin6p->sin6_flowinfo = 0;
1135 memcpy (&sin6p->sin6_addr,
1136 at2->addr, sizeof (struct in6_addr));
1137 sin6p->sin6_scope_id = at2->scopeid;
1139 else
1141 struct sockaddr_in *sinp =
1142 (struct sockaddr_in *) ai->ai_addr;
1143 sinp->sin_port = st2->port;
1144 memcpy (&sinp->sin_addr,
1145 at2->addr, sizeof (struct in_addr));
1146 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1149 pai = &(ai->ai_next);
1152 ++*naddrs;
1154 ignore:
1155 at2 = at2->next;
1159 free_and_return:
1160 if (malloc_name)
1161 free ((char *) name);
1162 free (addrmem);
1163 free (canonbuf);
1165 return result;
1169 struct sort_result
1171 struct addrinfo *dest_addr;
1172 /* Using sockaddr_storage is for now overkill. We only support IPv4
1173 and IPv6 so far. If this changes at some point we can adjust the
1174 type here. */
1175 struct sockaddr_in6 source_addr;
1176 uint8_t source_addr_len;
1177 bool got_source_addr;
1178 uint8_t source_addr_flags;
1179 uint8_t prefixlen;
1180 uint32_t index;
1181 int32_t native;
1184 struct sort_result_combo
1186 struct sort_result *results;
1187 int nresults;
1191 #if __BYTE_ORDER == __BIG_ENDIAN
1192 # define htonl_c(n) n
1193 #else
1194 # define htonl_c(n) __bswap_constant_32 (n)
1195 #endif
1197 static const struct scopeentry
1199 union
1201 char addr[4];
1202 uint32_t addr32;
1204 uint32_t netmask;
1205 int32_t scope;
1206 } default_scopes[] =
1208 /* Link-local addresses: scope 2. */
1209 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1210 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1211 /* Default: scope 14. */
1212 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1215 /* The label table. */
1216 static const struct scopeentry *scopes;
1219 static int
1220 get_scope (const struct sockaddr_in6 *in6)
1222 int scope;
1223 if (in6->sin6_family == PF_INET6)
1225 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1227 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1228 /* RFC 4291 2.5.3 says that the loopback address is to be
1229 treated like a link-local address. */
1230 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1231 scope = 2;
1232 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1233 scope = 5;
1234 else
1235 /* XXX Is this the correct default behavior? */
1236 scope = 14;
1238 else
1239 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1241 else if (in6->sin6_family == PF_INET)
1243 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1245 size_t cnt = 0;
1246 while (1)
1248 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1249 == scopes[cnt].addr32)
1250 return scopes[cnt].scope;
1252 ++cnt;
1254 /* NOTREACHED */
1256 else
1257 /* XXX What is a good default? */
1258 scope = 15;
1260 return scope;
1264 struct prefixentry
1266 struct in6_addr prefix;
1267 unsigned int bits;
1268 int val;
1272 /* The label table. */
1273 static const struct prefixentry *labels;
1275 /* Default labels. */
1276 static const struct prefixentry default_labels[] =
1278 /* See RFC 3484 for the details. */
1279 { { .__in6_u
1280 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1282 }, 128, 0 },
1283 { { .__in6_u
1284 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1286 }, 16, 2 },
1287 { { .__in6_u
1288 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1290 }, 96, 3 },
1291 { { .__in6_u
1292 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1294 }, 96, 4 },
1295 /* The next two entries differ from RFC 3484. We need to treat
1296 IPv6 site-local addresses special because they are never NATed,
1297 unlike site-locale IPv4 addresses. If this would not happen, on
1298 machines which have only IPv4 and IPv6 site-local addresses, the
1299 sorting would prefer the IPv6 site-local addresses, causing
1300 unnecessary delays when trying to connect to a global IPv6 address
1301 through a site-local IPv6 address. */
1302 { { .__in6_u
1303 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1305 }, 10, 5 },
1306 { { .__in6_u
1307 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1309 }, 7, 6 },
1310 /* Additional rule for Teredo tunnels. */
1311 { { .__in6_u
1312 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1314 }, 32, 7 },
1315 { { .__in6_u
1316 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1318 }, 0, 1 }
1322 /* The precedence table. */
1323 static const struct prefixentry *precedence;
1325 /* The default precedences. */
1326 static const struct prefixentry default_precedence[] =
1328 /* See RFC 3484 for the details. */
1329 { { .__in6_u
1330 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1332 }, 128, 50 },
1333 { { .__in6_u
1334 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1336 }, 16, 30 },
1337 { { .__in6_u
1338 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1340 }, 96, 20 },
1341 { { .__in6_u
1342 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1343 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1344 }, 96, 10 },
1345 { { .__in6_u
1346 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1348 }, 0, 40 }
1352 static int
1353 match_prefix (const struct sockaddr_in6 *in6,
1354 const struct prefixentry *list, int default_val)
1356 int idx;
1357 struct sockaddr_in6 in6_mem;
1359 if (in6->sin6_family == PF_INET)
1361 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1363 /* Construct a V4-to-6 mapped address. */
1364 in6_mem.sin6_family = PF_INET6;
1365 in6_mem.sin6_port = in->sin_port;
1366 in6_mem.sin6_flowinfo = 0;
1367 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1368 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1369 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1370 in6_mem.sin6_scope_id = 0;
1372 in6 = &in6_mem;
1374 else if (in6->sin6_family != PF_INET6)
1375 return default_val;
1377 for (idx = 0; ; ++idx)
1379 unsigned int bits = list[idx].bits;
1380 const uint8_t *mask = list[idx].prefix.s6_addr;
1381 const uint8_t *val = in6->sin6_addr.s6_addr;
1383 while (bits >= 8)
1385 if (*mask != *val)
1386 break;
1388 ++mask;
1389 ++val;
1390 bits -= 8;
1393 if (bits < 8)
1395 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1396 /* Match! */
1397 break;
1401 return list[idx].val;
1405 static int
1406 get_label (const struct sockaddr_in6 *in6)
1408 /* XXX What is a good default value? */
1409 return match_prefix (in6, labels, INT_MAX);
1413 static int
1414 get_precedence (const struct sockaddr_in6 *in6)
1416 /* XXX What is a good default value? */
1417 return match_prefix (in6, precedence, 0);
1421 /* Find last bit set in a word. */
1422 static int
1423 fls (uint32_t a)
1425 uint32_t mask;
1426 int n;
1427 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1428 if ((a & mask) != 0)
1429 break;
1430 return n;
1434 static int
1435 rfc3484_sort (const void *p1, const void *p2, void *arg)
1437 const size_t idx1 = *(const size_t *) p1;
1438 const size_t idx2 = *(const size_t *) p2;
1439 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1440 struct sort_result *a1 = &src->results[idx1];
1441 struct sort_result *a2 = &src->results[idx2];
1443 /* Rule 1: Avoid unusable destinations.
1444 We have the got_source_addr flag set if the destination is reachable. */
1445 if (a1->got_source_addr && ! a2->got_source_addr)
1446 return -1;
1447 if (! a1->got_source_addr && a2->got_source_addr)
1448 return 1;
1451 /* Rule 2: Prefer matching scope. Only interesting if both
1452 destination addresses are IPv6. */
1453 int a1_dst_scope
1454 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1456 int a2_dst_scope
1457 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1459 if (a1->got_source_addr)
1461 int a1_src_scope = get_scope (&a1->source_addr);
1462 int a2_src_scope = get_scope (&a2->source_addr);
1464 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1465 return -1;
1466 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1467 return 1;
1471 /* Rule 3: Avoid deprecated addresses. */
1472 if (a1->got_source_addr)
1474 if (!(a1->source_addr_flags & in6ai_deprecated)
1475 && (a2->source_addr_flags & in6ai_deprecated))
1476 return -1;
1477 if ((a1->source_addr_flags & in6ai_deprecated)
1478 && !(a2->source_addr_flags & in6ai_deprecated))
1479 return 1;
1482 /* Rule 4: Prefer home addresses. */
1483 if (a1->got_source_addr)
1485 if (!(a1->source_addr_flags & in6ai_homeaddress)
1486 && (a2->source_addr_flags & in6ai_homeaddress))
1487 return 1;
1488 if ((a1->source_addr_flags & in6ai_homeaddress)
1489 && !(a2->source_addr_flags & in6ai_homeaddress))
1490 return -1;
1493 /* Rule 5: Prefer matching label. */
1494 if (a1->got_source_addr)
1496 int a1_dst_label
1497 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1498 int a1_src_label = get_label (&a1->source_addr);
1500 int a2_dst_label
1501 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1502 int a2_src_label = get_label (&a2->source_addr);
1504 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1505 return -1;
1506 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1507 return 1;
1511 /* Rule 6: Prefer higher precedence. */
1512 int a1_prec
1513 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1514 int a2_prec
1515 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1517 if (a1_prec > a2_prec)
1518 return -1;
1519 if (a1_prec < a2_prec)
1520 return 1;
1523 /* Rule 7: Prefer native transport. */
1524 if (a1->got_source_addr)
1526 /* The same interface index means the same interface which means
1527 there is no difference in transport. This should catch many
1528 (most?) cases. */
1529 if (a1->index != a2->index)
1531 int a1_native = a1->native;
1532 int a2_native = a2->native;
1534 if (a1_native == -1 || a2_native == -1)
1536 uint32_t a1_index;
1537 if (a1_native == -1)
1539 /* If we do not have the information use 'native' as
1540 the default. */
1541 a1_native = 0;
1542 a1_index = a1->index;
1544 else
1545 a1_index = 0xffffffffu;
1547 uint32_t a2_index;
1548 if (a2_native == -1)
1550 /* If we do not have the information use 'native' as
1551 the default. */
1552 a2_native = 0;
1553 a2_index = a2->index;
1555 else
1556 a2_index = 0xffffffffu;
1558 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1560 /* Fill in the results in all the records. */
1561 for (int i = 0; i < src->nresults; ++i)
1562 if (a1_index != -1 && src->results[i].index == a1_index)
1564 assert (src->results[i].native == -1
1565 || src->results[i].native == a1_native);
1566 src->results[i].native = a1_native;
1568 else if (a2_index != -1 && src->results[i].index == a2_index)
1570 assert (src->results[i].native == -1
1571 || src->results[i].native == a2_native);
1572 src->results[i].native = a2_native;
1576 if (a1_native && !a2_native)
1577 return -1;
1578 if (!a1_native && a2_native)
1579 return 1;
1584 /* Rule 8: Prefer smaller scope. */
1585 if (a1_dst_scope < a2_dst_scope)
1586 return -1;
1587 if (a1_dst_scope > a2_dst_scope)
1588 return 1;
1591 /* Rule 9: Use longest matching prefix. */
1592 if (a1->got_source_addr
1593 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1595 int bit1 = 0;
1596 int bit2 = 0;
1598 if (a1->dest_addr->ai_family == PF_INET)
1600 assert (a1->source_addr.sin6_family == PF_INET);
1601 assert (a2->source_addr.sin6_family == PF_INET);
1603 /* Outside of subnets, as defined by the network masks,
1604 common address prefixes for IPv4 addresses make no sense.
1605 So, define a non-zero value only if source and
1606 destination address are on the same subnet. */
1607 struct sockaddr_in *in1_dst
1608 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1609 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1610 struct sockaddr_in *in1_src
1611 = (struct sockaddr_in *) &a1->source_addr;
1612 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1613 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1615 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1616 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1618 struct sockaddr_in *in2_dst
1619 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1620 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1621 struct sockaddr_in *in2_src
1622 = (struct sockaddr_in *) &a2->source_addr;
1623 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1624 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1626 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1627 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1629 else if (a1->dest_addr->ai_family == PF_INET6)
1631 assert (a1->source_addr.sin6_family == PF_INET6);
1632 assert (a2->source_addr.sin6_family == PF_INET6);
1634 struct sockaddr_in6 *in1_dst;
1635 struct sockaddr_in6 *in1_src;
1636 struct sockaddr_in6 *in2_dst;
1637 struct sockaddr_in6 *in2_src;
1639 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1640 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1641 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1642 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1644 int i;
1645 for (i = 0; i < 4; ++i)
1646 if (in1_dst->sin6_addr.s6_addr32[i]
1647 != in1_src->sin6_addr.s6_addr32[i]
1648 || (in2_dst->sin6_addr.s6_addr32[i]
1649 != in2_src->sin6_addr.s6_addr32[i]))
1650 break;
1652 if (i < 4)
1654 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1655 ^ in1_src->sin6_addr.s6_addr32[i]));
1656 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1657 ^ in2_src->sin6_addr.s6_addr32[i]));
1661 if (bit1 > bit2)
1662 return -1;
1663 if (bit1 < bit2)
1664 return 1;
1668 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1669 compare with the value indicating the order in which the entries
1670 have been received from the services. NB: no two entries can have
1671 the same order so the test will never return zero. */
1672 return idx1 < idx2 ? -1 : 1;
1676 static int
1677 in6aicmp (const void *p1, const void *p2)
1679 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1680 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1682 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1686 /* Name of the config file for RFC 3484 sorting (for now). */
1687 #define GAICONF_FNAME "/etc/gai.conf"
1690 /* Non-zero if we are supposed to reload the config file automatically
1691 whenever it changed. */
1692 static int gaiconf_reload_flag;
1694 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1695 static int gaiconf_reload_flag_ever_set;
1697 /* Last modification time. */
1698 #ifdef _STATBUF_ST_NSEC
1700 static struct timespec gaiconf_mtime;
1702 static inline void
1703 save_gaiconf_mtime (const struct stat64 *st)
1705 gaiconf_mtime = st->st_mtim;
1708 static inline bool
1709 check_gaiconf_mtime (const struct stat64 *st)
1711 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1712 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1715 #else
1717 static time_t gaiconf_mtime;
1719 static inline void
1720 save_gaiconf_mtime (const struct stat64 *st)
1722 gaiconf_mtime = st->st_mtime;
1725 static inline bool
1726 check_gaiconf_mtime (const struct stat64 *st)
1728 return st->st_mtime == gaiconf_mtime;
1731 #endif
1734 libc_freeres_fn(fini)
1736 if (labels != default_labels)
1738 const struct prefixentry *old = labels;
1739 labels = default_labels;
1740 free ((void *) old);
1743 if (precedence != default_precedence)
1745 const struct prefixentry *old = precedence;
1746 precedence = default_precedence;
1747 free ((void *) old);
1750 if (scopes != default_scopes)
1752 const struct scopeentry *old = scopes;
1753 scopes = default_scopes;
1754 free ((void *) old);
1759 struct prefixlist
1761 struct prefixentry entry;
1762 struct prefixlist *next;
1766 struct scopelist
1768 struct scopeentry entry;
1769 struct scopelist *next;
1773 static void
1774 free_prefixlist (struct prefixlist *list)
1776 while (list != NULL)
1778 struct prefixlist *oldp = list;
1779 list = list->next;
1780 free (oldp);
1785 static void
1786 free_scopelist (struct scopelist *list)
1788 while (list != NULL)
1790 struct scopelist *oldp = list;
1791 list = list->next;
1792 free (oldp);
1797 static int
1798 prefixcmp (const void *p1, const void *p2)
1800 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1801 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1803 if (e1->bits < e2->bits)
1804 return 1;
1805 if (e1->bits == e2->bits)
1806 return 0;
1807 return -1;
1811 static int
1812 scopecmp (const void *p1, const void *p2)
1814 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1815 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1817 if (e1->netmask > e2->netmask)
1818 return -1;
1819 if (e1->netmask == e2->netmask)
1820 return 0;
1821 return 1;
1825 static void
1826 gaiconf_init (void)
1828 struct prefixlist *labellist = NULL;
1829 size_t nlabellist = 0;
1830 bool labellist_nullbits = false;
1831 struct prefixlist *precedencelist = NULL;
1832 size_t nprecedencelist = 0;
1833 bool precedencelist_nullbits = false;
1834 struct scopelist *scopelist = NULL;
1835 size_t nscopelist = 0;
1836 bool scopelist_nullbits = false;
1838 FILE *fp = fopen (GAICONF_FNAME, "rce");
1839 if (fp != NULL)
1841 struct stat64 st;
1842 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1844 fclose (fp);
1845 goto no_file;
1848 char *line = NULL;
1849 size_t linelen = 0;
1851 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1853 while (!feof_unlocked (fp))
1855 ssize_t n = __getline (&line, &linelen, fp);
1856 if (n <= 0)
1857 break;
1859 /* Handle comments. No escaping possible so this is easy. */
1860 char *cp = strchr (line, '#');
1861 if (cp != NULL)
1862 *cp = '\0';
1864 cp = line;
1865 while (isspace (*cp))
1866 ++cp;
1868 char *cmd = cp;
1869 while (*cp != '\0' && !isspace (*cp))
1870 ++cp;
1871 size_t cmdlen = cp - cmd;
1873 if (*cp != '\0')
1874 *cp++ = '\0';
1875 while (isspace (*cp))
1876 ++cp;
1878 char *val1 = cp;
1879 while (*cp != '\0' && !isspace (*cp))
1880 ++cp;
1881 size_t val1len = cp - cmd;
1883 /* We always need at least two values. */
1884 if (val1len == 0)
1885 continue;
1887 if (*cp != '\0')
1888 *cp++ = '\0';
1889 while (isspace (*cp))
1890 ++cp;
1892 char *val2 = cp;
1893 while (*cp != '\0' && !isspace (*cp))
1894 ++cp;
1896 /* Ignore the rest of the line. */
1897 *cp = '\0';
1899 struct prefixlist **listp;
1900 size_t *lenp;
1901 bool *nullbitsp;
1902 switch (cmdlen)
1904 case 5:
1905 if (strcmp (cmd, "label") == 0)
1907 struct in6_addr prefix;
1908 unsigned long int bits;
1909 unsigned long int val;
1910 char *endp;
1912 listp = &labellist;
1913 lenp = &nlabellist;
1914 nullbitsp = &labellist_nullbits;
1916 new_elem:
1917 bits = 128;
1918 __set_errno (0);
1919 cp = strchr (val1, '/');
1920 if (cp != NULL)
1921 *cp++ = '\0';
1922 if (inet_pton (AF_INET6, val1, &prefix)
1923 && (cp == NULL
1924 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1925 || errno != ERANGE)
1926 && *endp == '\0'
1927 && bits <= 128
1928 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1929 || errno != ERANGE)
1930 && *endp == '\0'
1931 && val <= INT_MAX)
1933 struct prefixlist *newp = malloc (sizeof (*newp));
1934 if (newp == NULL)
1936 free (line);
1937 fclose (fp);
1938 goto no_file;
1941 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1942 newp->entry.bits = bits;
1943 newp->entry.val = val;
1944 newp->next = *listp;
1945 *listp = newp;
1946 ++*lenp;
1947 *nullbitsp |= bits == 0;
1950 break;
1952 case 6:
1953 if (strcmp (cmd, "reload") == 0)
1955 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1956 if (gaiconf_reload_flag)
1957 gaiconf_reload_flag_ever_set = 1;
1959 break;
1961 case 7:
1962 if (strcmp (cmd, "scopev4") == 0)
1964 struct in6_addr prefix;
1965 unsigned long int bits;
1966 unsigned long int val;
1967 char *endp;
1969 bits = 32;
1970 __set_errno (0);
1971 cp = strchr (val1, '/');
1972 if (cp != NULL)
1973 *cp++ = '\0';
1974 if (inet_pton (AF_INET6, val1, &prefix))
1976 bits = 128;
1977 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1978 && (cp == NULL
1979 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1980 || errno != ERANGE)
1981 && *endp == '\0'
1982 && bits >= 96
1983 && bits <= 128
1984 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1985 || errno != ERANGE)
1986 && *endp == '\0'
1987 && val <= INT_MAX)
1989 struct scopelist *newp;
1990 new_scope:
1991 newp = malloc (sizeof (*newp));
1992 if (newp == NULL)
1994 free (line);
1995 fclose (fp);
1996 goto no_file;
1999 newp->entry.netmask = htonl (bits != 96
2000 ? (0xffffffff
2001 << (128 - bits))
2002 : 0);
2003 newp->entry.addr32 = (prefix.s6_addr32[3]
2004 & newp->entry.netmask);
2005 newp->entry.scope = val;
2006 newp->next = scopelist;
2007 scopelist = newp;
2008 ++nscopelist;
2009 scopelist_nullbits |= bits == 96;
2012 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2013 && (cp == NULL
2014 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2015 || errno != ERANGE)
2016 && *endp == '\0'
2017 && bits <= 32
2018 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2019 || errno != ERANGE)
2020 && *endp == '\0'
2021 && val <= INT_MAX)
2023 bits += 96;
2024 goto new_scope;
2027 break;
2029 case 10:
2030 if (strcmp (cmd, "precedence") == 0)
2032 listp = &precedencelist;
2033 lenp = &nprecedencelist;
2034 nullbitsp = &precedencelist_nullbits;
2035 goto new_elem;
2037 break;
2041 free (line);
2043 fclose (fp);
2045 /* Create the array for the labels. */
2046 struct prefixentry *new_labels;
2047 if (nlabellist > 0)
2049 if (!labellist_nullbits)
2050 ++nlabellist;
2051 new_labels = malloc (nlabellist * sizeof (*new_labels));
2052 if (new_labels == NULL)
2053 goto no_file;
2055 int i = nlabellist;
2056 if (!labellist_nullbits)
2058 --i;
2059 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2060 new_labels[i].bits = 0;
2061 new_labels[i].val = 1;
2064 struct prefixlist *l = labellist;
2065 while (i-- > 0)
2067 new_labels[i] = l->entry;
2068 l = l->next;
2070 free_prefixlist (labellist);
2072 /* Sort the entries so that the most specific ones are at
2073 the beginning. */
2074 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2076 else
2077 new_labels = (struct prefixentry *) default_labels;
2079 struct prefixentry *new_precedence;
2080 if (nprecedencelist > 0)
2082 if (!precedencelist_nullbits)
2083 ++nprecedencelist;
2084 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2085 if (new_precedence == NULL)
2087 if (new_labels != default_labels)
2088 free (new_labels);
2089 goto no_file;
2092 int i = nprecedencelist;
2093 if (!precedencelist_nullbits)
2095 --i;
2096 memset (&new_precedence[i].prefix, '\0',
2097 sizeof (struct in6_addr));
2098 new_precedence[i].bits = 0;
2099 new_precedence[i].val = 40;
2102 struct prefixlist *l = precedencelist;
2103 while (i-- > 0)
2105 new_precedence[i] = l->entry;
2106 l = l->next;
2108 free_prefixlist (precedencelist);
2110 /* Sort the entries so that the most specific ones are at
2111 the beginning. */
2112 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2113 prefixcmp);
2115 else
2116 new_precedence = (struct prefixentry *) default_precedence;
2118 struct scopeentry *new_scopes;
2119 if (nscopelist > 0)
2121 if (!scopelist_nullbits)
2122 ++nscopelist;
2123 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2124 if (new_scopes == NULL)
2126 if (new_labels != default_labels)
2127 free (new_labels);
2128 if (new_precedence != default_precedence)
2129 free (new_precedence);
2130 goto no_file;
2133 int i = nscopelist;
2134 if (!scopelist_nullbits)
2136 --i;
2137 new_scopes[i].addr32 = 0;
2138 new_scopes[i].netmask = 0;
2139 new_scopes[i].scope = 14;
2142 struct scopelist *l = scopelist;
2143 while (i-- > 0)
2145 new_scopes[i] = l->entry;
2146 l = l->next;
2148 free_scopelist (scopelist);
2150 /* Sort the entries so that the most specific ones are at
2151 the beginning. */
2152 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2153 scopecmp);
2155 else
2156 new_scopes = (struct scopeentry *) default_scopes;
2158 /* Now we are ready to replace the values. */
2159 const struct prefixentry *old = labels;
2160 labels = new_labels;
2161 if (old != default_labels)
2162 free ((void *) old);
2164 old = precedence;
2165 precedence = new_precedence;
2166 if (old != default_precedence)
2167 free ((void *) old);
2169 const struct scopeentry *oldscope = scopes;
2170 scopes = new_scopes;
2171 if (oldscope != default_scopes)
2172 free ((void *) oldscope);
2174 save_gaiconf_mtime (&st);
2176 else
2178 no_file:
2179 free_prefixlist (labellist);
2180 free_prefixlist (precedencelist);
2181 free_scopelist (scopelist);
2183 /* If we previously read the file but it is gone now, free the
2184 old data and use the builtin one. Leave the reload flag
2185 alone. */
2186 fini ();
2191 static void
2192 gaiconf_reload (void)
2194 struct stat64 st;
2195 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2196 || !check_gaiconf_mtime (&st))
2197 gaiconf_init ();
2202 getaddrinfo (const char *name, const char *service,
2203 const struct addrinfo *hints, struct addrinfo **pai)
2205 int i = 0, last_i = 0;
2206 int nresults = 0;
2207 struct addrinfo *p = NULL;
2208 struct gaih_service gaih_service, *pservice;
2209 struct addrinfo local_hints;
2211 if (name != NULL && name[0] == '*' && name[1] == 0)
2212 name = NULL;
2214 if (service != NULL && service[0] == '*' && service[1] == 0)
2215 service = NULL;
2217 if (name == NULL && service == NULL)
2218 return EAI_NONAME;
2220 if (hints == NULL)
2221 hints = &default_hints;
2223 if (hints->ai_flags
2224 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2225 #ifdef HAVE_LIBIDN
2226 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2227 |AI_IDN_USE_STD3_ASCII_RULES
2228 #endif
2229 |AI_NUMERICSERV|AI_ALL))
2230 return EAI_BADFLAGS;
2232 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2233 return EAI_BADFLAGS;
2235 struct in6addrinfo *in6ai = NULL;
2236 size_t in6ailen = 0;
2237 bool seen_ipv4 = false;
2238 bool seen_ipv6 = false;
2239 bool check_pf_called = false;
2241 if (hints->ai_flags & AI_ADDRCONFIG)
2243 /* We might need information about what interfaces are available.
2244 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2245 cannot cache the results since new interfaces could be added at
2246 any time. */
2247 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2248 check_pf_called = true;
2250 /* Now make a decision on what we return, if anything. */
2251 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2253 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2254 narrow down the search. */
2255 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2257 local_hints = *hints;
2258 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2259 hints = &local_hints;
2262 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2263 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2265 /* We cannot possibly return a valid answer. */
2266 __free_in6ai (in6ai);
2267 return EAI_NONAME;
2271 if (service && service[0])
2273 char *c;
2274 gaih_service.name = service;
2275 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2276 if (*c != '\0')
2278 if (hints->ai_flags & AI_NUMERICSERV)
2280 __free_in6ai (in6ai);
2281 return EAI_NONAME;
2284 gaih_service.num = -1;
2287 pservice = &gaih_service;
2289 else
2290 pservice = NULL;
2292 struct addrinfo **end = &p;
2294 unsigned int naddrs = 0;
2295 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2296 || hints->ai_family == AF_INET6)
2298 struct scratch_buffer tmpbuf;
2299 scratch_buffer_init (&tmpbuf);
2300 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2301 scratch_buffer_free (&tmpbuf);
2303 if (last_i != 0)
2305 freeaddrinfo (p);
2306 __free_in6ai (in6ai);
2308 return -last_i;
2310 while (*end)
2312 end = &((*end)->ai_next);
2313 ++nresults;
2316 else
2318 __free_in6ai (in6ai);
2319 return EAI_FAMILY;
2322 if (naddrs > 1)
2324 /* Read the config file. */
2325 __libc_once_define (static, once);
2326 __typeof (once) old_once = once;
2327 __libc_once (once, gaiconf_init);
2328 /* Sort results according to RFC 3484. */
2329 struct sort_result *results;
2330 size_t *order;
2331 struct addrinfo *q;
2332 struct addrinfo *last = NULL;
2333 char *canonname = NULL;
2334 bool malloc_results;
2335 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2337 malloc_results
2338 = !__libc_use_alloca (alloc_size);
2339 if (malloc_results)
2341 results = malloc (alloc_size);
2342 if (results == NULL)
2344 __free_in6ai (in6ai);
2345 return EAI_MEMORY;
2348 else
2349 results = alloca (alloc_size);
2350 order = (size_t *) (results + nresults);
2352 /* Now we definitely need the interface information. */
2353 if (! check_pf_called)
2354 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2356 /* If we have information about deprecated and temporary addresses
2357 sort the array now. */
2358 if (in6ai != NULL)
2359 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2361 int fd = -1;
2362 int af = AF_UNSPEC;
2364 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2366 results[i].dest_addr = q;
2367 results[i].native = -1;
2368 order[i] = i;
2370 /* If we just looked up the address for a different
2371 protocol, reuse the result. */
2372 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2373 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2375 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2376 results[i - 1].source_addr_len);
2377 results[i].source_addr_len = results[i - 1].source_addr_len;
2378 results[i].got_source_addr = results[i - 1].got_source_addr;
2379 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2380 results[i].prefixlen = results[i - 1].prefixlen;
2381 results[i].index = results[i - 1].index;
2383 else
2385 results[i].got_source_addr = false;
2386 results[i].source_addr_flags = 0;
2387 results[i].prefixlen = 0;
2388 results[i].index = 0xffffffffu;
2390 /* We overwrite the type with SOCK_DGRAM since we do not
2391 want connect() to connect to the other side. If we
2392 cannot determine the source address remember this
2393 fact. */
2394 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2396 if (fd != -1)
2397 close_retry:
2398 __close_nocancel_nostatus (fd);
2399 af = q->ai_family;
2400 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2402 else
2404 /* Reset the connection. */
2405 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2406 __connect (fd, &sa, sizeof (sa));
2409 socklen_t sl = sizeof (results[i].source_addr);
2410 if (fd != -1
2411 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2412 && __getsockname (fd,
2413 (struct sockaddr *) &results[i].source_addr,
2414 &sl) == 0)
2416 results[i].source_addr_len = sl;
2417 results[i].got_source_addr = true;
2419 if (in6ai != NULL)
2421 /* See whether the source address is on the list of
2422 deprecated or temporary addresses. */
2423 struct in6addrinfo tmp;
2425 if (q->ai_family == AF_INET && af == AF_INET)
2427 struct sockaddr_in *sinp
2428 = (struct sockaddr_in *) &results[i].source_addr;
2429 tmp.addr[0] = 0;
2430 tmp.addr[1] = 0;
2431 tmp.addr[2] = htonl (0xffff);
2432 /* Special case for lo interface, the source address
2433 being possibly different than the interface
2434 address. */
2435 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2436 == 0x7f000000)
2437 tmp.addr[3] = htonl(0x7f000001);
2438 else
2439 tmp.addr[3] = sinp->sin_addr.s_addr;
2441 else
2443 struct sockaddr_in6 *sin6p
2444 = (struct sockaddr_in6 *) &results[i].source_addr;
2445 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2448 struct in6addrinfo *found
2449 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2450 in6aicmp);
2451 if (found != NULL)
2453 results[i].source_addr_flags = found->flags;
2454 results[i].prefixlen = found->prefixlen;
2455 results[i].index = found->index;
2459 if (q->ai_family == AF_INET && af == AF_INET6)
2461 /* We have to convert the address. The socket is
2462 IPv6 and the request is for IPv4. */
2463 struct sockaddr_in6 *sin6
2464 = (struct sockaddr_in6 *) &results[i].source_addr;
2465 struct sockaddr_in *sin
2466 = (struct sockaddr_in *) &results[i].source_addr;
2467 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2468 sin->sin_family = AF_INET;
2469 /* We do not have to initialize sin_port since this
2470 fields has the same position and size in the IPv6
2471 structure. */
2472 assert (offsetof (struct sockaddr_in, sin_port)
2473 == offsetof (struct sockaddr_in6, sin6_port));
2474 assert (sizeof (sin->sin_port)
2475 == sizeof (sin6->sin6_port));
2476 memcpy (&sin->sin_addr,
2477 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2478 results[i].source_addr_len = sizeof (struct sockaddr_in);
2481 else if (errno == EAFNOSUPPORT && af == AF_INET6
2482 && q->ai_family == AF_INET)
2483 /* This could mean IPv6 sockets are IPv6-only. */
2484 goto close_retry;
2485 else
2486 /* Just make sure that if we have to process the same
2487 address again we do not copy any memory. */
2488 results[i].source_addr_len = 0;
2491 /* Remember the canonical name. */
2492 if (q->ai_canonname != NULL)
2494 assert (canonname == NULL);
2495 canonname = q->ai_canonname;
2496 q->ai_canonname = NULL;
2500 if (fd != -1)
2501 __close_nocancel_nostatus (fd);
2503 /* We got all the source addresses we can get, now sort using
2504 the information. */
2505 struct sort_result_combo src
2506 = { .results = results, .nresults = nresults };
2507 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2509 __libc_lock_define_initialized (static, lock);
2511 __libc_lock_lock (lock);
2512 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2513 gaiconf_reload ();
2514 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2515 __libc_lock_unlock (lock);
2517 else
2518 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2520 /* Queue the results up as they come out of sorting. */
2521 q = p = results[order[0]].dest_addr;
2522 for (i = 1; i < nresults; ++i)
2523 q = q->ai_next = results[order[i]].dest_addr;
2524 q->ai_next = NULL;
2526 /* Fill in the canonical name into the new first entry. */
2527 p->ai_canonname = canonname;
2529 if (malloc_results)
2530 free (results);
2533 __free_in6ai (in6ai);
2535 if (p)
2537 *pai = p;
2538 return 0;
2541 return last_i ? -last_i : EAI_NONAME;
2543 libc_hidden_def (getaddrinfo)
2545 nss_interface_function (getaddrinfo)
2547 void
2548 freeaddrinfo (struct addrinfo *ai)
2550 struct addrinfo *p;
2552 while (ai != NULL)
2554 p = ai;
2555 ai = ai->ai_next;
2556 free (p->ai_canonname);
2557 free (p);
2560 libc_hidden_def (freeaddrinfo)