string: Hook up the default implementation on test-strcmp
[glibc.git] / sysdeps / posix / getaddrinfo.c
blobfd22dc4fcbc1dcd773f94e8b3202c10ab3be99fb
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 bool free_at;
124 bool got_ipv6;
127 /* Values for `protoflag'. */
128 #define GAI_PROTO_NOSERVICE 1
129 #define GAI_PROTO_PROTOANY 2
131 static const struct gaih_typeproto gaih_inet_typeproto[] =
133 { 0, 0, 0, false, "" },
134 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
135 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
136 #if defined SOCK_DCCP && defined IPPROTO_DCCP
137 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
138 #endif
139 #ifdef IPPROTO_UDPLITE
140 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
141 #endif
142 #ifdef IPPROTO_SCTP
143 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
144 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
145 #endif
146 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
147 { 0, 0, 0, false, "" }
150 static const struct addrinfo default_hints =
152 .ai_flags = AI_DEFAULT,
153 .ai_family = PF_UNSPEC,
154 .ai_socktype = 0,
155 .ai_protocol = 0,
156 .ai_addrlen = 0,
157 .ai_addr = NULL,
158 .ai_canonname = NULL,
159 .ai_next = NULL
162 static void
163 gaih_result_reset (struct gaih_result *res)
165 if (res->free_at)
166 free (res->at);
167 free (res->canon);
168 memset (res, 0, sizeof (*res));
171 static int
172 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
173 const struct addrinfo *req, struct gaih_servtuple *st,
174 struct scratch_buffer *tmpbuf)
176 struct servent *s;
177 struct servent ts;
178 int r;
182 r = __getservbyname_r (servicename, tp->name, &ts,
183 tmpbuf->data, tmpbuf->length, &s);
184 if (r != 0 || s == NULL)
186 if (r == ERANGE)
188 if (!scratch_buffer_grow (tmpbuf))
189 return -EAI_MEMORY;
191 else
192 return -EAI_SERVICE;
195 while (r);
197 st->socktype = tp->socktype;
198 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
199 ? req->ai_protocol : tp->protocol);
200 st->port = s->s_port;
201 st->set = true;
203 return 0;
206 /* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
207 is not copied, and the struct hostent object must not be deallocated
208 prematurely. The new addresses are appended to the tuple array in RES. */
209 static bool
210 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
211 struct hostent *h, struct gaih_result *res)
213 /* Count the number of addresses in h->h_addr_list. */
214 size_t count = 0;
215 for (char **p = h->h_addr_list; *p != NULL; ++p)
216 ++count;
218 /* Report no data if no addresses are available, or if the incoming
219 address size is larger than what we can store. */
220 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
221 return true;
223 struct gaih_addrtuple *array = res->at;
224 size_t old = 0;
226 while (array != NULL)
228 old++;
229 array = array->next;
232 array = realloc (res->at, (old + count) * sizeof (*array));
234 if (array == NULL)
235 return false;
237 res->got_ipv6 = family == AF_INET6;
238 res->at = array;
239 res->free_at = true;
241 /* Update the next pointers on reallocation. */
242 for (size_t i = 0; i < old; i++)
243 array[i].next = array + i + 1;
245 array += old;
247 memset (array, 0, count * sizeof (*array));
249 for (size_t i = 0; i < count; ++i)
251 if (family == AF_INET && req->ai_family == AF_INET6)
253 /* Perform address mapping. */
254 array[i].family = AF_INET6;
255 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
256 array[i].addr[2] = htonl (0xffff);
258 else
260 array[i].family = family;
261 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
263 array[i].next = array + i + 1;
265 array[0].name = h->h_name;
266 array[count - 1].next = NULL;
268 return true;
271 static int
272 gethosts (nss_gethostbyname3_r fct, int family, const char *name,
273 const struct addrinfo *req, struct scratch_buffer *tmpbuf,
274 struct gaih_result *res, enum nss_status *statusp, int *no_datap)
276 struct hostent th;
277 char *localcanon = NULL;
278 enum nss_status status;
280 *no_datap = 0;
281 while (1)
283 *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
284 tmpbuf->data, tmpbuf->length,
285 &errno, &h_errno, NULL,
286 &localcanon));
287 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
288 || errno != ERANGE)
289 break;
290 if (!scratch_buffer_grow (tmpbuf))
291 return -EAI_MEMORY;
293 if (status == NSS_STATUS_NOTFOUND
294 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
296 if (h_errno == NETDB_INTERNAL)
297 return -EAI_SYSTEM;
298 if (h_errno == TRY_AGAIN)
299 *no_datap = EAI_AGAIN;
300 else
301 *no_datap = h_errno == NO_DATA;
303 else if (status == NSS_STATUS_SUCCESS)
305 if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
306 return -EAI_MEMORY;
308 if (localcanon != NULL && res->canon == NULL)
310 char *canonbuf = __strdup (localcanon);
311 if (canonbuf == NULL)
312 return -EAI_MEMORY;
313 res->canon = canonbuf;
317 return 0;
320 /* This function is called if a canonical name is requested, but if
321 the service function did not provide it. It tries to obtain the
322 name using getcanonname_r from the same service NIP. If the name
323 cannot be canonicalized, return a copy of NAME. Return NULL on
324 memory allocation failure. The returned string is allocated on the
325 heap; the caller has to free it. */
326 static char *
327 getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
329 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
330 char *s = (char *) name;
331 if (cfct != NULL)
333 char buf[256];
334 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
335 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
336 /* If the canonical name cannot be determined, use the passed
337 string. */
338 s = (char *) name;
340 return __strdup (name);
343 /* Process looked up canonical name and if necessary, decode to IDNA. Result
344 is a new string written to CANONP and the earlier string is freed. */
346 static int
347 process_canonname (const struct addrinfo *req, const char *orig_name,
348 struct gaih_result *res)
350 char *canon = res->canon;
352 if ((req->ai_flags & AI_CANONNAME) != 0)
354 bool do_idn = req->ai_flags & AI_CANONIDN;
355 if (do_idn)
357 char *out;
358 int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
359 if (rc == 0)
361 free (canon);
362 canon = out;
364 else if (rc == EAI_IDN_ENCODE)
365 /* Use the punycode name as a fallback. */
366 do_idn = false;
367 else
368 return -rc;
370 if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
371 return -EAI_MEMORY;
374 res->canon = canon;
375 return 0;
378 static int
379 get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
380 struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
382 int i;
383 const struct gaih_typeproto *tp = gaih_inet_typeproto;
385 if (req->ai_protocol || req->ai_socktype)
387 ++tp;
389 while (tp->name[0]
390 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
391 || (req->ai_protocol != 0
392 && !(tp->protoflag & GAI_PROTO_PROTOANY)
393 && req->ai_protocol != tp->protocol)))
394 ++tp;
396 if (! tp->name[0])
398 if (req->ai_socktype)
399 return -EAI_SOCKTYPE;
400 else
401 return -EAI_SERVICE;
405 if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
406 return -EAI_SERVICE;
408 if (service == NULL || service->num >= 0)
410 int port = service != NULL ? htons (service->num) : 0;
412 if (req->ai_socktype || req->ai_protocol)
414 st[0].socktype = tp->socktype;
415 st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
416 ? req->ai_protocol : tp->protocol);
417 st[0].port = port;
418 st[0].set = true;
420 return 0;
423 /* Neither socket type nor protocol is set. Return all socket types
424 we know about. */
425 for (i = 0, ++tp; tp->name[0]; ++tp)
426 if (tp->defaultflag)
428 st[i].socktype = tp->socktype;
429 st[i].protocol = tp->protocol;
430 st[i].port = port;
431 st[i++].set = true;
434 return 0;
437 if (tp->name[0])
438 return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
440 for (i = 0, tp++; tp->name[0]; tp++)
442 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
443 continue;
445 if (req->ai_socktype != 0
446 && req->ai_socktype != tp->socktype)
447 continue;
448 if (req->ai_protocol != 0
449 && !(tp->protoflag & GAI_PROTO_PROTOANY)
450 && req->ai_protocol != tp->protocol)
451 continue;
453 if (gaih_inet_serv (service->name,
454 tp, req, &st[i], tmpbuf) != 0)
455 continue;
457 i++;
460 if (!st[0].set)
461 return -EAI_SERVICE;
463 return 0;
466 #ifdef USE_NSCD
467 /* Query addresses from nscd cache, returning a non-zero value on error.
468 RES members have the lookup result; RES->AT is NULL if there were no errors
469 but also no results. */
471 static int
472 get_nscd_addresses (const char *name, const struct addrinfo *req,
473 struct gaih_result *res)
475 if (__nss_not_use_nscd_hosts > 0
476 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
477 __nss_not_use_nscd_hosts = 0;
479 res->at = NULL;
481 if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
482 return 0;
484 /* Try to use nscd. */
485 struct nscd_ai_result *air = NULL;
486 int err = __nscd_getai (name, &air, &h_errno);
488 if (__glibc_unlikely (air == NULL))
490 /* The database contains a negative entry. */
491 if (err == 0)
492 return -EAI_NONAME;
493 if (__nss_not_use_nscd_hosts == 0)
495 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
496 return -EAI_MEMORY;
497 if (h_errno == TRY_AGAIN)
498 return -EAI_AGAIN;
499 return -EAI_SYSTEM;
501 return 0;
504 /* Transform into gaih_addrtuple list. */
505 int result = 0;
506 char *addrs = air->addrs;
508 struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
509 struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
510 if (at == NULL)
512 result = -EAI_MEMORY;
513 goto out;
516 res->free_at = true;
518 int count = 0;
519 for (int i = 0; i < air->naddrs; ++i)
521 socklen_t size = (air->family[i] == AF_INET
522 ? INADDRSZ : IN6ADDRSZ);
524 if (!((air->family[i] == AF_INET
525 && req->ai_family == AF_INET6
526 && (req->ai_flags & AI_V4MAPPED) != 0)
527 || req->ai_family == AF_UNSPEC
528 || air->family[i] == req->ai_family))
530 /* Skip over non-matching result. */
531 addrs += size;
532 continue;
535 if (air->family[i] == AF_INET && req->ai_family == AF_INET6
536 && (req->ai_flags & AI_V4MAPPED))
538 at[count].family = AF_INET6;
539 at[count].addr[3] = *(uint32_t *) addrs;
540 at[count].addr[2] = htonl (0xffff);
542 else if (req->ai_family == AF_UNSPEC
543 || air->family[i] == req->ai_family)
545 at[count].family = air->family[i];
546 memcpy (at[count].addr, addrs, size);
547 if (air->family[i] == AF_INET6)
548 res->got_ipv6 = true;
550 at[count].next = at + count + 1;
551 count++;
552 addrs += size;
555 if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
557 char *canonbuf = __strdup (air->canon);
558 if (canonbuf == NULL)
560 result = -EAI_MEMORY;
561 goto out;
563 res->canon = canonbuf;
566 if (count == 0)
568 result = -EAI_NONAME;
569 goto out;
572 at[count - 1].next = NULL;
574 res->at = at;
576 out:
577 free (air);
578 if (result != 0)
580 free (at);
581 res->free_at = false;
584 return result;
586 #endif
588 static int
589 get_nss_addresses (const char *name, const struct addrinfo *req,
590 struct scratch_buffer *tmpbuf, struct gaih_result *res)
592 int no_data = 0;
593 int no_inet6_data = 0;
594 nss_action_list nip;
595 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
596 enum nss_status status = NSS_STATUS_UNAVAIL;
597 int no_more;
598 struct resolv_context *res_ctx = NULL;
599 bool do_merge = false;
600 int result = 0;
602 no_more = !__nss_database_get (nss_database_hosts, &nip);
604 /* If we are looking for both IPv4 and IPv6 address we don't
605 want the lookup functions to automatically promote IPv4
606 addresses to IPv6 addresses, so we use the no_inet6
607 function variant. */
608 res_ctx = __resolv_context_get ();
609 if (res_ctx == NULL)
610 no_more = 1;
612 while (!no_more)
614 /* Always start afresh; continue should discard previous results
615 and the hosts database does not support merge. */
616 gaih_result_reset (res);
618 if (do_merge)
620 __set_h_errno (NETDB_INTERNAL);
621 __set_errno (EBUSY);
622 break;
625 no_data = 0;
626 nss_gethostbyname4_r *fct4 = NULL;
628 /* gethostbyname4_r sends out parallel A and AAAA queries and
629 is thus only suitable for PF_UNSPEC. */
630 if (req->ai_family == PF_UNSPEC)
631 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
633 if (fct4 != NULL)
635 while (1)
637 status = DL_CALL_FCT (fct4, (name, &res->at,
638 tmpbuf->data, tmpbuf->length,
639 &errno, &h_errno,
640 NULL));
641 if (status == NSS_STATUS_SUCCESS)
642 break;
643 /* gethostbyname4_r may write into AT, so reset it. */
644 res->at = NULL;
645 if (status != NSS_STATUS_TRYAGAIN
646 || errno != ERANGE || h_errno != NETDB_INTERNAL)
648 if (h_errno == TRY_AGAIN)
649 no_data = EAI_AGAIN;
650 else
651 no_data = h_errno == NO_DATA;
652 break;
655 if (!scratch_buffer_grow (tmpbuf))
657 __resolv_context_put (res_ctx);
658 result = -EAI_MEMORY;
659 goto out;
663 if (status == NSS_STATUS_SUCCESS)
665 assert (!no_data);
666 no_data = 1;
668 if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
670 char *canonbuf = __strdup (res->at->name);
671 if (canonbuf == NULL)
673 __resolv_context_put (res_ctx);
674 result = -EAI_MEMORY;
675 goto out;
677 res->canon = canonbuf;
680 struct gaih_addrtuple **pat = &res->at;
682 while (*pat != NULL)
684 if ((*pat)->family == AF_INET
685 && req->ai_family == AF_INET6
686 && (req->ai_flags & AI_V4MAPPED) != 0)
688 uint32_t *pataddr = (*pat)->addr;
689 (*pat)->family = AF_INET6;
690 pataddr[3] = pataddr[0];
691 pataddr[2] = htonl (0xffff);
692 pataddr[1] = 0;
693 pataddr[0] = 0;
694 pat = &((*pat)->next);
695 no_data = 0;
697 else if (req->ai_family == AF_UNSPEC
698 || (*pat)->family == req->ai_family)
700 pat = &((*pat)->next);
702 no_data = 0;
703 if (req->ai_family == AF_INET6)
704 res->got_ipv6 = true;
706 else
707 *pat = ((*pat)->next);
711 no_inet6_data = no_data;
713 else
715 nss_gethostbyname3_r *fct = NULL;
716 if (req->ai_flags & AI_CANONNAME)
717 /* No need to use this function if we do not look for
718 the canonical name. The function does not exist in
719 all NSS modules and therefore the lookup would
720 often fail. */
721 fct = __nss_lookup_function (nip, "gethostbyname3_r");
722 if (fct == NULL)
723 /* We are cheating here. The gethostbyname2_r
724 function does not have the same interface as
725 gethostbyname3_r but the extra arguments the
726 latter takes are added at the end. So the
727 gethostbyname2_r code will just ignore them. */
728 fct = __nss_lookup_function (nip, "gethostbyname2_r");
730 if (fct != NULL)
732 if (req->ai_family == AF_INET6
733 || req->ai_family == AF_UNSPEC)
735 if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
736 res, &status, &no_data)) != 0)
738 __resolv_context_put (res_ctx);
739 goto out;
741 no_inet6_data = no_data;
742 inet6_status = status;
744 if (req->ai_family == AF_INET
745 || req->ai_family == AF_UNSPEC
746 || (req->ai_family == AF_INET6
747 && (req->ai_flags & AI_V4MAPPED)
748 /* Avoid generating the mapped addresses if we
749 know we are not going to need them. */
750 && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
752 if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
753 res, &status, &no_data)) != 0)
755 __resolv_context_put (res_ctx);
756 goto out;
759 if (req->ai_family == AF_INET)
761 no_inet6_data = no_data;
762 inet6_status = status;
766 /* If we found one address for AF_INET or AF_INET6,
767 don't continue the search. */
768 if (inet6_status == NSS_STATUS_SUCCESS
769 || status == NSS_STATUS_SUCCESS)
771 if ((req->ai_flags & AI_CANONNAME) != 0
772 && res->canon == NULL)
774 char *canonbuf = getcanonname (nip, res->at, name);
775 if (canonbuf == NULL)
777 __resolv_context_put (res_ctx);
778 result = -EAI_MEMORY;
779 goto out;
781 res->canon = canonbuf;
783 status = NSS_STATUS_SUCCESS;
785 else
787 /* We can have different states for AF_INET and
788 AF_INET6. Try to find a useful one for both. */
789 if (inet6_status == NSS_STATUS_TRYAGAIN)
790 status = NSS_STATUS_TRYAGAIN;
791 else if (status == NSS_STATUS_UNAVAIL
792 && inet6_status != NSS_STATUS_UNAVAIL)
793 status = inet6_status;
796 else
798 /* Could not locate any of the lookup functions.
799 The NSS lookup code does not consistently set
800 errno, so we need to supply our own error
801 code here. The root cause could either be a
802 resource allocation failure, or a missing
803 service function in the DSO (so it should not
804 be listed in /etc/nsswitch.conf). Assume the
805 former, and return EBUSY. */
806 status = NSS_STATUS_UNAVAIL;
807 __set_h_errno (NETDB_INTERNAL);
808 __set_errno (EBUSY);
812 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
813 break;
815 /* The hosts database does not support MERGE. */
816 if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
817 do_merge = true;
819 nip++;
820 if (nip->module == NULL)
821 no_more = -1;
824 __resolv_context_put (res_ctx);
826 /* If we have a failure which sets errno, report it using
827 EAI_SYSTEM. */
828 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
829 && h_errno == NETDB_INTERNAL)
831 result = -EAI_SYSTEM;
832 goto out;
835 if (no_data != 0 && no_inet6_data != 0)
837 /* If both requests timed out report this. */
838 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
839 result = -EAI_AGAIN;
840 else
841 /* We made requests but they turned out no data. The name
842 is known, though. */
843 result = -EAI_NODATA;
846 out:
847 if (result != 0)
848 gaih_result_reset (res);
849 return result;
852 /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
853 NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
854 the function cannot determine a result, RES->AT is set to NULL and 0
855 returned. */
857 static int
858 text_to_binary_address (const char *name, const struct addrinfo *req,
859 struct gaih_result *res)
861 struct gaih_addrtuple *at = res->at;
862 int result = 0;
864 assert (at != NULL);
866 memset (at->addr, 0, sizeof (at->addr));
867 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
869 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
870 at->family = AF_INET;
871 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
873 at->addr[3] = at->addr[0];
874 at->addr[2] = htonl (0xffff);
875 at->addr[1] = 0;
876 at->addr[0] = 0;
877 at->family = AF_INET6;
879 else
881 result = -EAI_ADDRFAMILY;
882 goto out;
885 if (req->ai_flags & AI_CANONNAME)
887 char *canonbuf = __strdup (name);
888 if (canonbuf == NULL)
890 result = -EAI_MEMORY;
891 goto out;
893 res->canon = canonbuf;
895 return 0;
898 char *scope_delim = strchr (name, SCOPE_DELIMITER);
899 int e;
901 if (scope_delim == NULL)
902 e = inet_pton (AF_INET6, name, at->addr);
903 else
904 e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr);
906 if (e > 0)
908 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
909 at->family = AF_INET6;
910 else if (req->ai_family == AF_INET
911 && IN6_IS_ADDR_V4MAPPED (at->addr))
913 at->addr[0] = at->addr[3];
914 at->family = AF_INET;
916 else
918 result = -EAI_ADDRFAMILY;
919 goto out;
922 if (scope_delim != NULL
923 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
924 scope_delim + 1, &at->scopeid) != 0)
926 result = -EAI_NONAME;
927 goto out;
930 if (req->ai_flags & AI_CANONNAME)
932 char *canonbuf = __strdup (name);
933 if (canonbuf == NULL)
935 result = -EAI_MEMORY;
936 goto out;
938 res->canon = canonbuf;
940 return 0;
943 if ((req->ai_flags & AI_NUMERICHOST))
944 result = -EAI_NONAME;
946 out:
947 res->at = NULL;
948 return result;
951 /* If possible, call the simple, old functions, which do not support IPv6 scope
952 ids, nor retrieving the canonical name. */
954 static int
955 try_simple_gethostbyname (const char *name, const struct addrinfo *req,
956 struct scratch_buffer *tmpbuf,
957 struct gaih_result *res)
959 res->at = NULL;
961 if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
962 return 0;
964 int rc;
965 struct hostent th;
966 struct hostent *h;
968 while (1)
970 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
971 tmpbuf->length, &h, &h_errno);
972 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
973 break;
974 if (!scratch_buffer_grow (tmpbuf))
975 return -EAI_MEMORY;
978 if (rc == 0)
980 if (h != NULL)
982 /* We found data, convert it. RES->AT from the conversion will
983 either be an allocated block or NULL, both of which are safe to
984 pass to free (). */
985 if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
986 return -EAI_MEMORY;
988 res->free_at = true;
989 return 0;
991 if (h_errno == NO_DATA)
992 return -EAI_NODATA;
994 return -EAI_NONAME;
997 if (h_errno == NETDB_INTERNAL)
998 return -EAI_SYSTEM;
999 if (h_errno == TRY_AGAIN)
1000 return -EAI_AGAIN;
1002 /* We made requests but they turned out no data.
1003 The name is known, though. */
1004 return -EAI_NODATA;
1007 /* Add local address information into RES. RES->AT is assumed to have enough
1008 space for two tuples and is zeroed out. */
1010 static void
1011 get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
1013 struct gaih_addrtuple *atr = res->at;
1014 if (req->ai_family == AF_UNSPEC)
1015 res->at->next = res->at + 1;
1017 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1019 res->at->family = AF_INET6;
1020 if ((req->ai_flags & AI_PASSIVE) == 0)
1021 memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1022 atr = res->at->next;
1025 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1027 atr->family = AF_INET;
1028 if ((req->ai_flags & AI_PASSIVE) == 0)
1029 atr->addr[0] = htonl (INADDR_LOOPBACK);
1033 /* Generate results in PAI and its count in NADDRS. Return 0 on success or an
1034 error code on failure. */
1036 static int
1037 generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
1038 const struct gaih_servtuple *st, struct addrinfo **pai,
1039 unsigned int *naddrs)
1041 size_t socklen;
1042 sa_family_t family;
1044 /* Buffer is the size of an unformatted IPv6 address in printable format. */
1045 for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
1047 family = at->family;
1048 if (family == AF_INET6)
1050 socklen = sizeof (struct sockaddr_in6);
1052 /* If we looked up IPv4 mapped address discard them here if
1053 the caller isn't interested in all address and we have
1054 found at least one IPv6 address. */
1055 if (res->got_ipv6
1056 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1057 && IN6_IS_ADDR_V4MAPPED (at->addr))
1058 continue;
1060 else
1061 socklen = sizeof (struct sockaddr_in);
1063 for (int i = 0; st[i].set; i++)
1065 struct addrinfo *ai;
1066 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1067 if (ai == NULL)
1068 return -EAI_MEMORY;
1070 ai->ai_flags = req->ai_flags;
1071 ai->ai_family = family;
1072 ai->ai_socktype = st[i].socktype;
1073 ai->ai_protocol = st[i].protocol;
1074 ai->ai_addrlen = socklen;
1075 ai->ai_addr = (void *) (ai + 1);
1077 /* We only add the canonical name once. */
1078 ai->ai_canonname = res->canon;
1079 res->canon = NULL;
1081 #ifdef _HAVE_SA_LEN
1082 ai->ai_addr->sa_len = socklen;
1083 #endif /* _HAVE_SA_LEN */
1084 ai->ai_addr->sa_family = family;
1086 /* In case of an allocation error the list must be NULL
1087 terminated. */
1088 ai->ai_next = NULL;
1090 if (family == AF_INET6)
1092 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
1093 sin6p->sin6_port = st[i].port;
1094 sin6p->sin6_flowinfo = 0;
1095 memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
1096 sin6p->sin6_scope_id = at->scopeid;
1098 else
1100 struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
1101 sinp->sin_port = st[i].port;
1102 memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
1103 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1106 pai = &(ai->ai_next);
1109 ++*naddrs;
1111 return 0;
1114 static int
1115 gaih_inet (const char *name, const struct gaih_service *service,
1116 const struct addrinfo *req, struct addrinfo **pai,
1117 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
1119 struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
1120 / sizeof (struct gaih_typeproto)] = {0};
1122 const char *orig_name = name;
1124 int rc;
1125 if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
1126 return rc;
1128 bool malloc_name = false;
1129 struct gaih_addrtuple *addrmem = NULL;
1130 int result = 0;
1132 struct gaih_result res = {0};
1133 struct gaih_addrtuple local_at[2] = {0};
1135 res.at = local_at;
1137 if (__glibc_unlikely (name == NULL))
1139 get_local_addresses (req, &res);
1140 goto process_list;
1143 if (req->ai_flags & AI_IDN)
1145 char *out;
1146 result = __idna_to_dns_encoding (name, &out);
1147 if (result != 0)
1148 return -result;
1149 name = out;
1150 malloc_name = true;
1153 if ((result = text_to_binary_address (name, req, &res)) != 0)
1154 goto free_and_return;
1155 else if (res.at != NULL)
1156 goto process_list;
1158 if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
1159 goto free_and_return;
1160 else if (res.at != NULL)
1161 goto process_list;
1163 #ifdef USE_NSCD
1164 if ((result = get_nscd_addresses (name, req, &res)) != 0)
1165 goto free_and_return;
1166 else if (res.at != NULL)
1167 goto process_list;
1168 #endif
1170 if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
1171 goto free_and_return;
1172 else if (res.at != NULL)
1173 goto process_list;
1175 /* None of the lookups worked, so name not found. */
1176 result = -EAI_NONAME;
1177 goto free_and_return;
1179 process_list:
1180 /* Set up the canonical name if we need it. */
1181 if ((result = process_canonname (req, orig_name, &res)) != 0)
1182 goto free_and_return;
1184 result = generate_addrinfo (req, &res, st, pai, naddrs);
1186 free_and_return:
1187 if (malloc_name)
1188 free ((char *) name);
1189 free (addrmem);
1190 if (res.free_at)
1191 free (res.at);
1192 free (res.canon);
1194 return result;
1198 struct sort_result
1200 struct addrinfo *dest_addr;
1201 /* Using sockaddr_storage is for now overkill. We only support IPv4
1202 and IPv6 so far. If this changes at some point we can adjust the
1203 type here. */
1204 struct sockaddr_in6 source_addr;
1205 uint8_t source_addr_len;
1206 bool got_source_addr;
1207 uint8_t source_addr_flags;
1208 uint8_t prefixlen;
1209 uint32_t index;
1210 int32_t native;
1213 struct sort_result_combo
1215 struct sort_result *results;
1216 int nresults;
1220 #if __BYTE_ORDER == __BIG_ENDIAN
1221 # define htonl_c(n) n
1222 #else
1223 # define htonl_c(n) __bswap_constant_32 (n)
1224 #endif
1226 static const struct scopeentry
1228 union
1230 char addr[4];
1231 uint32_t addr32;
1233 uint32_t netmask;
1234 int32_t scope;
1235 } default_scopes[] =
1237 /* Link-local addresses: scope 2. */
1238 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1239 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1240 /* Default: scope 14. */
1241 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1244 /* The label table. */
1245 static const struct scopeentry *scopes;
1248 static int
1249 get_scope (const struct sockaddr_in6 *in6)
1251 int scope;
1252 if (in6->sin6_family == PF_INET6)
1254 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1256 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1257 /* RFC 4291 2.5.3 says that the loopback address is to be
1258 treated like a link-local address. */
1259 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1260 scope = 2;
1261 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1262 scope = 5;
1263 else
1264 /* XXX Is this the correct default behavior? */
1265 scope = 14;
1267 else
1268 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1270 else if (in6->sin6_family == PF_INET)
1272 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1274 size_t cnt = 0;
1275 while (1)
1277 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1278 == scopes[cnt].addr32)
1279 return scopes[cnt].scope;
1281 ++cnt;
1283 /* NOTREACHED */
1285 else
1286 /* XXX What is a good default? */
1287 scope = 15;
1289 return scope;
1293 struct prefixentry
1295 struct in6_addr prefix;
1296 unsigned int bits;
1297 int val;
1301 /* The label table. */
1302 static const struct prefixentry *labels;
1304 /* Default labels. */
1305 static const struct prefixentry default_labels[] =
1307 /* See RFC 3484 for the details. */
1308 { { .__in6_u
1309 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1311 }, 128, 0 },
1312 { { .__in6_u
1313 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1315 }, 16, 2 },
1316 { { .__in6_u
1317 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1319 }, 96, 3 },
1320 { { .__in6_u
1321 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1323 }, 96, 4 },
1324 /* The next two entries differ from RFC 3484. We need to treat
1325 IPv6 site-local addresses special because they are never NATed,
1326 unlike site-locale IPv4 addresses. If this would not happen, on
1327 machines which have only IPv4 and IPv6 site-local addresses, the
1328 sorting would prefer the IPv6 site-local addresses, causing
1329 unnecessary delays when trying to connect to a global IPv6 address
1330 through a site-local IPv6 address. */
1331 { { .__in6_u
1332 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1334 }, 10, 5 },
1335 { { .__in6_u
1336 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1338 }, 7, 6 },
1339 /* Additional rule for Teredo tunnels. */
1340 { { .__in6_u
1341 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1343 }, 32, 7 },
1344 { { .__in6_u
1345 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1347 }, 0, 1 }
1351 /* The precedence table. */
1352 static const struct prefixentry *precedence;
1354 /* The default precedences. */
1355 static const struct prefixentry default_precedence[] =
1357 /* See RFC 3484 for the details. */
1358 { { .__in6_u
1359 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1361 }, 128, 50 },
1362 { { .__in6_u
1363 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1365 }, 16, 30 },
1366 { { .__in6_u
1367 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1369 }, 96, 20 },
1370 { { .__in6_u
1371 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1373 }, 96, 10 },
1374 { { .__in6_u
1375 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1377 }, 0, 40 }
1381 static int
1382 match_prefix (const struct sockaddr_in6 *in6,
1383 const struct prefixentry *list, int default_val)
1385 int idx;
1386 struct sockaddr_in6 in6_mem;
1388 if (in6->sin6_family == PF_INET)
1390 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1392 /* Construct a V4-to-6 mapped address. */
1393 in6_mem.sin6_family = PF_INET6;
1394 in6_mem.sin6_port = in->sin_port;
1395 in6_mem.sin6_flowinfo = 0;
1396 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1397 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1398 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1399 in6_mem.sin6_scope_id = 0;
1401 in6 = &in6_mem;
1403 else if (in6->sin6_family != PF_INET6)
1404 return default_val;
1406 for (idx = 0; ; ++idx)
1408 unsigned int bits = list[idx].bits;
1409 const uint8_t *mask = list[idx].prefix.s6_addr;
1410 const uint8_t *val = in6->sin6_addr.s6_addr;
1412 while (bits >= 8)
1414 if (*mask != *val)
1415 break;
1417 ++mask;
1418 ++val;
1419 bits -= 8;
1422 if (bits < 8)
1424 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1425 /* Match! */
1426 break;
1430 return list[idx].val;
1434 static int
1435 get_label (const struct sockaddr_in6 *in6)
1437 /* XXX What is a good default value? */
1438 return match_prefix (in6, labels, INT_MAX);
1442 static int
1443 get_precedence (const struct sockaddr_in6 *in6)
1445 /* XXX What is a good default value? */
1446 return match_prefix (in6, precedence, 0);
1450 /* Find last bit set in a word. */
1451 static int
1452 fls (uint32_t a)
1454 uint32_t mask;
1455 int n;
1456 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1457 if ((a & mask) != 0)
1458 break;
1459 return n;
1463 static int
1464 rfc3484_sort (const void *p1, const void *p2, void *arg)
1466 const size_t idx1 = *(const size_t *) p1;
1467 const size_t idx2 = *(const size_t *) p2;
1468 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1469 struct sort_result *a1 = &src->results[idx1];
1470 struct sort_result *a2 = &src->results[idx2];
1472 /* Rule 1: Avoid unusable destinations.
1473 We have the got_source_addr flag set if the destination is reachable. */
1474 if (a1->got_source_addr && ! a2->got_source_addr)
1475 return -1;
1476 if (! a1->got_source_addr && a2->got_source_addr)
1477 return 1;
1480 /* Rule 2: Prefer matching scope. Only interesting if both
1481 destination addresses are IPv6. */
1482 int a1_dst_scope
1483 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1485 int a2_dst_scope
1486 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1488 if (a1->got_source_addr)
1490 int a1_src_scope = get_scope (&a1->source_addr);
1491 int a2_src_scope = get_scope (&a2->source_addr);
1493 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1494 return -1;
1495 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1496 return 1;
1500 /* Rule 3: Avoid deprecated addresses. */
1501 if (a1->got_source_addr)
1503 if (!(a1->source_addr_flags & in6ai_deprecated)
1504 && (a2->source_addr_flags & in6ai_deprecated))
1505 return -1;
1506 if ((a1->source_addr_flags & in6ai_deprecated)
1507 && !(a2->source_addr_flags & in6ai_deprecated))
1508 return 1;
1511 /* Rule 4: Prefer home addresses. */
1512 if (a1->got_source_addr)
1514 if (!(a1->source_addr_flags & in6ai_homeaddress)
1515 && (a2->source_addr_flags & in6ai_homeaddress))
1516 return 1;
1517 if ((a1->source_addr_flags & in6ai_homeaddress)
1518 && !(a2->source_addr_flags & in6ai_homeaddress))
1519 return -1;
1522 /* Rule 5: Prefer matching label. */
1523 if (a1->got_source_addr)
1525 int a1_dst_label
1526 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1527 int a1_src_label = get_label (&a1->source_addr);
1529 int a2_dst_label
1530 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1531 int a2_src_label = get_label (&a2->source_addr);
1533 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1534 return -1;
1535 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1536 return 1;
1540 /* Rule 6: Prefer higher precedence. */
1541 int a1_prec
1542 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1543 int a2_prec
1544 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1546 if (a1_prec > a2_prec)
1547 return -1;
1548 if (a1_prec < a2_prec)
1549 return 1;
1552 /* Rule 7: Prefer native transport. */
1553 if (a1->got_source_addr)
1555 /* The same interface index means the same interface which means
1556 there is no difference in transport. This should catch many
1557 (most?) cases. */
1558 if (a1->index != a2->index)
1560 int a1_native = a1->native;
1561 int a2_native = a2->native;
1563 if (a1_native == -1 || a2_native == -1)
1565 uint32_t a1_index;
1566 if (a1_native == -1)
1568 /* If we do not have the information use 'native' as
1569 the default. */
1570 a1_native = 0;
1571 a1_index = a1->index;
1573 else
1574 a1_index = 0xffffffffu;
1576 uint32_t a2_index;
1577 if (a2_native == -1)
1579 /* If we do not have the information use 'native' as
1580 the default. */
1581 a2_native = 0;
1582 a2_index = a2->index;
1584 else
1585 a2_index = 0xffffffffu;
1587 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1589 /* Fill in the results in all the records. */
1590 for (int i = 0; i < src->nresults; ++i)
1591 if (a1_index != -1 && src->results[i].index == a1_index)
1593 assert (src->results[i].native == -1
1594 || src->results[i].native == a1_native);
1595 src->results[i].native = a1_native;
1597 else if (a2_index != -1 && src->results[i].index == a2_index)
1599 assert (src->results[i].native == -1
1600 || src->results[i].native == a2_native);
1601 src->results[i].native = a2_native;
1605 if (a1_native && !a2_native)
1606 return -1;
1607 if (!a1_native && a2_native)
1608 return 1;
1613 /* Rule 8: Prefer smaller scope. */
1614 if (a1_dst_scope < a2_dst_scope)
1615 return -1;
1616 if (a1_dst_scope > a2_dst_scope)
1617 return 1;
1620 /* Rule 9: Use longest matching prefix. */
1621 if (a1->got_source_addr
1622 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1624 int bit1 = 0;
1625 int bit2 = 0;
1627 if (a1->dest_addr->ai_family == PF_INET)
1629 assert (a1->source_addr.sin6_family == PF_INET);
1630 assert (a2->source_addr.sin6_family == PF_INET);
1632 /* Outside of subnets, as defined by the network masks,
1633 common address prefixes for IPv4 addresses make no sense.
1634 So, define a non-zero value only if source and
1635 destination address are on the same subnet. */
1636 struct sockaddr_in *in1_dst
1637 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1638 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1639 struct sockaddr_in *in1_src
1640 = (struct sockaddr_in *) &a1->source_addr;
1641 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1642 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1644 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1645 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1647 struct sockaddr_in *in2_dst
1648 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1649 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1650 struct sockaddr_in *in2_src
1651 = (struct sockaddr_in *) &a2->source_addr;
1652 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1653 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1655 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1656 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1658 else if (a1->dest_addr->ai_family == PF_INET6)
1660 assert (a1->source_addr.sin6_family == PF_INET6);
1661 assert (a2->source_addr.sin6_family == PF_INET6);
1663 struct sockaddr_in6 *in1_dst;
1664 struct sockaddr_in6 *in1_src;
1665 struct sockaddr_in6 *in2_dst;
1666 struct sockaddr_in6 *in2_src;
1668 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1669 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1670 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1671 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1673 int i;
1674 for (i = 0; i < 4; ++i)
1675 if (in1_dst->sin6_addr.s6_addr32[i]
1676 != in1_src->sin6_addr.s6_addr32[i]
1677 || (in2_dst->sin6_addr.s6_addr32[i]
1678 != in2_src->sin6_addr.s6_addr32[i]))
1679 break;
1681 if (i < 4)
1683 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1684 ^ in1_src->sin6_addr.s6_addr32[i]));
1685 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1686 ^ in2_src->sin6_addr.s6_addr32[i]));
1690 if (bit1 > bit2)
1691 return -1;
1692 if (bit1 < bit2)
1693 return 1;
1697 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1698 compare with the value indicating the order in which the entries
1699 have been received from the services. NB: no two entries can have
1700 the same order so the test will never return zero. */
1701 return idx1 < idx2 ? -1 : 1;
1705 static int
1706 in6aicmp (const void *p1, const void *p2)
1708 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1709 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1711 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1715 /* Name of the config file for RFC 3484 sorting (for now). */
1716 #define GAICONF_FNAME "/etc/gai.conf"
1719 /* Non-zero if we are supposed to reload the config file automatically
1720 whenever it changed. */
1721 static int gaiconf_reload_flag;
1723 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1724 static int gaiconf_reload_flag_ever_set;
1726 /* Last modification time. */
1727 #ifdef _STATBUF_ST_NSEC
1729 static struct __timespec64 gaiconf_mtime;
1731 static inline void
1732 save_gaiconf_mtime (const struct __stat64_t64 *st)
1734 gaiconf_mtime = (struct __timespec64) { st->st_mtim.tv_sec,
1735 st->st_mtim.tv_nsec };
1738 static inline bool
1739 check_gaiconf_mtime (const struct __stat64_t64 *st)
1741 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1742 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1745 #else
1747 static time_t gaiconf_mtime;
1749 static inline void
1750 save_gaiconf_mtime (const struct __stat64_t64 *st)
1752 gaiconf_mtime = st->st_mtime;
1755 static inline bool
1756 check_gaiconf_mtime (const struct __stat64_t64 *st)
1758 return st->st_mtime == gaiconf_mtime;
1761 #endif
1764 libc_freeres_fn(fini)
1766 if (labels != default_labels)
1768 const struct prefixentry *old = labels;
1769 labels = default_labels;
1770 free ((void *) old);
1773 if (precedence != default_precedence)
1775 const struct prefixentry *old = precedence;
1776 precedence = default_precedence;
1777 free ((void *) old);
1780 if (scopes != default_scopes)
1782 const struct scopeentry *old = scopes;
1783 scopes = default_scopes;
1784 free ((void *) old);
1789 struct prefixlist
1791 struct prefixentry entry;
1792 struct prefixlist *next;
1796 struct scopelist
1798 struct scopeentry entry;
1799 struct scopelist *next;
1803 static void
1804 free_prefixlist (struct prefixlist *list)
1806 while (list != NULL)
1808 struct prefixlist *oldp = list;
1809 list = list->next;
1810 free (oldp);
1815 static void
1816 free_scopelist (struct scopelist *list)
1818 while (list != NULL)
1820 struct scopelist *oldp = list;
1821 list = list->next;
1822 free (oldp);
1827 static int
1828 prefixcmp (const void *p1, const void *p2)
1830 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1831 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1833 if (e1->bits < e2->bits)
1834 return 1;
1835 if (e1->bits == e2->bits)
1836 return 0;
1837 return -1;
1841 static int
1842 scopecmp (const void *p1, const void *p2)
1844 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1845 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1847 if (e1->netmask > e2->netmask)
1848 return -1;
1849 if (e1->netmask == e2->netmask)
1850 return 0;
1851 return 1;
1854 static bool
1855 add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
1856 char *val1, char *val2, char **pos)
1858 struct in6_addr prefix;
1859 unsigned long int bits;
1860 unsigned long int val;
1861 char *endp;
1863 bits = 128;
1864 __set_errno (0);
1865 char *cp = strchr (val1, '/');
1866 if (cp != NULL)
1867 *cp++ = '\0';
1868 *pos = cp;
1869 if (inet_pton (AF_INET6, val1, &prefix)
1870 && (cp == NULL
1871 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1872 || errno != ERANGE)
1873 && *endp == '\0'
1874 && bits <= 128
1875 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1876 || errno != ERANGE)
1877 && *endp == '\0'
1878 && val <= INT_MAX)
1880 struct prefixlist *newp = malloc (sizeof (*newp));
1881 if (newp == NULL)
1882 return false;
1884 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1885 newp->entry.bits = bits;
1886 newp->entry.val = val;
1887 newp->next = *listp;
1888 *listp = newp;
1889 ++*lenp;
1890 *nullbitsp |= bits == 0;
1892 return true;
1895 static bool
1896 add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
1897 const struct in6_addr *prefixp, unsigned long int bits,
1898 unsigned long int val)
1900 struct scopelist *newp = malloc (sizeof (*newp));
1901 if (newp == NULL)
1902 return false;
1904 newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
1905 newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
1906 newp->entry.scope = val;
1907 newp->next = *listp;
1908 *listp = newp;
1909 ++*lenp;
1910 *nullbitsp |= bits == 96;
1912 return true;
1915 static void
1916 gaiconf_init (void)
1918 struct prefixlist *labellist = NULL;
1919 size_t nlabellist = 0;
1920 bool labellist_nullbits = false;
1921 struct prefixlist *precedencelist = NULL;
1922 size_t nprecedencelist = 0;
1923 bool precedencelist_nullbits = false;
1924 struct scopelist *scopelist = NULL;
1925 size_t nscopelist = 0;
1926 bool scopelist_nullbits = false;
1928 FILE *fp = fopen (GAICONF_FNAME, "rce");
1929 if (fp == NULL)
1930 goto no_file;
1932 struct __stat64_t64 st;
1933 if (__fstat64_time64 (fileno (fp), &st) != 0)
1935 fclose (fp);
1936 goto no_file;
1939 char *line = NULL;
1940 size_t linelen = 0;
1942 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1944 while (!feof_unlocked (fp))
1946 ssize_t n = __getline (&line, &linelen, fp);
1947 if (n <= 0)
1948 break;
1950 /* Handle comments. No escaping possible so this is easy. */
1951 char *cp = strchr (line, '#');
1952 if (cp != NULL)
1953 *cp = '\0';
1955 cp = line;
1956 while (isspace (*cp))
1957 ++cp;
1959 char *cmd = cp;
1960 while (*cp != '\0' && !isspace (*cp))
1961 ++cp;
1962 size_t cmdlen = cp - cmd;
1964 if (*cp != '\0')
1965 *cp++ = '\0';
1966 while (isspace (*cp))
1967 ++cp;
1969 char *val1 = cp;
1970 while (*cp != '\0' && !isspace (*cp))
1971 ++cp;
1972 size_t val1len = cp - cmd;
1974 /* We always need at least two values. */
1975 if (val1len == 0)
1976 continue;
1978 if (*cp != '\0')
1979 *cp++ = '\0';
1980 while (isspace (*cp))
1981 ++cp;
1983 char *val2 = cp;
1984 while (*cp != '\0' && !isspace (*cp))
1985 ++cp;
1987 /* Ignore the rest of the line. */
1988 *cp = '\0';
1990 switch (cmdlen)
1992 case 5:
1993 if (strcmp (cmd, "label") == 0)
1995 if (!add_prefixlist (&labellist, &nlabellist,
1996 &labellist_nullbits, val1, val2, &cp))
1998 free (line);
1999 fclose (fp);
2000 goto no_file;
2003 break;
2005 case 6:
2006 if (strcmp (cmd, "reload") == 0)
2008 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2009 if (gaiconf_reload_flag)
2010 gaiconf_reload_flag_ever_set = 1;
2012 break;
2014 case 7:
2015 if (strcmp (cmd, "scopev4") == 0)
2017 struct in6_addr prefix;
2018 unsigned long int bits;
2019 unsigned long int val;
2020 char *endp;
2022 bits = 32;
2023 __set_errno (0);
2024 cp = strchr (val1, '/');
2025 if (cp != NULL)
2026 *cp++ = '\0';
2027 if (inet_pton (AF_INET6, val1, &prefix))
2029 bits = 128;
2030 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2031 && (cp == NULL
2032 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2033 || errno != ERANGE)
2034 && *endp == '\0'
2035 && bits >= 96
2036 && bits <= 128
2037 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2038 || errno != ERANGE)
2039 && *endp == '\0'
2040 && val <= INT_MAX)
2042 if (!add_scopelist (&scopelist, &nscopelist,
2043 &scopelist_nullbits, &prefix,
2044 bits, val))
2046 free (line);
2047 fclose (fp);
2048 goto no_file;
2052 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2053 && (cp == NULL
2054 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2055 || errno != ERANGE)
2056 && *endp == '\0'
2057 && bits <= 32
2058 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2059 || errno != ERANGE)
2060 && *endp == '\0'
2061 && val <= INT_MAX)
2063 if (!add_scopelist (&scopelist, &nscopelist,
2064 &scopelist_nullbits, &prefix,
2065 bits + 96, val))
2067 free (line);
2068 fclose (fp);
2069 goto no_file;
2073 break;
2075 case 10:
2076 if (strcmp (cmd, "precedence") == 0)
2078 if (!add_prefixlist (&precedencelist, &nprecedencelist,
2079 &precedencelist_nullbits, val1, val2,
2080 &cp))
2082 free (line);
2083 fclose (fp);
2084 goto no_file;
2087 break;
2091 free (line);
2093 fclose (fp);
2095 /* Create the array for the labels. */
2096 struct prefixentry *new_labels;
2097 if (nlabellist > 0)
2099 if (!labellist_nullbits)
2100 ++nlabellist;
2101 new_labels = malloc (nlabellist * sizeof (*new_labels));
2102 if (new_labels == NULL)
2103 goto no_file;
2105 int i = nlabellist;
2106 if (!labellist_nullbits)
2108 --i;
2109 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2110 new_labels[i].bits = 0;
2111 new_labels[i].val = 1;
2114 struct prefixlist *l = labellist;
2115 while (i-- > 0)
2117 new_labels[i] = l->entry;
2118 l = l->next;
2120 free_prefixlist (labellist);
2121 labellist = NULL;
2123 /* Sort the entries so that the most specific ones are at
2124 the beginning. */
2125 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2127 else
2128 new_labels = (struct prefixentry *) default_labels;
2130 struct prefixentry *new_precedence;
2131 if (nprecedencelist > 0)
2133 if (!precedencelist_nullbits)
2134 ++nprecedencelist;
2135 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2136 if (new_precedence == NULL)
2138 if (new_labels != default_labels)
2139 free (new_labels);
2140 goto no_file;
2143 int i = nprecedencelist;
2144 if (!precedencelist_nullbits)
2146 --i;
2147 memset (&new_precedence[i].prefix, '\0',
2148 sizeof (struct in6_addr));
2149 new_precedence[i].bits = 0;
2150 new_precedence[i].val = 40;
2153 struct prefixlist *l = precedencelist;
2154 while (i-- > 0)
2156 new_precedence[i] = l->entry;
2157 l = l->next;
2159 free_prefixlist (precedencelist);
2160 precedencelist = NULL;
2162 /* Sort the entries so that the most specific ones are at
2163 the beginning. */
2164 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2165 prefixcmp);
2167 else
2168 new_precedence = (struct prefixentry *) default_precedence;
2170 struct scopeentry *new_scopes;
2171 if (nscopelist > 0)
2173 if (!scopelist_nullbits)
2174 ++nscopelist;
2175 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2176 if (new_scopes == NULL)
2178 if (new_labels != default_labels)
2179 free (new_labels);
2180 if (new_precedence != default_precedence)
2181 free (new_precedence);
2182 goto no_file;
2185 int i = nscopelist;
2186 if (!scopelist_nullbits)
2188 --i;
2189 new_scopes[i].addr32 = 0;
2190 new_scopes[i].netmask = 0;
2191 new_scopes[i].scope = 14;
2194 struct scopelist *l = scopelist;
2195 while (i-- > 0)
2197 new_scopes[i] = l->entry;
2198 l = l->next;
2200 free_scopelist (scopelist);
2202 /* Sort the entries so that the most specific ones are at
2203 the beginning. */
2204 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2205 scopecmp);
2207 else
2208 new_scopes = (struct scopeentry *) default_scopes;
2210 /* Now we are ready to replace the values. */
2211 const struct prefixentry *old = labels;
2212 labels = new_labels;
2213 if (old != default_labels)
2214 free ((void *) old);
2216 old = precedence;
2217 precedence = new_precedence;
2218 if (old != default_precedence)
2219 free ((void *) old);
2221 const struct scopeentry *oldscope = scopes;
2222 scopes = new_scopes;
2223 if (oldscope != default_scopes)
2224 free ((void *) oldscope);
2226 save_gaiconf_mtime (&st);
2227 return;
2229 no_file:
2230 free_prefixlist (labellist);
2231 free_prefixlist (precedencelist);
2232 free_scopelist (scopelist);
2234 /* If we previously read the file but it is gone now, free the old data and
2235 use the builtin one. Leave the reload flag alone. */
2236 fini ();
2240 static void
2241 gaiconf_reload (void)
2243 struct __stat64_t64 st;
2244 if (__stat64_time64 (GAICONF_FNAME, &st) != 0
2245 || !check_gaiconf_mtime (&st))
2246 gaiconf_init ();
2249 static bool
2250 try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
2251 const struct sockaddr *addr, socklen_t addrlen, int family)
2253 int fd = *fdp;
2254 int af = *afp;
2255 socklen_t sl = sizeof (*source_addrp);
2257 while (true)
2259 if (fd != -1 && __connect (fd, addr, addrlen) == 0
2260 && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
2261 return true;
2263 if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
2265 /* This could mean IPv6 sockets are IPv6-only. */
2266 if (fd != -1)
2267 __close_nocancel_nostatus (fd);
2268 *afp = af = AF_INET;
2269 *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
2270 IPPROTO_IP);
2271 continue;
2274 return false;
2277 __builtin_unreachable ();
2281 getaddrinfo (const char *name, const char *service,
2282 const struct addrinfo *hints, struct addrinfo **pai)
2284 int i = 0, last_i = 0;
2285 int nresults = 0;
2286 struct addrinfo *p = NULL;
2287 struct gaih_service gaih_service, *pservice;
2288 struct addrinfo local_hints;
2290 if (name != NULL && name[0] == '*' && name[1] == 0)
2291 name = NULL;
2293 if (service != NULL && service[0] == '*' && service[1] == 0)
2294 service = NULL;
2296 if (name == NULL && service == NULL)
2297 return EAI_NONAME;
2299 if (hints == NULL)
2300 hints = &default_hints;
2302 if (hints->ai_flags
2303 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2304 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2305 |AI_NUMERICSERV|AI_ALL))
2306 return EAI_BADFLAGS;
2308 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2309 return EAI_BADFLAGS;
2311 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2312 && hints->ai_family != AF_INET6)
2313 return EAI_FAMILY;
2315 struct in6addrinfo *in6ai = NULL;
2316 size_t in6ailen = 0;
2317 bool seen_ipv4 = false;
2318 bool seen_ipv6 = false;
2319 bool check_pf_called = false;
2321 if (hints->ai_flags & AI_ADDRCONFIG)
2323 /* We might need information about what interfaces are available.
2324 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2325 cannot cache the results since new interfaces could be added at
2326 any time. */
2327 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2328 check_pf_called = true;
2330 /* Now make a decision on what we return, if anything. */
2331 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2333 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2334 narrow down the search. */
2335 if (seen_ipv4 != seen_ipv6)
2337 local_hints = *hints;
2338 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2339 hints = &local_hints;
2342 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2343 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2345 /* We cannot possibly return a valid answer. */
2346 __free_in6ai (in6ai);
2347 return EAI_NONAME;
2351 if (service && service[0])
2353 char *c;
2354 gaih_service.name = service;
2355 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2356 if (*c != '\0')
2358 if (hints->ai_flags & AI_NUMERICSERV)
2360 __free_in6ai (in6ai);
2361 return EAI_NONAME;
2364 gaih_service.num = -1;
2367 pservice = &gaih_service;
2369 else
2370 pservice = NULL;
2372 struct addrinfo **end = &p;
2373 unsigned int naddrs = 0;
2374 struct scratch_buffer tmpbuf;
2376 scratch_buffer_init (&tmpbuf);
2377 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2378 scratch_buffer_free (&tmpbuf);
2380 if (last_i != 0)
2382 freeaddrinfo (p);
2383 __free_in6ai (in6ai);
2385 return -last_i;
2388 while (*end)
2390 end = &((*end)->ai_next);
2391 ++nresults;
2394 if (naddrs > 1)
2396 /* Read the config file. */
2397 __libc_once_define (static, once);
2398 __typeof (once) old_once = once;
2399 __libc_once (once, gaiconf_init);
2400 /* Sort results according to RFC 3484. */
2401 struct sort_result *results;
2402 size_t *order;
2403 struct addrinfo *q;
2404 struct addrinfo *last = NULL;
2405 char *canonname = NULL;
2406 bool malloc_results;
2407 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2409 malloc_results
2410 = !__libc_use_alloca (alloc_size);
2411 if (malloc_results)
2413 results = malloc (alloc_size);
2414 if (results == NULL)
2416 __free_in6ai (in6ai);
2417 return EAI_MEMORY;
2420 else
2421 results = alloca (alloc_size);
2422 order = (size_t *) (results + nresults);
2424 /* Now we definitely need the interface information. */
2425 if (! check_pf_called)
2426 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2428 /* If we have information about deprecated and temporary addresses
2429 sort the array now. */
2430 if (in6ai != NULL)
2431 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2433 int fd = -1;
2434 int af = AF_UNSPEC;
2436 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2438 results[i].dest_addr = q;
2439 results[i].native = -1;
2440 order[i] = i;
2442 /* If we just looked up the address for a different
2443 protocol, reuse the result. */
2444 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2445 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2447 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2448 results[i - 1].source_addr_len);
2449 results[i].source_addr_len = results[i - 1].source_addr_len;
2450 results[i].got_source_addr = results[i - 1].got_source_addr;
2451 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2452 results[i].prefixlen = results[i - 1].prefixlen;
2453 results[i].index = results[i - 1].index;
2455 else
2457 results[i].got_source_addr = false;
2458 results[i].source_addr_flags = 0;
2459 results[i].prefixlen = 0;
2460 results[i].index = 0xffffffffu;
2462 /* We overwrite the type with SOCK_DGRAM since we do not
2463 want connect() to connect to the other side. If we
2464 cannot determine the source address remember this
2465 fact. */
2466 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2468 if (fd != -1)
2469 __close_nocancel_nostatus (fd);
2470 af = q->ai_family;
2471 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2473 else
2475 /* Reset the connection. */
2476 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2477 __connect (fd, &sa, sizeof (sa));
2480 if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
2481 q->ai_addrlen, q->ai_family))
2483 results[i].source_addr_len = sizeof (results[i].source_addr);
2484 results[i].got_source_addr = true;
2486 if (in6ai != NULL)
2488 /* See whether the source address is on the list of
2489 deprecated or temporary addresses. */
2490 struct in6addrinfo tmp;
2492 if (q->ai_family == AF_INET && af == AF_INET)
2494 struct sockaddr_in *sinp
2495 = (struct sockaddr_in *) &results[i].source_addr;
2496 tmp.addr[0] = 0;
2497 tmp.addr[1] = 0;
2498 tmp.addr[2] = htonl (0xffff);
2499 /* Special case for lo interface, the source address
2500 being possibly different than the interface
2501 address. */
2502 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2503 == 0x7f000000)
2504 tmp.addr[3] = htonl(0x7f000001);
2505 else
2506 tmp.addr[3] = sinp->sin_addr.s_addr;
2508 else
2510 struct sockaddr_in6 *sin6p
2511 = (struct sockaddr_in6 *) &results[i].source_addr;
2512 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2515 struct in6addrinfo *found
2516 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2517 in6aicmp);
2518 if (found != NULL)
2520 results[i].source_addr_flags = found->flags;
2521 results[i].prefixlen = found->prefixlen;
2522 results[i].index = found->index;
2526 if (q->ai_family == AF_INET && af == AF_INET6)
2528 /* We have to convert the address. The socket is
2529 IPv6 and the request is for IPv4. */
2530 struct sockaddr_in6 *sin6
2531 = (struct sockaddr_in6 *) &results[i].source_addr;
2532 struct sockaddr_in *sin
2533 = (struct sockaddr_in *) &results[i].source_addr;
2534 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2535 sin->sin_family = AF_INET;
2536 /* We do not have to initialize sin_port since this
2537 fields has the same position and size in the IPv6
2538 structure. */
2539 assert (offsetof (struct sockaddr_in, sin_port)
2540 == offsetof (struct sockaddr_in6, sin6_port));
2541 assert (sizeof (sin->sin_port)
2542 == sizeof (sin6->sin6_port));
2543 memcpy (&sin->sin_addr,
2544 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2545 results[i].source_addr_len = sizeof (struct sockaddr_in);
2548 else
2549 /* Just make sure that if we have to process the same
2550 address again we do not copy any memory. */
2551 results[i].source_addr_len = 0;
2554 /* Remember the canonical name. */
2555 if (q->ai_canonname != NULL)
2557 assert (canonname == NULL);
2558 canonname = q->ai_canonname;
2559 q->ai_canonname = NULL;
2563 if (fd != -1)
2564 __close_nocancel_nostatus (fd);
2566 /* We got all the source addresses we can get, now sort using
2567 the information. */
2568 struct sort_result_combo src
2569 = { .results = results, .nresults = nresults };
2570 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2572 __libc_lock_define_initialized (static, lock);
2574 __libc_lock_lock (lock);
2575 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2576 gaiconf_reload ();
2577 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2578 __libc_lock_unlock (lock);
2580 else
2581 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2583 /* Queue the results up as they come out of sorting. */
2584 q = p = results[order[0]].dest_addr;
2585 for (i = 1; i < nresults; ++i)
2586 q = q->ai_next = results[order[i]].dest_addr;
2587 q->ai_next = NULL;
2589 /* Fill in the canonical name into the new first entry. */
2590 p->ai_canonname = canonname;
2592 if (malloc_results)
2593 free (results);
2596 __free_in6ai (in6ai);
2598 if (p)
2600 *pai = p;
2601 return 0;
2604 return last_i ? -last_i : EAI_NONAME;
2606 libc_hidden_def (getaddrinfo)
2608 nss_interface_function (getaddrinfo)
2610 void
2611 freeaddrinfo (struct addrinfo *ai)
2613 struct addrinfo *p;
2615 while (ai != NULL)
2617 p = ai;
2618 ai = ai->ai_next;
2619 free (p->ai_canonname);
2620 free (p);
2623 libc_hidden_def (freeaddrinfo)