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