1/* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
19/* The Inner Net License, Version 2.00
20
21 The author(s) grant permission for redistribution and use in source and
22binary forms, with or without modification, of the software and documentation
23provided that the following conditions are met:
24
250. 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.
291. All terms of the all other applicable copyrights and licenses must be
30 followed.
312. Redistributions of source code must retain the authors' copyright
32 notice(s), this list of conditions, and the following disclaimer.
333. 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.
364. [The copyright holder has authorized the removal of this clause.]
375. 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.
40
41THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
42EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
45DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48ANY 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
50SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51
52 If these license terms cause you a real problem, contact the author. */
53
54/* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
55
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>
86
87/* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
88 flags, now ignored. */
89#define DEPRECATED_AI_IDN 0x300
90
91#if IS_IN (libc)
92# define feof_unlocked(fp) __feof_unlocked (fp)
93#endif
94
95struct gaih_service
96 {
97 const char *name;
98 int num;
99 };
100
101struct gaih_servtuple
102 {
103 struct gaih_servtuple *next;
104 int socktype;
105 int protocol;
106 int port;
107 };
108
109static const struct gaih_servtuple nullserv;
110
111
112struct gaih_typeproto
113 {
114 int socktype;
115 int protocol;
116 uint8_t protoflag;
117 bool defaultflag;
118 char name[8];
119 };
120
121/* Values for `protoflag'. */
122#define GAI_PROTO_NOSERVICE 1
123#define GAI_PROTO_PROTOANY 2
124
125static const struct gaih_typeproto gaih_inet_typeproto[] =
126{
127 { 0, 0, 0, false, "" },
128 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
129 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
130#if defined SOCK_DCCP && defined IPPROTO_DCCP
131 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
132#endif
133#ifdef IPPROTO_UDPLITE
134 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
135#endif
136#ifdef IPPROTO_SCTP
137 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
138 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
139#endif
140 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
141 { 0, 0, 0, false, "" }
142};
143
144static const struct addrinfo default_hints =
145 {
146 .ai_flags = AI_DEFAULT,
147 .ai_family = PF_UNSPEC,
148 .ai_socktype = 0,
149 .ai_protocol = 0,
150 .ai_addrlen = 0,
151 .ai_addr = NULL,
152 .ai_canonname = NULL,
153 .ai_next = NULL
154 };
155
156
157static int
158gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
159 const struct addrinfo *req, struct gaih_servtuple *st,
160 struct scratch_buffer *tmpbuf)
161{
162 struct servent *s;
163 struct servent ts;
164 int r;
165
166 do
167 {
168 r = __getservbyname_r (servicename, tp->name, &ts,
169 tmpbuf->data, tmpbuf->length, &s);
170 if (r != 0 || s == NULL)
171 {
172 if (r == ERANGE)
173 {
174 if (!scratch_buffer_grow (tmpbuf))
175 return -EAI_MEMORY;
176 }
177 else
178 return -EAI_SERVICE;
179 }
180 }
181 while (r);
182
183 st->next = NULL;
184 st->socktype = tp->socktype;
185 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
186 ? req->ai_protocol : tp->protocol);
187 st->port = s->s_port;
188
189 return 0;
190}
191
192/* Convert struct hostent to a list of struct gaih_addrtuple objects.
193 h_name is not copied, and the struct hostent object must not be
194 deallocated prematurely. *RESULT must be NULL or a pointer to a
195 linked-list. The new addresses are appended at the end. */
196static bool
197convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
198 int family,
199 struct hostent *h,
200 struct gaih_addrtuple **result)
201{
202 while (*result)
203 result = &(*result)->next;
204
205 /* Count the number of addresses in h->h_addr_list. */
206 size_t count = 0;
207 for (char **p = h->h_addr_list; *p != NULL; ++p)
208 ++count;
209
210 /* Report no data if no addresses are available, or if the incoming
211 address size is larger than what we can store. */
212 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
213 return true;
214
215 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
216 if (array == NULL)
217 return false;
218
219 for (size_t i = 0; i < count; ++i)
220 {
221 if (family == AF_INET && req->ai_family == AF_INET6)
222 {
223 /* Perform address mapping. */
224 array[i].family = AF_INET6;
225 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
226 array[i].addr[2] = htonl (0xffff);
227 }
228 else
229 {
230 array[i].family = family;
231 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
232 }
233 array[i].next = array + i + 1;
234 }
235 array[0].name = h->h_name;
236 array[count - 1].next = NULL;
237
238 *result = array;
239 return true;
240}
241
242#define gethosts(_family) \
243 { \
244 struct hostent th; \
245 char *localcanon = NULL; \
246 no_data = 0; \
247 while (1) \
248 { \
249 status = DL_CALL_FCT (fct, (name, _family, &th, \
250 tmpbuf->data, tmpbuf->length, \
251 &errno, &h_errno, NULL, &localcanon)); \
252 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
253 || errno != ERANGE) \
254 break; \
255 if (!scratch_buffer_grow (tmpbuf)) \
256 { \
257 __resolv_context_put (res_ctx); \
258 result = -EAI_MEMORY; \
259 goto free_and_return; \
260 } \
261 } \
262 if (status == NSS_STATUS_NOTFOUND \
263 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
264 { \
265 if (h_errno == NETDB_INTERNAL) \
266 { \
267 __resolv_context_put (res_ctx); \
268 result = -EAI_SYSTEM; \
269 goto free_and_return; \
270 } \
271 if (h_errno == TRY_AGAIN) \
272 no_data = EAI_AGAIN; \
273 else \
274 no_data = h_errno == NO_DATA; \
275 } \
276 else if (status == NSS_STATUS_SUCCESS) \
277 { \
278 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
279 { \
280 __resolv_context_put (res_ctx); \
281 result = -EAI_SYSTEM; \
282 goto free_and_return; \
283 } \
284 *pat = addrmem; \
285 \
286 if (localcanon != NULL && canon == NULL) \
287 { \
288 canonbuf = __strdup (localcanon); \
289 if (canonbuf == NULL) \
290 { \
291 __resolv_context_put (res_ctx); \
292 result = -EAI_SYSTEM; \
293 goto free_and_return; \
294 } \
295 canon = canonbuf; \
296 } \
297 if (_family == AF_INET6 && *pat != NULL) \
298 got_ipv6 = true; \
299 } \
300 }
301
302
303/* This function is called if a canonical name is requested, but if
304 the service function did not provide it. It tries to obtain the
305 name using getcanonname_r from the same service NIP. If the name
306 cannot be canonicalized, return a copy of NAME. Return NULL on
307 memory allocation failure. The returned string is allocated on the
308 heap; the caller has to free it. */
309static char *
310getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
311{
312 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
313 char *s = (char *) name;
314 if (cfct != NULL)
315 {
316 char buf[256];
317 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
318 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
319 /* If the canonical name cannot be determined, use the passed
320 string. */
321 s = (char *) name;
322 }
323 return __strdup (name);
324}
325
326static int
327gaih_inet (const char *name, const struct gaih_service *service,
328 const struct addrinfo *req, struct addrinfo **pai,
329 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
330{
331 const struct gaih_typeproto *tp = gaih_inet_typeproto;
332 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
333 struct gaih_addrtuple *at = NULL;
334 bool got_ipv6 = false;
335 const char *canon = NULL;
336 const char *orig_name = name;
337
338 /* Reserve stack memory for the scratch buffer in the getaddrinfo
339 function. */
340 size_t alloca_used = sizeof (struct scratch_buffer);
341
342 if (req->ai_protocol || req->ai_socktype)
343 {
344 ++tp;
345
346 while (tp->name[0]
347 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
348 || (req->ai_protocol != 0
349 && !(tp->protoflag & GAI_PROTO_PROTOANY)
350 && req->ai_protocol != tp->protocol)))
351 ++tp;
352
353 if (! tp->name[0])
354 {
355 if (req->ai_socktype)
356 return -EAI_SOCKTYPE;
357 else
358 return -EAI_SERVICE;
359 }
360 }
361
362 int port = 0;
363 if (service != NULL)
364 {
365 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
366 return -EAI_SERVICE;
367
368 if (service->num < 0)
369 {
370 if (tp->name[0])
371 {
372 st = (struct gaih_servtuple *)
373 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
374
375 int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
376 if (__glibc_unlikely (rc != 0))
377 return rc;
378 }
379 else
380 {
381 struct gaih_servtuple **pst = &st;
382 for (tp++; tp->name[0]; tp++)
383 {
384 struct gaih_servtuple *newp;
385
386 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
387 continue;
388
389 if (req->ai_socktype != 0
390 && req->ai_socktype != tp->socktype)
391 continue;
392 if (req->ai_protocol != 0
393 && !(tp->protoflag & GAI_PROTO_PROTOANY)
394 && req->ai_protocol != tp->protocol)
395 continue;
396
397 newp = (struct gaih_servtuple *)
398 alloca_account (sizeof (struct gaih_servtuple),
399 alloca_used);
400
401 if (gaih_inet_serv (service->name,
402 tp, req, newp, tmpbuf) != 0)
403 continue;
404
405 *pst = newp;
406 pst = &(newp->next);
407 }
408 if (st == (struct gaih_servtuple *) &nullserv)
409 return -EAI_SERVICE;
410 }
411 }
412 else
413 {
414 port = htons (service->num);
415 goto got_port;
416 }
417 }
418 else
419 {
420 got_port:
421
422 if (req->ai_socktype || req->ai_protocol)
423 {
424 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
425 st->next = NULL;
426 st->socktype = tp->socktype;
427 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
428 ? req->ai_protocol : tp->protocol);
429 st->port = port;
430 }
431 else
432 {
433 /* Neither socket type nor protocol is set. Return all socket types
434 we know about. */
435 struct gaih_servtuple **lastp = &st;
436 for (++tp; tp->name[0]; ++tp)
437 if (tp->defaultflag)
438 {
439 struct gaih_servtuple *newp;
440
441 newp = alloca_account (sizeof (struct gaih_servtuple),
442 alloca_used);
443 newp->next = NULL;
444 newp->socktype = tp->socktype;
445 newp->protocol = tp->protocol;
446 newp->port = port;
447
448 *lastp = newp;
449 lastp = &newp->next;
450 }
451 }
452 }
453
454 bool malloc_name = false;
455 struct gaih_addrtuple *addrmem = NULL;
456 char *canonbuf = NULL;
457 int result = 0;
458
459 if (name != NULL)
460 {
461 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
462 at->family = AF_UNSPEC;
463 at->scopeid = 0;
464 at->next = NULL;
465
466 if (req->ai_flags & AI_IDN)
467 {
468 char *out;
469 result = __idna_to_dns_encoding (name, &out);
470 if (result != 0)
471 return -result;
472 name = out;
473 malloc_name = true;
474 }
475
476 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
477 {
478 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
479 at->family = AF_INET;
480 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
481 {
482 at->addr[3] = at->addr[0];
483 at->addr[2] = htonl (0xffff);
484 at->addr[1] = 0;
485 at->addr[0] = 0;
486 at->family = AF_INET6;
487 }
488 else
489 {
490 result = -EAI_ADDRFAMILY;
491 goto free_and_return;
492 }
493
494 if (req->ai_flags & AI_CANONNAME)
495 canon = name;
496 }
497 else if (at->family == AF_UNSPEC)
498 {
499 char *scope_delim = strchr (name, SCOPE_DELIMITER);
500 int e;
501 if (scope_delim == NULL)
502 e = inet_pton (AF_INET6, name, at->addr);
503 else
504 e = __inet_pton_length (AF_INET6, name, scope_delim - name,
505 at->addr);
506 if (e > 0)
507 {
508 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
509 at->family = AF_INET6;
510 else if (req->ai_family == AF_INET
511 && IN6_IS_ADDR_V4MAPPED (at->addr))
512 {
513 at->addr[0] = at->addr[3];
514 at->family = AF_INET;
515 }
516 else
517 {
518 result = -EAI_ADDRFAMILY;
519 goto free_and_return;
520 }
521
522 if (scope_delim != NULL
523 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
524 scope_delim + 1,
525 &at->scopeid) != 0)
526 {
527 result = -EAI_NONAME;
528 goto free_and_return;
529 }
530
531 if (req->ai_flags & AI_CANONNAME)
532 canon = name;
533 }
534 }
535
536 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
537 {
538 struct gaih_addrtuple **pat = &at;
539 int no_data = 0;
540 int no_inet6_data = 0;
541 nss_action_list nip;
542 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
543 enum nss_status status = NSS_STATUS_UNAVAIL;
544 int no_more;
545 struct resolv_context *res_ctx = NULL;
546
547 /* If we do not have to look for IPv6 addresses or the canonical
548 name, use the simple, old functions, which do not support
549 IPv6 scope ids, nor retrieving the canonical name. */
550 if (req->ai_family == AF_INET
551 && (req->ai_flags & AI_CANONNAME) == 0)
552 {
553 int rc;
554 struct hostent th;
555 struct hostent *h;
556
557 while (1)
558 {
559 rc = __gethostbyname2_r (name, AF_INET, &th,
560 tmpbuf->data, tmpbuf->length,
561 &h, &h_errno);
562 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
563 break;
564 if (!scratch_buffer_grow (tmpbuf))
565 {
566 result = -EAI_MEMORY;
567 goto free_and_return;
568 }
569 }
570
571 if (rc == 0)
572 {
573 if (h != NULL)
574 {
575 /* We found data, convert it. */
576 if (!convert_hostent_to_gaih_addrtuple
577 (req, AF_INET, h, &addrmem))
578 {
579 result = -EAI_MEMORY;
580 goto free_and_return;
581 }
582 *pat = addrmem;
583 }
584 else
585 {
586 if (h_errno == NO_DATA)
587 result = -EAI_NODATA;
588 else
589 result = -EAI_NONAME;
590 goto free_and_return;
591 }
592 }
593 else
594 {
595 if (h_errno == NETDB_INTERNAL)
596 result = -EAI_SYSTEM;
597 else if (h_errno == TRY_AGAIN)
598 result = -EAI_AGAIN;
599 else
600 /* We made requests but they turned out no data.
601 The name is known, though. */
602 result = -EAI_NODATA;
603
604 goto free_and_return;
605 }
606
607 goto process_list;
608 }
609
610#ifdef USE_NSCD
611 if (__nss_not_use_nscd_hosts > 0
612 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
613 __nss_not_use_nscd_hosts = 0;
614
615 if (!__nss_not_use_nscd_hosts
616 && !__nss_database_custom[NSS_DBSIDX_hosts])
617 {
618 /* Try to use nscd. */
619 struct nscd_ai_result *air = NULL;
620 int err = __nscd_getai (name, &air, &h_errno);
621 if (air != NULL)
622 {
623 /* Transform into gaih_addrtuple list. */
624 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
625 char *addrs = air->addrs;
626
627 addrmem = calloc (air->naddrs, sizeof (*addrmem));
628 if (addrmem == NULL)
629 {
630 result = -EAI_MEMORY;
631 goto free_and_return;
632 }
633
634 struct gaih_addrtuple *addrfree = addrmem;
635 for (int i = 0; i < air->naddrs; ++i)
636 {
637 socklen_t size = (air->family[i] == AF_INET
638 ? INADDRSZ : IN6ADDRSZ);
639
640 if (!((air->family[i] == AF_INET
641 && req->ai_family == AF_INET6
642 && (req->ai_flags & AI_V4MAPPED) != 0)
643 || req->ai_family == AF_UNSPEC
644 || air->family[i] == req->ai_family))
645 {
646 /* Skip over non-matching result. */
647 addrs += size;
648 continue;
649 }
650
651 if (*pat == NULL)
652 {
653 *pat = addrfree++;
654 (*pat)->scopeid = 0;
655 }
656 uint32_t *pataddr = (*pat)->addr;
657 (*pat)->next = NULL;
658 if (added_canon || air->canon == NULL)
659 (*pat)->name = NULL;
660 else if (canonbuf == NULL)
661 {
662 canonbuf = __strdup (air->canon);
663 if (canonbuf == NULL)
664 {
665 result = -EAI_MEMORY;
666 goto free_and_return;
667 }
668 canon = (*pat)->name = canonbuf;
669 }
670
671 if (air->family[i] == AF_INET
672 && req->ai_family == AF_INET6
673 && (req->ai_flags & AI_V4MAPPED))
674 {
675 (*pat)->family = AF_INET6;
676 pataddr[3] = *(uint32_t *) addrs;
677 pataddr[2] = htonl (0xffff);
678 pataddr[1] = 0;
679 pataddr[0] = 0;
680 pat = &((*pat)->next);
681 added_canon = true;
682 }
683 else if (req->ai_family == AF_UNSPEC
684 || air->family[i] == req->ai_family)
685 {
686 (*pat)->family = air->family[i];
687 memcpy (pataddr, addrs, size);
688 pat = &((*pat)->next);
689 added_canon = true;
690 if (air->family[i] == AF_INET6)
691 got_ipv6 = true;
692 }
693 addrs += size;
694 }
695
696 free (air);
697
698 if (at->family == AF_UNSPEC)
699 {
700 result = -EAI_NONAME;
701 goto free_and_return;
702 }
703
704 goto process_list;
705 }
706 else if (err == 0)
707 /* The database contains a negative entry. */
708 goto free_and_return;
709 else if (__nss_not_use_nscd_hosts == 0)
710 {
711 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
712 result = -EAI_MEMORY;
713 else if (h_errno == TRY_AGAIN)
714 result = -EAI_AGAIN;
715 else
716 result = -EAI_SYSTEM;
717
718 goto free_and_return;
719 }
720 }
721#endif
722
723 no_more = !__nss_database_get (nss_database_hosts, &nip);
724
725 /* If we are looking for both IPv4 and IPv6 address we don't
726 want the lookup functions to automatically promote IPv4
727 addresses to IPv6 addresses, so we use the no_inet6
728 function variant. */
729 res_ctx = __resolv_context_get ();
730 if (res_ctx == NULL)
731 no_more = 1;
732
733 while (!no_more)
734 {
735 no_data = 0;
736 nss_gethostbyname4_r *fct4 = NULL;
737
738 /* gethostbyname4_r sends out parallel A and AAAA queries and
739 is thus only suitable for PF_UNSPEC. */
740 if (req->ai_family == PF_UNSPEC)
741 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
742
743 if (fct4 != NULL)
744 {
745 while (1)
746 {
747 status = DL_CALL_FCT (fct4, (name, pat,
748 tmpbuf->data, tmpbuf->length,
749 &errno, &h_errno,
750 NULL));
751 if (status == NSS_STATUS_SUCCESS)
752 break;
753 if (status != NSS_STATUS_TRYAGAIN
754 || errno != ERANGE || h_errno != NETDB_INTERNAL)
755 {
756 if (h_errno == TRY_AGAIN)
757 no_data = EAI_AGAIN;
758 else
759 no_data = h_errno == NO_DATA;
760 break;
761 }
762
763 if (!scratch_buffer_grow (tmpbuf))
764 {
765 __resolv_context_put (res_ctx);
766 result = -EAI_MEMORY;
767 goto free_and_return;
768 }
769 }
770
771 if (status == NSS_STATUS_SUCCESS)
772 {
773 assert (!no_data);
774 no_data = 1;
775
776 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
777 canon = (*pat)->name;
778
779 while (*pat != NULL)
780 {
781 if ((*pat)->family == AF_INET
782 && req->ai_family == AF_INET6
783 && (req->ai_flags & AI_V4MAPPED) != 0)
784 {
785 uint32_t *pataddr = (*pat)->addr;
786 (*pat)->family = AF_INET6;
787 pataddr[3] = pataddr[0];
788 pataddr[2] = htonl (0xffff);
789 pataddr[1] = 0;
790 pataddr[0] = 0;
791 pat = &((*pat)->next);
792 no_data = 0;
793 }
794 else if (req->ai_family == AF_UNSPEC
795 || (*pat)->family == req->ai_family)
796 {
797 pat = &((*pat)->next);
798
799 no_data = 0;
800 if (req->ai_family == AF_INET6)
801 got_ipv6 = true;
802 }
803 else
804 *pat = ((*pat)->next);
805 }
806 }
807
808 no_inet6_data = no_data;
809 }
810 else
811 {
812 nss_gethostbyname3_r *fct = NULL;
813 if (req->ai_flags & AI_CANONNAME)
814 /* No need to use this function if we do not look for
815 the canonical name. The function does not exist in
816 all NSS modules and therefore the lookup would
817 often fail. */
818 fct = __nss_lookup_function (nip, "gethostbyname3_r");
819 if (fct == NULL)
820 /* We are cheating here. The gethostbyname2_r
821 function does not have the same interface as
822 gethostbyname3_r but the extra arguments the
823 latter takes are added at the end. So the
824 gethostbyname2_r code will just ignore them. */
825 fct = __nss_lookup_function (nip, "gethostbyname2_r");
826
827 if (fct != NULL)
828 {
829 if (req->ai_family == AF_INET6
830 || req->ai_family == AF_UNSPEC)
831 {
832 gethosts (AF_INET6);
833 no_inet6_data = no_data;
834 inet6_status = status;
835 }
836 if (req->ai_family == AF_INET
837 || req->ai_family == AF_UNSPEC
838 || (req->ai_family == AF_INET6
839 && (req->ai_flags & AI_V4MAPPED)
840 /* Avoid generating the mapped addresses if we
841 know we are not going to need them. */
842 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
843 {
844 gethosts (AF_INET);
845
846 if (req->ai_family == AF_INET)
847 {
848 no_inet6_data = no_data;
849 inet6_status = status;
850 }
851 }
852
853 /* If we found one address for AF_INET or AF_INET6,
854 don't continue the search. */
855 if (inet6_status == NSS_STATUS_SUCCESS
856 || status == NSS_STATUS_SUCCESS)
857 {
858 if ((req->ai_flags & AI_CANONNAME) != 0
859 && canon == NULL)
860 {
861 canonbuf = getcanonname (nip, at, name);
862 if (canonbuf == NULL)
863 {
864 __resolv_context_put (res_ctx);
865 result = -EAI_MEMORY;
866 goto free_and_return;
867 }
868 canon = canonbuf;
869 }
870 status = NSS_STATUS_SUCCESS;
871 }
872 else
873 {
874 /* We can have different states for AF_INET and
875 AF_INET6. Try to find a useful one for both. */
876 if (inet6_status == NSS_STATUS_TRYAGAIN)
877 status = NSS_STATUS_TRYAGAIN;
878 else if (status == NSS_STATUS_UNAVAIL
879 && inet6_status != NSS_STATUS_UNAVAIL)
880 status = inet6_status;
881 }
882 }
883 else
884 {
885 /* Could not locate any of the lookup functions.
886 The NSS lookup code does not consistently set
887 errno, so we need to supply our own error
888 code here. The root cause could either be a
889 resource allocation failure, or a missing
890 service function in the DSO (so it should not
891 be listed in /etc/nsswitch.conf). Assume the
892 former, and return EBUSY. */
893 status = NSS_STATUS_UNAVAIL;
894 __set_h_errno (NETDB_INTERNAL);
895 __set_errno (EBUSY);
896 }
897 }
898
899 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
900 break;
901
902 nip++;
903 if (nip->module == NULL)
904 no_more = -1;
905 }
906
907 __resolv_context_put (res_ctx);
908
909 /* If we have a failure which sets errno, report it using
910 EAI_SYSTEM. */
911 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
912 && h_errno == NETDB_INTERNAL)
913 {
914 result = -EAI_SYSTEM;
915 goto free_and_return;
916 }
917
918 if (no_data != 0 && no_inet6_data != 0)
919 {
920 /* If both requests timed out report this. */
921 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
922 result = -EAI_AGAIN;
923 else
924 /* We made requests but they turned out no data. The name
925 is known, though. */
926 result = -EAI_NODATA;
927
928 goto free_and_return;
929 }
930 }
931
932 process_list:
933 if (at->family == AF_UNSPEC)
934 {
935 result = -EAI_NONAME;
936 goto free_and_return;
937 }
938 }
939 else
940 {
941 struct gaih_addrtuple *atr;
942 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
943 memset (at, '\0', sizeof (struct gaih_addrtuple));
944
945 if (req->ai_family == AF_UNSPEC)
946 {
947 at->next = __alloca (sizeof (struct gaih_addrtuple));
948 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
949 }
950
951 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
952 {
953 at->family = AF_INET6;
954 if ((req->ai_flags & AI_PASSIVE) == 0)
955 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
956 atr = at->next;
957 }
958
959 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
960 {
961 atr->family = AF_INET;
962 if ((req->ai_flags & AI_PASSIVE) == 0)
963 atr->addr[0] = htonl (INADDR_LOOPBACK);
964 }
965 }
966
967 {
968 struct gaih_servtuple *st2;
969 struct gaih_addrtuple *at2 = at;
970 size_t socklen;
971 sa_family_t family;
972
973 /*
974 buffer is the size of an unformatted IPv6 address in printable format.
975 */
976 while (at2 != NULL)
977 {
978 /* Only the first entry gets the canonical name. */
979 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
980 {
981 if (canon == NULL)
982 /* If the canonical name cannot be determined, use
983 the passed in string. */
984 canon = orig_name;
985
986 bool do_idn = req->ai_flags & AI_CANONIDN;
987 if (do_idn)
988 {
989 char *out;
990 int rc = __idna_from_dns_encoding (canon, &out);
991 if (rc == 0)
992 canon = out;
993 else if (rc == EAI_IDN_ENCODE)
994 /* Use the punycode name as a fallback. */
995 do_idn = false;
996 else
997 {
998 result = -rc;
999 goto free_and_return;
1000 }
1001 }
1002 if (!do_idn)
1003 {
1004 if (canonbuf != NULL)
1005 /* We already allocated the string using malloc, but
1006 the buffer is now owned by canon. */
1007 canonbuf = NULL;
1008 else
1009 {
1010 canon = __strdup (canon);
1011 if (canon == NULL)
1012 {
1013 result = -EAI_MEMORY;
1014 goto free_and_return;
1015 }
1016 }
1017 }
1018 }
1019
1020 family = at2->family;
1021 if (family == AF_INET6)
1022 {
1023 socklen = sizeof (struct sockaddr_in6);
1024
1025 /* If we looked up IPv4 mapped address discard them here if
1026 the caller isn't interested in all address and we have
1027 found at least one IPv6 address. */
1028 if (got_ipv6
1029 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1030 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1031 goto ignore;
1032 }
1033 else
1034 socklen = sizeof (struct sockaddr_in);
1035
1036 for (st2 = st; st2 != NULL; st2 = st2->next)
1037 {
1038 struct addrinfo *ai;
1039 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1040 if (ai == NULL)
1041 {
1042 free ((char *) canon);
1043 result = -EAI_MEMORY;
1044 goto free_and_return;
1045 }
1046
1047 ai->ai_flags = req->ai_flags;
1048 ai->ai_family = family;
1049 ai->ai_socktype = st2->socktype;
1050 ai->ai_protocol = st2->protocol;
1051 ai->ai_addrlen = socklen;
1052 ai->ai_addr = (void *) (ai + 1);
1053
1054 /* We only add the canonical name once. */
1055 ai->ai_canonname = (char *) canon;
1056 canon = NULL;
1057
1058#ifdef _HAVE_SA_LEN
1059 ai->ai_addr->sa_len = socklen;
1060#endif /* _HAVE_SA_LEN */
1061 ai->ai_addr->sa_family = family;
1062
1063 /* In case of an allocation error the list must be NULL
1064 terminated. */
1065 ai->ai_next = NULL;
1066
1067 if (family == AF_INET6)
1068 {
1069 struct sockaddr_in6 *sin6p =
1070 (struct sockaddr_in6 *) ai->ai_addr;
1071
1072 sin6p->sin6_port = st2->port;
1073 sin6p->sin6_flowinfo = 0;
1074 memcpy (&sin6p->sin6_addr,
1075 at2->addr, sizeof (struct in6_addr));
1076 sin6p->sin6_scope_id = at2->scopeid;
1077 }
1078 else
1079 {
1080 struct sockaddr_in *sinp =
1081 (struct sockaddr_in *) ai->ai_addr;
1082 sinp->sin_port = st2->port;
1083 memcpy (&sinp->sin_addr,
1084 at2->addr, sizeof (struct in_addr));
1085 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1086 }
1087
1088 pai = &(ai->ai_next);
1089 }
1090
1091 ++*naddrs;
1092
1093 ignore:
1094 at2 = at2->next;
1095 }
1096 }
1097
1098 free_and_return:
1099 if (malloc_name)
1100 free ((char *) name);
1101 free (addrmem);
1102 free (canonbuf);
1103
1104 return result;
1105}
1106
1107
1108struct sort_result
1109{
1110 struct addrinfo *dest_addr;
1111 /* Using sockaddr_storage is for now overkill. We only support IPv4
1112 and IPv6 so far. If this changes at some point we can adjust the
1113 type here. */
1114 struct sockaddr_in6 source_addr;
1115 uint8_t source_addr_len;
1116 bool got_source_addr;
1117 uint8_t source_addr_flags;
1118 uint8_t prefixlen;
1119 uint32_t index;
1120 int32_t native;
1121};
1122
1123struct sort_result_combo
1124{
1125 struct sort_result *results;
1126 int nresults;
1127};
1128
1129
1130#if __BYTE_ORDER == __BIG_ENDIAN
1131# define htonl_c(n) n
1132#else
1133# define htonl_c(n) __bswap_constant_32 (n)
1134#endif
1135
1136static const struct scopeentry
1137{
1138 union
1139 {
1140 char addr[4];
1141 uint32_t addr32;
1142 };
1143 uint32_t netmask;
1144 int32_t scope;
1145} default_scopes[] =
1146 {
1147 /* Link-local addresses: scope 2. */
1148 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1149 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1150 /* Default: scope 14. */
1151 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1152 };
1153
1154/* The label table. */
1155static const struct scopeentry *scopes;
1156
1157
1158static int
1159get_scope (const struct sockaddr_in6 *in6)
1160{
1161 int scope;
1162 if (in6->sin6_family == PF_INET6)
1163 {
1164 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1165 {
1166 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1167 /* RFC 4291 2.5.3 says that the loopback address is to be
1168 treated like a link-local address. */
1169 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1170 scope = 2;
1171 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1172 scope = 5;
1173 else
1174 /* XXX Is this the correct default behavior? */
1175 scope = 14;
1176 }
1177 else
1178 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1179 }
1180 else if (in6->sin6_family == PF_INET)
1181 {
1182 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1183
1184 size_t cnt = 0;
1185 while (1)
1186 {
1187 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1188 == scopes[cnt].addr32)
1189 return scopes[cnt].scope;
1190
1191 ++cnt;
1192 }
1193 /* NOTREACHED */
1194 }
1195 else
1196 /* XXX What is a good default? */
1197 scope = 15;
1198
1199 return scope;
1200}
1201
1202
1203struct prefixentry
1204{
1205 struct in6_addr prefix;
1206 unsigned int bits;
1207 int val;
1208};
1209
1210
1211/* The label table. */
1212static const struct prefixentry *labels;
1213
1214/* Default labels. */
1215static const struct prefixentry default_labels[] =
1216 {
1217 /* See RFC 3484 for the details. */
1218 { { .__in6_u
1219 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1221 }, 128, 0 },
1222 { { .__in6_u
1223 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1225 }, 16, 2 },
1226 { { .__in6_u
1227 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1229 }, 96, 3 },
1230 { { .__in6_u
1231 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1232 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1233 }, 96, 4 },
1234 /* The next two entries differ from RFC 3484. We need to treat
1235 IPv6 site-local addresses special because they are never NATed,
1236 unlike site-locale IPv4 addresses. If this would not happen, on
1237 machines which have only IPv4 and IPv6 site-local addresses, the
1238 sorting would prefer the IPv6 site-local addresses, causing
1239 unnecessary delays when trying to connect to a global IPv6 address
1240 through a site-local IPv6 address. */
1241 { { .__in6_u
1242 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1244 }, 10, 5 },
1245 { { .__in6_u
1246 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1248 }, 7, 6 },
1249 /* Additional rule for Teredo tunnels. */
1250 { { .__in6_u
1251 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1253 }, 32, 7 },
1254 { { .__in6_u
1255 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1257 }, 0, 1 }
1258 };
1259
1260
1261/* The precedence table. */
1262static const struct prefixentry *precedence;
1263
1264/* The default precedences. */
1265static const struct prefixentry default_precedence[] =
1266 {
1267 /* See RFC 3484 for the details. */
1268 { { .__in6_u
1269 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1271 }, 128, 50 },
1272 { { .__in6_u
1273 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1275 }, 16, 30 },
1276 { { .__in6_u
1277 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1279 }, 96, 20 },
1280 { { .__in6_u
1281 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1283 }, 96, 10 },
1284 { { .__in6_u
1285 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1287 }, 0, 40 }
1288 };
1289
1290
1291static int
1292match_prefix (const struct sockaddr_in6 *in6,
1293 const struct prefixentry *list, int default_val)
1294{
1295 int idx;
1296 struct sockaddr_in6 in6_mem;
1297
1298 if (in6->sin6_family == PF_INET)
1299 {
1300 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1301
1302 /* Construct a V4-to-6 mapped address. */
1303 in6_mem.sin6_family = PF_INET6;
1304 in6_mem.sin6_port = in->sin_port;
1305 in6_mem.sin6_flowinfo = 0;
1306 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1307 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1308 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1309 in6_mem.sin6_scope_id = 0;
1310
1311 in6 = &in6_mem;
1312 }
1313 else if (in6->sin6_family != PF_INET6)
1314 return default_val;
1315
1316 for (idx = 0; ; ++idx)
1317 {
1318 unsigned int bits = list[idx].bits;
1319 const uint8_t *mask = list[idx].prefix.s6_addr;
1320 const uint8_t *val = in6->sin6_addr.s6_addr;
1321
1322 while (bits >= 8)
1323 {
1324 if (*mask != *val)
1325 break;
1326
1327 ++mask;
1328 ++val;
1329 bits -= 8;
1330 }
1331
1332 if (bits < 8)
1333 {
1334 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1335 /* Match! */
1336 break;
1337 }
1338 }
1339
1340 return list[idx].val;
1341}
1342
1343
1344static int
1345get_label (const struct sockaddr_in6 *in6)
1346{
1347 /* XXX What is a good default value? */
1348 return match_prefix (in6, labels, INT_MAX);
1349}
1350
1351
1352static int
1353get_precedence (const struct sockaddr_in6 *in6)
1354{
1355 /* XXX What is a good default value? */
1356 return match_prefix (in6, precedence, 0);
1357}
1358
1359
1360/* Find last bit set in a word. */
1361static int
1362fls (uint32_t a)
1363{
1364 uint32_t mask;
1365 int n;
1366 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1367 if ((a & mask) != 0)
1368 break;
1369 return n;
1370}
1371
1372
1373static int
1374rfc3484_sort (const void *p1, const void *p2, void *arg)
1375{
1376 const size_t idx1 = *(const size_t *) p1;
1377 const size_t idx2 = *(const size_t *) p2;
1378 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1379 struct sort_result *a1 = &src->results[idx1];
1380 struct sort_result *a2 = &src->results[idx2];
1381
1382 /* Rule 1: Avoid unusable destinations.
1383 We have the got_source_addr flag set if the destination is reachable. */
1384 if (a1->got_source_addr && ! a2->got_source_addr)
1385 return -1;
1386 if (! a1->got_source_addr && a2->got_source_addr)
1387 return 1;
1388
1389
1390 /* Rule 2: Prefer matching scope. Only interesting if both
1391 destination addresses are IPv6. */
1392 int a1_dst_scope
1393 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1394
1395 int a2_dst_scope
1396 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1397
1398 if (a1->got_source_addr)
1399 {
1400 int a1_src_scope = get_scope (&a1->source_addr);
1401 int a2_src_scope = get_scope (&a2->source_addr);
1402
1403 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1404 return -1;
1405 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1406 return 1;
1407 }
1408
1409
1410 /* Rule 3: Avoid deprecated addresses. */
1411 if (a1->got_source_addr)
1412 {
1413 if (!(a1->source_addr_flags & in6ai_deprecated)
1414 && (a2->source_addr_flags & in6ai_deprecated))
1415 return -1;
1416 if ((a1->source_addr_flags & in6ai_deprecated)
1417 && !(a2->source_addr_flags & in6ai_deprecated))
1418 return 1;
1419 }
1420
1421 /* Rule 4: Prefer home addresses. */
1422 if (a1->got_source_addr)
1423 {
1424 if (!(a1->source_addr_flags & in6ai_homeaddress)
1425 && (a2->source_addr_flags & in6ai_homeaddress))
1426 return 1;
1427 if ((a1->source_addr_flags & in6ai_homeaddress)
1428 && !(a2->source_addr_flags & in6ai_homeaddress))
1429 return -1;
1430 }
1431
1432 /* Rule 5: Prefer matching label. */
1433 if (a1->got_source_addr)
1434 {
1435 int a1_dst_label
1436 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1437 int a1_src_label = get_label (&a1->source_addr);
1438
1439 int a2_dst_label
1440 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1441 int a2_src_label = get_label (&a2->source_addr);
1442
1443 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1444 return -1;
1445 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1446 return 1;
1447 }
1448
1449
1450 /* Rule 6: Prefer higher precedence. */
1451 int a1_prec
1452 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1453 int a2_prec
1454 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1455
1456 if (a1_prec > a2_prec)
1457 return -1;
1458 if (a1_prec < a2_prec)
1459 return 1;
1460
1461
1462 /* Rule 7: Prefer native transport. */
1463 if (a1->got_source_addr)
1464 {
1465 /* The same interface index means the same interface which means
1466 there is no difference in transport. This should catch many
1467 (most?) cases. */
1468 if (a1->index != a2->index)
1469 {
1470 int a1_native = a1->native;
1471 int a2_native = a2->native;
1472
1473 if (a1_native == -1 || a2_native == -1)
1474 {
1475 uint32_t a1_index;
1476 if (a1_native == -1)
1477 {
1478 /* If we do not have the information use 'native' as
1479 the default. */
1480 a1_native = 0;
1481 a1_index = a1->index;
1482 }
1483 else
1484 a1_index = 0xffffffffu;
1485
1486 uint32_t a2_index;
1487 if (a2_native == -1)
1488 {
1489 /* If we do not have the information use 'native' as
1490 the default. */
1491 a2_native = 0;
1492 a2_index = a2->index;
1493 }
1494 else
1495 a2_index = 0xffffffffu;
1496
1497 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1498
1499 /* Fill in the results in all the records. */
1500 for (int i = 0; i < src->nresults; ++i)
1501 if (a1_index != -1 && src->results[i].index == a1_index)
1502 {
1503 assert (src->results[i].native == -1
1504 || src->results[i].native == a1_native);
1505 src->results[i].native = a1_native;
1506 }
1507 else if (a2_index != -1 && src->results[i].index == a2_index)
1508 {
1509 assert (src->results[i].native == -1
1510 || src->results[i].native == a2_native);
1511 src->results[i].native = a2_native;
1512 }
1513 }
1514
1515 if (a1_native && !a2_native)
1516 return -1;
1517 if (!a1_native && a2_native)
1518 return 1;
1519 }
1520 }
1521
1522
1523 /* Rule 8: Prefer smaller scope. */
1524 if (a1_dst_scope < a2_dst_scope)
1525 return -1;
1526 if (a1_dst_scope > a2_dst_scope)
1527 return 1;
1528
1529
1530 /* Rule 9: Use longest matching prefix. */
1531 if (a1->got_source_addr
1532 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1533 {
1534 int bit1 = 0;
1535 int bit2 = 0;
1536
1537 if (a1->dest_addr->ai_family == PF_INET)
1538 {
1539 assert (a1->source_addr.sin6_family == PF_INET);
1540 assert (a2->source_addr.sin6_family == PF_INET);
1541
1542 /* Outside of subnets, as defined by the network masks,
1543 common address prefixes for IPv4 addresses make no sense.
1544 So, define a non-zero value only if source and
1545 destination address are on the same subnet. */
1546 struct sockaddr_in *in1_dst
1547 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1548 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1549 struct sockaddr_in *in1_src
1550 = (struct sockaddr_in *) &a1->source_addr;
1551 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1552 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1553
1554 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1555 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1556
1557 struct sockaddr_in *in2_dst
1558 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1559 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1560 struct sockaddr_in *in2_src
1561 = (struct sockaddr_in *) &a2->source_addr;
1562 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1563 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1564
1565 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1566 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1567 }
1568 else if (a1->dest_addr->ai_family == PF_INET6)
1569 {
1570 assert (a1->source_addr.sin6_family == PF_INET6);
1571 assert (a2->source_addr.sin6_family == PF_INET6);
1572
1573 struct sockaddr_in6 *in1_dst;
1574 struct sockaddr_in6 *in1_src;
1575 struct sockaddr_in6 *in2_dst;
1576 struct sockaddr_in6 *in2_src;
1577
1578 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1579 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1580 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1581 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1582
1583 int i;
1584 for (i = 0; i < 4; ++i)
1585 if (in1_dst->sin6_addr.s6_addr32[i]
1586 != in1_src->sin6_addr.s6_addr32[i]
1587 || (in2_dst->sin6_addr.s6_addr32[i]
1588 != in2_src->sin6_addr.s6_addr32[i]))
1589 break;
1590
1591 if (i < 4)
1592 {
1593 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1594 ^ in1_src->sin6_addr.s6_addr32[i]));
1595 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1596 ^ in2_src->sin6_addr.s6_addr32[i]));
1597 }
1598 }
1599
1600 if (bit1 > bit2)
1601 return -1;
1602 if (bit1 < bit2)
1603 return 1;
1604 }
1605
1606
1607 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1608 compare with the value indicating the order in which the entries
1609 have been received from the services. NB: no two entries can have
1610 the same order so the test will never return zero. */
1611 return idx1 < idx2 ? -1 : 1;
1612}
1613
1614
1615static int
1616in6aicmp (const void *p1, const void *p2)
1617{
1618 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1619 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1620
1621 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1622}
1623
1624
1625/* Name of the config file for RFC 3484 sorting (for now). */
1626#define GAICONF_FNAME "/etc/gai.conf"
1627
1628
1629/* Non-zero if we are supposed to reload the config file automatically
1630 whenever it changed. */
1631static int gaiconf_reload_flag;
1632
1633/* Non-zero if gaiconf_reload_flag was ever set to true. */
1634static int gaiconf_reload_flag_ever_set;
1635
1636/* Last modification time. */
1637#ifdef _STATBUF_ST_NSEC
1638
1639static struct __timespec64 gaiconf_mtime;
1640
1641static inline void
1642save_gaiconf_mtime (const struct __stat64_t64 *st)
1643{
1644 gaiconf_mtime = (struct __timespec64) { st->st_mtim.tv_sec,
1645 st->st_mtim.tv_nsec };
1646}
1647
1648static inline bool
1649check_gaiconf_mtime (const struct __stat64_t64 *st)
1650{
1651 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1652 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1653}
1654
1655#else
1656
1657static time_t gaiconf_mtime;
1658
1659static inline void
1660save_gaiconf_mtime (const struct __stat64_t64 *st)
1661{
1662 gaiconf_mtime = st->st_mtime;
1663}
1664
1665static inline bool
1666check_gaiconf_mtime (const struct __stat64_t64 *st)
1667{
1668 return st->st_mtime == gaiconf_mtime;
1669}
1670
1671#endif
1672
1673
1674libc_freeres_fn(fini)
1675{
1676 if (labels != default_labels)
1677 {
1678 const struct prefixentry *old = labels;
1679 labels = default_labels;
1680 free ((void *) old);
1681 }
1682
1683 if (precedence != default_precedence)
1684 {
1685 const struct prefixentry *old = precedence;
1686 precedence = default_precedence;
1687 free ((void *) old);
1688 }
1689
1690 if (scopes != default_scopes)
1691 {
1692 const struct scopeentry *old = scopes;
1693 scopes = default_scopes;
1694 free ((void *) old);
1695 }
1696}
1697
1698
1699struct prefixlist
1700{
1701 struct prefixentry entry;
1702 struct prefixlist *next;
1703};
1704
1705
1706struct scopelist
1707{
1708 struct scopeentry entry;
1709 struct scopelist *next;
1710};
1711
1712
1713static void
1714free_prefixlist (struct prefixlist *list)
1715{
1716 while (list != NULL)
1717 {
1718 struct prefixlist *oldp = list;
1719 list = list->next;
1720 free (oldp);
1721 }
1722}
1723
1724
1725static void
1726free_scopelist (struct scopelist *list)
1727{
1728 while (list != NULL)
1729 {
1730 struct scopelist *oldp = list;
1731 list = list->next;
1732 free (oldp);
1733 }
1734}
1735
1736
1737static int
1738prefixcmp (const void *p1, const void *p2)
1739{
1740 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1741 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1742
1743 if (e1->bits < e2->bits)
1744 return 1;
1745 if (e1->bits == e2->bits)
1746 return 0;
1747 return -1;
1748}
1749
1750
1751static int
1752scopecmp (const void *p1, const void *p2)
1753{
1754 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1755 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1756
1757 if (e1->netmask > e2->netmask)
1758 return -1;
1759 if (e1->netmask == e2->netmask)
1760 return 0;
1761 return 1;
1762}
1763
1764
1765static void
1766gaiconf_init (void)
1767{
1768 struct prefixlist *labellist = NULL;
1769 size_t nlabellist = 0;
1770 bool labellist_nullbits = false;
1771 struct prefixlist *precedencelist = NULL;
1772 size_t nprecedencelist = 0;
1773 bool precedencelist_nullbits = false;
1774 struct scopelist *scopelist = NULL;
1775 size_t nscopelist = 0;
1776 bool scopelist_nullbits = false;
1777
1778 FILE *fp = fopen (GAICONF_FNAME, "rce");
1779 if (fp != NULL)
1780 {
1781 struct __stat64_t64 st;
1782 if (__fstat64_time64 (fileno (fp), &st) != 0)
1783 {
1784 fclose (fp);
1785 goto no_file;
1786 }
1787
1788 char *line = NULL;
1789 size_t linelen = 0;
1790
1791 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1792
1793 while (!feof_unlocked (fp))
1794 {
1795 ssize_t n = __getline (&line, &linelen, fp);
1796 if (n <= 0)
1797 break;
1798
1799 /* Handle comments. No escaping possible so this is easy. */
1800 char *cp = strchr (line, '#');
1801 if (cp != NULL)
1802 *cp = '\0';
1803
1804 cp = line;
1805 while (isspace (*cp))
1806 ++cp;
1807
1808 char *cmd = cp;
1809 while (*cp != '\0' && !isspace (*cp))
1810 ++cp;
1811 size_t cmdlen = cp - cmd;
1812
1813 if (*cp != '\0')
1814 *cp++ = '\0';
1815 while (isspace (*cp))
1816 ++cp;
1817
1818 char *val1 = cp;
1819 while (*cp != '\0' && !isspace (*cp))
1820 ++cp;
1821 size_t val1len = cp - cmd;
1822
1823 /* We always need at least two values. */
1824 if (val1len == 0)
1825 continue;
1826
1827 if (*cp != '\0')
1828 *cp++ = '\0';
1829 while (isspace (*cp))
1830 ++cp;
1831
1832 char *val2 = cp;
1833 while (*cp != '\0' && !isspace (*cp))
1834 ++cp;
1835
1836 /* Ignore the rest of the line. */
1837 *cp = '\0';
1838
1839 struct prefixlist **listp;
1840 size_t *lenp;
1841 bool *nullbitsp;
1842 switch (cmdlen)
1843 {
1844 case 5:
1845 if (strcmp (cmd, "label") == 0)
1846 {
1847 struct in6_addr prefix;
1848 unsigned long int bits;
1849 unsigned long int val;
1850 char *endp;
1851
1852 listp = &labellist;
1853 lenp = &nlabellist;
1854 nullbitsp = &labellist_nullbits;
1855
1856 new_elem:
1857 bits = 128;
1858 __set_errno (0);
1859 cp = strchr (val1, '/');
1860 if (cp != NULL)
1861 *cp++ = '\0';
1862 if (inet_pton (AF_INET6, val1, &prefix)
1863 && (cp == NULL
1864 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1865 || errno != ERANGE)
1866 && *endp == '\0'
1867 && bits <= 128
1868 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1869 || errno != ERANGE)
1870 && *endp == '\0'
1871 && val <= INT_MAX)
1872 {
1873 struct prefixlist *newp = malloc (sizeof (*newp));
1874 if (newp == NULL)
1875 {
1876 free (line);
1877 fclose (fp);
1878 goto no_file;
1879 }
1880
1881 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1882 newp->entry.bits = bits;
1883 newp->entry.val = val;
1884 newp->next = *listp;
1885 *listp = newp;
1886 ++*lenp;
1887 *nullbitsp |= bits == 0;
1888 }
1889 }
1890 break;
1891
1892 case 6:
1893 if (strcmp (cmd, "reload") == 0)
1894 {
1895 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1896 if (gaiconf_reload_flag)
1897 gaiconf_reload_flag_ever_set = 1;
1898 }
1899 break;
1900
1901 case 7:
1902 if (strcmp (cmd, "scopev4") == 0)
1903 {
1904 struct in6_addr prefix;
1905 unsigned long int bits;
1906 unsigned long int val;
1907 char *endp;
1908
1909 bits = 32;
1910 __set_errno (0);
1911 cp = strchr (val1, '/');
1912 if (cp != NULL)
1913 *cp++ = '\0';
1914 if (inet_pton (AF_INET6, val1, &prefix))
1915 {
1916 bits = 128;
1917 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1918 && (cp == NULL
1919 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1920 || errno != ERANGE)
1921 && *endp == '\0'
1922 && bits >= 96
1923 && bits <= 128
1924 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1925 || errno != ERANGE)
1926 && *endp == '\0'
1927 && val <= INT_MAX)
1928 {
1929 struct scopelist *newp;
1930 new_scope:
1931 newp = malloc (sizeof (*newp));
1932 if (newp == NULL)
1933 {
1934 free (line);
1935 fclose (fp);
1936 goto no_file;
1937 }
1938
1939 newp->entry.netmask = htonl (bits != 96
1940 ? (0xffffffff
1941 << (128 - bits))
1942 : 0);
1943 newp->entry.addr32 = (prefix.s6_addr32[3]
1944 & newp->entry.netmask);
1945 newp->entry.scope = val;
1946 newp->next = scopelist;
1947 scopelist = newp;
1948 ++nscopelist;
1949 scopelist_nullbits |= bits == 96;
1950 }
1951 }
1952 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1953 && (cp == NULL
1954 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1955 || errno != ERANGE)
1956 && *endp == '\0'
1957 && bits <= 32
1958 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1959 || errno != ERANGE)
1960 && *endp == '\0'
1961 && val <= INT_MAX)
1962 {
1963 bits += 96;
1964 goto new_scope;
1965 }
1966 }
1967 break;
1968
1969 case 10:
1970 if (strcmp (cmd, "precedence") == 0)
1971 {
1972 listp = &precedencelist;
1973 lenp = &nprecedencelist;
1974 nullbitsp = &precedencelist_nullbits;
1975 goto new_elem;
1976 }
1977 break;
1978 }
1979 }
1980
1981 free (line);
1982
1983 fclose (fp);
1984
1985 /* Create the array for the labels. */
1986 struct prefixentry *new_labels;
1987 if (nlabellist > 0)
1988 {
1989 if (!labellist_nullbits)
1990 ++nlabellist;
1991 new_labels = malloc (nlabellist * sizeof (*new_labels));
1992 if (new_labels == NULL)
1993 goto no_file;
1994
1995 int i = nlabellist;
1996 if (!labellist_nullbits)
1997 {
1998 --i;
1999 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2000 new_labels[i].bits = 0;
2001 new_labels[i].val = 1;
2002 }
2003
2004 struct prefixlist *l = labellist;
2005 while (i-- > 0)
2006 {
2007 new_labels[i] = l->entry;
2008 l = l->next;
2009 }
2010 free_prefixlist (labellist);
2011 labellist = NULL;
2012
2013 /* Sort the entries so that the most specific ones are at
2014 the beginning. */
2015 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2016 }
2017 else
2018 new_labels = (struct prefixentry *) default_labels;
2019
2020 struct prefixentry *new_precedence;
2021 if (nprecedencelist > 0)
2022 {
2023 if (!precedencelist_nullbits)
2024 ++nprecedencelist;
2025 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2026 if (new_precedence == NULL)
2027 {
2028 if (new_labels != default_labels)
2029 free (new_labels);
2030 goto no_file;
2031 }
2032
2033 int i = nprecedencelist;
2034 if (!precedencelist_nullbits)
2035 {
2036 --i;
2037 memset (&new_precedence[i].prefix, '\0',
2038 sizeof (struct in6_addr));
2039 new_precedence[i].bits = 0;
2040 new_precedence[i].val = 40;
2041 }
2042
2043 struct prefixlist *l = precedencelist;
2044 while (i-- > 0)
2045 {
2046 new_precedence[i] = l->entry;
2047 l = l->next;
2048 }
2049 free_prefixlist (precedencelist);
2050 precedencelist = NULL;
2051
2052 /* Sort the entries so that the most specific ones are at
2053 the beginning. */
2054 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2055 prefixcmp);
2056 }
2057 else
2058 new_precedence = (struct prefixentry *) default_precedence;
2059
2060 struct scopeentry *new_scopes;
2061 if (nscopelist > 0)
2062 {
2063 if (!scopelist_nullbits)
2064 ++nscopelist;
2065 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2066 if (new_scopes == NULL)
2067 {
2068 if (new_labels != default_labels)
2069 free (new_labels);
2070 if (new_precedence != default_precedence)
2071 free (new_precedence);
2072 goto no_file;
2073 }
2074
2075 int i = nscopelist;
2076 if (!scopelist_nullbits)
2077 {
2078 --i;
2079 new_scopes[i].addr32 = 0;
2080 new_scopes[i].netmask = 0;
2081 new_scopes[i].scope = 14;
2082 }
2083
2084 struct scopelist *l = scopelist;
2085 while (i-- > 0)
2086 {
2087 new_scopes[i] = l->entry;
2088 l = l->next;
2089 }
2090 free_scopelist (scopelist);
2091
2092 /* Sort the entries so that the most specific ones are at
2093 the beginning. */
2094 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2095 scopecmp);
2096 }
2097 else
2098 new_scopes = (struct scopeentry *) default_scopes;
2099
2100 /* Now we are ready to replace the values. */
2101 const struct prefixentry *old = labels;
2102 labels = new_labels;
2103 if (old != default_labels)
2104 free ((void *) old);
2105
2106 old = precedence;
2107 precedence = new_precedence;
2108 if (old != default_precedence)
2109 free ((void *) old);
2110
2111 const struct scopeentry *oldscope = scopes;
2112 scopes = new_scopes;
2113 if (oldscope != default_scopes)
2114 free ((void *) oldscope);
2115
2116 save_gaiconf_mtime (&st);
2117 }
2118 else
2119 {
2120 no_file:
2121 free_prefixlist (labellist);
2122 free_prefixlist (precedencelist);
2123 free_scopelist (scopelist);
2124
2125 /* If we previously read the file but it is gone now, free the
2126 old data and use the builtin one. Leave the reload flag
2127 alone. */
2128 fini ();
2129 }
2130}
2131
2132
2133static void
2134gaiconf_reload (void)
2135{
2136 struct __stat64_t64 st;
2137 if (__stat64_time64 (GAICONF_FNAME, &st) != 0
2138 || !check_gaiconf_mtime (&st))
2139 gaiconf_init ();
2140}
2141
2142
2143int
2144getaddrinfo (const char *name, const char *service,
2145 const struct addrinfo *hints, struct addrinfo **pai)
2146{
2147 int i = 0, last_i = 0;
2148 int nresults = 0;
2149 struct addrinfo *p = NULL;
2150 struct gaih_service gaih_service, *pservice;
2151 struct addrinfo local_hints;
2152
2153 if (name != NULL && name[0] == '*' && name[1] == 0)
2154 name = NULL;
2155
2156 if (service != NULL && service[0] == '*' && service[1] == 0)
2157 service = NULL;
2158
2159 if (name == NULL && service == NULL)
2160 return EAI_NONAME;
2161
2162 if (hints == NULL)
2163 hints = &default_hints;
2164
2165 if (hints->ai_flags
2166 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2167 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2168 |AI_NUMERICSERV|AI_ALL))
2169 return EAI_BADFLAGS;
2170
2171 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2172 return EAI_BADFLAGS;
2173
2174 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2175 && hints->ai_family != AF_INET6)
2176 return EAI_FAMILY;
2177
2178 struct in6addrinfo *in6ai = NULL;
2179 size_t in6ailen = 0;
2180 bool seen_ipv4 = false;
2181 bool seen_ipv6 = false;
2182 bool check_pf_called = false;
2183
2184 if (hints->ai_flags & AI_ADDRCONFIG)
2185 {
2186 /* We might need information about what interfaces are available.
2187 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2188 cannot cache the results since new interfaces could be added at
2189 any time. */
2190 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2191 check_pf_called = true;
2192
2193 /* Now make a decision on what we return, if anything. */
2194 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2195 {
2196 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2197 narrow down the search. */
2198 if (seen_ipv4 != seen_ipv6)
2199 {
2200 local_hints = *hints;
2201 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2202 hints = &local_hints;
2203 }
2204 }
2205 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2206 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2207 {
2208 /* We cannot possibly return a valid answer. */
2209 __free_in6ai (in6ai);
2210 return EAI_NONAME;
2211 }
2212 }
2213
2214 if (service && service[0])
2215 {
2216 char *c;
2217 gaih_service.name = service;
2218 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2219 if (*c != '\0')
2220 {
2221 if (hints->ai_flags & AI_NUMERICSERV)
2222 {
2223 __free_in6ai (in6ai);
2224 return EAI_NONAME;
2225 }
2226
2227 gaih_service.num = -1;
2228 }
2229
2230 pservice = &gaih_service;
2231 }
2232 else
2233 pservice = NULL;
2234
2235 struct addrinfo **end = &p;
2236 unsigned int naddrs = 0;
2237 struct scratch_buffer tmpbuf;
2238
2239 scratch_buffer_init (&tmpbuf);
2240 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2241 scratch_buffer_free (&tmpbuf);
2242
2243 if (last_i != 0)
2244 {
2245 freeaddrinfo (p);
2246 __free_in6ai (in6ai);
2247
2248 return -last_i;
2249 }
2250
2251 while (*end)
2252 {
2253 end = &((*end)->ai_next);
2254 ++nresults;
2255 }
2256
2257 if (naddrs > 1)
2258 {
2259 /* Read the config file. */
2260 __libc_once_define (static, once);
2261 __typeof (once) old_once = once;
2262 __libc_once (once, gaiconf_init);
2263 /* Sort results according to RFC 3484. */
2264 struct sort_result *results;
2265 size_t *order;
2266 struct addrinfo *q;
2267 struct addrinfo *last = NULL;
2268 char *canonname = NULL;
2269 bool malloc_results;
2270 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2271
2272 malloc_results
2273 = !__libc_use_alloca (alloc_size);
2274 if (malloc_results)
2275 {
2276 results = malloc (alloc_size);
2277 if (results == NULL)
2278 {
2279 __free_in6ai (in6ai);
2280 return EAI_MEMORY;
2281 }
2282 }
2283 else
2284 results = alloca (alloc_size);
2285 order = (size_t *) (results + nresults);
2286
2287 /* Now we definitely need the interface information. */
2288 if (! check_pf_called)
2289 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2290
2291 /* If we have information about deprecated and temporary addresses
2292 sort the array now. */
2293 if (in6ai != NULL)
2294 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2295
2296 int fd = -1;
2297 int af = AF_UNSPEC;
2298
2299 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2300 {
2301 results[i].dest_addr = q;
2302 results[i].native = -1;
2303 order[i] = i;
2304
2305 /* If we just looked up the address for a different
2306 protocol, reuse the result. */
2307 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2308 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2309 {
2310 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2311 results[i - 1].source_addr_len);
2312 results[i].source_addr_len = results[i - 1].source_addr_len;
2313 results[i].got_source_addr = results[i - 1].got_source_addr;
2314 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2315 results[i].prefixlen = results[i - 1].prefixlen;
2316 results[i].index = results[i - 1].index;
2317 }
2318 else
2319 {
2320 results[i].got_source_addr = false;
2321 results[i].source_addr_flags = 0;
2322 results[i].prefixlen = 0;
2323 results[i].index = 0xffffffffu;
2324
2325 /* We overwrite the type with SOCK_DGRAM since we do not
2326 want connect() to connect to the other side. If we
2327 cannot determine the source address remember this
2328 fact. */
2329 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2330 {
2331 if (fd != -1)
2332 close_retry:
2333 __close_nocancel_nostatus (fd);
2334 af = q->ai_family;
2335 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2336 }
2337 else
2338 {
2339 /* Reset the connection. */
2340 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2341 __connect (fd, &sa, sizeof (sa));
2342 }
2343
2344 socklen_t sl = sizeof (results[i].source_addr);
2345 if (fd != -1
2346 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2347 && __getsockname (fd,
2348 (struct sockaddr *) &results[i].source_addr,
2349 &sl) == 0)
2350 {
2351 results[i].source_addr_len = sl;
2352 results[i].got_source_addr = true;
2353
2354 if (in6ai != NULL)
2355 {
2356 /* See whether the source address is on the list of
2357 deprecated or temporary addresses. */
2358 struct in6addrinfo tmp;
2359
2360 if (q->ai_family == AF_INET && af == AF_INET)
2361 {
2362 struct sockaddr_in *sinp
2363 = (struct sockaddr_in *) &results[i].source_addr;
2364 tmp.addr[0] = 0;
2365 tmp.addr[1] = 0;
2366 tmp.addr[2] = htonl (0xffff);
2367 /* Special case for lo interface, the source address
2368 being possibly different than the interface
2369 address. */
2370 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2371 == 0x7f000000)
2372 tmp.addr[3] = htonl(0x7f000001);
2373 else
2374 tmp.addr[3] = sinp->sin_addr.s_addr;
2375 }
2376 else
2377 {
2378 struct sockaddr_in6 *sin6p
2379 = (struct sockaddr_in6 *) &results[i].source_addr;
2380 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2381 }
2382
2383 struct in6addrinfo *found
2384 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2385 in6aicmp);
2386 if (found != NULL)
2387 {
2388 results[i].source_addr_flags = found->flags;
2389 results[i].prefixlen = found->prefixlen;
2390 results[i].index = found->index;
2391 }
2392 }
2393
2394 if (q->ai_family == AF_INET && af == AF_INET6)
2395 {
2396 /* We have to convert the address. The socket is
2397 IPv6 and the request is for IPv4. */
2398 struct sockaddr_in6 *sin6
2399 = (struct sockaddr_in6 *) &results[i].source_addr;
2400 struct sockaddr_in *sin
2401 = (struct sockaddr_in *) &results[i].source_addr;
2402 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2403 sin->sin_family = AF_INET;
2404 /* We do not have to initialize sin_port since this
2405 fields has the same position and size in the IPv6
2406 structure. */
2407 assert (offsetof (struct sockaddr_in, sin_port)
2408 == offsetof (struct sockaddr_in6, sin6_port));
2409 assert (sizeof (sin->sin_port)
2410 == sizeof (sin6->sin6_port));
2411 memcpy (&sin->sin_addr,
2412 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2413 results[i].source_addr_len = sizeof (struct sockaddr_in);
2414 }
2415 }
2416 else if (errno == EAFNOSUPPORT && af == AF_INET6
2417 && q->ai_family == AF_INET)
2418 /* This could mean IPv6 sockets are IPv6-only. */
2419 goto close_retry;
2420 else
2421 /* Just make sure that if we have to process the same
2422 address again we do not copy any memory. */
2423 results[i].source_addr_len = 0;
2424 }
2425
2426 /* Remember the canonical name. */
2427 if (q->ai_canonname != NULL)
2428 {
2429 assert (canonname == NULL);
2430 canonname = q->ai_canonname;
2431 q->ai_canonname = NULL;
2432 }
2433 }
2434
2435 if (fd != -1)
2436 __close_nocancel_nostatus (fd);
2437
2438 /* We got all the source addresses we can get, now sort using
2439 the information. */
2440 struct sort_result_combo src
2441 = { .results = results, .nresults = nresults };
2442 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2443 {
2444 __libc_lock_define_initialized (static, lock);
2445
2446 __libc_lock_lock (lock);
2447 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2448 gaiconf_reload ();
2449 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2450 __libc_lock_unlock (lock);
2451 }
2452 else
2453 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2454
2455 /* Queue the results up as they come out of sorting. */
2456 q = p = results[order[0]].dest_addr;
2457 for (i = 1; i < nresults; ++i)
2458 q = q->ai_next = results[order[i]].dest_addr;
2459 q->ai_next = NULL;
2460
2461 /* Fill in the canonical name into the new first entry. */
2462 p->ai_canonname = canonname;
2463
2464 if (malloc_results)
2465 free (results);
2466 }
2467
2468 __free_in6ai (in6ai);
2469
2470 if (p)
2471 {
2472 *pai = p;
2473 return 0;
2474 }
2475
2476 return last_i ? -last_i : EAI_NONAME;
2477}
2478libc_hidden_def (getaddrinfo)
2479
2480nss_interface_function (getaddrinfo)
2481
2482void
2483freeaddrinfo (struct addrinfo *ai)
2484{
2485 struct addrinfo *p;
2486
2487 while (ai != NULL)
2488 {
2489 p = ai;
2490 ai = ai->ai_next;
2491 free (p->ai_canonname);
2492 free (p);
2493 }
2494}
2495libc_hidden_def (freeaddrinfo)
2496