getaddrinfo: Use &h_errno has the h_errno pointer
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob4edd5e2a1b4c87d619c2e661d2ec269a9bcaabba
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 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
90 extern int __idna_to_unicode_lzlz (const char *input, char **output,
91 int flags);
92 # include <libidn/idna.h>
93 #endif
95 struct gaih_service
97 const char *name;
98 int num;
101 struct gaih_servtuple
103 struct gaih_servtuple *next;
104 int socktype;
105 int protocol;
106 int port;
109 static const struct gaih_servtuple nullserv;
112 struct gaih_typeproto
114 int socktype;
115 int protocol;
116 uint8_t protoflag;
117 bool defaultflag;
118 char name[8];
121 /* Values for `protoflag'. */
122 #define GAI_PROTO_NOSERVICE 1
123 #define GAI_PROTO_PROTOANY 2
125 static const struct gaih_typeproto gaih_inet_typeproto[] =
127 { 0, 0, 0, false, "" },
128 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
129 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
130 #if defined SOCK_DCCP && defined IPPROTO_DCCP
131 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
132 #endif
133 #ifdef IPPROTO_UDPLITE
134 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
135 #endif
136 #ifdef IPPROTO_SCTP
137 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
138 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
139 #endif
140 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
141 { 0, 0, 0, false, "" }
144 static const struct addrinfo default_hints =
146 .ai_flags = AI_DEFAULT,
147 .ai_family = PF_UNSPEC,
148 .ai_socktype = 0,
149 .ai_protocol = 0,
150 .ai_addrlen = 0,
151 .ai_addr = NULL,
152 .ai_canonname = NULL,
153 .ai_next = NULL
157 static int
158 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
159 const struct addrinfo *req, struct gaih_servtuple *st,
160 struct scratch_buffer *tmpbuf)
162 struct servent *s;
163 struct servent ts;
164 int r;
168 r = __getservbyname_r (servicename, tp->name, &ts,
169 tmpbuf->data, tmpbuf->length, &s);
170 if (r != 0 || s == NULL)
172 if (r == ERANGE)
174 if (!scratch_buffer_grow (tmpbuf))
175 return -EAI_MEMORY;
177 else
178 return -EAI_SERVICE;
181 while (r);
183 st->next = NULL;
184 st->socktype = tp->socktype;
185 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
186 ? req->ai_protocol : tp->protocol);
187 st->port = s->s_port;
189 return 0;
192 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
193 h_name is not copied, and the struct hostent object must not be
194 deallocated prematurely. *RESULT must be NULL or a pointer to a
195 linked-list. The new addresses are appended at the end. */
196 static bool
197 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
198 int family,
199 struct hostent *h,
200 struct gaih_addrtuple **result)
202 while (*result)
203 result = &(*result)->next;
205 /* Count the number of addresses in h->h_addr_list. */
206 size_t count = 0;
207 for (char **p = h->h_addr_list; *p != NULL; ++p)
208 ++count;
210 /* Report no data if no addresses are available, or if the incoming
211 address size is larger than what we can store. */
212 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
213 return true;
215 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
216 if (array == NULL)
217 return false;
219 for (size_t i = 0; i < count; ++i)
221 if (family == AF_INET && req->ai_family == AF_INET6)
223 /* Perform address mapping. */
224 array[i].family = AF_INET6;
225 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
226 array[i].addr[2] = htonl (0xffff);
228 else
230 array[i].family = family;
231 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
233 array[i].next = array + i + 1;
235 array[0].name = h->h_name;
236 array[count - 1].next = NULL;
238 *result = array;
239 return true;
242 #define gethosts(_family, _type) \
244 struct hostent th; \
245 struct hostent *h; \
246 char *localcanon = NULL; \
247 no_data = 0; \
248 while (1) { \
249 status = DL_CALL_FCT (fct, (name, _family, &th, \
250 tmpbuf->data, tmpbuf->length, \
251 &errno, &h_errno, NULL, &localcanon)); \
252 if (errno != ERANGE || h_errno != NETDB_INTERNAL) \
253 break; \
254 if (!scratch_buffer_grow (tmpbuf)) \
256 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
257 __resolv_context_put (res_ctx); \
258 result = -EAI_MEMORY; \
259 goto free_and_return; \
262 if (status == NSS_STATUS_SUCCESS && errno == 0) \
263 h = &th; \
264 else \
265 h = NULL; \
266 if (errno != 0) \
268 if (h_errno == NETDB_INTERNAL) \
270 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
271 __resolv_context_put (res_ctx); \
272 result = -EAI_SYSTEM; \
273 goto free_and_return; \
275 if (h_errno == TRY_AGAIN) \
276 no_data = EAI_AGAIN; \
277 else \
278 no_data = h_errno == NO_DATA; \
280 else if (h != NULL) \
282 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
284 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
285 __resolv_context_put (res_ctx); \
286 result = -EAI_SYSTEM; \
287 goto free_and_return; \
289 *pat = addrmem; \
291 if (localcanon != NULL && canon == NULL) \
293 canonbuf = __strdup (localcanon); \
294 if (canonbuf == NULL) \
296 result = -EAI_SYSTEM; \
297 goto free_and_return; \
299 canon = canonbuf; \
301 if (_family == AF_INET6 && *pat != NULL) \
302 got_ipv6 = true; \
307 typedef enum nss_status (*nss_gethostbyname4_r)
308 (const char *name, struct gaih_addrtuple **pat,
309 char *buffer, size_t buflen, int *errnop,
310 int *h_errnop, int32_t *ttlp);
311 typedef enum nss_status (*nss_gethostbyname3_r)
312 (const char *name, int af, struct hostent *host,
313 char *buffer, size_t buflen, int *errnop,
314 int *h_errnop, int32_t *ttlp, char **canonp);
315 typedef enum nss_status (*nss_getcanonname_r)
316 (const char *name, char *buffer, size_t buflen, char **result,
317 int *errnop, int *h_errnop);
319 /* This function is called if a canonical name is requested, but if
320 the service function did not provide it. It tries to obtain the
321 name using getcanonname_r from the same service NIP. If the name
322 cannot be canonicalized, return a copy of NAME. Return NULL on
323 memory allocation failure. The returned string is allocated on the
324 heap; the caller has to free it. */
325 static char *
326 getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name)
328 nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r");
329 char *s = (char *) name;
330 if (cfct != NULL)
332 char buf[256];
333 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
334 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
335 /* If the canonical name cannot be determined, use the passed
336 string. */
337 s = (char *) name;
339 return __strdup (name);
342 static int
343 gaih_inet (const char *name, const struct gaih_service *service,
344 const struct addrinfo *req, struct addrinfo **pai,
345 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
347 const struct gaih_typeproto *tp = gaih_inet_typeproto;
348 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
349 struct gaih_addrtuple *at = NULL;
350 bool got_ipv6 = false;
351 const char *canon = NULL;
352 const char *orig_name = name;
354 /* Reserve stack memory for the scratch buffer in the getaddrinfo
355 function. */
356 size_t alloca_used = sizeof (struct scratch_buffer);
358 if (req->ai_protocol || req->ai_socktype)
360 ++tp;
362 while (tp->name[0]
363 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
364 || (req->ai_protocol != 0
365 && !(tp->protoflag & GAI_PROTO_PROTOANY)
366 && req->ai_protocol != tp->protocol)))
367 ++tp;
369 if (! tp->name[0])
371 if (req->ai_socktype)
372 return -EAI_SOCKTYPE;
373 else
374 return -EAI_SERVICE;
378 int port = 0;
379 if (service != NULL)
381 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
382 return -EAI_SERVICE;
384 if (service->num < 0)
386 if (tp->name[0])
388 st = (struct gaih_servtuple *)
389 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
391 int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
392 if (__glibc_unlikely (rc != 0))
393 return rc;
395 else
397 struct gaih_servtuple **pst = &st;
398 for (tp++; tp->name[0]; tp++)
400 struct gaih_servtuple *newp;
402 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
403 continue;
405 if (req->ai_socktype != 0
406 && req->ai_socktype != tp->socktype)
407 continue;
408 if (req->ai_protocol != 0
409 && !(tp->protoflag & GAI_PROTO_PROTOANY)
410 && req->ai_protocol != tp->protocol)
411 continue;
413 newp = (struct gaih_servtuple *)
414 alloca_account (sizeof (struct gaih_servtuple),
415 alloca_used);
417 if (gaih_inet_serv (service->name,
418 tp, req, newp, tmpbuf) != 0)
419 continue;
421 *pst = newp;
422 pst = &(newp->next);
424 if (st == (struct gaih_servtuple *) &nullserv)
425 return -EAI_SERVICE;
428 else
430 port = htons (service->num);
431 goto got_port;
434 else
436 got_port:
438 if (req->ai_socktype || req->ai_protocol)
440 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
441 st->next = NULL;
442 st->socktype = tp->socktype;
443 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
444 ? req->ai_protocol : tp->protocol);
445 st->port = port;
447 else
449 /* Neither socket type nor protocol is set. Return all socket types
450 we know about. */
451 struct gaih_servtuple **lastp = &st;
452 for (++tp; tp->name[0]; ++tp)
453 if (tp->defaultflag)
455 struct gaih_servtuple *newp;
457 newp = alloca_account (sizeof (struct gaih_servtuple),
458 alloca_used);
459 newp->next = NULL;
460 newp->socktype = tp->socktype;
461 newp->protocol = tp->protocol;
462 newp->port = port;
464 *lastp = newp;
465 lastp = &newp->next;
470 bool malloc_name = false;
471 struct gaih_addrtuple *addrmem = NULL;
472 char *canonbuf = NULL;
473 int result = 0;
475 if (name != NULL)
477 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
478 at->family = AF_UNSPEC;
479 at->scopeid = 0;
480 at->next = NULL;
482 #ifdef HAVE_LIBIDN
483 if (req->ai_flags & AI_IDN)
485 int idn_flags = 0;
486 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
487 idn_flags |= IDNA_ALLOW_UNASSIGNED;
488 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
489 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
491 char *p = NULL;
492 int rc = __idna_to_ascii_lz (name, &p, idn_flags);
493 if (rc != IDNA_SUCCESS)
495 /* No need to jump to free_and_return here. */
496 if (rc == IDNA_MALLOC_ERROR)
497 return -EAI_MEMORY;
498 if (rc == IDNA_DLOPEN_ERROR)
499 return -EAI_SYSTEM;
500 return -EAI_IDN_ENCODE;
502 /* In case the output string is the same as the input string
503 no new string has been allocated. */
504 if (p != name)
506 name = p;
507 malloc_name = true;
510 #endif
512 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
514 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
515 at->family = AF_INET;
516 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
518 at->addr[3] = at->addr[0];
519 at->addr[2] = htonl (0xffff);
520 at->addr[1] = 0;
521 at->addr[0] = 0;
522 at->family = AF_INET6;
524 else
526 result = -EAI_ADDRFAMILY;
527 goto free_and_return;
530 if (req->ai_flags & AI_CANONNAME)
531 canon = name;
533 else if (at->family == AF_UNSPEC)
535 char *scope_delim = strchr (name, SCOPE_DELIMITER);
536 int e;
537 if (scope_delim == NULL)
538 e = inet_pton (AF_INET6, name, at->addr);
539 else
540 e = __inet_pton_length (AF_INET6, name, scope_delim - name,
541 at->addr);
542 if (e > 0)
544 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
545 at->family = AF_INET6;
546 else if (req->ai_family == AF_INET
547 && IN6_IS_ADDR_V4MAPPED (at->addr))
549 at->addr[0] = at->addr[3];
550 at->family = AF_INET;
552 else
554 result = -EAI_ADDRFAMILY;
555 goto free_and_return;
558 if (scope_delim != NULL
559 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
560 scope_delim + 1,
561 &at->scopeid) != 0)
563 result = -EAI_NONAME;
564 goto free_and_return;
567 if (req->ai_flags & AI_CANONNAME)
568 canon = name;
572 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
574 struct gaih_addrtuple **pat = &at;
575 int no_data = 0;
576 int no_inet6_data = 0;
577 service_user *nip;
578 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
579 enum nss_status status = NSS_STATUS_UNAVAIL;
580 int no_more;
581 struct resolv_context *res_ctx = NULL;
582 bool res_enable_inet6 = false;
584 /* If we do not have to look for IPv6 addresses or the canonical
585 name, use the simple, old functions, which do not support
586 IPv6 scope ids, nor retrieving the canonical name. */
587 if (req->ai_family == AF_INET
588 && (req->ai_flags & AI_CANONNAME) == 0)
590 int rc;
591 struct hostent th;
592 struct hostent *h;
594 while (1)
596 rc = __gethostbyname2_r (name, AF_INET, &th,
597 tmpbuf->data, tmpbuf->length,
598 &h, &h_errno);
599 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
600 break;
601 if (!scratch_buffer_grow (tmpbuf))
603 result = -EAI_MEMORY;
604 goto free_and_return;
608 if (rc == 0)
610 if (h != NULL)
612 /* We found data, convert it. */
613 if (!convert_hostent_to_gaih_addrtuple
614 (req, AF_INET, h, &addrmem))
616 result = -EAI_MEMORY;
617 goto free_and_return;
619 *pat = addrmem;
622 else
624 if (h_errno == NETDB_INTERNAL)
625 result = -EAI_SYSTEM;
626 else if (h_errno == TRY_AGAIN)
627 result = -EAI_AGAIN;
628 else
629 /* We made requests but they turned out no data.
630 The name is known, though. */
631 result = -EAI_NODATA;
633 goto free_and_return;
636 goto process_list;
639 #ifdef USE_NSCD
640 if (__nss_not_use_nscd_hosts > 0
641 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
642 __nss_not_use_nscd_hosts = 0;
644 if (!__nss_not_use_nscd_hosts
645 && !__nss_database_custom[NSS_DBSIDX_hosts])
647 /* Try to use nscd. */
648 struct nscd_ai_result *air = NULL;
649 int err = __nscd_getai (name, &air, &h_errno);
650 if (air != NULL)
652 /* Transform into gaih_addrtuple list. */
653 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
654 char *addrs = air->addrs;
656 addrmem = calloc (air->naddrs, sizeof (*addrmem));
657 if (addrmem == NULL)
659 result = -EAI_MEMORY;
660 goto free_and_return;
663 struct gaih_addrtuple *addrfree = addrmem;
664 for (int i = 0; i < air->naddrs; ++i)
666 socklen_t size = (air->family[i] == AF_INET
667 ? INADDRSZ : IN6ADDRSZ);
669 if (!((air->family[i] == AF_INET
670 && req->ai_family == AF_INET6
671 && (req->ai_flags & AI_V4MAPPED) != 0)
672 || req->ai_family == AF_UNSPEC
673 || air->family[i] == req->ai_family))
675 /* Skip over non-matching result. */
676 addrs += size;
677 continue;
680 if (*pat == NULL)
682 *pat = addrfree++;
683 (*pat)->scopeid = 0;
685 uint32_t *pataddr = (*pat)->addr;
686 (*pat)->next = NULL;
687 if (added_canon || air->canon == NULL)
688 (*pat)->name = NULL;
689 else if (canonbuf == NULL)
691 canonbuf = __strdup (air->canon);
692 if (canonbuf == NULL)
694 result = -EAI_MEMORY;
695 goto free_and_return;
697 canon = (*pat)->name = canonbuf;
700 if (air->family[i] == AF_INET
701 && req->ai_family == AF_INET6
702 && (req->ai_flags & AI_V4MAPPED))
704 (*pat)->family = AF_INET6;
705 pataddr[3] = *(uint32_t *) addrs;
706 pataddr[2] = htonl (0xffff);
707 pataddr[1] = 0;
708 pataddr[0] = 0;
709 pat = &((*pat)->next);
710 added_canon = true;
712 else if (req->ai_family == AF_UNSPEC
713 || air->family[i] == req->ai_family)
715 (*pat)->family = air->family[i];
716 memcpy (pataddr, addrs, size);
717 pat = &((*pat)->next);
718 added_canon = true;
719 if (air->family[i] == AF_INET6)
720 got_ipv6 = true;
722 addrs += size;
725 free (air);
727 if (at->family == AF_UNSPEC)
729 result = -EAI_NONAME;
730 goto free_and_return;
733 goto process_list;
735 else if (err == 0)
736 /* The database contains a negative entry. */
737 goto free_and_return;
738 else if (__nss_not_use_nscd_hosts == 0)
740 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
741 result = -EAI_MEMORY;
742 else if (h_errno == TRY_AGAIN)
743 result = -EAI_AGAIN;
744 else
745 result = -EAI_SYSTEM;
747 goto free_and_return;
750 #endif
752 if (__nss_hosts_database == NULL)
753 no_more = __nss_database_lookup ("hosts", NULL,
754 "dns [!UNAVAIL=return] files",
755 &__nss_hosts_database);
756 else
757 no_more = 0;
758 nip = __nss_hosts_database;
760 /* If we are looking for both IPv4 and IPv6 address we don't
761 want the lookup functions to automatically promote IPv4
762 addresses to IPv6 addresses, so we use the no_inet6
763 function variant. */
764 res_ctx = __resolv_context_get ();
765 res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx);
766 if (res_ctx == NULL)
767 no_more = 1;
769 while (!no_more)
771 no_data = 0;
772 nss_gethostbyname4_r fct4 = NULL;
774 /* gethostbyname4_r sends out parallel A and AAAA queries and
775 is thus only suitable for PF_UNSPEC. */
776 if (req->ai_family == PF_UNSPEC)
777 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
779 if (fct4 != NULL)
781 while (1)
783 status = DL_CALL_FCT (fct4, (name, pat,
784 tmpbuf->data, tmpbuf->length,
785 &errno, &h_errno,
786 NULL));
787 if (status == NSS_STATUS_SUCCESS)
788 break;
789 if (status != NSS_STATUS_TRYAGAIN
790 || errno != ERANGE || h_errno != NETDB_INTERNAL)
792 if (h_errno == TRY_AGAIN)
793 no_data = EAI_AGAIN;
794 else
795 no_data = h_errno == NO_DATA;
796 break;
799 if (!scratch_buffer_grow (tmpbuf))
801 __resolv_context_enable_inet6
802 (res_ctx, res_enable_inet6);
803 __resolv_context_put (res_ctx);
804 result = -EAI_MEMORY;
805 goto free_and_return;
809 if (status == NSS_STATUS_SUCCESS)
811 assert (!no_data);
812 no_data = 1;
814 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
815 canon = (*pat)->name;
817 while (*pat != NULL)
819 if ((*pat)->family == AF_INET
820 && req->ai_family == AF_INET6
821 && (req->ai_flags & AI_V4MAPPED) != 0)
823 uint32_t *pataddr = (*pat)->addr;
824 (*pat)->family = AF_INET6;
825 pataddr[3] = pataddr[0];
826 pataddr[2] = htonl (0xffff);
827 pataddr[1] = 0;
828 pataddr[0] = 0;
829 pat = &((*pat)->next);
830 no_data = 0;
832 else if (req->ai_family == AF_UNSPEC
833 || (*pat)->family == req->ai_family)
835 pat = &((*pat)->next);
837 no_data = 0;
838 if (req->ai_family == AF_INET6)
839 got_ipv6 = true;
841 else
842 *pat = ((*pat)->next);
846 no_inet6_data = no_data;
848 else
850 nss_gethostbyname3_r fct = NULL;
851 if (req->ai_flags & AI_CANONNAME)
852 /* No need to use this function if we do not look for
853 the canonical name. The function does not exist in
854 all NSS modules and therefore the lookup would
855 often fail. */
856 fct = __nss_lookup_function (nip, "gethostbyname3_r");
857 if (fct == NULL)
858 /* We are cheating here. The gethostbyname2_r
859 function does not have the same interface as
860 gethostbyname3_r but the extra arguments the
861 latter takes are added at the end. So the
862 gethostbyname2_r code will just ignore them. */
863 fct = __nss_lookup_function (nip, "gethostbyname2_r");
865 if (fct != NULL)
867 if (req->ai_family == AF_INET6
868 || req->ai_family == AF_UNSPEC)
870 gethosts (AF_INET6, struct in6_addr);
871 no_inet6_data = no_data;
872 inet6_status = status;
874 if (req->ai_family == AF_INET
875 || req->ai_family == AF_UNSPEC
876 || (req->ai_family == AF_INET6
877 && (req->ai_flags & AI_V4MAPPED)
878 /* Avoid generating the mapped addresses if we
879 know we are not going to need them. */
880 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
882 gethosts (AF_INET, struct in_addr);
884 if (req->ai_family == AF_INET)
886 no_inet6_data = no_data;
887 inet6_status = status;
891 /* If we found one address for AF_INET or AF_INET6,
892 don't continue the search. */
893 if (inet6_status == NSS_STATUS_SUCCESS
894 || status == NSS_STATUS_SUCCESS)
896 if ((req->ai_flags & AI_CANONNAME) != 0
897 && canon == NULL)
899 canonbuf = getcanonname (nip, at, name);
900 if (canonbuf == NULL)
902 __resolv_context_enable_inet6
903 (res_ctx, res_enable_inet6);
904 __resolv_context_put (res_ctx);
905 result = -EAI_MEMORY;
906 goto free_and_return;
908 canon = canonbuf;
910 status = NSS_STATUS_SUCCESS;
912 else
914 /* We can have different states for AF_INET and
915 AF_INET6. Try to find a useful one for both. */
916 if (inet6_status == NSS_STATUS_TRYAGAIN)
917 status = NSS_STATUS_TRYAGAIN;
918 else if (status == NSS_STATUS_UNAVAIL
919 && inet6_status != NSS_STATUS_UNAVAIL)
920 status = inet6_status;
923 else
925 status = NSS_STATUS_UNAVAIL;
926 /* Could not load any of the lookup functions. Indicate
927 an internal error if the failure was due to a system
928 error other than the file not being found. We use the
929 errno from the last failed callback. */
930 if (errno != 0 && errno != ENOENT)
931 __set_h_errno (NETDB_INTERNAL);
935 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
936 break;
938 if (nip->next == NULL)
939 no_more = -1;
940 else
941 nip = nip->next;
944 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6);
945 __resolv_context_put (res_ctx);
947 if (h_errno == NETDB_INTERNAL)
949 result = -EAI_SYSTEM;
950 goto free_and_return;
953 if (no_data != 0 && no_inet6_data != 0)
955 /* If both requests timed out report this. */
956 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
957 result = -EAI_AGAIN;
958 else
959 /* We made requests but they turned out no data. The name
960 is known, though. */
961 result = -EAI_NODATA;
963 goto free_and_return;
967 process_list:
968 if (at->family == AF_UNSPEC)
970 result = -EAI_NONAME;
971 goto free_and_return;
974 else
976 struct gaih_addrtuple *atr;
977 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
978 memset (at, '\0', sizeof (struct gaih_addrtuple));
980 if (req->ai_family == AF_UNSPEC)
982 at->next = __alloca (sizeof (struct gaih_addrtuple));
983 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
986 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
988 at->family = AF_INET6;
989 if ((req->ai_flags & AI_PASSIVE) == 0)
990 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
991 atr = at->next;
994 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
996 atr->family = AF_INET;
997 if ((req->ai_flags & AI_PASSIVE) == 0)
998 atr->addr[0] = htonl (INADDR_LOOPBACK);
1003 struct gaih_servtuple *st2;
1004 struct gaih_addrtuple *at2 = at;
1005 size_t socklen;
1006 sa_family_t family;
1009 buffer is the size of an unformatted IPv6 address in printable format.
1011 while (at2 != NULL)
1013 /* Only the first entry gets the canonical name. */
1014 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1016 if (canon == NULL)
1017 /* If the canonical name cannot be determined, use
1018 the passed in string. */
1019 canon = orig_name;
1021 #ifdef HAVE_LIBIDN
1022 if (req->ai_flags & AI_CANONIDN)
1024 int idn_flags = 0;
1025 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1026 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1027 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1028 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1030 char *out;
1031 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1032 if (rc != IDNA_SUCCESS)
1034 if (rc == IDNA_MALLOC_ERROR)
1035 result = -EAI_MEMORY;
1036 else if (rc == IDNA_DLOPEN_ERROR)
1037 result = -EAI_SYSTEM;
1038 else
1039 result = -EAI_IDN_ENCODE;
1040 goto free_and_return;
1042 /* In case the output string is the same as the input
1043 string no new string has been allocated and we
1044 make a copy. */
1045 if (out == canon)
1046 goto make_copy;
1047 canon = out;
1049 else
1050 #endif
1052 #ifdef HAVE_LIBIDN
1053 make_copy:
1054 #endif
1055 if (canonbuf != NULL)
1056 /* We already allocated the string using malloc, but
1057 the buffer is now owned by canon. */
1058 canonbuf = NULL;
1059 else
1061 canon = __strdup (canon);
1062 if (canon == NULL)
1064 result = -EAI_MEMORY;
1065 goto free_and_return;
1071 family = at2->family;
1072 if (family == AF_INET6)
1074 socklen = sizeof (struct sockaddr_in6);
1076 /* If we looked up IPv4 mapped address discard them here if
1077 the caller isn't interested in all address and we have
1078 found at least one IPv6 address. */
1079 if (got_ipv6
1080 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1081 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1082 goto ignore;
1084 else
1085 socklen = sizeof (struct sockaddr_in);
1087 for (st2 = st; st2 != NULL; st2 = st2->next)
1089 struct addrinfo *ai;
1090 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1091 if (ai == NULL)
1093 free ((char *) canon);
1094 result = -EAI_MEMORY;
1095 goto free_and_return;
1098 ai->ai_flags = req->ai_flags;
1099 ai->ai_family = family;
1100 ai->ai_socktype = st2->socktype;
1101 ai->ai_protocol = st2->protocol;
1102 ai->ai_addrlen = socklen;
1103 ai->ai_addr = (void *) (ai + 1);
1105 /* We only add the canonical name once. */
1106 ai->ai_canonname = (char *) canon;
1107 canon = NULL;
1109 #ifdef _HAVE_SA_LEN
1110 ai->ai_addr->sa_len = socklen;
1111 #endif /* _HAVE_SA_LEN */
1112 ai->ai_addr->sa_family = family;
1114 /* In case of an allocation error the list must be NULL
1115 terminated. */
1116 ai->ai_next = NULL;
1118 if (family == AF_INET6)
1120 struct sockaddr_in6 *sin6p =
1121 (struct sockaddr_in6 *) ai->ai_addr;
1123 sin6p->sin6_port = st2->port;
1124 sin6p->sin6_flowinfo = 0;
1125 memcpy (&sin6p->sin6_addr,
1126 at2->addr, sizeof (struct in6_addr));
1127 sin6p->sin6_scope_id = at2->scopeid;
1129 else
1131 struct sockaddr_in *sinp =
1132 (struct sockaddr_in *) ai->ai_addr;
1133 sinp->sin_port = st2->port;
1134 memcpy (&sinp->sin_addr,
1135 at2->addr, sizeof (struct in_addr));
1136 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1139 pai = &(ai->ai_next);
1142 ++*naddrs;
1144 ignore:
1145 at2 = at2->next;
1149 free_and_return:
1150 if (malloc_name)
1151 free ((char *) name);
1152 free (addrmem);
1153 free (canonbuf);
1155 return result;
1159 struct sort_result
1161 struct addrinfo *dest_addr;
1162 /* Using sockaddr_storage is for now overkill. We only support IPv4
1163 and IPv6 so far. If this changes at some point we can adjust the
1164 type here. */
1165 struct sockaddr_in6 source_addr;
1166 uint8_t source_addr_len;
1167 bool got_source_addr;
1168 uint8_t source_addr_flags;
1169 uint8_t prefixlen;
1170 uint32_t index;
1171 int32_t native;
1174 struct sort_result_combo
1176 struct sort_result *results;
1177 int nresults;
1181 #if __BYTE_ORDER == __BIG_ENDIAN
1182 # define htonl_c(n) n
1183 #else
1184 # define htonl_c(n) __bswap_constant_32 (n)
1185 #endif
1187 static const struct scopeentry
1189 union
1191 char addr[4];
1192 uint32_t addr32;
1194 uint32_t netmask;
1195 int32_t scope;
1196 } default_scopes[] =
1198 /* Link-local addresses: scope 2. */
1199 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1200 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1201 /* Default: scope 14. */
1202 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1205 /* The label table. */
1206 static const struct scopeentry *scopes;
1209 static int
1210 get_scope (const struct sockaddr_in6 *in6)
1212 int scope;
1213 if (in6->sin6_family == PF_INET6)
1215 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1217 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1218 /* RFC 4291 2.5.3 says that the loopback address is to be
1219 treated like a link-local address. */
1220 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1221 scope = 2;
1222 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1223 scope = 5;
1224 else
1225 /* XXX Is this the correct default behavior? */
1226 scope = 14;
1228 else
1229 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1231 else if (in6->sin6_family == PF_INET)
1233 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1235 size_t cnt = 0;
1236 while (1)
1238 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1239 == scopes[cnt].addr32)
1240 return scopes[cnt].scope;
1242 ++cnt;
1244 /* NOTREACHED */
1246 else
1247 /* XXX What is a good default? */
1248 scope = 15;
1250 return scope;
1254 struct prefixentry
1256 struct in6_addr prefix;
1257 unsigned int bits;
1258 int val;
1262 /* The label table. */
1263 static const struct prefixentry *labels;
1265 /* Default labels. */
1266 static const struct prefixentry default_labels[] =
1268 /* See RFC 3484 for the details. */
1269 { { .__in6_u
1270 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1272 }, 128, 0 },
1273 { { .__in6_u
1274 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1276 }, 16, 2 },
1277 { { .__in6_u
1278 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1280 }, 96, 3 },
1281 { { .__in6_u
1282 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1283 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1284 }, 96, 4 },
1285 /* The next two entries differ from RFC 3484. We need to treat
1286 IPv6 site-local addresses special because they are never NATed,
1287 unlike site-locale IPv4 addresses. If this would not happen, on
1288 machines which have only IPv4 and IPv6 site-local addresses, the
1289 sorting would prefer the IPv6 site-local addresses, causing
1290 unnecessary delays when trying to connect to a global IPv6 address
1291 through a site-local IPv6 address. */
1292 { { .__in6_u
1293 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1295 }, 10, 5 },
1296 { { .__in6_u
1297 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1299 }, 7, 6 },
1300 /* Additional rule for Teredo tunnels. */
1301 { { .__in6_u
1302 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1304 }, 32, 7 },
1305 { { .__in6_u
1306 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1308 }, 0, 1 }
1312 /* The precedence table. */
1313 static const struct prefixentry *precedence;
1315 /* The default precedences. */
1316 static const struct prefixentry default_precedence[] =
1318 /* See RFC 3484 for the details. */
1319 { { .__in6_u
1320 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1322 }, 128, 50 },
1323 { { .__in6_u
1324 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1326 }, 16, 30 },
1327 { { .__in6_u
1328 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1330 }, 96, 20 },
1331 { { .__in6_u
1332 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1334 }, 96, 10 },
1335 { { .__in6_u
1336 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1338 }, 0, 40 }
1342 static int
1343 match_prefix (const struct sockaddr_in6 *in6,
1344 const struct prefixentry *list, int default_val)
1346 int idx;
1347 struct sockaddr_in6 in6_mem;
1349 if (in6->sin6_family == PF_INET)
1351 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1353 /* Construct a V4-to-6 mapped address. */
1354 in6_mem.sin6_family = PF_INET6;
1355 in6_mem.sin6_port = in->sin_port;
1356 in6_mem.sin6_flowinfo = 0;
1357 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1358 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1359 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1360 in6_mem.sin6_scope_id = 0;
1362 in6 = &in6_mem;
1364 else if (in6->sin6_family != PF_INET6)
1365 return default_val;
1367 for (idx = 0; ; ++idx)
1369 unsigned int bits = list[idx].bits;
1370 const uint8_t *mask = list[idx].prefix.s6_addr;
1371 const uint8_t *val = in6->sin6_addr.s6_addr;
1373 while (bits >= 8)
1375 if (*mask != *val)
1376 break;
1378 ++mask;
1379 ++val;
1380 bits -= 8;
1383 if (bits < 8)
1385 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1386 /* Match! */
1387 break;
1391 return list[idx].val;
1395 static int
1396 get_label (const struct sockaddr_in6 *in6)
1398 /* XXX What is a good default value? */
1399 return match_prefix (in6, labels, INT_MAX);
1403 static int
1404 get_precedence (const struct sockaddr_in6 *in6)
1406 /* XXX What is a good default value? */
1407 return match_prefix (in6, precedence, 0);
1411 /* Find last bit set in a word. */
1412 static int
1413 fls (uint32_t a)
1415 uint32_t mask;
1416 int n;
1417 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1418 if ((a & mask) != 0)
1419 break;
1420 return n;
1424 static int
1425 rfc3484_sort (const void *p1, const void *p2, void *arg)
1427 const size_t idx1 = *(const size_t *) p1;
1428 const size_t idx2 = *(const size_t *) p2;
1429 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1430 struct sort_result *a1 = &src->results[idx1];
1431 struct sort_result *a2 = &src->results[idx2];
1433 /* Rule 1: Avoid unusable destinations.
1434 We have the got_source_addr flag set if the destination is reachable. */
1435 if (a1->got_source_addr && ! a2->got_source_addr)
1436 return -1;
1437 if (! a1->got_source_addr && a2->got_source_addr)
1438 return 1;
1441 /* Rule 2: Prefer matching scope. Only interesting if both
1442 destination addresses are IPv6. */
1443 int a1_dst_scope
1444 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1446 int a2_dst_scope
1447 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1449 if (a1->got_source_addr)
1451 int a1_src_scope = get_scope (&a1->source_addr);
1452 int a2_src_scope = get_scope (&a2->source_addr);
1454 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1455 return -1;
1456 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1457 return 1;
1461 /* Rule 3: Avoid deprecated addresses. */
1462 if (a1->got_source_addr)
1464 if (!(a1->source_addr_flags & in6ai_deprecated)
1465 && (a2->source_addr_flags & in6ai_deprecated))
1466 return -1;
1467 if ((a1->source_addr_flags & in6ai_deprecated)
1468 && !(a2->source_addr_flags & in6ai_deprecated))
1469 return 1;
1472 /* Rule 4: Prefer home addresses. */
1473 if (a1->got_source_addr)
1475 if (!(a1->source_addr_flags & in6ai_homeaddress)
1476 && (a2->source_addr_flags & in6ai_homeaddress))
1477 return 1;
1478 if ((a1->source_addr_flags & in6ai_homeaddress)
1479 && !(a2->source_addr_flags & in6ai_homeaddress))
1480 return -1;
1483 /* Rule 5: Prefer matching label. */
1484 if (a1->got_source_addr)
1486 int a1_dst_label
1487 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1488 int a1_src_label = get_label (&a1->source_addr);
1490 int a2_dst_label
1491 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1492 int a2_src_label = get_label (&a2->source_addr);
1494 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1495 return -1;
1496 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1497 return 1;
1501 /* Rule 6: Prefer higher precedence. */
1502 int a1_prec
1503 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1504 int a2_prec
1505 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1507 if (a1_prec > a2_prec)
1508 return -1;
1509 if (a1_prec < a2_prec)
1510 return 1;
1513 /* Rule 7: Prefer native transport. */
1514 if (a1->got_source_addr)
1516 /* The same interface index means the same interface which means
1517 there is no difference in transport. This should catch many
1518 (most?) cases. */
1519 if (a1->index != a2->index)
1521 int a1_native = a1->native;
1522 int a2_native = a2->native;
1524 if (a1_native == -1 || a2_native == -1)
1526 uint32_t a1_index;
1527 if (a1_native == -1)
1529 /* If we do not have the information use 'native' as
1530 the default. */
1531 a1_native = 0;
1532 a1_index = a1->index;
1534 else
1535 a1_index = 0xffffffffu;
1537 uint32_t a2_index;
1538 if (a2_native == -1)
1540 /* If we do not have the information use 'native' as
1541 the default. */
1542 a2_native = 0;
1543 a2_index = a2->index;
1545 else
1546 a2_index = 0xffffffffu;
1548 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1550 /* Fill in the results in all the records. */
1551 for (int i = 0; i < src->nresults; ++i)
1552 if (a1_index != -1 && src->results[i].index == a1_index)
1554 assert (src->results[i].native == -1
1555 || src->results[i].native == a1_native);
1556 src->results[i].native = a1_native;
1558 else if (a2_index != -1 && src->results[i].index == a2_index)
1560 assert (src->results[i].native == -1
1561 || src->results[i].native == a2_native);
1562 src->results[i].native = a2_native;
1566 if (a1_native && !a2_native)
1567 return -1;
1568 if (!a1_native && a2_native)
1569 return 1;
1574 /* Rule 8: Prefer smaller scope. */
1575 if (a1_dst_scope < a2_dst_scope)
1576 return -1;
1577 if (a1_dst_scope > a2_dst_scope)
1578 return 1;
1581 /* Rule 9: Use longest matching prefix. */
1582 if (a1->got_source_addr
1583 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1585 int bit1 = 0;
1586 int bit2 = 0;
1588 if (a1->dest_addr->ai_family == PF_INET)
1590 assert (a1->source_addr.sin6_family == PF_INET);
1591 assert (a2->source_addr.sin6_family == PF_INET);
1593 /* Outside of subnets, as defined by the network masks,
1594 common address prefixes for IPv4 addresses make no sense.
1595 So, define a non-zero value only if source and
1596 destination address are on the same subnet. */
1597 struct sockaddr_in *in1_dst
1598 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1599 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1600 struct sockaddr_in *in1_src
1601 = (struct sockaddr_in *) &a1->source_addr;
1602 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1603 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1605 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1606 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1608 struct sockaddr_in *in2_dst
1609 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1610 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1611 struct sockaddr_in *in2_src
1612 = (struct sockaddr_in *) &a2->source_addr;
1613 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1614 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1616 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1617 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1619 else if (a1->dest_addr->ai_family == PF_INET6)
1621 assert (a1->source_addr.sin6_family == PF_INET6);
1622 assert (a2->source_addr.sin6_family == PF_INET6);
1624 struct sockaddr_in6 *in1_dst;
1625 struct sockaddr_in6 *in1_src;
1626 struct sockaddr_in6 *in2_dst;
1627 struct sockaddr_in6 *in2_src;
1629 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1630 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1631 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1632 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1634 int i;
1635 for (i = 0; i < 4; ++i)
1636 if (in1_dst->sin6_addr.s6_addr32[i]
1637 != in1_src->sin6_addr.s6_addr32[i]
1638 || (in2_dst->sin6_addr.s6_addr32[i]
1639 != in2_src->sin6_addr.s6_addr32[i]))
1640 break;
1642 if (i < 4)
1644 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1645 ^ in1_src->sin6_addr.s6_addr32[i]));
1646 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1647 ^ in2_src->sin6_addr.s6_addr32[i]));
1651 if (bit1 > bit2)
1652 return -1;
1653 if (bit1 < bit2)
1654 return 1;
1658 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1659 compare with the value indicating the order in which the entries
1660 have been received from the services. NB: no two entries can have
1661 the same order so the test will never return zero. */
1662 return idx1 < idx2 ? -1 : 1;
1666 static int
1667 in6aicmp (const void *p1, const void *p2)
1669 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1670 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1672 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1676 /* Name of the config file for RFC 3484 sorting (for now). */
1677 #define GAICONF_FNAME "/etc/gai.conf"
1680 /* Non-zero if we are supposed to reload the config file automatically
1681 whenever it changed. */
1682 static int gaiconf_reload_flag;
1684 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1685 static int gaiconf_reload_flag_ever_set;
1687 /* Last modification time. */
1688 #ifdef _STATBUF_ST_NSEC
1690 static struct timespec gaiconf_mtime;
1692 static inline void
1693 save_gaiconf_mtime (const struct stat64 *st)
1695 gaiconf_mtime = st->st_mtim;
1698 static inline bool
1699 check_gaiconf_mtime (const struct stat64 *st)
1701 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1702 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1705 #else
1707 static time_t gaiconf_mtime;
1709 static inline void
1710 save_gaiconf_mtime (const struct stat64 *st)
1712 gaiconf_mtime = st->st_mtime;
1715 static inline bool
1716 check_gaiconf_mtime (const struct stat64 *st)
1718 return st->st_mtime == gaiconf_mtime;
1721 #endif
1724 libc_freeres_fn(fini)
1726 if (labels != default_labels)
1728 const struct prefixentry *old = labels;
1729 labels = default_labels;
1730 free ((void *) old);
1733 if (precedence != default_precedence)
1735 const struct prefixentry *old = precedence;
1736 precedence = default_precedence;
1737 free ((void *) old);
1740 if (scopes != default_scopes)
1742 const struct scopeentry *old = scopes;
1743 scopes = default_scopes;
1744 free ((void *) old);
1749 struct prefixlist
1751 struct prefixentry entry;
1752 struct prefixlist *next;
1756 struct scopelist
1758 struct scopeentry entry;
1759 struct scopelist *next;
1763 static void
1764 free_prefixlist (struct prefixlist *list)
1766 while (list != NULL)
1768 struct prefixlist *oldp = list;
1769 list = list->next;
1770 free (oldp);
1775 static void
1776 free_scopelist (struct scopelist *list)
1778 while (list != NULL)
1780 struct scopelist *oldp = list;
1781 list = list->next;
1782 free (oldp);
1787 static int
1788 prefixcmp (const void *p1, const void *p2)
1790 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1791 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1793 if (e1->bits < e2->bits)
1794 return 1;
1795 if (e1->bits == e2->bits)
1796 return 0;
1797 return -1;
1801 static int
1802 scopecmp (const void *p1, const void *p2)
1804 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1805 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1807 if (e1->netmask > e2->netmask)
1808 return -1;
1809 if (e1->netmask == e2->netmask)
1810 return 0;
1811 return 1;
1815 static void
1816 gaiconf_init (void)
1818 struct prefixlist *labellist = NULL;
1819 size_t nlabellist = 0;
1820 bool labellist_nullbits = false;
1821 struct prefixlist *precedencelist = NULL;
1822 size_t nprecedencelist = 0;
1823 bool precedencelist_nullbits = false;
1824 struct scopelist *scopelist = NULL;
1825 size_t nscopelist = 0;
1826 bool scopelist_nullbits = false;
1828 FILE *fp = fopen (GAICONF_FNAME, "rce");
1829 if (fp != NULL)
1831 struct stat64 st;
1832 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1834 fclose (fp);
1835 goto no_file;
1838 char *line = NULL;
1839 size_t linelen = 0;
1841 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1843 while (!feof_unlocked (fp))
1845 ssize_t n = __getline (&line, &linelen, fp);
1846 if (n <= 0)
1847 break;
1849 /* Handle comments. No escaping possible so this is easy. */
1850 char *cp = strchr (line, '#');
1851 if (cp != NULL)
1852 *cp = '\0';
1854 cp = line;
1855 while (isspace (*cp))
1856 ++cp;
1858 char *cmd = cp;
1859 while (*cp != '\0' && !isspace (*cp))
1860 ++cp;
1861 size_t cmdlen = cp - cmd;
1863 if (*cp != '\0')
1864 *cp++ = '\0';
1865 while (isspace (*cp))
1866 ++cp;
1868 char *val1 = cp;
1869 while (*cp != '\0' && !isspace (*cp))
1870 ++cp;
1871 size_t val1len = cp - cmd;
1873 /* We always need at least two values. */
1874 if (val1len == 0)
1875 continue;
1877 if (*cp != '\0')
1878 *cp++ = '\0';
1879 while (isspace (*cp))
1880 ++cp;
1882 char *val2 = cp;
1883 while (*cp != '\0' && !isspace (*cp))
1884 ++cp;
1886 /* Ignore the rest of the line. */
1887 *cp = '\0';
1889 struct prefixlist **listp;
1890 size_t *lenp;
1891 bool *nullbitsp;
1892 switch (cmdlen)
1894 case 5:
1895 if (strcmp (cmd, "label") == 0)
1897 struct in6_addr prefix;
1898 unsigned long int bits;
1899 unsigned long int val;
1900 char *endp;
1902 listp = &labellist;
1903 lenp = &nlabellist;
1904 nullbitsp = &labellist_nullbits;
1906 new_elem:
1907 bits = 128;
1908 __set_errno (0);
1909 cp = strchr (val1, '/');
1910 if (cp != NULL)
1911 *cp++ = '\0';
1912 if (inet_pton (AF_INET6, val1, &prefix)
1913 && (cp == NULL
1914 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1915 || errno != ERANGE)
1916 && *endp == '\0'
1917 && bits <= 128
1918 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1919 || errno != ERANGE)
1920 && *endp == '\0'
1921 && val <= INT_MAX)
1923 struct prefixlist *newp = malloc (sizeof (*newp));
1924 if (newp == NULL)
1926 free (line);
1927 fclose (fp);
1928 goto no_file;
1931 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1932 newp->entry.bits = bits;
1933 newp->entry.val = val;
1934 newp->next = *listp;
1935 *listp = newp;
1936 ++*lenp;
1937 *nullbitsp |= bits == 0;
1940 break;
1942 case 6:
1943 if (strcmp (cmd, "reload") == 0)
1945 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1946 if (gaiconf_reload_flag)
1947 gaiconf_reload_flag_ever_set = 1;
1949 break;
1951 case 7:
1952 if (strcmp (cmd, "scopev4") == 0)
1954 struct in6_addr prefix;
1955 unsigned long int bits;
1956 unsigned long int val;
1957 char *endp;
1959 bits = 32;
1960 __set_errno (0);
1961 cp = strchr (val1, '/');
1962 if (cp != NULL)
1963 *cp++ = '\0';
1964 if (inet_pton (AF_INET6, val1, &prefix))
1966 bits = 128;
1967 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1968 && (cp == NULL
1969 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1970 || errno != ERANGE)
1971 && *endp == '\0'
1972 && bits >= 96
1973 && bits <= 128
1974 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1975 || errno != ERANGE)
1976 && *endp == '\0'
1977 && val <= INT_MAX)
1979 struct scopelist *newp;
1980 new_scope:
1981 newp = malloc (sizeof (*newp));
1982 if (newp == NULL)
1984 free (line);
1985 fclose (fp);
1986 goto no_file;
1989 newp->entry.netmask = htonl (bits != 96
1990 ? (0xffffffff
1991 << (128 - bits))
1992 : 0);
1993 newp->entry.addr32 = (prefix.s6_addr32[3]
1994 & newp->entry.netmask);
1995 newp->entry.scope = val;
1996 newp->next = scopelist;
1997 scopelist = newp;
1998 ++nscopelist;
1999 scopelist_nullbits |= bits == 96;
2002 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2003 && (cp == NULL
2004 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2005 || errno != ERANGE)
2006 && *endp == '\0'
2007 && bits <= 32
2008 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2009 || errno != ERANGE)
2010 && *endp == '\0'
2011 && val <= INT_MAX)
2013 bits += 96;
2014 goto new_scope;
2017 break;
2019 case 10:
2020 if (strcmp (cmd, "precedence") == 0)
2022 listp = &precedencelist;
2023 lenp = &nprecedencelist;
2024 nullbitsp = &precedencelist_nullbits;
2025 goto new_elem;
2027 break;
2031 free (line);
2033 fclose (fp);
2035 /* Create the array for the labels. */
2036 struct prefixentry *new_labels;
2037 if (nlabellist > 0)
2039 if (!labellist_nullbits)
2040 ++nlabellist;
2041 new_labels = malloc (nlabellist * sizeof (*new_labels));
2042 if (new_labels == NULL)
2043 goto no_file;
2045 int i = nlabellist;
2046 if (!labellist_nullbits)
2048 --i;
2049 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2050 new_labels[i].bits = 0;
2051 new_labels[i].val = 1;
2054 struct prefixlist *l = labellist;
2055 while (i-- > 0)
2057 new_labels[i] = l->entry;
2058 l = l->next;
2060 free_prefixlist (labellist);
2062 /* Sort the entries so that the most specific ones are at
2063 the beginning. */
2064 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2066 else
2067 new_labels = (struct prefixentry *) default_labels;
2069 struct prefixentry *new_precedence;
2070 if (nprecedencelist > 0)
2072 if (!precedencelist_nullbits)
2073 ++nprecedencelist;
2074 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2075 if (new_precedence == NULL)
2077 if (new_labels != default_labels)
2078 free (new_labels);
2079 goto no_file;
2082 int i = nprecedencelist;
2083 if (!precedencelist_nullbits)
2085 --i;
2086 memset (&new_precedence[i].prefix, '\0',
2087 sizeof (struct in6_addr));
2088 new_precedence[i].bits = 0;
2089 new_precedence[i].val = 40;
2092 struct prefixlist *l = precedencelist;
2093 while (i-- > 0)
2095 new_precedence[i] = l->entry;
2096 l = l->next;
2098 free_prefixlist (precedencelist);
2100 /* Sort the entries so that the most specific ones are at
2101 the beginning. */
2102 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2103 prefixcmp);
2105 else
2106 new_precedence = (struct prefixentry *) default_precedence;
2108 struct scopeentry *new_scopes;
2109 if (nscopelist > 0)
2111 if (!scopelist_nullbits)
2112 ++nscopelist;
2113 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2114 if (new_scopes == NULL)
2116 if (new_labels != default_labels)
2117 free (new_labels);
2118 if (new_precedence != default_precedence)
2119 free (new_precedence);
2120 goto no_file;
2123 int i = nscopelist;
2124 if (!scopelist_nullbits)
2126 --i;
2127 new_scopes[i].addr32 = 0;
2128 new_scopes[i].netmask = 0;
2129 new_scopes[i].scope = 14;
2132 struct scopelist *l = scopelist;
2133 while (i-- > 0)
2135 new_scopes[i] = l->entry;
2136 l = l->next;
2138 free_scopelist (scopelist);
2140 /* Sort the entries so that the most specific ones are at
2141 the beginning. */
2142 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2143 scopecmp);
2145 else
2146 new_scopes = (struct scopeentry *) default_scopes;
2148 /* Now we are ready to replace the values. */
2149 const struct prefixentry *old = labels;
2150 labels = new_labels;
2151 if (old != default_labels)
2152 free ((void *) old);
2154 old = precedence;
2155 precedence = new_precedence;
2156 if (old != default_precedence)
2157 free ((void *) old);
2159 const struct scopeentry *oldscope = scopes;
2160 scopes = new_scopes;
2161 if (oldscope != default_scopes)
2162 free ((void *) oldscope);
2164 save_gaiconf_mtime (&st);
2166 else
2168 no_file:
2169 free_prefixlist (labellist);
2170 free_prefixlist (precedencelist);
2171 free_scopelist (scopelist);
2173 /* If we previously read the file but it is gone now, free the
2174 old data and use the builtin one. Leave the reload flag
2175 alone. */
2176 fini ();
2181 static void
2182 gaiconf_reload (void)
2184 struct stat64 st;
2185 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2186 || !check_gaiconf_mtime (&st))
2187 gaiconf_init ();
2192 getaddrinfo (const char *name, const char *service,
2193 const struct addrinfo *hints, struct addrinfo **pai)
2195 int i = 0, last_i = 0;
2196 int nresults = 0;
2197 struct addrinfo *p = NULL;
2198 struct gaih_service gaih_service, *pservice;
2199 struct addrinfo local_hints;
2201 if (name != NULL && name[0] == '*' && name[1] == 0)
2202 name = NULL;
2204 if (service != NULL && service[0] == '*' && service[1] == 0)
2205 service = NULL;
2207 if (name == NULL && service == NULL)
2208 return EAI_NONAME;
2210 if (hints == NULL)
2211 hints = &default_hints;
2213 if (hints->ai_flags
2214 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2215 #ifdef HAVE_LIBIDN
2216 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2217 |AI_IDN_USE_STD3_ASCII_RULES
2218 #endif
2219 |AI_NUMERICSERV|AI_ALL))
2220 return EAI_BADFLAGS;
2222 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2223 return EAI_BADFLAGS;
2225 struct in6addrinfo *in6ai = NULL;
2226 size_t in6ailen = 0;
2227 bool seen_ipv4 = false;
2228 bool seen_ipv6 = false;
2229 bool check_pf_called = false;
2231 if (hints->ai_flags & AI_ADDRCONFIG)
2233 /* We might need information about what interfaces are available.
2234 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2235 cannot cache the results since new interfaces could be added at
2236 any time. */
2237 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2238 check_pf_called = true;
2240 /* Now make a decision on what we return, if anything. */
2241 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2243 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2244 narrow down the search. */
2245 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2247 local_hints = *hints;
2248 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2249 hints = &local_hints;
2252 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2253 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2255 /* We cannot possibly return a valid answer. */
2256 __free_in6ai (in6ai);
2257 return EAI_NONAME;
2261 if (service && service[0])
2263 char *c;
2264 gaih_service.name = service;
2265 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2266 if (*c != '\0')
2268 if (hints->ai_flags & AI_NUMERICSERV)
2270 __free_in6ai (in6ai);
2271 return EAI_NONAME;
2274 gaih_service.num = -1;
2277 pservice = &gaih_service;
2279 else
2280 pservice = NULL;
2282 struct addrinfo **end = &p;
2284 unsigned int naddrs = 0;
2285 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2286 || hints->ai_family == AF_INET6)
2288 struct scratch_buffer tmpbuf;
2289 scratch_buffer_init (&tmpbuf);
2290 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2291 scratch_buffer_free (&tmpbuf);
2293 if (last_i != 0)
2295 freeaddrinfo (p);
2296 __free_in6ai (in6ai);
2298 return -last_i;
2300 while (*end)
2302 end = &((*end)->ai_next);
2303 ++nresults;
2306 else
2308 __free_in6ai (in6ai);
2309 return EAI_FAMILY;
2312 if (naddrs > 1)
2314 /* Read the config file. */
2315 __libc_once_define (static, once);
2316 __typeof (once) old_once = once;
2317 __libc_once (once, gaiconf_init);
2318 /* Sort results according to RFC 3484. */
2319 struct sort_result *results;
2320 size_t *order;
2321 struct addrinfo *q;
2322 struct addrinfo *last = NULL;
2323 char *canonname = NULL;
2324 bool malloc_results;
2325 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2327 malloc_results
2328 = !__libc_use_alloca (alloc_size);
2329 if (malloc_results)
2331 results = malloc (alloc_size);
2332 if (results == NULL)
2334 __free_in6ai (in6ai);
2335 return EAI_MEMORY;
2338 else
2339 results = alloca (alloc_size);
2340 order = (size_t *) (results + nresults);
2342 /* Now we definitely need the interface information. */
2343 if (! check_pf_called)
2344 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2346 /* If we have information about deprecated and temporary addresses
2347 sort the array now. */
2348 if (in6ai != NULL)
2349 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2351 int fd = -1;
2352 int af = AF_UNSPEC;
2354 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2356 results[i].dest_addr = q;
2357 results[i].native = -1;
2358 order[i] = i;
2360 /* If we just looked up the address for a different
2361 protocol, reuse the result. */
2362 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2363 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2365 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2366 results[i - 1].source_addr_len);
2367 results[i].source_addr_len = results[i - 1].source_addr_len;
2368 results[i].got_source_addr = results[i - 1].got_source_addr;
2369 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2370 results[i].prefixlen = results[i - 1].prefixlen;
2371 results[i].index = results[i - 1].index;
2373 else
2375 results[i].got_source_addr = false;
2376 results[i].source_addr_flags = 0;
2377 results[i].prefixlen = 0;
2378 results[i].index = 0xffffffffu;
2380 /* We overwrite the type with SOCK_DGRAM since we do not
2381 want connect() to connect to the other side. If we
2382 cannot determine the source address remember this
2383 fact. */
2384 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2386 if (fd != -1)
2387 close_retry:
2388 __close_nocancel_nostatus (fd);
2389 af = q->ai_family;
2390 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2392 else
2394 /* Reset the connection. */
2395 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2396 __connect (fd, &sa, sizeof (sa));
2399 socklen_t sl = sizeof (results[i].source_addr);
2400 if (fd != -1
2401 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2402 && __getsockname (fd,
2403 (struct sockaddr *) &results[i].source_addr,
2404 &sl) == 0)
2406 results[i].source_addr_len = sl;
2407 results[i].got_source_addr = true;
2409 if (in6ai != NULL)
2411 /* See whether the source address is on the list of
2412 deprecated or temporary addresses. */
2413 struct in6addrinfo tmp;
2415 if (q->ai_family == AF_INET && af == AF_INET)
2417 struct sockaddr_in *sinp
2418 = (struct sockaddr_in *) &results[i].source_addr;
2419 tmp.addr[0] = 0;
2420 tmp.addr[1] = 0;
2421 tmp.addr[2] = htonl (0xffff);
2422 /* Special case for lo interface, the source address
2423 being possibly different than the interface
2424 address. */
2425 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2426 == 0x7f000000)
2427 tmp.addr[3] = htonl(0x7f000001);
2428 else
2429 tmp.addr[3] = sinp->sin_addr.s_addr;
2431 else
2433 struct sockaddr_in6 *sin6p
2434 = (struct sockaddr_in6 *) &results[i].source_addr;
2435 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2438 struct in6addrinfo *found
2439 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2440 in6aicmp);
2441 if (found != NULL)
2443 results[i].source_addr_flags = found->flags;
2444 results[i].prefixlen = found->prefixlen;
2445 results[i].index = found->index;
2449 if (q->ai_family == AF_INET && af == AF_INET6)
2451 /* We have to convert the address. The socket is
2452 IPv6 and the request is for IPv4. */
2453 struct sockaddr_in6 *sin6
2454 = (struct sockaddr_in6 *) &results[i].source_addr;
2455 struct sockaddr_in *sin
2456 = (struct sockaddr_in *) &results[i].source_addr;
2457 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2458 sin->sin_family = AF_INET;
2459 /* We do not have to initialize sin_port since this
2460 fields has the same position and size in the IPv6
2461 structure. */
2462 assert (offsetof (struct sockaddr_in, sin_port)
2463 == offsetof (struct sockaddr_in6, sin6_port));
2464 assert (sizeof (sin->sin_port)
2465 == sizeof (sin6->sin6_port));
2466 memcpy (&sin->sin_addr,
2467 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2468 results[i].source_addr_len = sizeof (struct sockaddr_in);
2471 else if (errno == EAFNOSUPPORT && af == AF_INET6
2472 && q->ai_family == AF_INET)
2473 /* This could mean IPv6 sockets are IPv6-only. */
2474 goto close_retry;
2475 else
2476 /* Just make sure that if we have to process the same
2477 address again we do not copy any memory. */
2478 results[i].source_addr_len = 0;
2481 /* Remember the canonical name. */
2482 if (q->ai_canonname != NULL)
2484 assert (canonname == NULL);
2485 canonname = q->ai_canonname;
2486 q->ai_canonname = NULL;
2490 if (fd != -1)
2491 __close_nocancel_nostatus (fd);
2493 /* We got all the source addresses we can get, now sort using
2494 the information. */
2495 struct sort_result_combo src
2496 = { .results = results, .nresults = nresults };
2497 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2499 __libc_lock_define_initialized (static, lock);
2501 __libc_lock_lock (lock);
2502 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2503 gaiconf_reload ();
2504 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2505 __libc_lock_unlock (lock);
2507 else
2508 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2510 /* Queue the results up as they come out of sorting. */
2511 q = p = results[order[0]].dest_addr;
2512 for (i = 1; i < nresults; ++i)
2513 q = q->ai_next = results[order[i]].dest_addr;
2514 q->ai_next = NULL;
2516 /* Fill in the canonical name into the new first entry. */
2517 p->ai_canonname = canonname;
2519 if (malloc_results)
2520 free (results);
2523 __free_in6ai (in6ai);
2525 if (p)
2527 *pai = p;
2528 return 0;
2531 return last_i ? -last_i : EAI_NONAME;
2533 libc_hidden_def (getaddrinfo)
2535 nss_interface_function (getaddrinfo)
2537 void
2538 freeaddrinfo (struct addrinfo *ai)
2540 struct addrinfo *p;
2542 while (ai != NULL)
2544 p = ai;
2545 ai = ai->ai_next;
2546 free (p->ai_canonname);
2547 free (p);
2550 libc_hidden_def (freeaddrinfo)