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