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