support: Add support_set_vma_name
[glibc.git] / nss / getaddrinfo.c
blob531124958d037733ccee13bf59f97ab4a36ffdd4
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2023 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 <https://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 <stdbool.h>
65 #include <stdio.h>
66 #include <stdio_ext.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <stdint.h>
70 #include <arpa/inet.h>
71 #include <net/if.h>
72 #include <netinet/in.h>
73 #include <sys/socket.h>
74 #include <sys/stat.h>
75 #include <sys/types.h>
76 #include <sys/un.h>
77 #include <sys/utsname.h>
78 #include <unistd.h>
79 #include <nsswitch.h>
80 #include <libc-lock.h>
81 #include <not-cancel.h>
82 #include <nscd/nscd-client.h>
83 #include <nscd/nscd_proto.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
87 /* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
88 flags, now ignored. */
89 #define DEPRECATED_AI_IDN 0x300
91 #if IS_IN (libc)
92 # define feof_unlocked(fp) __feof_unlocked (fp)
93 #endif
95 struct gaih_service
97 const char *name;
98 int num;
101 struct gaih_servtuple
103 int socktype;
104 int protocol;
105 int port;
106 bool set;
110 struct gaih_typeproto
112 int socktype;
113 int protocol;
114 uint8_t protoflag;
115 bool defaultflag;
116 char name[8];
119 struct gaih_result
121 struct gaih_addrtuple *at;
122 char *canon;
123 char *h_name;
124 bool free_at;
125 bool got_ipv6;
128 /* Values for `protoflag'. */
129 #define GAI_PROTO_NOSERVICE 1
130 #define GAI_PROTO_PROTOANY 2
132 static const struct gaih_typeproto gaih_inet_typeproto[] =
134 { 0, 0, 0, false, "" },
135 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
136 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
137 #if defined SOCK_DCCP && defined IPPROTO_DCCP
138 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
139 #endif
140 #ifdef IPPROTO_UDPLITE
141 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
142 #endif
143 #ifdef IPPROTO_SCTP
144 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
145 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
146 #endif
147 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
148 { 0, 0, 0, false, "" }
151 static const struct addrinfo default_hints =
153 .ai_flags = AI_DEFAULT,
154 .ai_family = PF_UNSPEC,
155 .ai_socktype = 0,
156 .ai_protocol = 0,
157 .ai_addrlen = 0,
158 .ai_addr = NULL,
159 .ai_canonname = NULL,
160 .ai_next = NULL
163 static void
164 gaih_result_reset (struct gaih_result *res)
166 if (res->free_at)
167 free (res->at);
168 free (res->canon);
169 free (res->h_name);
170 memset (res, 0, sizeof (*res));
173 static int
174 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
175 const struct addrinfo *req, struct gaih_servtuple *st,
176 struct scratch_buffer *tmpbuf)
178 struct servent *s;
179 struct servent ts;
180 int r;
184 r = __getservbyname_r (servicename, tp->name, &ts,
185 tmpbuf->data, tmpbuf->length, &s);
186 if (r != 0 || s == NULL)
188 if (r == ERANGE)
190 if (!scratch_buffer_grow (tmpbuf))
191 return -EAI_MEMORY;
193 else
194 return -EAI_SERVICE;
197 while (r);
199 st->socktype = tp->socktype;
200 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
201 ? req->ai_protocol : tp->protocol);
202 st->port = s->s_port;
203 st->set = true;
205 return 0;
208 /* Convert struct hostent to a list of struct gaih_addrtuple objects. The new
209 addresses are appended to the tuple array in RES. */
210 static bool
211 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
212 struct hostent *h, struct gaih_result *res)
214 /* Count the number of addresses in h->h_addr_list. */
215 size_t count = 0;
216 for (char **p = h->h_addr_list; *p != NULL; ++p)
217 ++count;
219 /* Report no data if no addresses are available, or if the incoming
220 address size is larger than what we can store. */
221 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
222 return true;
224 struct gaih_addrtuple *array = res->at;
225 size_t old = 0;
227 while (array != NULL)
229 old++;
230 array = array->next;
233 array = realloc (res->at, (old + count) * sizeof (*array));
235 if (array == NULL)
236 return false;
238 res->got_ipv6 = family == AF_INET6;
239 res->at = array;
240 res->free_at = true;
242 /* Duplicate h_name because it may get reclaimed when the underlying storage
243 is freed. */
244 if (res->h_name == NULL)
246 res->h_name = __strdup (h->h_name);
247 if (res->h_name == NULL)
248 return false;
251 /* Update the next pointers on reallocation. */
252 for (size_t i = 0; i < old; i++)
253 array[i].next = array + i + 1;
255 array += old;
257 memset (array, 0, count * sizeof (*array));
259 for (size_t i = 0; i < count; ++i)
261 if (family == AF_INET && req->ai_family == AF_INET6)
263 /* Perform address mapping. */
264 array[i].family = AF_INET6;
265 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
266 array[i].addr[2] = htonl (0xffff);
268 else
270 array[i].family = family;
271 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
273 array[i].next = array + i + 1;
275 array[count - 1].next = NULL;
277 return true;
280 static int
281 gethosts (nss_gethostbyname3_r fct, int family, const char *name,
282 const struct addrinfo *req, struct scratch_buffer *tmpbuf,
283 struct gaih_result *res, enum nss_status *statusp, int *no_datap)
285 struct hostent th;
286 char *localcanon = NULL;
287 enum nss_status status;
289 *no_datap = 0;
290 while (1)
292 *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
293 tmpbuf->data, tmpbuf->length,
294 &errno, &h_errno, NULL,
295 &localcanon));
296 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
297 || errno != ERANGE)
298 break;
299 if (!scratch_buffer_grow (tmpbuf))
300 return -EAI_MEMORY;
302 if (status == NSS_STATUS_NOTFOUND
303 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
305 if (h_errno == NETDB_INTERNAL)
306 return -EAI_SYSTEM;
307 if (h_errno == TRY_AGAIN)
308 *no_datap = EAI_AGAIN;
309 else
310 *no_datap = h_errno == NO_DATA;
312 else if (status == NSS_STATUS_SUCCESS)
314 if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
315 return -EAI_MEMORY;
317 if (localcanon != NULL && res->canon == NULL)
319 char *canonbuf = __strdup (localcanon);
320 if (canonbuf == NULL)
321 return -EAI_MEMORY;
322 res->canon = canonbuf;
326 return 0;
329 /* This function is called if a canonical name is requested, but if
330 the service function did not provide it. It tries to obtain the
331 name using getcanonname_r from the same service NIP. If the name
332 cannot be canonicalized, return a copy of NAME. Return NULL on
333 memory allocation failure. The returned string is allocated on the
334 heap; the caller has to free it. */
335 static char *
336 getcanonname (nss_action_list nip, const char *hname, const char *name)
338 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
339 char *s = (char *) name;
340 if (cfct != NULL)
342 char buf[256];
343 if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno,
344 &h_errno)) != NSS_STATUS_SUCCESS)
345 /* If the canonical name cannot be determined, use the passed
346 string. */
347 s = (char *) name;
349 return __strdup (s);
352 /* Process looked up canonical name and if necessary, decode to IDNA. Result
353 is a new string written to CANONP and the earlier string is freed. */
355 static int
356 process_canonname (const struct addrinfo *req, const char *orig_name,
357 struct gaih_result *res)
359 char *canon = res->canon;
361 if ((req->ai_flags & AI_CANONNAME) != 0)
363 bool do_idn = req->ai_flags & AI_CANONIDN;
364 if (do_idn)
366 char *out;
367 int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
368 if (rc == 0)
370 free (canon);
371 canon = out;
373 else if (rc == EAI_IDN_ENCODE)
374 /* Use the punycode name as a fallback. */
375 do_idn = false;
376 else
377 return -rc;
379 if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
380 return -EAI_MEMORY;
383 res->canon = canon;
384 return 0;
387 static int
388 get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
389 struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
391 int i;
392 const struct gaih_typeproto *tp = gaih_inet_typeproto;
394 if (req->ai_protocol || req->ai_socktype)
396 ++tp;
398 while (tp->name[0]
399 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
400 || (req->ai_protocol != 0
401 && !(tp->protoflag & GAI_PROTO_PROTOANY)
402 && req->ai_protocol != tp->protocol)))
403 ++tp;
405 if (! tp->name[0])
407 if (req->ai_socktype)
408 return -EAI_SOCKTYPE;
409 else
410 return -EAI_SERVICE;
414 if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
415 return -EAI_SERVICE;
417 if (service == NULL || service->num >= 0)
419 int port = service != NULL ? htons (service->num) : 0;
421 if (req->ai_socktype || req->ai_protocol)
423 st[0].socktype = tp->socktype;
424 st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
425 ? req->ai_protocol : tp->protocol);
426 st[0].port = port;
427 st[0].set = true;
429 return 0;
432 /* Neither socket type nor protocol is set. Return all socket types
433 we know about. */
434 for (i = 0, ++tp; tp->name[0]; ++tp)
435 if (tp->defaultflag)
437 st[i].socktype = tp->socktype;
438 st[i].protocol = tp->protocol;
439 st[i].port = port;
440 st[i++].set = true;
443 return 0;
446 if (tp->name[0])
447 return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
449 for (i = 0, tp++; tp->name[0]; tp++)
451 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
452 continue;
454 if (req->ai_socktype != 0
455 && req->ai_socktype != tp->socktype)
456 continue;
457 if (req->ai_protocol != 0
458 && !(tp->protoflag & GAI_PROTO_PROTOANY)
459 && req->ai_protocol != tp->protocol)
460 continue;
462 if (gaih_inet_serv (service->name,
463 tp, req, &st[i], tmpbuf) != 0)
464 continue;
466 i++;
469 if (!st[0].set)
470 return -EAI_SERVICE;
472 return 0;
475 #ifdef USE_NSCD
476 /* Query addresses from nscd cache, returning a non-zero value on error.
477 RES members have the lookup result; RES->AT is NULL if there were no errors
478 but also no results. */
480 static int
481 get_nscd_addresses (const char *name, const struct addrinfo *req,
482 struct gaih_result *res)
484 if (__nss_not_use_nscd_hosts > 0
485 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
486 __nss_not_use_nscd_hosts = 0;
488 res->at = NULL;
490 if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
491 return 0;
493 /* Try to use nscd. */
494 struct nscd_ai_result *air = NULL;
495 int err = __nscd_getai (name, &air, &h_errno);
497 if (__glibc_unlikely (air == NULL))
499 /* The database contains a negative entry. */
500 if (err == 0)
501 return -EAI_NONAME;
502 if (__nss_not_use_nscd_hosts == 0)
504 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
505 return -EAI_MEMORY;
506 if (h_errno == TRY_AGAIN)
507 return -EAI_AGAIN;
508 return -EAI_SYSTEM;
510 return 0;
513 /* Transform into gaih_addrtuple list. */
514 int result = 0;
515 char *addrs = air->addrs;
517 struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
518 struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
519 if (at == NULL)
521 result = -EAI_MEMORY;
522 goto out;
525 res->free_at = true;
527 int count = 0;
528 for (int i = 0; i < air->naddrs; ++i)
530 socklen_t size = (air->family[i] == AF_INET
531 ? INADDRSZ : IN6ADDRSZ);
533 if (!((air->family[i] == AF_INET
534 && req->ai_family == AF_INET6
535 && (req->ai_flags & AI_V4MAPPED) != 0)
536 || req->ai_family == AF_UNSPEC
537 || air->family[i] == req->ai_family))
539 /* Skip over non-matching result. */
540 addrs += size;
541 continue;
544 if (air->family[i] == AF_INET && req->ai_family == AF_INET6
545 && (req->ai_flags & AI_V4MAPPED))
547 at[count].family = AF_INET6;
548 at[count].addr[3] = *(uint32_t *) addrs;
549 at[count].addr[2] = htonl (0xffff);
551 else if (req->ai_family == AF_UNSPEC
552 || air->family[i] == req->ai_family)
554 at[count].family = air->family[i];
555 memcpy (at[count].addr, addrs, size);
556 if (air->family[i] == AF_INET6)
557 res->got_ipv6 = true;
559 at[count].next = at + count + 1;
560 count++;
561 addrs += size;
564 if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
566 char *canonbuf = __strdup (air->canon);
567 if (canonbuf == NULL)
569 result = -EAI_MEMORY;
570 goto out;
572 res->canon = canonbuf;
575 if (count == 0)
577 result = -EAI_NONAME;
578 goto out;
581 at[count - 1].next = NULL;
583 res->at = at;
585 out:
586 free (air);
587 if (result != 0)
589 free (at);
590 res->free_at = false;
593 return result;
595 #endif
597 static int
598 get_nss_addresses (const char *name, const struct addrinfo *req,
599 struct scratch_buffer *tmpbuf, struct gaih_result *res)
601 int no_data = 0;
602 int no_inet6_data = 0;
603 nss_action_list nip;
604 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
605 enum nss_status status = NSS_STATUS_UNAVAIL;
606 int no_more;
607 struct resolv_context *res_ctx = NULL;
608 bool do_merge = false;
609 int result = 0;
611 no_more = !__nss_database_get (nss_database_hosts, &nip);
613 /* If we are looking for both IPv4 and IPv6 address we don't
614 want the lookup functions to automatically promote IPv4
615 addresses to IPv6 addresses, so we use the no_inet6
616 function variant. */
617 res_ctx = __resolv_context_get ();
618 if (res_ctx == NULL)
619 no_more = 1;
621 while (!no_more)
623 /* Always start afresh; continue should discard previous results
624 and the hosts database does not support merge. */
625 gaih_result_reset (res);
627 if (do_merge)
629 __set_h_errno (NETDB_INTERNAL);
630 __set_errno (EBUSY);
631 break;
634 no_data = 0;
635 nss_gethostbyname4_r *fct4 = NULL;
637 /* gethostbyname4_r sends out parallel A and AAAA queries and
638 is thus only suitable for PF_UNSPEC. */
639 if (req->ai_family == PF_UNSPEC)
640 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
642 if (fct4 != NULL)
644 while (1)
646 status = DL_CALL_FCT (fct4, (name, &res->at,
647 tmpbuf->data, tmpbuf->length,
648 &errno, &h_errno,
649 NULL));
650 if (status == NSS_STATUS_SUCCESS)
651 break;
652 /* gethostbyname4_r may write into AT, so reset it. */
653 res->at = NULL;
654 if (status != NSS_STATUS_TRYAGAIN
655 || errno != ERANGE || h_errno != NETDB_INTERNAL)
657 if (h_errno == TRY_AGAIN)
658 no_data = EAI_AGAIN;
659 else
660 no_data = h_errno == NO_DATA;
661 break;
664 if (!scratch_buffer_grow (tmpbuf))
666 __resolv_context_put (res_ctx);
667 result = -EAI_MEMORY;
668 goto out;
672 if (status == NSS_STATUS_SUCCESS)
674 assert (!no_data);
675 no_data = 1;
677 if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
679 char *canonbuf = __strdup (res->at->name);
680 if (canonbuf == NULL)
682 __resolv_context_put (res_ctx);
683 result = -EAI_MEMORY;
684 goto out;
686 res->canon = canonbuf;
689 struct gaih_addrtuple **pat = &res->at;
691 while (*pat != NULL)
693 if ((*pat)->family == AF_INET
694 && req->ai_family == AF_INET6
695 && (req->ai_flags & AI_V4MAPPED) != 0)
697 uint32_t *pataddr = (*pat)->addr;
698 (*pat)->family = AF_INET6;
699 pataddr[3] = pataddr[0];
700 pataddr[2] = htonl (0xffff);
701 pataddr[1] = 0;
702 pataddr[0] = 0;
703 pat = &((*pat)->next);
704 no_data = 0;
706 else if (req->ai_family == AF_UNSPEC
707 || (*pat)->family == req->ai_family)
709 pat = &((*pat)->next);
711 no_data = 0;
712 if (req->ai_family == AF_INET6)
713 res->got_ipv6 = true;
715 else
716 *pat = ((*pat)->next);
720 no_inet6_data = no_data;
722 else
724 nss_gethostbyname3_r *fct = NULL;
725 if (req->ai_flags & AI_CANONNAME)
726 /* No need to use this function if we do not look for
727 the canonical name. The function does not exist in
728 all NSS modules and therefore the lookup would
729 often fail. */
730 fct = __nss_lookup_function (nip, "gethostbyname3_r");
731 if (fct == NULL)
732 /* We are cheating here. The gethostbyname2_r
733 function does not have the same interface as
734 gethostbyname3_r but the extra arguments the
735 latter takes are added at the end. So the
736 gethostbyname2_r code will just ignore them. */
737 fct = __nss_lookup_function (nip, "gethostbyname2_r");
739 if (fct != NULL)
741 if (req->ai_family == AF_INET6
742 || req->ai_family == AF_UNSPEC)
744 if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
745 res, &status, &no_data)) != 0)
747 __resolv_context_put (res_ctx);
748 goto out;
750 no_inet6_data = no_data;
751 inet6_status = status;
753 if (req->ai_family == AF_INET
754 || req->ai_family == AF_UNSPEC
755 || (req->ai_family == AF_INET6
756 && (req->ai_flags & AI_V4MAPPED)
757 /* Avoid generating the mapped addresses if we
758 know we are not going to need them. */
759 && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
761 if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
762 res, &status, &no_data)) != 0)
764 __resolv_context_put (res_ctx);
765 goto out;
768 if (req->ai_family == AF_INET)
770 no_inet6_data = no_data;
771 inet6_status = status;
775 /* If we found one address for AF_INET or AF_INET6,
776 don't continue the search. */
777 if (inet6_status == NSS_STATUS_SUCCESS
778 || status == NSS_STATUS_SUCCESS)
780 if ((req->ai_flags & AI_CANONNAME) != 0
781 && res->canon == NULL)
783 char *canonbuf = getcanonname (nip, res->h_name, name);
784 if (canonbuf == NULL)
786 __resolv_context_put (res_ctx);
787 result = -EAI_MEMORY;
788 goto out;
790 res->canon = canonbuf;
792 status = NSS_STATUS_SUCCESS;
794 else
796 /* We can have different states for AF_INET and
797 AF_INET6. Try to find a useful one for both. */
798 if (inet6_status == NSS_STATUS_TRYAGAIN)
799 status = NSS_STATUS_TRYAGAIN;
800 else if (status == NSS_STATUS_UNAVAIL
801 && inet6_status != NSS_STATUS_UNAVAIL)
802 status = inet6_status;
805 else
807 /* Could not locate any of the lookup functions.
808 The NSS lookup code does not consistently set
809 errno, so we need to supply our own error
810 code here. The root cause could either be a
811 resource allocation failure, or a missing
812 service function in the DSO (so it should not
813 be listed in /etc/nsswitch.conf). Assume the
814 former, and return EBUSY. */
815 status = NSS_STATUS_UNAVAIL;
816 __set_h_errno (NETDB_INTERNAL);
817 __set_errno (EBUSY);
821 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
822 break;
824 /* The hosts database does not support MERGE. */
825 if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
826 do_merge = true;
828 nip++;
829 if (nip->module == NULL)
830 no_more = -1;
833 __resolv_context_put (res_ctx);
835 /* If we have a failure which sets errno, report it using
836 EAI_SYSTEM. */
837 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
838 && h_errno == NETDB_INTERNAL)
840 result = -EAI_SYSTEM;
841 goto out;
844 if (no_data != 0 && no_inet6_data != 0)
846 /* If both requests timed out report this. */
847 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
848 result = -EAI_AGAIN;
849 else
850 /* We made requests but they turned out no data. The name
851 is known, though. */
852 result = -EAI_NODATA;
855 out:
856 if (result != 0)
857 gaih_result_reset (res);
858 return result;
861 /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
862 NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
863 the function cannot determine a result, RES->AT is set to NULL and 0
864 returned. */
866 static int
867 text_to_binary_address (const char *name, const struct addrinfo *req,
868 struct gaih_result *res)
870 struct gaih_addrtuple *at = res->at;
871 int result = 0;
873 assert (at != NULL);
875 memset (at->addr, 0, sizeof (at->addr));
876 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
878 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
879 at->family = AF_INET;
880 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
882 at->addr[3] = at->addr[0];
883 at->addr[2] = htonl (0xffff);
884 at->addr[1] = 0;
885 at->addr[0] = 0;
886 at->family = AF_INET6;
888 else
890 result = -EAI_ADDRFAMILY;
891 goto out;
894 if (req->ai_flags & AI_CANONNAME)
896 char *canonbuf = __strdup (name);
897 if (canonbuf == NULL)
899 result = -EAI_MEMORY;
900 goto out;
902 res->canon = canonbuf;
904 return 0;
907 char *scope_delim = strchr (name, SCOPE_DELIMITER);
908 int e;
910 if (scope_delim == NULL)
911 e = inet_pton (AF_INET6, name, at->addr);
912 else
913 e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr);
915 if (e > 0)
917 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
918 at->family = AF_INET6;
919 else if (req->ai_family == AF_INET
920 && IN6_IS_ADDR_V4MAPPED (at->addr))
922 at->addr[0] = at->addr[3];
923 at->family = AF_INET;
925 else
927 result = -EAI_ADDRFAMILY;
928 goto out;
931 if (scope_delim != NULL
932 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
933 scope_delim + 1, &at->scopeid) != 0)
935 result = -EAI_NONAME;
936 goto out;
939 if (req->ai_flags & AI_CANONNAME)
941 char *canonbuf = __strdup (name);
942 if (canonbuf == NULL)
944 result = -EAI_MEMORY;
945 goto out;
947 res->canon = canonbuf;
949 return 0;
952 if ((req->ai_flags & AI_NUMERICHOST))
953 result = -EAI_NONAME;
955 out:
956 res->at = NULL;
957 return result;
960 /* If possible, call the simple, old functions, which do not support IPv6 scope
961 ids, nor retrieving the canonical name. */
963 static int
964 try_simple_gethostbyname (const char *name, const struct addrinfo *req,
965 struct scratch_buffer *tmpbuf,
966 struct gaih_result *res)
968 res->at = NULL;
970 if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
971 return 0;
973 int rc;
974 struct hostent th;
975 struct hostent *h;
977 while (1)
979 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
980 tmpbuf->length, &h, &h_errno);
981 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
982 break;
983 if (!scratch_buffer_grow (tmpbuf))
984 return -EAI_MEMORY;
987 if (rc == 0)
989 if (h != NULL)
991 /* We found data, convert it. RES->AT from the conversion will
992 either be an allocated block or NULL, both of which are safe to
993 pass to free (). */
994 if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
995 return -EAI_MEMORY;
997 res->free_at = true;
998 return 0;
1000 if (h_errno == NO_DATA)
1001 return -EAI_NODATA;
1003 return -EAI_NONAME;
1006 if (h_errno == NETDB_INTERNAL)
1007 return -EAI_SYSTEM;
1008 if (h_errno == TRY_AGAIN)
1009 return -EAI_AGAIN;
1011 /* We made requests but they turned out no data.
1012 The name is known, though. */
1013 return -EAI_NODATA;
1016 /* Add local address information into RES. RES->AT is assumed to have enough
1017 space for two tuples and is zeroed out. */
1019 static void
1020 get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
1022 struct gaih_addrtuple *atr = res->at;
1023 if (req->ai_family == AF_UNSPEC)
1024 res->at->next = res->at + 1;
1026 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1028 res->at->family = AF_INET6;
1029 if ((req->ai_flags & AI_PASSIVE) == 0)
1030 memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1031 atr = res->at->next;
1034 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1036 atr->family = AF_INET;
1037 if ((req->ai_flags & AI_PASSIVE) == 0)
1038 atr->addr[0] = htonl (INADDR_LOOPBACK);
1042 /* Generate results in PAI and its count in NADDRS. Return 0 on success or an
1043 error code on failure. */
1045 static int
1046 generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
1047 const struct gaih_servtuple *st, struct addrinfo **pai,
1048 unsigned int *naddrs)
1050 size_t socklen;
1051 sa_family_t family;
1053 /* Buffer is the size of an unformatted IPv6 address in printable format. */
1054 for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
1056 family = at->family;
1057 if (family == AF_INET6)
1059 socklen = sizeof (struct sockaddr_in6);
1061 /* If we looked up IPv4 mapped address discard them here if
1062 the caller isn't interested in all address and we have
1063 found at least one IPv6 address. */
1064 if (res->got_ipv6
1065 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1066 && IN6_IS_ADDR_V4MAPPED (at->addr))
1067 continue;
1069 else
1070 socklen = sizeof (struct sockaddr_in);
1072 for (int i = 0; st[i].set; i++)
1074 struct addrinfo *ai;
1075 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1076 if (ai == NULL)
1077 return -EAI_MEMORY;
1079 ai->ai_flags = req->ai_flags;
1080 ai->ai_family = family;
1081 ai->ai_socktype = st[i].socktype;
1082 ai->ai_protocol = st[i].protocol;
1083 ai->ai_addrlen = socklen;
1084 ai->ai_addr = (void *) (ai + 1);
1086 /* We only add the canonical name once. */
1087 ai->ai_canonname = res->canon;
1088 res->canon = NULL;
1090 #ifdef _HAVE_SA_LEN
1091 ai->ai_addr->sa_len = socklen;
1092 #endif /* _HAVE_SA_LEN */
1093 ai->ai_addr->sa_family = family;
1095 /* In case of an allocation error the list must be NULL
1096 terminated. */
1097 ai->ai_next = NULL;
1099 if (family == AF_INET6)
1101 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
1102 sin6p->sin6_port = st[i].port;
1103 sin6p->sin6_flowinfo = 0;
1104 memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
1105 sin6p->sin6_scope_id = at->scopeid;
1107 else
1109 struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
1110 sinp->sin_port = st[i].port;
1111 memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
1112 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1115 pai = &(ai->ai_next);
1118 ++*naddrs;
1120 return 0;
1123 static int
1124 gaih_inet (const char *name, const struct gaih_service *service,
1125 const struct addrinfo *req, struct addrinfo **pai,
1126 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
1128 struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
1129 / sizeof (struct gaih_typeproto)] = {0};
1131 const char *orig_name = name;
1133 int rc;
1134 if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
1135 return rc;
1137 bool malloc_name = false;
1138 struct gaih_addrtuple *addrmem = NULL;
1139 int result = 0;
1141 struct gaih_result res = {0};
1142 struct gaih_addrtuple local_at[2] = {0};
1144 res.at = local_at;
1146 if (__glibc_unlikely (name == NULL))
1148 get_local_addresses (req, &res);
1149 goto process_list;
1152 if (req->ai_flags & AI_IDN)
1154 char *out;
1155 result = __idna_to_dns_encoding (name, &out);
1156 if (result != 0)
1157 return -result;
1158 name = out;
1159 malloc_name = true;
1162 if ((result = text_to_binary_address (name, req, &res)) != 0)
1163 goto free_and_return;
1164 else if (res.at != NULL)
1165 goto process_list;
1167 if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
1168 goto free_and_return;
1169 else if (res.at != NULL)
1170 goto process_list;
1172 #ifdef USE_NSCD
1173 if ((result = get_nscd_addresses (name, req, &res)) != 0)
1174 goto free_and_return;
1175 else if (res.at != NULL)
1176 goto process_list;
1177 #endif
1179 if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
1180 goto free_and_return;
1181 else if (res.at != NULL)
1182 goto process_list;
1184 /* None of the lookups worked, so name not found. */
1185 result = -EAI_NONAME;
1186 goto free_and_return;
1188 process_list:
1189 /* Set up the canonical name if we need it. */
1190 if ((result = process_canonname (req, orig_name, &res)) != 0)
1191 goto free_and_return;
1193 result = generate_addrinfo (req, &res, st, pai, naddrs);
1195 free_and_return:
1196 if (malloc_name)
1197 free ((char *) name);
1198 free (addrmem);
1199 gaih_result_reset (&res);
1201 return result;
1205 struct sort_result
1207 struct addrinfo *dest_addr;
1208 /* Using sockaddr_storage is for now overkill. We only support IPv4
1209 and IPv6 so far. If this changes at some point we can adjust the
1210 type here. */
1211 struct sockaddr_in6 source_addr;
1212 uint8_t source_addr_len;
1213 bool got_source_addr;
1214 uint8_t source_addr_flags;
1215 uint8_t prefixlen;
1216 uint32_t index;
1217 int32_t native;
1220 struct sort_result_combo
1222 struct sort_result *results;
1223 int nresults;
1227 #if __BYTE_ORDER == __BIG_ENDIAN
1228 # define htonl_c(n) n
1229 #else
1230 # define htonl_c(n) __bswap_constant_32 (n)
1231 #endif
1233 static const struct scopeentry
1235 union
1237 char addr[4];
1238 uint32_t addr32;
1240 uint32_t netmask;
1241 int32_t scope;
1242 } default_scopes[] =
1244 /* Link-local addresses: scope 2. */
1245 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1246 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1247 /* Default: scope 14. */
1248 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1251 /* The label table. */
1252 static const struct scopeentry *scopes;
1255 static int
1256 get_scope (const struct sockaddr_in6 *in6)
1258 int scope;
1259 if (in6->sin6_family == PF_INET6)
1261 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1263 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1264 /* RFC 4291 2.5.3 says that the loopback address is to be
1265 treated like a link-local address. */
1266 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1267 scope = 2;
1268 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1269 scope = 5;
1270 else
1271 /* XXX Is this the correct default behavior? */
1272 scope = 14;
1274 else
1275 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1277 else if (in6->sin6_family == PF_INET)
1279 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1281 size_t cnt = 0;
1282 while (1)
1284 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1285 == scopes[cnt].addr32)
1286 return scopes[cnt].scope;
1288 ++cnt;
1290 /* NOTREACHED */
1292 else
1293 /* XXX What is a good default? */
1294 scope = 15;
1296 return scope;
1300 struct prefixentry
1302 struct in6_addr prefix;
1303 unsigned int bits;
1304 int val;
1308 /* The label table. */
1309 static const struct prefixentry *labels;
1311 /* Default labels. */
1312 static const struct prefixentry default_labels[] =
1314 /* See RFC 3484 for the details. */
1315 { { .__in6_u
1316 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1318 }, 128, 0 },
1319 { { .__in6_u
1320 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1322 }, 16, 2 },
1323 { { .__in6_u
1324 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1326 }, 96, 3 },
1327 { { .__in6_u
1328 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1330 }, 96, 4 },
1331 /* The next two entries differ from RFC 3484. We need to treat
1332 IPv6 site-local addresses special because they are never NATed,
1333 unlike site-locale IPv4 addresses. If this would not happen, on
1334 machines which have only IPv4 and IPv6 site-local addresses, the
1335 sorting would prefer the IPv6 site-local addresses, causing
1336 unnecessary delays when trying to connect to a global IPv6 address
1337 through a site-local IPv6 address. */
1338 { { .__in6_u
1339 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1341 }, 10, 5 },
1342 { { .__in6_u
1343 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1345 }, 7, 6 },
1346 /* Additional rule for Teredo tunnels. */
1347 { { .__in6_u
1348 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1350 }, 32, 7 },
1351 { { .__in6_u
1352 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1354 }, 0, 1 }
1358 /* The precedence table. */
1359 static const struct prefixentry *precedence;
1361 /* The default precedences. */
1362 static const struct prefixentry default_precedence[] =
1364 /* See RFC 3484 for the details. */
1365 { { .__in6_u
1366 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1368 }, 128, 50 },
1369 { { .__in6_u
1370 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1372 }, 16, 30 },
1373 { { .__in6_u
1374 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1376 }, 96, 20 },
1377 { { .__in6_u
1378 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1380 }, 96, 10 },
1381 { { .__in6_u
1382 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1384 }, 0, 40 }
1388 static int
1389 match_prefix (const struct sockaddr_in6 *in6,
1390 const struct prefixentry *list, int default_val)
1392 int idx;
1393 struct sockaddr_in6 in6_mem;
1395 if (in6->sin6_family == PF_INET)
1397 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1399 /* Construct a V4-to-6 mapped address. */
1400 in6_mem.sin6_family = PF_INET6;
1401 in6_mem.sin6_port = in->sin_port;
1402 in6_mem.sin6_flowinfo = 0;
1403 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1404 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1405 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1406 in6_mem.sin6_scope_id = 0;
1408 in6 = &in6_mem;
1410 else if (in6->sin6_family != PF_INET6)
1411 return default_val;
1413 for (idx = 0; ; ++idx)
1415 unsigned int bits = list[idx].bits;
1416 const uint8_t *mask = list[idx].prefix.s6_addr;
1417 const uint8_t *val = in6->sin6_addr.s6_addr;
1419 while (bits >= 8)
1421 if (*mask != *val)
1422 break;
1424 ++mask;
1425 ++val;
1426 bits -= 8;
1429 if (bits < 8)
1431 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1432 /* Match! */
1433 break;
1437 return list[idx].val;
1441 static int
1442 get_label (const struct sockaddr_in6 *in6)
1444 /* XXX What is a good default value? */
1445 return match_prefix (in6, labels, INT_MAX);
1449 static int
1450 get_precedence (const struct sockaddr_in6 *in6)
1452 /* XXX What is a good default value? */
1453 return match_prefix (in6, precedence, 0);
1457 /* Find last bit set in a word. */
1458 static int
1459 fls (uint32_t a)
1461 uint32_t mask;
1462 int n;
1463 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1464 if ((a & mask) != 0)
1465 break;
1466 return n;
1470 static int
1471 rfc3484_sort (const void *p1, const void *p2, void *arg)
1473 const size_t idx1 = *(const size_t *) p1;
1474 const size_t idx2 = *(const size_t *) p2;
1475 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1476 struct sort_result *a1 = &src->results[idx1];
1477 struct sort_result *a2 = &src->results[idx2];
1479 /* Rule 1: Avoid unusable destinations.
1480 We have the got_source_addr flag set if the destination is reachable. */
1481 if (a1->got_source_addr && ! a2->got_source_addr)
1482 return -1;
1483 if (! a1->got_source_addr && a2->got_source_addr)
1484 return 1;
1487 /* Rule 2: Prefer matching scope. Only interesting if both
1488 destination addresses are IPv6. */
1489 int a1_dst_scope
1490 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1492 int a2_dst_scope
1493 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1495 if (a1->got_source_addr)
1497 int a1_src_scope = get_scope (&a1->source_addr);
1498 int a2_src_scope = get_scope (&a2->source_addr);
1500 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1501 return -1;
1502 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1503 return 1;
1507 /* Rule 3: Avoid deprecated addresses. */
1508 if (a1->got_source_addr)
1510 if (!(a1->source_addr_flags & in6ai_deprecated)
1511 && (a2->source_addr_flags & in6ai_deprecated))
1512 return -1;
1513 if ((a1->source_addr_flags & in6ai_deprecated)
1514 && !(a2->source_addr_flags & in6ai_deprecated))
1515 return 1;
1518 /* Rule 4: Prefer home addresses. */
1519 if (a1->got_source_addr)
1521 if (!(a1->source_addr_flags & in6ai_homeaddress)
1522 && (a2->source_addr_flags & in6ai_homeaddress))
1523 return 1;
1524 if ((a1->source_addr_flags & in6ai_homeaddress)
1525 && !(a2->source_addr_flags & in6ai_homeaddress))
1526 return -1;
1529 /* Rule 5: Prefer matching label. */
1530 if (a1->got_source_addr)
1532 int a1_dst_label
1533 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1534 int a1_src_label = get_label (&a1->source_addr);
1536 int a2_dst_label
1537 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1538 int a2_src_label = get_label (&a2->source_addr);
1540 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1541 return -1;
1542 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1543 return 1;
1547 /* Rule 6: Prefer higher precedence. */
1548 int a1_prec
1549 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1550 int a2_prec
1551 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1553 if (a1_prec > a2_prec)
1554 return -1;
1555 if (a1_prec < a2_prec)
1556 return 1;
1559 /* Rule 7: Prefer native transport. */
1560 if (a1->got_source_addr)
1562 /* The same interface index means the same interface which means
1563 there is no difference in transport. This should catch many
1564 (most?) cases. */
1565 if (a1->index != a2->index)
1567 int a1_native = a1->native;
1568 int a2_native = a2->native;
1570 if (a1_native == -1 || a2_native == -1)
1572 uint32_t a1_index;
1573 if (a1_native == -1)
1575 /* If we do not have the information use 'native' as
1576 the default. */
1577 a1_native = 0;
1578 a1_index = a1->index;
1580 else
1581 a1_index = 0xffffffffu;
1583 uint32_t a2_index;
1584 if (a2_native == -1)
1586 /* If we do not have the information use 'native' as
1587 the default. */
1588 a2_native = 0;
1589 a2_index = a2->index;
1591 else
1592 a2_index = 0xffffffffu;
1594 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1596 /* Fill in the results in all the records. */
1597 for (int i = 0; i < src->nresults; ++i)
1598 if (a1_index != -1 && src->results[i].index == a1_index)
1600 assert (src->results[i].native == -1
1601 || src->results[i].native == a1_native);
1602 src->results[i].native = a1_native;
1604 else if (a2_index != -1 && src->results[i].index == a2_index)
1606 assert (src->results[i].native == -1
1607 || src->results[i].native == a2_native);
1608 src->results[i].native = a2_native;
1612 if (a1_native && !a2_native)
1613 return -1;
1614 if (!a1_native && a2_native)
1615 return 1;
1620 /* Rule 8: Prefer smaller scope. */
1621 if (a1_dst_scope < a2_dst_scope)
1622 return -1;
1623 if (a1_dst_scope > a2_dst_scope)
1624 return 1;
1627 /* Rule 9: Use longest matching prefix. */
1628 if (a1->got_source_addr
1629 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1631 int bit1 = 0;
1632 int bit2 = 0;
1634 if (a1->dest_addr->ai_family == PF_INET)
1636 assert (a1->source_addr.sin6_family == PF_INET);
1637 assert (a2->source_addr.sin6_family == PF_INET);
1639 /* Outside of subnets, as defined by the network masks,
1640 common address prefixes for IPv4 addresses make no sense.
1641 So, define a non-zero value only if source and
1642 destination address are on the same subnet. */
1643 struct sockaddr_in *in1_dst
1644 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1645 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1646 struct sockaddr_in *in1_src
1647 = (struct sockaddr_in *) &a1->source_addr;
1648 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1649 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1651 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1652 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1654 struct sockaddr_in *in2_dst
1655 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1656 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1657 struct sockaddr_in *in2_src
1658 = (struct sockaddr_in *) &a2->source_addr;
1659 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1660 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1662 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1663 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1665 else if (a1->dest_addr->ai_family == PF_INET6)
1667 assert (a1->source_addr.sin6_family == PF_INET6);
1668 assert (a2->source_addr.sin6_family == PF_INET6);
1670 struct sockaddr_in6 *in1_dst;
1671 struct sockaddr_in6 *in1_src;
1672 struct sockaddr_in6 *in2_dst;
1673 struct sockaddr_in6 *in2_src;
1675 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1676 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1677 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1678 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1680 int i;
1681 for (i = 0; i < 4; ++i)
1682 if (in1_dst->sin6_addr.s6_addr32[i]
1683 != in1_src->sin6_addr.s6_addr32[i]
1684 || (in2_dst->sin6_addr.s6_addr32[i]
1685 != in2_src->sin6_addr.s6_addr32[i]))
1686 break;
1688 if (i < 4)
1690 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1691 ^ in1_src->sin6_addr.s6_addr32[i]));
1692 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1693 ^ in2_src->sin6_addr.s6_addr32[i]));
1697 if (bit1 > bit2)
1698 return -1;
1699 if (bit1 < bit2)
1700 return 1;
1704 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1705 compare with the value indicating the order in which the entries
1706 have been received from the services. NB: no two entries can have
1707 the same order so the test will never return zero. */
1708 return idx1 < idx2 ? -1 : 1;
1712 static int
1713 in6aicmp (const void *p1, const void *p2)
1715 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1716 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1718 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1722 /* Name of the config file for RFC 3484 sorting (for now). */
1723 #define GAICONF_FNAME "/etc/gai.conf"
1726 /* Non-zero if we are supposed to reload the config file automatically
1727 whenever it changed. */
1728 static int gaiconf_reload_flag;
1730 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1731 static int gaiconf_reload_flag_ever_set;
1733 /* Last modification time. */
1734 #ifdef _STATBUF_ST_NSEC
1736 static struct __timespec64 gaiconf_mtime;
1738 static inline void
1739 save_gaiconf_mtime (const struct __stat64_t64 *st)
1741 gaiconf_mtime = (struct __timespec64) { st->st_mtim.tv_sec,
1742 st->st_mtim.tv_nsec };
1745 static inline bool
1746 check_gaiconf_mtime (const struct __stat64_t64 *st)
1748 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1749 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1752 #else
1754 static time_t gaiconf_mtime;
1756 static inline void
1757 save_gaiconf_mtime (const struct __stat64_t64 *st)
1759 gaiconf_mtime = st->st_mtime;
1762 static inline bool
1763 check_gaiconf_mtime (const struct __stat64_t64 *st)
1765 return st->st_mtime == gaiconf_mtime;
1768 #endif
1771 void
1772 __libc_getaddrinfo_freemem (void)
1774 if (labels != default_labels)
1776 const struct prefixentry *old = labels;
1777 labels = default_labels;
1778 free ((void *) old);
1781 if (precedence != default_precedence)
1783 const struct prefixentry *old = precedence;
1784 precedence = default_precedence;
1785 free ((void *) old);
1788 if (scopes != default_scopes)
1790 const struct scopeentry *old = scopes;
1791 scopes = default_scopes;
1792 free ((void *) old);
1797 struct prefixlist
1799 struct prefixentry entry;
1800 struct prefixlist *next;
1804 struct scopelist
1806 struct scopeentry entry;
1807 struct scopelist *next;
1811 static void
1812 free_prefixlist (struct prefixlist *list)
1814 while (list != NULL)
1816 struct prefixlist *oldp = list;
1817 list = list->next;
1818 free (oldp);
1823 static void
1824 free_scopelist (struct scopelist *list)
1826 while (list != NULL)
1828 struct scopelist *oldp = list;
1829 list = list->next;
1830 free (oldp);
1835 static int
1836 prefixcmp (const void *p1, const void *p2)
1838 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1839 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1841 if (e1->bits < e2->bits)
1842 return 1;
1843 if (e1->bits == e2->bits)
1844 return 0;
1845 return -1;
1849 static int
1850 scopecmp (const void *p1, const void *p2)
1852 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1853 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1855 if (e1->netmask > e2->netmask)
1856 return -1;
1857 if (e1->netmask == e2->netmask)
1858 return 0;
1859 return 1;
1862 static bool
1863 add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
1864 char *val1, char *val2, char **pos)
1866 struct in6_addr prefix;
1867 unsigned long int bits;
1868 unsigned long int val;
1869 char *endp;
1871 bits = 128;
1872 __set_errno (0);
1873 char *cp = strchr (val1, '/');
1874 if (cp != NULL)
1875 *cp++ = '\0';
1876 *pos = cp;
1877 if (inet_pton (AF_INET6, val1, &prefix)
1878 && (cp == NULL
1879 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1880 || errno != ERANGE)
1881 && *endp == '\0'
1882 && bits <= 128
1883 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1884 || errno != ERANGE)
1885 && *endp == '\0'
1886 && val <= INT_MAX)
1888 struct prefixlist *newp = malloc (sizeof (*newp));
1889 if (newp == NULL)
1890 return false;
1892 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1893 newp->entry.bits = bits;
1894 newp->entry.val = val;
1895 newp->next = *listp;
1896 *listp = newp;
1897 ++*lenp;
1898 *nullbitsp |= bits == 0;
1900 return true;
1903 static bool
1904 add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
1905 const struct in6_addr *prefixp, unsigned long int bits,
1906 unsigned long int val)
1908 struct scopelist *newp = malloc (sizeof (*newp));
1909 if (newp == NULL)
1910 return false;
1912 newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
1913 newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
1914 newp->entry.scope = val;
1915 newp->next = *listp;
1916 *listp = newp;
1917 ++*lenp;
1918 *nullbitsp |= bits == 96;
1920 return true;
1923 static void
1924 gaiconf_init (void)
1926 struct prefixlist *labellist = NULL;
1927 size_t nlabellist = 0;
1928 bool labellist_nullbits = false;
1929 struct prefixlist *precedencelist = NULL;
1930 size_t nprecedencelist = 0;
1931 bool precedencelist_nullbits = false;
1932 struct scopelist *scopelist = NULL;
1933 size_t nscopelist = 0;
1934 bool scopelist_nullbits = false;
1936 FILE *fp = fopen (GAICONF_FNAME, "rce");
1937 if (fp == NULL)
1938 goto no_file;
1940 struct __stat64_t64 st;
1941 if (__fstat64_time64 (fileno (fp), &st) != 0)
1943 fclose (fp);
1944 goto no_file;
1947 char *line = NULL;
1948 size_t linelen = 0;
1950 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1952 while (!feof_unlocked (fp))
1954 ssize_t n = __getline (&line, &linelen, fp);
1955 if (n <= 0)
1956 break;
1958 /* Handle comments. No escaping possible so this is easy. */
1959 char *cp = strchr (line, '#');
1960 if (cp != NULL)
1961 *cp = '\0';
1963 cp = line;
1964 while (isspace (*cp))
1965 ++cp;
1967 char *cmd = cp;
1968 while (*cp != '\0' && !isspace (*cp))
1969 ++cp;
1970 size_t cmdlen = cp - cmd;
1972 if (*cp != '\0')
1973 *cp++ = '\0';
1974 while (isspace (*cp))
1975 ++cp;
1977 char *val1 = cp;
1978 while (*cp != '\0' && !isspace (*cp))
1979 ++cp;
1980 size_t val1len = cp - cmd;
1982 /* We always need at least two values. */
1983 if (val1len == 0)
1984 continue;
1986 if (*cp != '\0')
1987 *cp++ = '\0';
1988 while (isspace (*cp))
1989 ++cp;
1991 char *val2 = cp;
1992 while (*cp != '\0' && !isspace (*cp))
1993 ++cp;
1995 /* Ignore the rest of the line. */
1996 *cp = '\0';
1998 switch (cmdlen)
2000 case 5:
2001 if (strcmp (cmd, "label") == 0)
2003 if (!add_prefixlist (&labellist, &nlabellist,
2004 &labellist_nullbits, val1, val2, &cp))
2006 free (line);
2007 fclose (fp);
2008 goto no_file;
2011 break;
2013 case 6:
2014 if (strcmp (cmd, "reload") == 0)
2016 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2017 if (gaiconf_reload_flag)
2018 gaiconf_reload_flag_ever_set = 1;
2020 break;
2022 case 7:
2023 if (strcmp (cmd, "scopev4") == 0)
2025 struct in6_addr prefix;
2026 unsigned long int bits;
2027 unsigned long int val;
2028 char *endp;
2030 bits = 32;
2031 __set_errno (0);
2032 cp = strchr (val1, '/');
2033 if (cp != NULL)
2034 *cp++ = '\0';
2035 if (inet_pton (AF_INET6, val1, &prefix))
2037 bits = 128;
2038 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2039 && (cp == NULL
2040 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2041 || errno != ERANGE)
2042 && *endp == '\0'
2043 && bits >= 96
2044 && bits <= 128
2045 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2046 || errno != ERANGE)
2047 && *endp == '\0'
2048 && val <= INT_MAX)
2050 if (!add_scopelist (&scopelist, &nscopelist,
2051 &scopelist_nullbits, &prefix,
2052 bits, val))
2054 free (line);
2055 fclose (fp);
2056 goto no_file;
2060 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2061 && (cp == NULL
2062 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2063 || errno != ERANGE)
2064 && *endp == '\0'
2065 && bits <= 32
2066 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2067 || errno != ERANGE)
2068 && *endp == '\0'
2069 && val <= INT_MAX)
2071 if (!add_scopelist (&scopelist, &nscopelist,
2072 &scopelist_nullbits, &prefix,
2073 bits + 96, val))
2075 free (line);
2076 fclose (fp);
2077 goto no_file;
2081 break;
2083 case 10:
2084 if (strcmp (cmd, "precedence") == 0)
2086 if (!add_prefixlist (&precedencelist, &nprecedencelist,
2087 &precedencelist_nullbits, val1, val2,
2088 &cp))
2090 free (line);
2091 fclose (fp);
2092 goto no_file;
2095 break;
2099 free (line);
2101 fclose (fp);
2103 /* Create the array for the labels. */
2104 struct prefixentry *new_labels;
2105 if (nlabellist > 0)
2107 if (!labellist_nullbits)
2108 ++nlabellist;
2109 new_labels = malloc (nlabellist * sizeof (*new_labels));
2110 if (new_labels == NULL)
2111 goto no_file;
2113 int i = nlabellist;
2114 if (!labellist_nullbits)
2116 --i;
2117 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2118 new_labels[i].bits = 0;
2119 new_labels[i].val = 1;
2122 struct prefixlist *l = labellist;
2123 while (i-- > 0)
2125 new_labels[i] = l->entry;
2126 l = l->next;
2128 free_prefixlist (labellist);
2129 labellist = NULL;
2131 /* Sort the entries so that the most specific ones are at
2132 the beginning. */
2133 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2135 else
2136 new_labels = (struct prefixentry *) default_labels;
2138 struct prefixentry *new_precedence;
2139 if (nprecedencelist > 0)
2141 if (!precedencelist_nullbits)
2142 ++nprecedencelist;
2143 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2144 if (new_precedence == NULL)
2146 if (new_labels != default_labels)
2147 free (new_labels);
2148 goto no_file;
2151 int i = nprecedencelist;
2152 if (!precedencelist_nullbits)
2154 --i;
2155 memset (&new_precedence[i].prefix, '\0',
2156 sizeof (struct in6_addr));
2157 new_precedence[i].bits = 0;
2158 new_precedence[i].val = 40;
2161 struct prefixlist *l = precedencelist;
2162 while (i-- > 0)
2164 new_precedence[i] = l->entry;
2165 l = l->next;
2167 free_prefixlist (precedencelist);
2168 precedencelist = NULL;
2170 /* Sort the entries so that the most specific ones are at
2171 the beginning. */
2172 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2173 prefixcmp);
2175 else
2176 new_precedence = (struct prefixentry *) default_precedence;
2178 struct scopeentry *new_scopes;
2179 if (nscopelist > 0)
2181 if (!scopelist_nullbits)
2182 ++nscopelist;
2183 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2184 if (new_scopes == NULL)
2186 if (new_labels != default_labels)
2187 free (new_labels);
2188 if (new_precedence != default_precedence)
2189 free (new_precedence);
2190 goto no_file;
2193 int i = nscopelist;
2194 if (!scopelist_nullbits)
2196 --i;
2197 new_scopes[i].addr32 = 0;
2198 new_scopes[i].netmask = 0;
2199 new_scopes[i].scope = 14;
2202 struct scopelist *l = scopelist;
2203 while (i-- > 0)
2205 new_scopes[i] = l->entry;
2206 l = l->next;
2208 free_scopelist (scopelist);
2210 /* Sort the entries so that the most specific ones are at
2211 the beginning. */
2212 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2213 scopecmp);
2215 else
2216 new_scopes = (struct scopeentry *) default_scopes;
2218 /* Now we are ready to replace the values. */
2219 const struct prefixentry *old = labels;
2220 labels = new_labels;
2221 if (old != default_labels)
2222 free ((void *) old);
2224 old = precedence;
2225 precedence = new_precedence;
2226 if (old != default_precedence)
2227 free ((void *) old);
2229 const struct scopeentry *oldscope = scopes;
2230 scopes = new_scopes;
2231 if (oldscope != default_scopes)
2232 free ((void *) oldscope);
2234 save_gaiconf_mtime (&st);
2235 return;
2237 no_file:
2238 free_prefixlist (labellist);
2239 free_prefixlist (precedencelist);
2240 free_scopelist (scopelist);
2242 /* If we previously read the file but it is gone now, free the old data and
2243 use the builtin one. Leave the reload flag alone. */
2244 __libc_getaddrinfo_freemem ();
2248 static void
2249 gaiconf_reload (void)
2251 struct __stat64_t64 st;
2252 if (__stat64_time64 (GAICONF_FNAME, &st) != 0
2253 || !check_gaiconf_mtime (&st))
2254 gaiconf_init ();
2257 static bool
2258 try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
2259 const struct sockaddr *addr, socklen_t addrlen, int family)
2261 int fd = *fdp;
2262 int af = *afp;
2263 socklen_t sl = sizeof (*source_addrp);
2265 while (true)
2267 if (fd != -1 && __connect (fd, addr, addrlen) == 0
2268 && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
2269 return true;
2271 if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
2273 /* This could mean IPv6 sockets are IPv6-only. */
2274 if (fd != -1)
2275 __close_nocancel_nostatus (fd);
2276 *afp = af = AF_INET;
2277 *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
2278 IPPROTO_IP);
2279 continue;
2282 return false;
2285 __builtin_unreachable ();
2289 getaddrinfo (const char *name, const char *service,
2290 const struct addrinfo *hints, struct addrinfo **pai)
2292 int i = 0, last_i = 0;
2293 int nresults = 0;
2294 struct addrinfo *p = NULL;
2295 struct gaih_service gaih_service, *pservice;
2296 struct addrinfo local_hints;
2298 if (name != NULL && name[0] == '*' && name[1] == 0)
2299 name = NULL;
2301 if (service != NULL && service[0] == '*' && service[1] == 0)
2302 service = NULL;
2304 if (name == NULL && service == NULL)
2305 return EAI_NONAME;
2307 if (hints == NULL)
2308 hints = &default_hints;
2310 if (hints->ai_flags
2311 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2312 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2313 |AI_NUMERICSERV|AI_ALL))
2314 return EAI_BADFLAGS;
2316 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2317 return EAI_BADFLAGS;
2319 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2320 && hints->ai_family != AF_INET6)
2321 return EAI_FAMILY;
2323 struct in6addrinfo *in6ai = NULL;
2324 size_t in6ailen = 0;
2325 bool seen_ipv4 = false;
2326 bool seen_ipv6 = false;
2327 bool check_pf_called = false;
2329 if (hints->ai_flags & AI_ADDRCONFIG)
2331 /* We might need information about what interfaces are available.
2332 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2333 cannot cache the results since new interfaces could be added at
2334 any time. */
2335 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2336 check_pf_called = true;
2338 /* Now make a decision on what we return, if anything. */
2339 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2341 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2342 narrow down the search. */
2343 if (seen_ipv4 != seen_ipv6)
2345 local_hints = *hints;
2346 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2347 hints = &local_hints;
2350 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2351 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2353 /* We cannot possibly return a valid answer. */
2354 __free_in6ai (in6ai);
2355 return EAI_NONAME;
2359 if (service && service[0])
2361 char *c;
2362 gaih_service.name = service;
2363 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2364 if (*c != '\0')
2366 if (hints->ai_flags & AI_NUMERICSERV)
2368 __free_in6ai (in6ai);
2369 return EAI_NONAME;
2372 gaih_service.num = -1;
2375 pservice = &gaih_service;
2377 else
2378 pservice = NULL;
2380 struct addrinfo **end = &p;
2381 unsigned int naddrs = 0;
2382 struct scratch_buffer tmpbuf;
2384 scratch_buffer_init (&tmpbuf);
2385 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2386 scratch_buffer_free (&tmpbuf);
2388 if (last_i != 0)
2390 freeaddrinfo (p);
2391 __free_in6ai (in6ai);
2393 return -last_i;
2396 while (*end)
2398 end = &((*end)->ai_next);
2399 ++nresults;
2402 if (naddrs > 1)
2404 /* Read the config file. */
2405 __libc_once_define (static, once);
2406 __typeof (once) old_once = once;
2407 __libc_once (once, gaiconf_init);
2408 /* Sort results according to RFC 3484. */
2409 struct sort_result *results;
2410 size_t *order;
2411 struct addrinfo *q;
2412 struct addrinfo *last = NULL;
2413 char *canonname = NULL;
2414 struct scratch_buffer buf;
2415 scratch_buffer_init (&buf);
2417 if (!scratch_buffer_set_array_size (&buf, nresults,
2418 sizeof (*results) + sizeof (size_t)))
2420 __free_in6ai (in6ai);
2421 return EAI_MEMORY;
2423 results = buf.data;
2425 order = (size_t *) (results + nresults);
2427 /* Now we definitely need the interface information. */
2428 if (! check_pf_called)
2429 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2431 /* If we have information about deprecated and temporary addresses
2432 sort the array now. */
2433 if (in6ai != NULL)
2434 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2436 int fd = -1;
2437 int af = AF_UNSPEC;
2439 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2441 results[i].dest_addr = q;
2442 results[i].native = -1;
2443 order[i] = i;
2445 /* If we just looked up the address for a different
2446 protocol, reuse the result. */
2447 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2448 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2450 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2451 results[i - 1].source_addr_len);
2452 results[i].source_addr_len = results[i - 1].source_addr_len;
2453 results[i].got_source_addr = results[i - 1].got_source_addr;
2454 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2455 results[i].prefixlen = results[i - 1].prefixlen;
2456 results[i].index = results[i - 1].index;
2458 else
2460 results[i].got_source_addr = false;
2461 results[i].source_addr_flags = 0;
2462 results[i].prefixlen = 0;
2463 results[i].index = 0xffffffffu;
2465 /* We overwrite the type with SOCK_DGRAM since we do not
2466 want connect() to connect to the other side. If we
2467 cannot determine the source address remember this
2468 fact. */
2469 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2471 if (fd != -1)
2472 __close_nocancel_nostatus (fd);
2473 af = q->ai_family;
2474 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2476 else
2478 /* Reset the connection. */
2479 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2480 __connect (fd, &sa, sizeof (sa));
2483 if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
2484 q->ai_addrlen, q->ai_family))
2486 results[i].source_addr_len = sizeof (results[i].source_addr);
2487 results[i].got_source_addr = true;
2489 if (in6ai != NULL)
2491 /* See whether the source address is on the list of
2492 deprecated or temporary addresses. */
2493 struct in6addrinfo tmp;
2495 if (q->ai_family == AF_INET && af == AF_INET)
2497 struct sockaddr_in *sinp
2498 = (struct sockaddr_in *) &results[i].source_addr;
2499 tmp.addr[0] = 0;
2500 tmp.addr[1] = 0;
2501 tmp.addr[2] = htonl (0xffff);
2502 /* Special case for lo interface, the source address
2503 being possibly different than the interface
2504 address. */
2505 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2506 == 0x7f000000)
2507 tmp.addr[3] = htonl(0x7f000001);
2508 else
2509 tmp.addr[3] = sinp->sin_addr.s_addr;
2511 else
2513 struct sockaddr_in6 *sin6p
2514 = (struct sockaddr_in6 *) &results[i].source_addr;
2515 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2518 struct in6addrinfo *found
2519 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2520 in6aicmp);
2521 if (found != NULL)
2523 results[i].source_addr_flags = found->flags;
2524 results[i].prefixlen = found->prefixlen;
2525 results[i].index = found->index;
2529 if (q->ai_family == AF_INET && af == AF_INET6)
2531 /* We have to convert the address. The socket is
2532 IPv6 and the request is for IPv4. */
2533 struct sockaddr_in6 *sin6
2534 = (struct sockaddr_in6 *) &results[i].source_addr;
2535 struct sockaddr_in *sin
2536 = (struct sockaddr_in *) &results[i].source_addr;
2537 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2538 sin->sin_family = AF_INET;
2539 /* We do not have to initialize sin_port since this
2540 fields has the same position and size in the IPv6
2541 structure. */
2542 assert (offsetof (struct sockaddr_in, sin_port)
2543 == offsetof (struct sockaddr_in6, sin6_port));
2544 assert (sizeof (sin->sin_port)
2545 == sizeof (sin6->sin6_port));
2546 memcpy (&sin->sin_addr,
2547 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2548 results[i].source_addr_len = sizeof (struct sockaddr_in);
2551 else
2552 /* Just make sure that if we have to process the same
2553 address again we do not copy any memory. */
2554 results[i].source_addr_len = 0;
2557 /* Remember the canonical name. */
2558 if (q->ai_canonname != NULL)
2560 assert (canonname == NULL);
2561 canonname = q->ai_canonname;
2562 q->ai_canonname = NULL;
2566 if (fd != -1)
2567 __close_nocancel_nostatus (fd);
2569 /* We got all the source addresses we can get, now sort using
2570 the information. */
2571 struct sort_result_combo src
2572 = { .results = results, .nresults = nresults };
2573 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2575 __libc_lock_define_initialized (static, lock);
2577 __libc_lock_lock (lock);
2578 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2579 gaiconf_reload ();
2580 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2581 __libc_lock_unlock (lock);
2583 else
2584 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2586 /* Queue the results up as they come out of sorting. */
2587 q = p = results[order[0]].dest_addr;
2588 for (i = 1; i < nresults; ++i)
2589 q = q->ai_next = results[order[i]].dest_addr;
2590 q->ai_next = NULL;
2592 /* Fill in the canonical name into the new first entry. */
2593 p->ai_canonname = canonname;
2595 scratch_buffer_free (&buf);
2598 __free_in6ai (in6ai);
2600 if (p)
2602 *pai = p;
2603 return 0;
2606 return last_i ? -last_i : EAI_NONAME;
2608 libc_hidden_def (getaddrinfo)
2610 nss_interface_function (getaddrinfo)
2612 void
2613 freeaddrinfo (struct addrinfo *ai)
2615 struct addrinfo *p;
2617 while (ai != NULL)
2619 p = ai;
2620 ai = ai->ai_next;
2621 free (p->ai_canonname);
2622 free (p);
2625 libc_hidden_def (freeaddrinfo)