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