Remove powerpc, sparc fdim inlines (bug 22987).
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob740bdd1ed7e7e896270aa45cabf5b5d8ef90d914
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
28 way or form.
29 1. All terms of the all other applicable copyrights and licenses must be
30 followed.
31 2. Redistributions of source code must retain the authors' copyright
32 notice(s), this list of conditions, and the following disclaimer.
33 3. Redistributions in binary form must reproduce the authors' copyright
34 notice(s), this list of conditions, and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36 4. [The copyright holder has authorized the removal of this clause.]
37 5. Neither the name(s) of the author(s) nor the names of its contributors
38 may be used to endorse or promote products derived from this software
39 without specific prior written permission.
41 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
42 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
45 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 If these license terms cause you a real problem, contact the author. */
54 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
56 #include <assert.h>
57 #include <ctype.h>
58 #include <errno.h>
59 #include <ifaddrs.h>
60 #include <netdb.h>
61 #include <nss.h>
62 #include <resolv/resolv-internal.h>
63 #include <resolv/resolv_context.h>
64 #include <resolv/res_use_inet6.h>
65 #include <stdbool.h>
66 #include <stdio.h>
67 #include <stdio_ext.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <stdint.h>
71 #include <arpa/inet.h>
72 #include <net/if.h>
73 #include <netinet/in.h>
74 #include <sys/socket.h>
75 #include <sys/stat.h>
76 #include <sys/types.h>
77 #include <sys/un.h>
78 #include <sys/utsname.h>
79 #include <unistd.h>
80 #include <nsswitch.h>
81 #include <libc-lock.h>
82 #include <not-cancel.h>
83 #include <nscd/nscd-client.h>
84 #include <nscd/nscd_proto.h>
85 #include <scratch_buffer.h>
86 #include <inet/net-internal.h>
88 #ifdef HAVE_LIBIDN
89 # include <idna.h>
90 #endif
92 #if IS_IN (libc)
93 # define feof_unlocked(fp) __feof_unlocked (fp)
94 #endif
96 struct gaih_service
98 const char *name;
99 int num;
102 struct gaih_servtuple
104 struct gaih_servtuple *next;
105 int socktype;
106 int protocol;
107 int port;
110 static const struct gaih_servtuple nullserv;
113 struct gaih_typeproto
115 int socktype;
116 int protocol;
117 uint8_t protoflag;
118 bool defaultflag;
119 char name[8];
122 /* Values for `protoflag'. */
123 #define GAI_PROTO_NOSERVICE 1
124 #define GAI_PROTO_PROTOANY 2
126 static const struct gaih_typeproto gaih_inet_typeproto[] =
128 { 0, 0, 0, false, "" },
129 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
130 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
131 #if defined SOCK_DCCP && defined IPPROTO_DCCP
132 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
133 #endif
134 #ifdef IPPROTO_UDPLITE
135 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
136 #endif
137 #ifdef IPPROTO_SCTP
138 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
139 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
140 #endif
141 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
142 { 0, 0, 0, false, "" }
145 static const struct addrinfo default_hints =
147 .ai_flags = AI_DEFAULT,
148 .ai_family = PF_UNSPEC,
149 .ai_socktype = 0,
150 .ai_protocol = 0,
151 .ai_addrlen = 0,
152 .ai_addr = NULL,
153 .ai_canonname = NULL,
154 .ai_next = NULL
158 static int
159 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
160 const struct addrinfo *req, struct gaih_servtuple *st,
161 struct scratch_buffer *tmpbuf)
163 struct servent *s;
164 struct servent ts;
165 int r;
169 r = __getservbyname_r (servicename, tp->name, &ts,
170 tmpbuf->data, tmpbuf->length, &s);
171 if (r != 0 || s == NULL)
173 if (r == ERANGE)
175 if (!scratch_buffer_grow (tmpbuf))
176 return -EAI_MEMORY;
178 else
179 return -EAI_SERVICE;
182 while (r);
184 st->next = NULL;
185 st->socktype = tp->socktype;
186 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
187 ? req->ai_protocol : tp->protocol);
188 st->port = s->s_port;
190 return 0;
193 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
194 h_name is not copied, and the struct hostent object must not be
195 deallocated prematurely. *RESULT must be NULL or a pointer to a
196 linked-list. The new addresses are appended at the end. */
197 static bool
198 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
199 int family,
200 struct hostent *h,
201 struct gaih_addrtuple **result)
203 while (*result)
204 result = &(*result)->next;
206 /* Count the number of addresses in h->h_addr_list. */
207 size_t count = 0;
208 for (char **p = h->h_addr_list; *p != NULL; ++p)
209 ++count;
211 /* Report no data if no addresses are available, or if the incoming
212 address size is larger than what we can store. */
213 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
214 return true;
216 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
217 if (array == NULL)
218 return false;
220 for (size_t i = 0; i < count; ++i)
222 if (family == AF_INET && req->ai_family == AF_INET6)
224 /* Perform address mapping. */
225 array[i].family = AF_INET6;
226 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
227 array[i].addr[2] = htonl (0xffff);
229 else
231 array[i].family = family;
232 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
234 array[i].next = array + i + 1;
236 array[0].name = h->h_name;
237 array[count - 1].next = NULL;
239 *result = array;
240 return true;
243 #define gethosts(_family, _type) \
245 struct hostent th; \
246 char *localcanon = NULL; \
247 no_data = 0; \
248 while (1) \
250 status = DL_CALL_FCT (fct, (name, _family, &th, \
251 tmpbuf->data, tmpbuf->length, \
252 &errno, &h_errno, NULL, &localcanon)); \
253 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
254 || errno != ERANGE) \
255 break; \
256 if (!scratch_buffer_grow (tmpbuf)) \
258 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
259 __resolv_context_put (res_ctx); \
260 result = -EAI_MEMORY; \
261 goto free_and_return; \
264 if (status == NSS_STATUS_NOTFOUND \
265 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
267 if (h_errno == NETDB_INTERNAL) \
269 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
270 __resolv_context_put (res_ctx); \
271 result = -EAI_SYSTEM; \
272 goto free_and_return; \
274 if (h_errno == TRY_AGAIN) \
275 no_data = EAI_AGAIN; \
276 else \
277 no_data = h_errno == NO_DATA; \
279 else if (status == NSS_STATUS_SUCCESS) \
281 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
283 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
284 __resolv_context_put (res_ctx); \
285 result = -EAI_SYSTEM; \
286 goto free_and_return; \
288 *pat = addrmem; \
290 if (localcanon != NULL && canon == NULL) \
292 canonbuf = __strdup (localcanon); \
293 if (canonbuf == NULL) \
295 result = -EAI_SYSTEM; \
296 goto free_and_return; \
298 canon = canonbuf; \
300 if (_family == AF_INET6 && *pat != NULL) \
301 got_ipv6 = true; \
306 typedef enum nss_status (*nss_gethostbyname4_r)
307 (const char *name, struct gaih_addrtuple **pat,
308 char *buffer, size_t buflen, int *errnop,
309 int *h_errnop, int32_t *ttlp);
310 typedef enum nss_status (*nss_gethostbyname3_r)
311 (const char *name, int af, struct hostent *host,
312 char *buffer, size_t buflen, int *errnop,
313 int *h_errnop, int32_t *ttlp, char **canonp);
314 typedef enum nss_status (*nss_getcanonname_r)
315 (const char *name, char *buffer, size_t buflen, char **result,
316 int *errnop, int *h_errnop);
318 /* This function is called if a canonical name is requested, but if
319 the service function did not provide it. It tries to obtain the
320 name using getcanonname_r from the same service NIP. If the name
321 cannot be canonicalized, return a copy of NAME. Return NULL on
322 memory allocation failure. The returned string is allocated on the
323 heap; the caller has to free it. */
324 static char *
325 getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name)
327 nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r");
328 char *s = (char *) name;
329 if (cfct != NULL)
331 char buf[256];
332 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
333 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
334 /* If the canonical name cannot be determined, use the passed
335 string. */
336 s = (char *) name;
338 return __strdup (name);
341 static int
342 gaih_inet (const char *name, const struct gaih_service *service,
343 const struct addrinfo *req, struct addrinfo **pai,
344 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
346 const struct gaih_typeproto *tp = gaih_inet_typeproto;
347 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
348 struct gaih_addrtuple *at = NULL;
349 bool got_ipv6 = false;
350 const char *canon = NULL;
351 const char *orig_name = name;
353 /* Reserve stack memory for the scratch buffer in the getaddrinfo
354 function. */
355 size_t alloca_used = sizeof (struct scratch_buffer);
357 if (req->ai_protocol || req->ai_socktype)
359 ++tp;
361 while (tp->name[0]
362 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
363 || (req->ai_protocol != 0
364 && !(tp->protoflag & GAI_PROTO_PROTOANY)
365 && req->ai_protocol != tp->protocol)))
366 ++tp;
368 if (! tp->name[0])
370 if (req->ai_socktype)
371 return -EAI_SOCKTYPE;
372 else
373 return -EAI_SERVICE;
377 int port = 0;
378 if (service != NULL)
380 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
381 return -EAI_SERVICE;
383 if (service->num < 0)
385 if (tp->name[0])
387 st = (struct gaih_servtuple *)
388 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
390 int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
391 if (__glibc_unlikely (rc != 0))
392 return rc;
394 else
396 struct gaih_servtuple **pst = &st;
397 for (tp++; tp->name[0]; tp++)
399 struct gaih_servtuple *newp;
401 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
402 continue;
404 if (req->ai_socktype != 0
405 && req->ai_socktype != tp->socktype)
406 continue;
407 if (req->ai_protocol != 0
408 && !(tp->protoflag & GAI_PROTO_PROTOANY)
409 && req->ai_protocol != tp->protocol)
410 continue;
412 newp = (struct gaih_servtuple *)
413 alloca_account (sizeof (struct gaih_servtuple),
414 alloca_used);
416 if (gaih_inet_serv (service->name,
417 tp, req, newp, tmpbuf) != 0)
418 continue;
420 *pst = newp;
421 pst = &(newp->next);
423 if (st == (struct gaih_servtuple *) &nullserv)
424 return -EAI_SERVICE;
427 else
429 port = htons (service->num);
430 goto got_port;
433 else
435 got_port:
437 if (req->ai_socktype || req->ai_protocol)
439 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
440 st->next = NULL;
441 st->socktype = tp->socktype;
442 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
443 ? req->ai_protocol : tp->protocol);
444 st->port = port;
446 else
448 /* Neither socket type nor protocol is set. Return all socket types
449 we know about. */
450 struct gaih_servtuple **lastp = &st;
451 for (++tp; tp->name[0]; ++tp)
452 if (tp->defaultflag)
454 struct gaih_servtuple *newp;
456 newp = alloca_account (sizeof (struct gaih_servtuple),
457 alloca_used);
458 newp->next = NULL;
459 newp->socktype = tp->socktype;
460 newp->protocol = tp->protocol;
461 newp->port = port;
463 *lastp = newp;
464 lastp = &newp->next;
469 bool malloc_name = false;
470 struct gaih_addrtuple *addrmem = NULL;
471 char *canonbuf = NULL;
472 int result = 0;
474 if (name != NULL)
476 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
477 at->family = AF_UNSPEC;
478 at->scopeid = 0;
479 at->next = NULL;
481 #ifdef HAVE_LIBIDN
482 if (req->ai_flags & AI_IDN)
484 int idn_flags = 0;
485 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
486 idn_flags |= IDNA_ALLOW_UNASSIGNED;
487 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
488 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
490 char *p = NULL;
491 int rc = __idna_to_ascii_lz (name, &p, idn_flags);
492 if (rc != IDNA_SUCCESS)
494 /* No need to jump to free_and_return here. */
495 if (rc == IDNA_MALLOC_ERROR)
496 return -EAI_MEMORY;
497 if (rc == IDNA_DLOPEN_ERROR)
498 return -EAI_SYSTEM;
499 return -EAI_IDN_ENCODE;
501 /* In case the output string is the same as the input string
502 no new string has been allocated. */
503 if (p != name)
505 name = p;
506 malloc_name = true;
509 #endif
511 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
513 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
514 at->family = AF_INET;
515 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
517 at->addr[3] = at->addr[0];
518 at->addr[2] = htonl (0xffff);
519 at->addr[1] = 0;
520 at->addr[0] = 0;
521 at->family = AF_INET6;
523 else
525 result = -EAI_ADDRFAMILY;
526 goto free_and_return;
529 if (req->ai_flags & AI_CANONNAME)
530 canon = name;
532 else if (at->family == AF_UNSPEC)
534 char *scope_delim = strchr (name, SCOPE_DELIMITER);
535 int e;
536 if (scope_delim == NULL)
537 e = inet_pton (AF_INET6, name, at->addr);
538 else
539 e = __inet_pton_length (AF_INET6, name, scope_delim - name,
540 at->addr);
541 if (e > 0)
543 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
544 at->family = AF_INET6;
545 else if (req->ai_family == AF_INET
546 && IN6_IS_ADDR_V4MAPPED (at->addr))
548 at->addr[0] = at->addr[3];
549 at->family = AF_INET;
551 else
553 result = -EAI_ADDRFAMILY;
554 goto free_and_return;
557 if (scope_delim != NULL
558 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
559 scope_delim + 1,
560 &at->scopeid) != 0)
562 result = -EAI_NONAME;
563 goto free_and_return;
566 if (req->ai_flags & AI_CANONNAME)
567 canon = name;
571 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
573 struct gaih_addrtuple **pat = &at;
574 int no_data = 0;
575 int no_inet6_data = 0;
576 service_user *nip;
577 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
578 enum nss_status status = NSS_STATUS_UNAVAIL;
579 int no_more;
580 struct resolv_context *res_ctx = NULL;
581 bool res_enable_inet6 = false;
583 /* If we do not have to look for IPv6 addresses or the canonical
584 name, use the simple, old functions, which do not support
585 IPv6 scope ids, nor retrieving the canonical name. */
586 if (req->ai_family == AF_INET
587 && (req->ai_flags & AI_CANONNAME) == 0)
589 int rc;
590 struct hostent th;
591 struct hostent *h;
593 while (1)
595 rc = __gethostbyname2_r (name, AF_INET, &th,
596 tmpbuf->data, tmpbuf->length,
597 &h, &h_errno);
598 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
599 break;
600 if (!scratch_buffer_grow (tmpbuf))
602 result = -EAI_MEMORY;
603 goto free_and_return;
607 if (rc == 0)
609 if (h != NULL)
611 /* We found data, convert it. */
612 if (!convert_hostent_to_gaih_addrtuple
613 (req, AF_INET, h, &addrmem))
615 result = -EAI_MEMORY;
616 goto free_and_return;
618 *pat = addrmem;
620 else
622 if (h_errno == NO_DATA)
623 result = -EAI_NODATA;
624 else
625 result = -EAI_NONAME;
626 goto free_and_return;
629 else
631 if (h_errno == NETDB_INTERNAL)
632 result = -EAI_SYSTEM;
633 else if (h_errno == TRY_AGAIN)
634 result = -EAI_AGAIN;
635 else
636 /* We made requests but they turned out no data.
637 The name is known, though. */
638 result = -EAI_NODATA;
640 goto free_and_return;
643 goto process_list;
646 #ifdef USE_NSCD
647 if (__nss_not_use_nscd_hosts > 0
648 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
649 __nss_not_use_nscd_hosts = 0;
651 if (!__nss_not_use_nscd_hosts
652 && !__nss_database_custom[NSS_DBSIDX_hosts])
654 /* Try to use nscd. */
655 struct nscd_ai_result *air = NULL;
656 int err = __nscd_getai (name, &air, &h_errno);
657 if (air != NULL)
659 /* Transform into gaih_addrtuple list. */
660 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
661 char *addrs = air->addrs;
663 addrmem = calloc (air->naddrs, sizeof (*addrmem));
664 if (addrmem == NULL)
666 result = -EAI_MEMORY;
667 goto free_and_return;
670 struct gaih_addrtuple *addrfree = addrmem;
671 for (int i = 0; i < air->naddrs; ++i)
673 socklen_t size = (air->family[i] == AF_INET
674 ? INADDRSZ : IN6ADDRSZ);
676 if (!((air->family[i] == AF_INET
677 && req->ai_family == AF_INET6
678 && (req->ai_flags & AI_V4MAPPED) != 0)
679 || req->ai_family == AF_UNSPEC
680 || air->family[i] == req->ai_family))
682 /* Skip over non-matching result. */
683 addrs += size;
684 continue;
687 if (*pat == NULL)
689 *pat = addrfree++;
690 (*pat)->scopeid = 0;
692 uint32_t *pataddr = (*pat)->addr;
693 (*pat)->next = NULL;
694 if (added_canon || air->canon == NULL)
695 (*pat)->name = NULL;
696 else if (canonbuf == NULL)
698 canonbuf = __strdup (air->canon);
699 if (canonbuf == NULL)
701 result = -EAI_MEMORY;
702 goto free_and_return;
704 canon = (*pat)->name = canonbuf;
707 if (air->family[i] == AF_INET
708 && req->ai_family == AF_INET6
709 && (req->ai_flags & AI_V4MAPPED))
711 (*pat)->family = AF_INET6;
712 pataddr[3] = *(uint32_t *) addrs;
713 pataddr[2] = htonl (0xffff);
714 pataddr[1] = 0;
715 pataddr[0] = 0;
716 pat = &((*pat)->next);
717 added_canon = true;
719 else if (req->ai_family == AF_UNSPEC
720 || air->family[i] == req->ai_family)
722 (*pat)->family = air->family[i];
723 memcpy (pataddr, addrs, size);
724 pat = &((*pat)->next);
725 added_canon = true;
726 if (air->family[i] == AF_INET6)
727 got_ipv6 = true;
729 addrs += size;
732 free (air);
734 if (at->family == AF_UNSPEC)
736 result = -EAI_NONAME;
737 goto free_and_return;
740 goto process_list;
742 else if (err == 0)
743 /* The database contains a negative entry. */
744 goto free_and_return;
745 else if (__nss_not_use_nscd_hosts == 0)
747 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
748 result = -EAI_MEMORY;
749 else if (h_errno == TRY_AGAIN)
750 result = -EAI_AGAIN;
751 else
752 result = -EAI_SYSTEM;
754 goto free_and_return;
757 #endif
759 if (__nss_hosts_database == NULL)
760 no_more = __nss_database_lookup ("hosts", NULL,
761 "dns [!UNAVAIL=return] files",
762 &__nss_hosts_database);
763 else
764 no_more = 0;
765 nip = __nss_hosts_database;
767 /* If we are looking for both IPv4 and IPv6 address we don't
768 want the lookup functions to automatically promote IPv4
769 addresses to IPv6 addresses, so we use the no_inet6
770 function variant. */
771 res_ctx = __resolv_context_get ();
772 res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx);
773 if (res_ctx == NULL)
774 no_more = 1;
776 while (!no_more)
778 no_data = 0;
779 nss_gethostbyname4_r fct4 = NULL;
781 /* gethostbyname4_r sends out parallel A and AAAA queries and
782 is thus only suitable for PF_UNSPEC. */
783 if (req->ai_family == PF_UNSPEC)
784 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
786 if (fct4 != NULL)
788 while (1)
790 status = DL_CALL_FCT (fct4, (name, pat,
791 tmpbuf->data, tmpbuf->length,
792 &errno, &h_errno,
793 NULL));
794 if (status == NSS_STATUS_SUCCESS)
795 break;
796 if (status != NSS_STATUS_TRYAGAIN
797 || errno != ERANGE || h_errno != NETDB_INTERNAL)
799 if (h_errno == TRY_AGAIN)
800 no_data = EAI_AGAIN;
801 else
802 no_data = h_errno == NO_DATA;
803 break;
806 if (!scratch_buffer_grow (tmpbuf))
808 __resolv_context_enable_inet6
809 (res_ctx, res_enable_inet6);
810 __resolv_context_put (res_ctx);
811 result = -EAI_MEMORY;
812 goto free_and_return;
816 if (status == NSS_STATUS_SUCCESS)
818 assert (!no_data);
819 no_data = 1;
821 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
822 canon = (*pat)->name;
824 while (*pat != NULL)
826 if ((*pat)->family == AF_INET
827 && req->ai_family == AF_INET6
828 && (req->ai_flags & AI_V4MAPPED) != 0)
830 uint32_t *pataddr = (*pat)->addr;
831 (*pat)->family = AF_INET6;
832 pataddr[3] = pataddr[0];
833 pataddr[2] = htonl (0xffff);
834 pataddr[1] = 0;
835 pataddr[0] = 0;
836 pat = &((*pat)->next);
837 no_data = 0;
839 else if (req->ai_family == AF_UNSPEC
840 || (*pat)->family == req->ai_family)
842 pat = &((*pat)->next);
844 no_data = 0;
845 if (req->ai_family == AF_INET6)
846 got_ipv6 = true;
848 else
849 *pat = ((*pat)->next);
853 no_inet6_data = no_data;
855 else
857 nss_gethostbyname3_r fct = NULL;
858 if (req->ai_flags & AI_CANONNAME)
859 /* No need to use this function if we do not look for
860 the canonical name. The function does not exist in
861 all NSS modules and therefore the lookup would
862 often fail. */
863 fct = __nss_lookup_function (nip, "gethostbyname3_r");
864 if (fct == NULL)
865 /* We are cheating here. The gethostbyname2_r
866 function does not have the same interface as
867 gethostbyname3_r but the extra arguments the
868 latter takes are added at the end. So the
869 gethostbyname2_r code will just ignore them. */
870 fct = __nss_lookup_function (nip, "gethostbyname2_r");
872 if (fct != NULL)
874 if (req->ai_family == AF_INET6
875 || req->ai_family == AF_UNSPEC)
877 gethosts (AF_INET6, struct in6_addr);
878 no_inet6_data = no_data;
879 inet6_status = status;
881 if (req->ai_family == AF_INET
882 || req->ai_family == AF_UNSPEC
883 || (req->ai_family == AF_INET6
884 && (req->ai_flags & AI_V4MAPPED)
885 /* Avoid generating the mapped addresses if we
886 know we are not going to need them. */
887 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
889 gethosts (AF_INET, struct in_addr);
891 if (req->ai_family == AF_INET)
893 no_inet6_data = no_data;
894 inet6_status = status;
898 /* If we found one address for AF_INET or AF_INET6,
899 don't continue the search. */
900 if (inet6_status == NSS_STATUS_SUCCESS
901 || status == NSS_STATUS_SUCCESS)
903 if ((req->ai_flags & AI_CANONNAME) != 0
904 && canon == NULL)
906 canonbuf = getcanonname (nip, at, name);
907 if (canonbuf == NULL)
909 __resolv_context_enable_inet6
910 (res_ctx, res_enable_inet6);
911 __resolv_context_put (res_ctx);
912 result = -EAI_MEMORY;
913 goto free_and_return;
915 canon = canonbuf;
917 status = NSS_STATUS_SUCCESS;
919 else
921 /* We can have different states for AF_INET and
922 AF_INET6. Try to find a useful one for both. */
923 if (inet6_status == NSS_STATUS_TRYAGAIN)
924 status = NSS_STATUS_TRYAGAIN;
925 else if (status == NSS_STATUS_UNAVAIL
926 && inet6_status != NSS_STATUS_UNAVAIL)
927 status = inet6_status;
930 else
932 /* Could not locate any of the lookup functions.
933 The NSS lookup code does not consistently set
934 errno, so we need to supply our own error
935 code here. The root cause could either be a
936 resource allocation failure, or a missing
937 service function in the DSO (so it should not
938 be listed in /etc/nsswitch.conf). Assume the
939 former, and return EBUSY. */
940 status = NSS_STATUS_UNAVAIL;
941 __set_h_errno (NETDB_INTERNAL);
942 __set_errno (EBUSY);
946 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
947 break;
949 if (nip->next == NULL)
950 no_more = -1;
951 else
952 nip = nip->next;
955 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6);
956 __resolv_context_put (res_ctx);
958 /* If we have a failure which sets errno, report it using
959 EAI_SYSTEM. */
960 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
961 && h_errno == NETDB_INTERNAL)
963 result = -EAI_SYSTEM;
964 goto free_and_return;
967 if (no_data != 0 && no_inet6_data != 0)
969 /* If both requests timed out report this. */
970 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
971 result = -EAI_AGAIN;
972 else
973 /* We made requests but they turned out no data. The name
974 is known, though. */
975 result = -EAI_NODATA;
977 goto free_and_return;
981 process_list:
982 if (at->family == AF_UNSPEC)
984 result = -EAI_NONAME;
985 goto free_and_return;
988 else
990 struct gaih_addrtuple *atr;
991 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
992 memset (at, '\0', sizeof (struct gaih_addrtuple));
994 if (req->ai_family == AF_UNSPEC)
996 at->next = __alloca (sizeof (struct gaih_addrtuple));
997 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1000 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1002 at->family = AF_INET6;
1003 if ((req->ai_flags & AI_PASSIVE) == 0)
1004 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1005 atr = at->next;
1008 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1010 atr->family = AF_INET;
1011 if ((req->ai_flags & AI_PASSIVE) == 0)
1012 atr->addr[0] = htonl (INADDR_LOOPBACK);
1017 struct gaih_servtuple *st2;
1018 struct gaih_addrtuple *at2 = at;
1019 size_t socklen;
1020 sa_family_t family;
1023 buffer is the size of an unformatted IPv6 address in printable format.
1025 while (at2 != NULL)
1027 /* Only the first entry gets the canonical name. */
1028 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1030 if (canon == NULL)
1031 /* If the canonical name cannot be determined, use
1032 the passed in string. */
1033 canon = orig_name;
1035 #ifdef HAVE_LIBIDN
1036 if (req->ai_flags & AI_CANONIDN)
1038 int idn_flags = 0;
1039 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1040 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1041 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1042 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1044 char *out;
1045 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1046 if (rc != IDNA_SUCCESS)
1048 if (rc == IDNA_MALLOC_ERROR)
1049 result = -EAI_MEMORY;
1050 else if (rc == IDNA_DLOPEN_ERROR)
1051 result = -EAI_SYSTEM;
1052 else
1053 result = -EAI_IDN_ENCODE;
1054 goto free_and_return;
1056 /* In case the output string is the same as the input
1057 string no new string has been allocated and we
1058 make a copy. */
1059 if (out == canon)
1060 goto make_copy;
1061 canon = out;
1063 else
1064 #endif
1066 #ifdef HAVE_LIBIDN
1067 make_copy:
1068 #endif
1069 if (canonbuf != NULL)
1070 /* We already allocated the string using malloc, but
1071 the buffer is now owned by canon. */
1072 canonbuf = NULL;
1073 else
1075 canon = __strdup (canon);
1076 if (canon == NULL)
1078 result = -EAI_MEMORY;
1079 goto free_and_return;
1085 family = at2->family;
1086 if (family == AF_INET6)
1088 socklen = sizeof (struct sockaddr_in6);
1090 /* If we looked up IPv4 mapped address discard them here if
1091 the caller isn't interested in all address and we have
1092 found at least one IPv6 address. */
1093 if (got_ipv6
1094 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1095 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1096 goto ignore;
1098 else
1099 socklen = sizeof (struct sockaddr_in);
1101 for (st2 = st; st2 != NULL; st2 = st2->next)
1103 struct addrinfo *ai;
1104 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1105 if (ai == NULL)
1107 free ((char *) canon);
1108 result = -EAI_MEMORY;
1109 goto free_and_return;
1112 ai->ai_flags = req->ai_flags;
1113 ai->ai_family = family;
1114 ai->ai_socktype = st2->socktype;
1115 ai->ai_protocol = st2->protocol;
1116 ai->ai_addrlen = socklen;
1117 ai->ai_addr = (void *) (ai + 1);
1119 /* We only add the canonical name once. */
1120 ai->ai_canonname = (char *) canon;
1121 canon = NULL;
1123 #ifdef _HAVE_SA_LEN
1124 ai->ai_addr->sa_len = socklen;
1125 #endif /* _HAVE_SA_LEN */
1126 ai->ai_addr->sa_family = family;
1128 /* In case of an allocation error the list must be NULL
1129 terminated. */
1130 ai->ai_next = NULL;
1132 if (family == AF_INET6)
1134 struct sockaddr_in6 *sin6p =
1135 (struct sockaddr_in6 *) ai->ai_addr;
1137 sin6p->sin6_port = st2->port;
1138 sin6p->sin6_flowinfo = 0;
1139 memcpy (&sin6p->sin6_addr,
1140 at2->addr, sizeof (struct in6_addr));
1141 sin6p->sin6_scope_id = at2->scopeid;
1143 else
1145 struct sockaddr_in *sinp =
1146 (struct sockaddr_in *) ai->ai_addr;
1147 sinp->sin_port = st2->port;
1148 memcpy (&sinp->sin_addr,
1149 at2->addr, sizeof (struct in_addr));
1150 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1153 pai = &(ai->ai_next);
1156 ++*naddrs;
1158 ignore:
1159 at2 = at2->next;
1163 free_and_return:
1164 if (malloc_name)
1165 free ((char *) name);
1166 free (addrmem);
1167 free (canonbuf);
1169 return result;
1173 struct sort_result
1175 struct addrinfo *dest_addr;
1176 /* Using sockaddr_storage is for now overkill. We only support IPv4
1177 and IPv6 so far. If this changes at some point we can adjust the
1178 type here. */
1179 struct sockaddr_in6 source_addr;
1180 uint8_t source_addr_len;
1181 bool got_source_addr;
1182 uint8_t source_addr_flags;
1183 uint8_t prefixlen;
1184 uint32_t index;
1185 int32_t native;
1188 struct sort_result_combo
1190 struct sort_result *results;
1191 int nresults;
1195 #if __BYTE_ORDER == __BIG_ENDIAN
1196 # define htonl_c(n) n
1197 #else
1198 # define htonl_c(n) __bswap_constant_32 (n)
1199 #endif
1201 static const struct scopeentry
1203 union
1205 char addr[4];
1206 uint32_t addr32;
1208 uint32_t netmask;
1209 int32_t scope;
1210 } default_scopes[] =
1212 /* Link-local addresses: scope 2. */
1213 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1214 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1215 /* Default: scope 14. */
1216 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1219 /* The label table. */
1220 static const struct scopeentry *scopes;
1223 static int
1224 get_scope (const struct sockaddr_in6 *in6)
1226 int scope;
1227 if (in6->sin6_family == PF_INET6)
1229 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1231 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1232 /* RFC 4291 2.5.3 says that the loopback address is to be
1233 treated like a link-local address. */
1234 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1235 scope = 2;
1236 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1237 scope = 5;
1238 else
1239 /* XXX Is this the correct default behavior? */
1240 scope = 14;
1242 else
1243 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1245 else if (in6->sin6_family == PF_INET)
1247 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1249 size_t cnt = 0;
1250 while (1)
1252 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1253 == scopes[cnt].addr32)
1254 return scopes[cnt].scope;
1256 ++cnt;
1258 /* NOTREACHED */
1260 else
1261 /* XXX What is a good default? */
1262 scope = 15;
1264 return scope;
1268 struct prefixentry
1270 struct in6_addr prefix;
1271 unsigned int bits;
1272 int val;
1276 /* The label table. */
1277 static const struct prefixentry *labels;
1279 /* Default labels. */
1280 static const struct prefixentry default_labels[] =
1282 /* See RFC 3484 for the details. */
1283 { { .__in6_u
1284 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1286 }, 128, 0 },
1287 { { .__in6_u
1288 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1290 }, 16, 2 },
1291 { { .__in6_u
1292 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1294 }, 96, 3 },
1295 { { .__in6_u
1296 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1297 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1298 }, 96, 4 },
1299 /* The next two entries differ from RFC 3484. We need to treat
1300 IPv6 site-local addresses special because they are never NATed,
1301 unlike site-locale IPv4 addresses. If this would not happen, on
1302 machines which have only IPv4 and IPv6 site-local addresses, the
1303 sorting would prefer the IPv6 site-local addresses, causing
1304 unnecessary delays when trying to connect to a global IPv6 address
1305 through a site-local IPv6 address. */
1306 { { .__in6_u
1307 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1309 }, 10, 5 },
1310 { { .__in6_u
1311 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1313 }, 7, 6 },
1314 /* Additional rule for Teredo tunnels. */
1315 { { .__in6_u
1316 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1318 }, 32, 7 },
1319 { { .__in6_u
1320 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1322 }, 0, 1 }
1326 /* The precedence table. */
1327 static const struct prefixentry *precedence;
1329 /* The default precedences. */
1330 static const struct prefixentry default_precedence[] =
1332 /* See RFC 3484 for the details. */
1333 { { .__in6_u
1334 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1336 }, 128, 50 },
1337 { { .__in6_u
1338 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1340 }, 16, 30 },
1341 { { .__in6_u
1342 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1344 }, 96, 20 },
1345 { { .__in6_u
1346 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1347 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1348 }, 96, 10 },
1349 { { .__in6_u
1350 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1352 }, 0, 40 }
1356 static int
1357 match_prefix (const struct sockaddr_in6 *in6,
1358 const struct prefixentry *list, int default_val)
1360 int idx;
1361 struct sockaddr_in6 in6_mem;
1363 if (in6->sin6_family == PF_INET)
1365 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1367 /* Construct a V4-to-6 mapped address. */
1368 in6_mem.sin6_family = PF_INET6;
1369 in6_mem.sin6_port = in->sin_port;
1370 in6_mem.sin6_flowinfo = 0;
1371 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1372 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1373 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1374 in6_mem.sin6_scope_id = 0;
1376 in6 = &in6_mem;
1378 else if (in6->sin6_family != PF_INET6)
1379 return default_val;
1381 for (idx = 0; ; ++idx)
1383 unsigned int bits = list[idx].bits;
1384 const uint8_t *mask = list[idx].prefix.s6_addr;
1385 const uint8_t *val = in6->sin6_addr.s6_addr;
1387 while (bits >= 8)
1389 if (*mask != *val)
1390 break;
1392 ++mask;
1393 ++val;
1394 bits -= 8;
1397 if (bits < 8)
1399 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1400 /* Match! */
1401 break;
1405 return list[idx].val;
1409 static int
1410 get_label (const struct sockaddr_in6 *in6)
1412 /* XXX What is a good default value? */
1413 return match_prefix (in6, labels, INT_MAX);
1417 static int
1418 get_precedence (const struct sockaddr_in6 *in6)
1420 /* XXX What is a good default value? */
1421 return match_prefix (in6, precedence, 0);
1425 /* Find last bit set in a word. */
1426 static int
1427 fls (uint32_t a)
1429 uint32_t mask;
1430 int n;
1431 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1432 if ((a & mask) != 0)
1433 break;
1434 return n;
1438 static int
1439 rfc3484_sort (const void *p1, const void *p2, void *arg)
1441 const size_t idx1 = *(const size_t *) p1;
1442 const size_t idx2 = *(const size_t *) p2;
1443 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1444 struct sort_result *a1 = &src->results[idx1];
1445 struct sort_result *a2 = &src->results[idx2];
1447 /* Rule 1: Avoid unusable destinations.
1448 We have the got_source_addr flag set if the destination is reachable. */
1449 if (a1->got_source_addr && ! a2->got_source_addr)
1450 return -1;
1451 if (! a1->got_source_addr && a2->got_source_addr)
1452 return 1;
1455 /* Rule 2: Prefer matching scope. Only interesting if both
1456 destination addresses are IPv6. */
1457 int a1_dst_scope
1458 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1460 int a2_dst_scope
1461 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1463 if (a1->got_source_addr)
1465 int a1_src_scope = get_scope (&a1->source_addr);
1466 int a2_src_scope = get_scope (&a2->source_addr);
1468 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1469 return -1;
1470 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1471 return 1;
1475 /* Rule 3: Avoid deprecated addresses. */
1476 if (a1->got_source_addr)
1478 if (!(a1->source_addr_flags & in6ai_deprecated)
1479 && (a2->source_addr_flags & in6ai_deprecated))
1480 return -1;
1481 if ((a1->source_addr_flags & in6ai_deprecated)
1482 && !(a2->source_addr_flags & in6ai_deprecated))
1483 return 1;
1486 /* Rule 4: Prefer home addresses. */
1487 if (a1->got_source_addr)
1489 if (!(a1->source_addr_flags & in6ai_homeaddress)
1490 && (a2->source_addr_flags & in6ai_homeaddress))
1491 return 1;
1492 if ((a1->source_addr_flags & in6ai_homeaddress)
1493 && !(a2->source_addr_flags & in6ai_homeaddress))
1494 return -1;
1497 /* Rule 5: Prefer matching label. */
1498 if (a1->got_source_addr)
1500 int a1_dst_label
1501 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1502 int a1_src_label = get_label (&a1->source_addr);
1504 int a2_dst_label
1505 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1506 int a2_src_label = get_label (&a2->source_addr);
1508 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1509 return -1;
1510 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1511 return 1;
1515 /* Rule 6: Prefer higher precedence. */
1516 int a1_prec
1517 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1518 int a2_prec
1519 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1521 if (a1_prec > a2_prec)
1522 return -1;
1523 if (a1_prec < a2_prec)
1524 return 1;
1527 /* Rule 7: Prefer native transport. */
1528 if (a1->got_source_addr)
1530 /* The same interface index means the same interface which means
1531 there is no difference in transport. This should catch many
1532 (most?) cases. */
1533 if (a1->index != a2->index)
1535 int a1_native = a1->native;
1536 int a2_native = a2->native;
1538 if (a1_native == -1 || a2_native == -1)
1540 uint32_t a1_index;
1541 if (a1_native == -1)
1543 /* If we do not have the information use 'native' as
1544 the default. */
1545 a1_native = 0;
1546 a1_index = a1->index;
1548 else
1549 a1_index = 0xffffffffu;
1551 uint32_t a2_index;
1552 if (a2_native == -1)
1554 /* If we do not have the information use 'native' as
1555 the default. */
1556 a2_native = 0;
1557 a2_index = a2->index;
1559 else
1560 a2_index = 0xffffffffu;
1562 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1564 /* Fill in the results in all the records. */
1565 for (int i = 0; i < src->nresults; ++i)
1566 if (a1_index != -1 && src->results[i].index == a1_index)
1568 assert (src->results[i].native == -1
1569 || src->results[i].native == a1_native);
1570 src->results[i].native = a1_native;
1572 else if (a2_index != -1 && src->results[i].index == a2_index)
1574 assert (src->results[i].native == -1
1575 || src->results[i].native == a2_native);
1576 src->results[i].native = a2_native;
1580 if (a1_native && !a2_native)
1581 return -1;
1582 if (!a1_native && a2_native)
1583 return 1;
1588 /* Rule 8: Prefer smaller scope. */
1589 if (a1_dst_scope < a2_dst_scope)
1590 return -1;
1591 if (a1_dst_scope > a2_dst_scope)
1592 return 1;
1595 /* Rule 9: Use longest matching prefix. */
1596 if (a1->got_source_addr
1597 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1599 int bit1 = 0;
1600 int bit2 = 0;
1602 if (a1->dest_addr->ai_family == PF_INET)
1604 assert (a1->source_addr.sin6_family == PF_INET);
1605 assert (a2->source_addr.sin6_family == PF_INET);
1607 /* Outside of subnets, as defined by the network masks,
1608 common address prefixes for IPv4 addresses make no sense.
1609 So, define a non-zero value only if source and
1610 destination address are on the same subnet. */
1611 struct sockaddr_in *in1_dst
1612 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1613 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1614 struct sockaddr_in *in1_src
1615 = (struct sockaddr_in *) &a1->source_addr;
1616 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1617 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1619 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1620 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1622 struct sockaddr_in *in2_dst
1623 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1624 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1625 struct sockaddr_in *in2_src
1626 = (struct sockaddr_in *) &a2->source_addr;
1627 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1628 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1630 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1631 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1633 else if (a1->dest_addr->ai_family == PF_INET6)
1635 assert (a1->source_addr.sin6_family == PF_INET6);
1636 assert (a2->source_addr.sin6_family == PF_INET6);
1638 struct sockaddr_in6 *in1_dst;
1639 struct sockaddr_in6 *in1_src;
1640 struct sockaddr_in6 *in2_dst;
1641 struct sockaddr_in6 *in2_src;
1643 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1644 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1645 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1646 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1648 int i;
1649 for (i = 0; i < 4; ++i)
1650 if (in1_dst->sin6_addr.s6_addr32[i]
1651 != in1_src->sin6_addr.s6_addr32[i]
1652 || (in2_dst->sin6_addr.s6_addr32[i]
1653 != in2_src->sin6_addr.s6_addr32[i]))
1654 break;
1656 if (i < 4)
1658 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1659 ^ in1_src->sin6_addr.s6_addr32[i]));
1660 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1661 ^ in2_src->sin6_addr.s6_addr32[i]));
1665 if (bit1 > bit2)
1666 return -1;
1667 if (bit1 < bit2)
1668 return 1;
1672 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1673 compare with the value indicating the order in which the entries
1674 have been received from the services. NB: no two entries can have
1675 the same order so the test will never return zero. */
1676 return idx1 < idx2 ? -1 : 1;
1680 static int
1681 in6aicmp (const void *p1, const void *p2)
1683 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1684 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1686 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1690 /* Name of the config file for RFC 3484 sorting (for now). */
1691 #define GAICONF_FNAME "/etc/gai.conf"
1694 /* Non-zero if we are supposed to reload the config file automatically
1695 whenever it changed. */
1696 static int gaiconf_reload_flag;
1698 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1699 static int gaiconf_reload_flag_ever_set;
1701 /* Last modification time. */
1702 #ifdef _STATBUF_ST_NSEC
1704 static struct timespec gaiconf_mtime;
1706 static inline void
1707 save_gaiconf_mtime (const struct stat64 *st)
1709 gaiconf_mtime = st->st_mtim;
1712 static inline bool
1713 check_gaiconf_mtime (const struct stat64 *st)
1715 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1716 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1719 #else
1721 static time_t gaiconf_mtime;
1723 static inline void
1724 save_gaiconf_mtime (const struct stat64 *st)
1726 gaiconf_mtime = st->st_mtime;
1729 static inline bool
1730 check_gaiconf_mtime (const struct stat64 *st)
1732 return st->st_mtime == gaiconf_mtime;
1735 #endif
1738 libc_freeres_fn(fini)
1740 if (labels != default_labels)
1742 const struct prefixentry *old = labels;
1743 labels = default_labels;
1744 free ((void *) old);
1747 if (precedence != default_precedence)
1749 const struct prefixentry *old = precedence;
1750 precedence = default_precedence;
1751 free ((void *) old);
1754 if (scopes != default_scopes)
1756 const struct scopeentry *old = scopes;
1757 scopes = default_scopes;
1758 free ((void *) old);
1763 struct prefixlist
1765 struct prefixentry entry;
1766 struct prefixlist *next;
1770 struct scopelist
1772 struct scopeentry entry;
1773 struct scopelist *next;
1777 static void
1778 free_prefixlist (struct prefixlist *list)
1780 while (list != NULL)
1782 struct prefixlist *oldp = list;
1783 list = list->next;
1784 free (oldp);
1789 static void
1790 free_scopelist (struct scopelist *list)
1792 while (list != NULL)
1794 struct scopelist *oldp = list;
1795 list = list->next;
1796 free (oldp);
1801 static int
1802 prefixcmp (const void *p1, const void *p2)
1804 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1805 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1807 if (e1->bits < e2->bits)
1808 return 1;
1809 if (e1->bits == e2->bits)
1810 return 0;
1811 return -1;
1815 static int
1816 scopecmp (const void *p1, const void *p2)
1818 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1819 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1821 if (e1->netmask > e2->netmask)
1822 return -1;
1823 if (e1->netmask == e2->netmask)
1824 return 0;
1825 return 1;
1829 static void
1830 gaiconf_init (void)
1832 struct prefixlist *labellist = NULL;
1833 size_t nlabellist = 0;
1834 bool labellist_nullbits = false;
1835 struct prefixlist *precedencelist = NULL;
1836 size_t nprecedencelist = 0;
1837 bool precedencelist_nullbits = false;
1838 struct scopelist *scopelist = NULL;
1839 size_t nscopelist = 0;
1840 bool scopelist_nullbits = false;
1842 FILE *fp = fopen (GAICONF_FNAME, "rce");
1843 if (fp != NULL)
1845 struct stat64 st;
1846 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1848 fclose (fp);
1849 goto no_file;
1852 char *line = NULL;
1853 size_t linelen = 0;
1855 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1857 while (!feof_unlocked (fp))
1859 ssize_t n = __getline (&line, &linelen, fp);
1860 if (n <= 0)
1861 break;
1863 /* Handle comments. No escaping possible so this is easy. */
1864 char *cp = strchr (line, '#');
1865 if (cp != NULL)
1866 *cp = '\0';
1868 cp = line;
1869 while (isspace (*cp))
1870 ++cp;
1872 char *cmd = cp;
1873 while (*cp != '\0' && !isspace (*cp))
1874 ++cp;
1875 size_t cmdlen = cp - cmd;
1877 if (*cp != '\0')
1878 *cp++ = '\0';
1879 while (isspace (*cp))
1880 ++cp;
1882 char *val1 = cp;
1883 while (*cp != '\0' && !isspace (*cp))
1884 ++cp;
1885 size_t val1len = cp - cmd;
1887 /* We always need at least two values. */
1888 if (val1len == 0)
1889 continue;
1891 if (*cp != '\0')
1892 *cp++ = '\0';
1893 while (isspace (*cp))
1894 ++cp;
1896 char *val2 = cp;
1897 while (*cp != '\0' && !isspace (*cp))
1898 ++cp;
1900 /* Ignore the rest of the line. */
1901 *cp = '\0';
1903 struct prefixlist **listp;
1904 size_t *lenp;
1905 bool *nullbitsp;
1906 switch (cmdlen)
1908 case 5:
1909 if (strcmp (cmd, "label") == 0)
1911 struct in6_addr prefix;
1912 unsigned long int bits;
1913 unsigned long int val;
1914 char *endp;
1916 listp = &labellist;
1917 lenp = &nlabellist;
1918 nullbitsp = &labellist_nullbits;
1920 new_elem:
1921 bits = 128;
1922 __set_errno (0);
1923 cp = strchr (val1, '/');
1924 if (cp != NULL)
1925 *cp++ = '\0';
1926 if (inet_pton (AF_INET6, val1, &prefix)
1927 && (cp == NULL
1928 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1929 || errno != ERANGE)
1930 && *endp == '\0'
1931 && bits <= 128
1932 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1933 || errno != ERANGE)
1934 && *endp == '\0'
1935 && val <= INT_MAX)
1937 struct prefixlist *newp = malloc (sizeof (*newp));
1938 if (newp == NULL)
1940 free (line);
1941 fclose (fp);
1942 goto no_file;
1945 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1946 newp->entry.bits = bits;
1947 newp->entry.val = val;
1948 newp->next = *listp;
1949 *listp = newp;
1950 ++*lenp;
1951 *nullbitsp |= bits == 0;
1954 break;
1956 case 6:
1957 if (strcmp (cmd, "reload") == 0)
1959 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1960 if (gaiconf_reload_flag)
1961 gaiconf_reload_flag_ever_set = 1;
1963 break;
1965 case 7:
1966 if (strcmp (cmd, "scopev4") == 0)
1968 struct in6_addr prefix;
1969 unsigned long int bits;
1970 unsigned long int val;
1971 char *endp;
1973 bits = 32;
1974 __set_errno (0);
1975 cp = strchr (val1, '/');
1976 if (cp != NULL)
1977 *cp++ = '\0';
1978 if (inet_pton (AF_INET6, val1, &prefix))
1980 bits = 128;
1981 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1982 && (cp == NULL
1983 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1984 || errno != ERANGE)
1985 && *endp == '\0'
1986 && bits >= 96
1987 && bits <= 128
1988 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1989 || errno != ERANGE)
1990 && *endp == '\0'
1991 && val <= INT_MAX)
1993 struct scopelist *newp;
1994 new_scope:
1995 newp = malloc (sizeof (*newp));
1996 if (newp == NULL)
1998 free (line);
1999 fclose (fp);
2000 goto no_file;
2003 newp->entry.netmask = htonl (bits != 96
2004 ? (0xffffffff
2005 << (128 - bits))
2006 : 0);
2007 newp->entry.addr32 = (prefix.s6_addr32[3]
2008 & newp->entry.netmask);
2009 newp->entry.scope = val;
2010 newp->next = scopelist;
2011 scopelist = newp;
2012 ++nscopelist;
2013 scopelist_nullbits |= bits == 96;
2016 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2017 && (cp == NULL
2018 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2019 || errno != ERANGE)
2020 && *endp == '\0'
2021 && bits <= 32
2022 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2023 || errno != ERANGE)
2024 && *endp == '\0'
2025 && val <= INT_MAX)
2027 bits += 96;
2028 goto new_scope;
2031 break;
2033 case 10:
2034 if (strcmp (cmd, "precedence") == 0)
2036 listp = &precedencelist;
2037 lenp = &nprecedencelist;
2038 nullbitsp = &precedencelist_nullbits;
2039 goto new_elem;
2041 break;
2045 free (line);
2047 fclose (fp);
2049 /* Create the array for the labels. */
2050 struct prefixentry *new_labels;
2051 if (nlabellist > 0)
2053 if (!labellist_nullbits)
2054 ++nlabellist;
2055 new_labels = malloc (nlabellist * sizeof (*new_labels));
2056 if (new_labels == NULL)
2057 goto no_file;
2059 int i = nlabellist;
2060 if (!labellist_nullbits)
2062 --i;
2063 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2064 new_labels[i].bits = 0;
2065 new_labels[i].val = 1;
2068 struct prefixlist *l = labellist;
2069 while (i-- > 0)
2071 new_labels[i] = l->entry;
2072 l = l->next;
2074 free_prefixlist (labellist);
2076 /* Sort the entries so that the most specific ones are at
2077 the beginning. */
2078 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2080 else
2081 new_labels = (struct prefixentry *) default_labels;
2083 struct prefixentry *new_precedence;
2084 if (nprecedencelist > 0)
2086 if (!precedencelist_nullbits)
2087 ++nprecedencelist;
2088 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2089 if (new_precedence == NULL)
2091 if (new_labels != default_labels)
2092 free (new_labels);
2093 goto no_file;
2096 int i = nprecedencelist;
2097 if (!precedencelist_nullbits)
2099 --i;
2100 memset (&new_precedence[i].prefix, '\0',
2101 sizeof (struct in6_addr));
2102 new_precedence[i].bits = 0;
2103 new_precedence[i].val = 40;
2106 struct prefixlist *l = precedencelist;
2107 while (i-- > 0)
2109 new_precedence[i] = l->entry;
2110 l = l->next;
2112 free_prefixlist (precedencelist);
2114 /* Sort the entries so that the most specific ones are at
2115 the beginning. */
2116 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2117 prefixcmp);
2119 else
2120 new_precedence = (struct prefixentry *) default_precedence;
2122 struct scopeentry *new_scopes;
2123 if (nscopelist > 0)
2125 if (!scopelist_nullbits)
2126 ++nscopelist;
2127 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2128 if (new_scopes == NULL)
2130 if (new_labels != default_labels)
2131 free (new_labels);
2132 if (new_precedence != default_precedence)
2133 free (new_precedence);
2134 goto no_file;
2137 int i = nscopelist;
2138 if (!scopelist_nullbits)
2140 --i;
2141 new_scopes[i].addr32 = 0;
2142 new_scopes[i].netmask = 0;
2143 new_scopes[i].scope = 14;
2146 struct scopelist *l = scopelist;
2147 while (i-- > 0)
2149 new_scopes[i] = l->entry;
2150 l = l->next;
2152 free_scopelist (scopelist);
2154 /* Sort the entries so that the most specific ones are at
2155 the beginning. */
2156 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2157 scopecmp);
2159 else
2160 new_scopes = (struct scopeentry *) default_scopes;
2162 /* Now we are ready to replace the values. */
2163 const struct prefixentry *old = labels;
2164 labels = new_labels;
2165 if (old != default_labels)
2166 free ((void *) old);
2168 old = precedence;
2169 precedence = new_precedence;
2170 if (old != default_precedence)
2171 free ((void *) old);
2173 const struct scopeentry *oldscope = scopes;
2174 scopes = new_scopes;
2175 if (oldscope != default_scopes)
2176 free ((void *) oldscope);
2178 save_gaiconf_mtime (&st);
2180 else
2182 no_file:
2183 free_prefixlist (labellist);
2184 free_prefixlist (precedencelist);
2185 free_scopelist (scopelist);
2187 /* If we previously read the file but it is gone now, free the
2188 old data and use the builtin one. Leave the reload flag
2189 alone. */
2190 fini ();
2195 static void
2196 gaiconf_reload (void)
2198 struct stat64 st;
2199 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2200 || !check_gaiconf_mtime (&st))
2201 gaiconf_init ();
2206 getaddrinfo (const char *name, const char *service,
2207 const struct addrinfo *hints, struct addrinfo **pai)
2209 int i = 0, last_i = 0;
2210 int nresults = 0;
2211 struct addrinfo *p = NULL;
2212 struct gaih_service gaih_service, *pservice;
2213 struct addrinfo local_hints;
2215 if (name != NULL && name[0] == '*' && name[1] == 0)
2216 name = NULL;
2218 if (service != NULL && service[0] == '*' && service[1] == 0)
2219 service = NULL;
2221 if (name == NULL && service == NULL)
2222 return EAI_NONAME;
2224 if (hints == NULL)
2225 hints = &default_hints;
2227 if (hints->ai_flags
2228 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2229 #ifdef HAVE_LIBIDN
2230 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2231 |AI_IDN_USE_STD3_ASCII_RULES
2232 #endif
2233 |AI_NUMERICSERV|AI_ALL))
2234 return EAI_BADFLAGS;
2236 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2237 return EAI_BADFLAGS;
2239 struct in6addrinfo *in6ai = NULL;
2240 size_t in6ailen = 0;
2241 bool seen_ipv4 = false;
2242 bool seen_ipv6 = false;
2243 bool check_pf_called = false;
2245 if (hints->ai_flags & AI_ADDRCONFIG)
2247 /* We might need information about what interfaces are available.
2248 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2249 cannot cache the results since new interfaces could be added at
2250 any time. */
2251 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2252 check_pf_called = true;
2254 /* Now make a decision on what we return, if anything. */
2255 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2257 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2258 narrow down the search. */
2259 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2261 local_hints = *hints;
2262 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2263 hints = &local_hints;
2266 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2267 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2269 /* We cannot possibly return a valid answer. */
2270 __free_in6ai (in6ai);
2271 return EAI_NONAME;
2275 if (service && service[0])
2277 char *c;
2278 gaih_service.name = service;
2279 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2280 if (*c != '\0')
2282 if (hints->ai_flags & AI_NUMERICSERV)
2284 __free_in6ai (in6ai);
2285 return EAI_NONAME;
2288 gaih_service.num = -1;
2291 pservice = &gaih_service;
2293 else
2294 pservice = NULL;
2296 struct addrinfo **end = &p;
2298 unsigned int naddrs = 0;
2299 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2300 || hints->ai_family == AF_INET6)
2302 struct scratch_buffer tmpbuf;
2303 scratch_buffer_init (&tmpbuf);
2304 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2305 scratch_buffer_free (&tmpbuf);
2307 if (last_i != 0)
2309 freeaddrinfo (p);
2310 __free_in6ai (in6ai);
2312 return -last_i;
2314 while (*end)
2316 end = &((*end)->ai_next);
2317 ++nresults;
2320 else
2322 __free_in6ai (in6ai);
2323 return EAI_FAMILY;
2326 if (naddrs > 1)
2328 /* Read the config file. */
2329 __libc_once_define (static, once);
2330 __typeof (once) old_once = once;
2331 __libc_once (once, gaiconf_init);
2332 /* Sort results according to RFC 3484. */
2333 struct sort_result *results;
2334 size_t *order;
2335 struct addrinfo *q;
2336 struct addrinfo *last = NULL;
2337 char *canonname = NULL;
2338 bool malloc_results;
2339 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2341 malloc_results
2342 = !__libc_use_alloca (alloc_size);
2343 if (malloc_results)
2345 results = malloc (alloc_size);
2346 if (results == NULL)
2348 __free_in6ai (in6ai);
2349 return EAI_MEMORY;
2352 else
2353 results = alloca (alloc_size);
2354 order = (size_t *) (results + nresults);
2356 /* Now we definitely need the interface information. */
2357 if (! check_pf_called)
2358 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2360 /* If we have information about deprecated and temporary addresses
2361 sort the array now. */
2362 if (in6ai != NULL)
2363 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2365 int fd = -1;
2366 int af = AF_UNSPEC;
2368 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2370 results[i].dest_addr = q;
2371 results[i].native = -1;
2372 order[i] = i;
2374 /* If we just looked up the address for a different
2375 protocol, reuse the result. */
2376 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2377 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2379 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2380 results[i - 1].source_addr_len);
2381 results[i].source_addr_len = results[i - 1].source_addr_len;
2382 results[i].got_source_addr = results[i - 1].got_source_addr;
2383 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2384 results[i].prefixlen = results[i - 1].prefixlen;
2385 results[i].index = results[i - 1].index;
2387 else
2389 results[i].got_source_addr = false;
2390 results[i].source_addr_flags = 0;
2391 results[i].prefixlen = 0;
2392 results[i].index = 0xffffffffu;
2394 /* We overwrite the type with SOCK_DGRAM since we do not
2395 want connect() to connect to the other side. If we
2396 cannot determine the source address remember this
2397 fact. */
2398 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2400 if (fd != -1)
2401 close_retry:
2402 __close_nocancel_nostatus (fd);
2403 af = q->ai_family;
2404 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2406 else
2408 /* Reset the connection. */
2409 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2410 __connect (fd, &sa, sizeof (sa));
2413 socklen_t sl = sizeof (results[i].source_addr);
2414 if (fd != -1
2415 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2416 && __getsockname (fd,
2417 (struct sockaddr *) &results[i].source_addr,
2418 &sl) == 0)
2420 results[i].source_addr_len = sl;
2421 results[i].got_source_addr = true;
2423 if (in6ai != NULL)
2425 /* See whether the source address is on the list of
2426 deprecated or temporary addresses. */
2427 struct in6addrinfo tmp;
2429 if (q->ai_family == AF_INET && af == AF_INET)
2431 struct sockaddr_in *sinp
2432 = (struct sockaddr_in *) &results[i].source_addr;
2433 tmp.addr[0] = 0;
2434 tmp.addr[1] = 0;
2435 tmp.addr[2] = htonl (0xffff);
2436 /* Special case for lo interface, the source address
2437 being possibly different than the interface
2438 address. */
2439 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2440 == 0x7f000000)
2441 tmp.addr[3] = htonl(0x7f000001);
2442 else
2443 tmp.addr[3] = sinp->sin_addr.s_addr;
2445 else
2447 struct sockaddr_in6 *sin6p
2448 = (struct sockaddr_in6 *) &results[i].source_addr;
2449 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2452 struct in6addrinfo *found
2453 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2454 in6aicmp);
2455 if (found != NULL)
2457 results[i].source_addr_flags = found->flags;
2458 results[i].prefixlen = found->prefixlen;
2459 results[i].index = found->index;
2463 if (q->ai_family == AF_INET && af == AF_INET6)
2465 /* We have to convert the address. The socket is
2466 IPv6 and the request is for IPv4. */
2467 struct sockaddr_in6 *sin6
2468 = (struct sockaddr_in6 *) &results[i].source_addr;
2469 struct sockaddr_in *sin
2470 = (struct sockaddr_in *) &results[i].source_addr;
2471 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2472 sin->sin_family = AF_INET;
2473 /* We do not have to initialize sin_port since this
2474 fields has the same position and size in the IPv6
2475 structure. */
2476 assert (offsetof (struct sockaddr_in, sin_port)
2477 == offsetof (struct sockaddr_in6, sin6_port));
2478 assert (sizeof (sin->sin_port)
2479 == sizeof (sin6->sin6_port));
2480 memcpy (&sin->sin_addr,
2481 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2482 results[i].source_addr_len = sizeof (struct sockaddr_in);
2485 else if (errno == EAFNOSUPPORT && af == AF_INET6
2486 && q->ai_family == AF_INET)
2487 /* This could mean IPv6 sockets are IPv6-only. */
2488 goto close_retry;
2489 else
2490 /* Just make sure that if we have to process the same
2491 address again we do not copy any memory. */
2492 results[i].source_addr_len = 0;
2495 /* Remember the canonical name. */
2496 if (q->ai_canonname != NULL)
2498 assert (canonname == NULL);
2499 canonname = q->ai_canonname;
2500 q->ai_canonname = NULL;
2504 if (fd != -1)
2505 __close_nocancel_nostatus (fd);
2507 /* We got all the source addresses we can get, now sort using
2508 the information. */
2509 struct sort_result_combo src
2510 = { .results = results, .nresults = nresults };
2511 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2513 __libc_lock_define_initialized (static, lock);
2515 __libc_lock_lock (lock);
2516 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2517 gaiconf_reload ();
2518 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2519 __libc_lock_unlock (lock);
2521 else
2522 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2524 /* Queue the results up as they come out of sorting. */
2525 q = p = results[order[0]].dest_addr;
2526 for (i = 1; i < nresults; ++i)
2527 q = q->ai_next = results[order[i]].dest_addr;
2528 q->ai_next = NULL;
2530 /* Fill in the canonical name into the new first entry. */
2531 p->ai_canonname = canonname;
2533 if (malloc_results)
2534 free (results);
2537 __free_in6ai (in6ai);
2539 if (p)
2541 *pai = p;
2542 return 0;
2545 return last_i ? -last_i : EAI_NONAME;
2547 libc_hidden_def (getaddrinfo)
2549 nss_interface_function (getaddrinfo)
2551 void
2552 freeaddrinfo (struct addrinfo *ai)
2554 struct addrinfo *p;
2556 while (ai != NULL)
2558 p = ai;
2559 ai = ai->ai_next;
2560 free (p->ai_canonname);
2561 free (p);
2564 libc_hidden_def (freeaddrinfo)