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 <stdbool.h>
64#include <stdio.h>
65#include <stdio_ext.h>
66#include <stdlib.h>
67#include <string.h>
68#include <stdint.h>
69#include <arpa/inet.h>
70#include <net/if.h>
71#include <netinet/in.h>
72#include <sys/socket.h>
73#include <sys/stat.h>
74#include <sys/types.h>
75#include <sys/un.h>
76#include <sys/utsname.h>
77#include <unistd.h>
78#include <nsswitch.h>
79#include <libc-lock.h>
80#include <not-cancel.h>
81#include <nscd/nscd-client.h>
82#include <nscd/nscd_proto.h>
83#include <resolv/res_hconf.h>
84#include <scratch_buffer.h>
85#include <inet/net-internal.h>
86
87#ifdef HAVE_LIBIDN
88extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
89extern int __idna_to_unicode_lzlz (const char *input, char **output,
90 int flags);
91# include <libidn/idna.h>
92#endif
93
94struct gaih_service
95 {
96 const char *name;
97 int num;
98 };
99
100struct gaih_servtuple
101 {
102 struct gaih_servtuple *next;
103 int socktype;
104 int protocol;
105 int port;
106 };
107
108static const struct gaih_servtuple nullserv;
109
110
111struct gaih_typeproto
112 {
113 int socktype;
114 int protocol;
115 uint8_t protoflag;
116 bool defaultflag;
117 char name[8];
118 };
119
120/* Values for `protoflag'. */
121#define GAI_PROTO_NOSERVICE 1
122#define GAI_PROTO_PROTOANY 2
123
124static const struct gaih_typeproto gaih_inet_typeproto[] =
125{
126 { 0, 0, 0, false, "" },
127 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
128 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
129#if defined SOCK_DCCP && defined IPPROTO_DCCP
130 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
131#endif
132#ifdef IPPROTO_UDPLITE
133 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
134#endif
135#ifdef IPPROTO_SCTP
136 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
137 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
138#endif
139 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
140 { 0, 0, 0, false, "" }
141};
142
143static const struct addrinfo default_hints =
144 {
145 .ai_flags = AI_DEFAULT,
146 .ai_family = PF_UNSPEC,
147 .ai_socktype = 0,
148 .ai_protocol = 0,
149 .ai_addrlen = 0,
150 .ai_addr = NULL,
151 .ai_canonname = NULL,
152 .ai_next = NULL
153 };
154
155
156static int
157gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
158 const struct addrinfo *req, struct gaih_servtuple *st,
159 struct scratch_buffer *tmpbuf)
160{
161 struct servent *s;
162 struct servent ts;
163 int r;
164
165 do
166 {
167 r = __getservbyname_r (servicename, tp->name, &ts,
168 tmpbuf->data, tmpbuf->length, &s);
169 if (r != 0 || s == NULL)
170 {
171 if (r == ERANGE)
172 {
173 if (!scratch_buffer_grow (tmpbuf))
174 return -EAI_MEMORY;
175 }
176 else
177 return -EAI_SERVICE;
178 }
179 }
180 while (r);
181
182 st->next = NULL;
183 st->socktype = tp->socktype;
184 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
185 ? req->ai_protocol : tp->protocol);
186 st->port = s->s_port;
187
188 return 0;
189}
190
191/* Convert struct hostent to a list of struct gaih_addrtuple objects.
192 h_name is not copied, and the struct hostent object must not be
193 deallocated prematurely. *RESULT must be NULL or a pointer to a
194 linked-list. The new addresses are appended at the end. */
195static bool
196convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
197 int family,
198 struct hostent *h,
199 struct gaih_addrtuple **result)
200{
201 while (*result)
202 result = &(*result)->next;
203
204 /* Count the number of addresses in h->h_addr_list. */
205 size_t count = 0;
206 for (char **p = h->h_addr_list; *p != NULL; ++p)
207 ++count;
208
209 /* Report no data if no addresses are available, or if the incoming
210 address size is larger than what we can store. */
211 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
212 return true;
213
214 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
215 if (array == NULL)
216 return false;
217
218 for (size_t i = 0; i < count; ++i)
219 {
220 if (family == AF_INET && req->ai_family == AF_INET6)
221 {
222 /* Perform address mapping. */
223 array[i].family = AF_INET6;
224 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
225 array[i].addr[2] = htonl (0xffff);
226 }
227 else
228 {
229 array[i].family = family;
230 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
231 }
232 array[i].next = array + i + 1;
233 }
234 array[0].name = h->h_name;
235 array[count - 1].next = NULL;
236
237 *result = array;
238 return true;
239}
240
241#define gethosts(_family, _type) \
242 { \
243 struct hostent th; \
244 char *localcanon = NULL; \
245 no_data = 0; \
246 while (1) \
247 { \
248 status = DL_CALL_FCT (fct, (name, _family, &th, \
249 tmpbuf->data, tmpbuf->length, \
250 &errno, &h_errno, NULL, &localcanon)); \
251 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
252 || errno != ERANGE) \
253 break; \
254 if (!scratch_buffer_grow (tmpbuf)) \
255 { \
256 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
257 result = -EAI_MEMORY; \
258 goto free_and_return; \
259 } \
260 } \
261 if (status == NSS_STATUS_NOTFOUND \
262 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
263 { \
264 if (h_errno == NETDB_INTERNAL) \
265 { \
266 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
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 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
280 result = -EAI_SYSTEM; \
281 goto free_and_return; \
282 } \
283 *pat = addrmem; \
284 \
285 if (localcanon != NULL && canon == NULL) \
286 { \
287 canonbuf = __strdup (localcanon); \
288 if (canonbuf == NULL) \
289 { \
290 result = -EAI_SYSTEM; \
291 goto free_and_return; \
292 } \
293 canon = canonbuf; \
294 } \
295 if (_family == AF_INET6 && *pat != NULL) \
296 got_ipv6 = true; \
297 } \
298 }
299
300
301typedef enum nss_status (*nss_gethostbyname4_r)
302 (const char *name, struct gaih_addrtuple **pat,
303 char *buffer, size_t buflen, int *errnop,
304 int *h_errnop, int32_t *ttlp);
305typedef enum nss_status (*nss_gethostbyname3_r)
306 (const char *name, int af, struct hostent *host,
307 char *buffer, size_t buflen, int *errnop,
308 int *h_errnop, int32_t *ttlp, char **canonp);
309typedef enum nss_status (*nss_getcanonname_r)
310 (const char *name, char *buffer, size_t buflen, char **result,
311 int *errnop, int *h_errnop);
312extern service_user *__nss_hosts_database attribute_hidden;
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 int old_res_options;
577
578 /* If we do not have to look for IPv6 addresses or the canonical
579 name, use the simple, old functions, which do not support
580 IPv6 scope ids, nor retrieving the canonical name. */
581 if (req->ai_family == AF_INET
582 && (req->ai_flags & AI_CANONNAME) == 0)
583 {
584 int rc;
585 struct hostent th;
586 struct hostent *h;
587
588 while (1)
589 {
590 rc = __gethostbyname2_r (name, AF_INET, &th,
591 tmpbuf->data, tmpbuf->length,
592 &h, &h_errno);
593 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
594 break;
595 if (!scratch_buffer_grow (tmpbuf))
596 {
597 result = -EAI_MEMORY;
598 goto free_and_return;
599 }
600 }
601
602 if (rc == 0)
603 {
604 if (h != NULL)
605 {
606 /* We found data, convert it. */
607 if (!convert_hostent_to_gaih_addrtuple
608 (req, AF_INET, h, &addrmem))
609 {
610 result = -EAI_MEMORY;
611 goto free_and_return;
612 }
613 *pat = addrmem;
614 }
615 else
616 {
617 if (h_errno == NO_DATA)
618 result = -EAI_NODATA;
619 else
620 result = -EAI_NONAME;
621 goto free_and_return;
622 }
623 }
624 else
625 {
626 if (h_errno == NETDB_INTERNAL)
627 result = -EAI_SYSTEM;
628 else if (h_errno == TRY_AGAIN)
629 result = -EAI_AGAIN;
630 else
631 /* We made requests but they turned out no data.
632 The name is known, though. */
633 result = -EAI_NODATA;
634
635 goto free_and_return;
636 }
637
638 goto process_list;
639 }
640
641#ifdef USE_NSCD
642 if (__nss_not_use_nscd_hosts > 0
643 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
644 __nss_not_use_nscd_hosts = 0;
645
646 if (!__nss_not_use_nscd_hosts
647 && !__nss_database_custom[NSS_DBSIDX_hosts])
648 {
649 /* Try to use nscd. */
650 struct nscd_ai_result *air = NULL;
651 int err = __nscd_getai (name, &air, &h_errno);
652 if (air != NULL)
653 {
654 /* Transform into gaih_addrtuple list. */
655 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
656 char *addrs = air->addrs;
657
658 addrmem = calloc (air->naddrs, sizeof (*addrmem));
659 if (addrmem == NULL)
660 {
661 result = -EAI_MEMORY;
662 goto free_and_return;
663 }
664
665 struct gaih_addrtuple *addrfree = addrmem;
666 for (int i = 0; i < air->naddrs; ++i)
667 {
668 socklen_t size = (air->family[i] == AF_INET
669 ? INADDRSZ : IN6ADDRSZ);
670
671 if (!((air->family[i] == AF_INET
672 && req->ai_family == AF_INET6
673 && (req->ai_flags & AI_V4MAPPED) != 0)
674 || req->ai_family == AF_UNSPEC
675 || air->family[i] == req->ai_family))
676 {
677 /* Skip over non-matching result. */
678 addrs += size;
679 continue;
680 }
681
682 if (*pat == NULL)
683 {
684 *pat = addrfree++;
685 (*pat)->scopeid = 0;
686 }
687 uint32_t *pataddr = (*pat)->addr;
688 (*pat)->next = NULL;
689 if (added_canon || air->canon == NULL)
690 (*pat)->name = NULL;
691 else if (canonbuf == NULL)
692 {
693 canonbuf = __strdup (air->canon);
694 if (canonbuf == NULL)
695 {
696 result = -EAI_MEMORY;
697 goto free_and_return;
698 }
699 canon = (*pat)->name = canonbuf;
700 }
701
702 if (air->family[i] == AF_INET
703 && req->ai_family == AF_INET6
704 && (req->ai_flags & AI_V4MAPPED))
705 {
706 (*pat)->family = AF_INET6;
707 pataddr[3] = *(uint32_t *) addrs;
708 pataddr[2] = htonl (0xffff);
709 pataddr[1] = 0;
710 pataddr[0] = 0;
711 pat = &((*pat)->next);
712 added_canon = true;
713 }
714 else if (req->ai_family == AF_UNSPEC
715 || air->family[i] == req->ai_family)
716 {
717 (*pat)->family = air->family[i];
718 memcpy (pataddr, addrs, size);
719 pat = &((*pat)->next);
720 added_canon = true;
721 if (air->family[i] == AF_INET6)
722 got_ipv6 = true;
723 }
724 addrs += size;
725 }
726
727 free (air);
728
729 if (at->family == AF_UNSPEC)
730 {
731 result = -EAI_NONAME;
732 goto free_and_return;
733 }
734
735 goto process_list;
736 }
737 else if (err == 0)
738 /* The database contains a negative entry. */
739 goto free_and_return;
740 else if (__nss_not_use_nscd_hosts == 0)
741 {
742 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
743 result = -EAI_MEMORY;
744 else if (h_errno == TRY_AGAIN)
745 result = -EAI_AGAIN;
746 else
747 result = -EAI_SYSTEM;
748
749 goto free_and_return;
750 }
751 }
752#endif
753
754 if (__nss_hosts_database == NULL)
755 no_more = __nss_database_lookup ("hosts", NULL,
756 "dns [!UNAVAIL=return] files",
757 &__nss_hosts_database);
758 else
759 no_more = 0;
760 nip = __nss_hosts_database;
761
762 /* Initialize configurations. */
763 _res_hconf_init ();
764 if (__res_maybe_init (&_res, 0) == -1)
765 no_more = 1;
766
767 /* If we are looking for both IPv4 and IPv6 address we don't
768 want the lookup functions to automatically promote IPv4
769 addresses to IPv6 addresses. Currently this is decided
770 by setting the RES_USE_INET6 bit in _res.options. */
771 old_res_options = _res.options;
772 _res.options &= ~DEPRECATED_RES_USE_INET6;
773
774 while (!no_more)
775 {
776 no_data = 0;
777 nss_gethostbyname4_r fct4 = NULL;
778
779 /* gethostbyname4_r sends out parallel A and AAAA queries and
780 is thus only suitable for PF_UNSPEC. */
781 if (req->ai_family == PF_UNSPEC)
782 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
783
784 if (fct4 != NULL)
785 {
786 while (1)
787 {
788 status = DL_CALL_FCT (fct4, (name, pat,
789 tmpbuf->data, tmpbuf->length,
790 &errno, &h_errno,
791 NULL));
792 if (status == NSS_STATUS_SUCCESS)
793 break;
794 if (status != NSS_STATUS_TRYAGAIN
795 || errno != ERANGE || h_errno != NETDB_INTERNAL)
796 {
797 if (h_errno == TRY_AGAIN)
798 no_data = EAI_AGAIN;
799 else
800 no_data = h_errno == NO_DATA;
801 break;
802 }
803
804 if (!scratch_buffer_grow (tmpbuf))
805 {
806 _res.options
807 |= old_res_options & DEPRECATED_RES_USE_INET6;
808 result = -EAI_MEMORY;
809 goto free_and_return;
810 }
811 }
812
813 if (status == NSS_STATUS_SUCCESS)
814 {
815 assert (!no_data);
816 no_data = 1;
817
818 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
819 canon = (*pat)->name;
820
821 while (*pat != NULL)
822 {
823 if ((*pat)->family == AF_INET
824 && req->ai_family == AF_INET6
825 && (req->ai_flags & AI_V4MAPPED) != 0)
826 {
827 uint32_t *pataddr = (*pat)->addr;
828 (*pat)->family = AF_INET6;
829 pataddr[3] = pataddr[0];
830 pataddr[2] = htonl (0xffff);
831 pataddr[1] = 0;
832 pataddr[0] = 0;
833 pat = &((*pat)->next);
834 no_data = 0;
835 }
836 else if (req->ai_family == AF_UNSPEC
837 || (*pat)->family == req->ai_family)
838 {
839 pat = &((*pat)->next);
840
841 no_data = 0;
842 if (req->ai_family == AF_INET6)
843 got_ipv6 = true;
844 }
845 else
846 *pat = ((*pat)->next);
847 }
848 }
849
850 no_inet6_data = no_data;
851 }
852 else
853 {
854 nss_gethostbyname3_r fct = NULL;
855 if (req->ai_flags & AI_CANONNAME)
856 /* No need to use this function if we do not look for
857 the canonical name. The function does not exist in
858 all NSS modules and therefore the lookup would
859 often fail. */
860 fct = __nss_lookup_function (nip, "gethostbyname3_r");
861 if (fct == NULL)
862 /* We are cheating here. The gethostbyname2_r
863 function does not have the same interface as
864 gethostbyname3_r but the extra arguments the
865 latter takes are added at the end. So the
866 gethostbyname2_r code will just ignore them. */
867 fct = __nss_lookup_function (nip, "gethostbyname2_r");
868
869 if (fct != NULL)
870 {
871 if (req->ai_family == AF_INET6
872 || req->ai_family == AF_UNSPEC)
873 {
874 gethosts (AF_INET6, struct in6_addr);
875 no_inet6_data = no_data;
876 inet6_status = status;
877 }
878 if (req->ai_family == AF_INET
879 || req->ai_family == AF_UNSPEC
880 || (req->ai_family == AF_INET6
881 && (req->ai_flags & AI_V4MAPPED)
882 /* Avoid generating the mapped addresses if we
883 know we are not going to need them. */
884 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
885 {
886 gethosts (AF_INET, struct in_addr);
887
888 if (req->ai_family == AF_INET)
889 {
890 no_inet6_data = no_data;
891 inet6_status = status;
892 }
893 }
894
895 /* If we found one address for AF_INET or AF_INET6,
896 don't continue the search. */
897 if (inet6_status == NSS_STATUS_SUCCESS
898 || status == NSS_STATUS_SUCCESS)
899 {
900 if ((req->ai_flags & AI_CANONNAME) != 0
901 && canon == NULL)
902 {
903 canonbuf = getcanonname (nip, at, name);
904 if (canonbuf == NULL)
905 {
906 _res.options
907 |= old_res_options
908 & DEPRECATED_RES_USE_INET6;
909 result = -EAI_MEMORY;
910 goto free_and_return;
911 }
912 canon = canonbuf;
913 }
914 status = NSS_STATUS_SUCCESS;
915 }
916 else
917 {
918 /* We can have different states for AF_INET and
919 AF_INET6. Try to find a useful one for both. */
920 if (inet6_status == NSS_STATUS_TRYAGAIN)
921 status = NSS_STATUS_TRYAGAIN;
922 else if (status == NSS_STATUS_UNAVAIL
923 && inet6_status != NSS_STATUS_UNAVAIL)
924 status = inet6_status;
925 }
926 }
927 else
928 {
929 /* Could not locate any of the lookup functions.
930 The NSS lookup code does not consistently set
931 errno, so we need to supply our own error
932 code here. The root cause could either be a
933 resource allocation failure, or a missing
934 service function in the DSO (so it should not
935 be listed in /etc/nsswitch.conf). Assume the
936 former, and return EBUSY. */
937 status = NSS_STATUS_UNAVAIL;
938 __set_h_errno (NETDB_INTERNAL);
939 __set_errno (EBUSY);
940 }
941 }
942
943 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
944 break;
945
946 if (nip->next == NULL)
947 no_more = -1;
948 else
949 nip = nip->next;
950 }
951
952 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6;
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_not_cancel_no_status (fd);
2399 af = q->ai_family;
2400 fd = __socket (af, SOCK_DGRAM, 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_not_cancel_no_status (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