* sysdeps/posix/getaddrinfo.c: Fix precedence for IP V4-to-V6
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob636ab743d45176b50683d574992bc2f88f31ee25
1 /* The Inner Net License, Version 2.00
3 The author(s) grant permission for redistribution and use in source and
4 binary forms, with or without modification, of the software and documentation
5 provided that the following conditions are met:
7 0. If you receive a version of the software that is specifically labelled
8 as not being for redistribution (check the version message and/or README),
9 you are not permitted to redistribute that version of the software in any
10 way or form.
11 1. All terms of the all other applicable copyrights and licenses must be
12 followed.
13 2. Redistributions of source code must retain the authors' copyright
14 notice(s), this list of conditions, and the following disclaimer.
15 3. Redistributions in binary form must reproduce the authors' copyright
16 notice(s), this list of conditions, and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 4. [The copyright holder has authorized the removal of this clause.]
19 5. Neither the name(s) of the author(s) nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
23 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
38 #include <assert.h>
39 #include <errno.h>
40 #include <ifaddrs.h>
41 #include <netdb.h>
42 #include <resolv.h>
43 #include <stdbool.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <arpa/inet.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <sys/types.h>
52 #include <sys/un.h>
53 #include <sys/utsname.h>
54 #include <net/if.h>
55 #include <nsswitch.h>
56 #include <not-cancel.h>
57 #include <nscd/nscd-client.h>
58 #include <nscd/nscd_proto.h>
60 #ifdef HAVE_LIBIDN
61 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
62 extern int __idna_to_unicode_lzlz (const char *input, char **output,
63 int flags);
64 # include <libidn/idna.h>
65 #endif
67 #define GAIH_OKIFUNSPEC 0x0100
68 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
70 #ifndef UNIX_PATH_MAX
71 #define UNIX_PATH_MAX 108
72 #endif
74 struct gaih_service
76 const char *name;
77 int num;
80 struct gaih_servtuple
82 struct gaih_servtuple *next;
83 int socktype;
84 int protocol;
85 int port;
88 static const struct gaih_servtuple nullserv;
90 struct gaih_addrtuple
92 struct gaih_addrtuple *next;
93 char *name;
94 int family;
95 uint32_t addr[4];
96 uint32_t scopeid;
99 struct gaih_typeproto
101 int socktype;
102 int protocol;
103 char name[4];
104 int protoflag;
107 /* Values for `protoflag'. */
108 #define GAI_PROTO_NOSERVICE 1
109 #define GAI_PROTO_PROTOANY 2
111 static const struct gaih_typeproto gaih_inet_typeproto[] =
113 { 0, 0, "", 0 },
114 { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 },
115 { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 },
116 { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
117 { 0, 0, "", 0 }
120 struct gaih
122 int family;
123 int (*gaih)(const char *name, const struct gaih_service *service,
124 const struct addrinfo *req, struct addrinfo **pai,
125 unsigned int *naddrs);
128 static const struct addrinfo default_hints =
130 .ai_flags = AI_DEFAULT,
131 .ai_family = PF_UNSPEC,
132 .ai_socktype = 0,
133 .ai_protocol = 0,
134 .ai_addrlen = 0,
135 .ai_addr = NULL,
136 .ai_canonname = NULL,
137 .ai_next = NULL
141 #if 0
142 /* Using Unix sockets this way is a security risk. */
143 static int
144 gaih_local (const char *name, const struct gaih_service *service,
145 const struct addrinfo *req, struct addrinfo **pai)
147 struct utsname utsname;
149 if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
150 return GAIH_OKIFUNSPEC | -EAI_NONAME;
152 if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
153 if (uname (&utsname) < 0)
154 return -EAI_SYSTEM;
156 if (name != NULL)
158 if (strcmp(name, "localhost") &&
159 strcmp(name, "local") &&
160 strcmp(name, "unix") &&
161 strcmp(name, utsname.nodename))
162 return GAIH_OKIFUNSPEC | -EAI_NONAME;
165 if (req->ai_protocol || req->ai_socktype)
167 const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
169 while (tp->name[0]
170 && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
171 || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
172 || (req->ai_protocol != 0
173 && !(tp->protoflag & GAI_PROTO_PROTOANY)
174 && req->ai_protocol != tp->protocol)))
175 ++tp;
177 if (! tp->name[0])
179 if (req->ai_socktype)
180 return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
181 else
182 return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
186 *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un)
187 + ((req->ai_flags & AI_CANONNAME)
188 ? (strlen(utsname.nodename) + 1): 0));
189 if (*pai == NULL)
190 return -EAI_MEMORY;
192 (*pai)->ai_next = NULL;
193 (*pai)->ai_flags = req->ai_flags;
194 (*pai)->ai_family = AF_LOCAL;
195 (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
196 (*pai)->ai_protocol = req->ai_protocol;
197 (*pai)->ai_addrlen = sizeof (struct sockaddr_un);
198 (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
200 #ifdef _HAVE_SA_LEN
201 ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len =
202 sizeof (struct sockaddr_un);
203 #endif /* _HAVE_SA_LEN */
205 ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
206 memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
208 if (service)
210 struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr;
212 if (strchr (service->name, '/') != NULL)
214 if (strlen (service->name) >= sizeof (sunp->sun_path))
215 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
217 strcpy (sunp->sun_path, service->name);
219 else
221 if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >=
222 sizeof (sunp->sun_path))
223 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
225 __stpcpy (__stpcpy (sunp->sun_path, P_tmpdir "/"), service->name);
228 else
230 /* This is a dangerous use of the interface since there is a time
231 window between the test for the file and the actual creation
232 (done by the caller) in which a file with the same name could
233 be created. */
234 char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path;
236 if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0),
237 0) != 0
238 || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0)
239 return -EAI_SYSTEM;
242 if (req->ai_flags & AI_CANONNAME)
243 (*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo)
244 + sizeof (struct sockaddr_un),
245 utsname.nodename);
246 else
247 (*pai)->ai_canonname = NULL;
248 return 0;
250 #endif /* 0 */
252 static int
253 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
254 const struct addrinfo *req, struct gaih_servtuple *st)
256 struct servent *s;
257 size_t tmpbuflen = 1024;
258 struct servent ts;
259 char *tmpbuf;
260 int r;
264 tmpbuf = __alloca (tmpbuflen);
266 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
267 &s);
268 if (r != 0 || s == NULL)
270 if (r == ERANGE)
271 tmpbuflen *= 2;
272 else
273 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
276 while (r);
278 st->next = NULL;
279 st->socktype = tp->socktype;
280 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
281 ? req->ai_protocol : tp->protocol);
282 st->port = s->s_port;
284 return 0;
287 #define gethosts(_family, _type) \
289 int i; \
290 int herrno; \
291 struct hostent th; \
292 struct hostent *h; \
293 char *localcanon = NULL; \
294 no_data = 0; \
295 while (1) { \
296 rc = 0; \
297 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
298 &rc, &herrno, NULL, &localcanon)); \
299 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
300 break; \
301 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
303 if (status == NSS_STATUS_SUCCESS && rc == 0) \
304 h = &th; \
305 else \
306 h = NULL; \
307 if (rc != 0) \
309 if (herrno == NETDB_INTERNAL) \
311 __set_h_errno (herrno); \
312 return -EAI_SYSTEM; \
314 if (herrno == TRY_AGAIN) \
315 no_data = EAI_AGAIN; \
316 else \
317 no_data = herrno == NO_DATA; \
319 else if (h != NULL) \
321 for (i = 0; h->h_addr_list[i]; i++) \
323 if (*pat == NULL) \
325 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
326 (*pat)->scopeid = 0; \
328 uint32_t *addr = (*pat)->addr; \
329 (*pat)->next = NULL; \
330 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
331 if (_family == AF_INET && req->ai_family == AF_INET6) \
333 (*pat)->family = AF_INET6; \
334 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
335 addr[2] = htonl (0xffff); \
336 addr[1] = 0; \
337 addr[0] = 0; \
339 else \
341 (*pat)->family = _family; \
342 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
344 pat = &((*pat)->next); \
347 if (localcanon != NULL && canon == NULL) \
348 canon = strdupa (localcanon); \
350 if (_family == AF_INET6 && i > 0) \
351 got_ipv6 = true; \
356 typedef enum nss_status (*nss_gethostbyname3_r)
357 (const char *name, int af, struct hostent *host,
358 char *buffer, size_t buflen, int *errnop,
359 int *h_errnop, int32_t *ttlp, char **canonp);
360 typedef enum nss_status (*nss_getcanonname_r)
361 (const char *name, char *buffer, size_t buflen, char **result,
362 int *errnop, int *h_errnop);
363 extern service_user *__nss_hosts_database attribute_hidden;
365 static int
366 gaih_inet (const char *name, const struct gaih_service *service,
367 const struct addrinfo *req, struct addrinfo **pai,
368 unsigned int *naddrs)
370 const struct gaih_typeproto *tp = gaih_inet_typeproto;
371 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
372 struct gaih_addrtuple *at = NULL;
373 int rc;
374 bool got_ipv6 = false;
375 const char *canon = NULL;
376 const char *orig_name = name;
378 if (req->ai_protocol || req->ai_socktype)
380 ++tp;
382 while (tp->name[0]
383 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
384 || (req->ai_protocol != 0
385 && !(tp->protoflag & GAI_PROTO_PROTOANY)
386 && req->ai_protocol != tp->protocol)))
387 ++tp;
389 if (! tp->name[0])
391 if (req->ai_socktype)
392 return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
393 else
394 return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
398 int port = 0;
399 if (service != NULL)
401 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
402 return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
404 if (service->num < 0)
406 if (tp->name[0])
408 st = (struct gaih_servtuple *)
409 __alloca (sizeof (struct gaih_servtuple));
411 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
412 return rc;
414 else
416 struct gaih_servtuple **pst = &st;
417 for (tp++; tp->name[0]; tp++)
419 struct gaih_servtuple *newp;
421 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
422 continue;
424 if (req->ai_socktype != 0
425 && req->ai_socktype != tp->socktype)
426 continue;
427 if (req->ai_protocol != 0
428 && !(tp->protoflag & GAI_PROTO_PROTOANY)
429 && req->ai_protocol != tp->protocol)
430 continue;
432 newp = (struct gaih_servtuple *)
433 __alloca (sizeof (struct gaih_servtuple));
435 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
437 if (rc & GAIH_OKIFUNSPEC)
438 continue;
439 return rc;
442 *pst = newp;
443 pst = &(newp->next);
445 if (st == (struct gaih_servtuple *) &nullserv)
446 return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
449 else
451 port = htons (service->num);
452 goto got_port;
455 else
457 got_port:
459 if (req->ai_socktype || req->ai_protocol)
461 st = __alloca (sizeof (struct gaih_servtuple));
462 st->next = NULL;
463 st->socktype = tp->socktype;
464 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
465 ? req->ai_protocol : tp->protocol);
466 st->port = port;
468 else
470 /* Neither socket type nor protocol is set. Return all socket types
471 we know about. */
472 struct gaih_servtuple **lastp = &st;
473 for (++tp; tp->name[0]; ++tp)
475 struct gaih_servtuple *newp;
477 newp = __alloca (sizeof (struct gaih_servtuple));
478 newp->next = NULL;
479 newp->socktype = tp->socktype;
480 newp->protocol = tp->protocol;
481 newp->port = port;
483 *lastp = newp;
484 lastp = &newp->next;
489 if (name != NULL)
491 at = __alloca (sizeof (struct gaih_addrtuple));
493 at->family = AF_UNSPEC;
494 at->scopeid = 0;
495 at->next = NULL;
497 #ifdef HAVE_LIBIDN
498 if (req->ai_flags & AI_IDN)
500 int idn_flags = 0;
501 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
502 idn_flags |= IDNA_ALLOW_UNASSIGNED;
503 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
504 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
506 char *p = NULL;
507 rc = __idna_to_ascii_lz (name, &p, idn_flags);
508 if (rc != IDNA_SUCCESS)
510 if (rc == IDNA_MALLOC_ERROR)
511 return -EAI_MEMORY;
512 if (rc == IDNA_DLOPEN_ERROR)
513 return -EAI_SYSTEM;
514 return -EAI_IDN_ENCODE;
516 /* In case the output string is the same as the input string
517 no new string has been allocated. */
518 if (p != name)
520 name = strdupa (p);
521 free (p);
524 #endif
526 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
528 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
529 at->family = AF_INET;
530 else if (req->ai_family == AF_INET6 && req->ai_flags & AI_V4MAPPED)
532 at->addr[3] = at->addr[0];
533 at->addr[2] = htonl (0xffff);
534 at->addr[1] = 0;
535 at->addr[0] = 0;
536 at->family = AF_INET6;
538 else
539 return -EAI_ADDRFAMILY;
541 if (req->ai_flags & AI_CANONNAME)
542 canon = name;
544 else if (at->family == AF_UNSPEC)
546 char *namebuf = (char *) name;
547 char *scope_delim = strchr (name, SCOPE_DELIMITER);
549 if (__builtin_expect (scope_delim != NULL, 0))
551 namebuf = alloca (scope_delim - name + 1);
552 *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
555 if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
557 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
558 at->family = AF_INET6;
559 else if (req->ai_family == AF_INET
560 && IN6_IS_ADDR_V4MAPPED (at->addr))
562 at->addr[0] = at->addr[3];
563 at->family = AF_INET;
565 else
566 return -EAI_ADDRFAMILY;
568 if (scope_delim != NULL)
570 int try_numericscope = 0;
571 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
572 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
574 at->scopeid = if_nametoindex (scope_delim + 1);
575 if (at->scopeid == 0)
576 try_numericscope = 1;
578 else
579 try_numericscope = 1;
581 if (try_numericscope != 0)
583 char *end;
584 assert (sizeof (uint32_t) <= sizeof (unsigned long));
585 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
586 10);
587 if (*end != '\0')
588 return GAIH_OKIFUNSPEC | -EAI_NONAME;
592 if (req->ai_flags & AI_CANONNAME)
593 canon = name;
597 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
599 struct gaih_addrtuple **pat = &at;
600 int no_data = 0;
601 int no_inet6_data = 0;
602 service_user *nip = NULL;
603 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
604 enum nss_status status = NSS_STATUS_UNAVAIL;
605 int no_more;
606 int old_res_options;
608 /* If we do not have to look for IPv4 and IPv6 together, use
609 the simple, old functions. */
610 if (req->ai_family == AF_INET
611 || (req->ai_family == AF_INET6
612 && ((req->ai_flags & AI_V4MAPPED) == 0
613 || (req->ai_flags & AI_ALL) == 0)))
615 int family = req->ai_family;
616 size_t tmpbuflen = 512;
617 char *tmpbuf = alloca (tmpbuflen);
618 int rc;
619 struct hostent th;
620 struct hostent *h;
621 int herrno;
623 simple_again:
624 while (1)
626 rc = __gethostbyname2_r (name, family, &th, tmpbuf,
627 tmpbuflen, &h, &herrno);
628 if (rc != ERANGE || herrno != NETDB_INTERNAL)
629 break;
630 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
633 if (rc == 0)
635 if (h == NULL)
637 if (req->ai_family == AF_INET6
638 && (req->ai_flags & AI_V4MAPPED)
639 && family == AF_INET6)
641 /* Try again, this time looking for IPv4
642 addresses. */
643 family = AF_INET;
644 goto simple_again;
647 else
649 /* We found data, now convert it into the list. */
650 for (int i = 0; h->h_addr_list[i]; ++i)
652 if (*pat == NULL)
654 *pat = __alloca (sizeof (struct gaih_addrtuple));
655 (*pat)->scopeid = 0;
657 (*pat)->next = NULL;
658 (*pat)->family = req->ai_family;
659 if (family == req->ai_family)
660 memcpy ((*pat)->addr, h->h_addr_list[i],
661 h->h_length);
662 else
664 uint32_t *addr = (uint32_t *) (*pat)->addr;
665 addr[3] = *(uint32_t *) h->h_addr_list[i];
666 addr[2] = htonl (0xffff);
667 addr[1] = 0;
668 addr[0] = 0;
670 pat = &((*pat)->next);
674 else
676 if (herrno == NETDB_INTERNAL)
678 __set_h_errno (herrno);
679 return -EAI_SYSTEM;
681 if (herrno == TRY_AGAIN)
683 return -EAI_AGAIN;
685 /* We made requests but they turned out no data.
686 The name is known, though. */
687 return (GAIH_OKIFUNSPEC | -EAI_NODATA);
690 goto process_list;
693 #ifdef USE_NSCD
694 if (__nss_not_use_nscd_hosts > 0
695 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
696 __nss_not_use_nscd_hosts = 0;
698 if (!__nss_not_use_nscd_hosts)
700 /* Try to use nscd. */
701 struct nscd_ai_result *air = NULL;
702 int herrno;
703 int err = __nscd_getai (name, &air, &herrno);
704 if (air != NULL)
706 /* Transform into gaih_addrtuple list. */
707 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
708 char *addrs = air->addrs;
710 for (int i = 0; i < air->naddrs; ++i)
712 socklen_t size = (air->family[i] == AF_INET
713 ? INADDRSZ : IN6ADDRSZ);
714 if (*pat == NULL)
716 *pat = __alloca (sizeof (struct gaih_addrtuple));
717 (*pat)->scopeid = 0;
719 uint32_t *pataddr = (*pat)->addr;
720 (*pat)->next = NULL;
721 if (added_canon || air->canon == NULL)
722 (*pat)->name = NULL;
723 else
724 canon = (*pat)->name = strdupa (air->canon);
726 if (air->family[i] == AF_INET
727 && req->ai_family == AF_INET6
728 && (req->ai_flags & AI_V4MAPPED))
730 (*pat)->family = AF_INET6;
731 pataddr[3] = *(uint32_t *) addrs;
732 pataddr[2] = htonl (0xffff);
733 pataddr[1] = 0;
734 pataddr[0] = 0;
735 pat = &((*pat)->next);
736 added_canon = true;
738 else if (req->ai_family == AF_UNSPEC
739 || air->family[i] == req->ai_family)
741 (*pat)->family = air->family[i];
742 memcpy (pataddr, addrs, size);
743 pat = &((*pat)->next);
744 added_canon = true;
745 if (air->family[i] == AF_INET6)
746 got_ipv6 = true;
748 addrs += size;
751 free (air);
753 if (at->family == AF_UNSPEC)
754 return (GAIH_OKIFUNSPEC | -EAI_NONAME);
756 goto process_list;
758 else if (err != 0 && __nss_not_use_nscd_hosts == 0)
760 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
761 return -EAI_MEMORY;
762 if (herrno == TRY_AGAIN)
763 return -EAI_AGAIN;
764 return -EAI_SYSTEM;
767 #endif
769 if (__nss_hosts_database != NULL)
771 no_more = 0;
772 nip = __nss_hosts_database;
774 else
775 no_more = __nss_database_lookup ("hosts", NULL,
776 "dns [!UNAVAIL=return] files",
777 &nip);
779 if (__res_maybe_init (&_res, 0) == -1)
780 no_more = 1;
782 /* If we are looking for both IPv4 and IPv6 address we don't
783 want the lookup functions to automatically promote IPv4
784 addresses to IPv6 addresses. Currently this is decided
785 by setting the RES_USE_INET6 bit in _res.options. */
786 old_res_options = _res.options;
787 _res.options &= ~RES_USE_INET6;
789 size_t tmpbuflen = 512;
790 char *tmpbuf = alloca (tmpbuflen);
792 while (!no_more)
794 nss_gethostbyname3_r fct = NULL;
795 if (req->ai_flags & AI_CANONNAME)
796 /* No need to use this function if we do not look for
797 the canonical name. The function does not exist in
798 all NSS modules and therefore the lookup would
799 often fail. */
800 fct = __nss_lookup_function (nip, "gethostbyname3_r");
801 if (fct == NULL)
802 /* We are cheating here. The gethostbyname2_r function does
803 not have the same interface as gethostbyname3_r but the
804 extra arguments the latter takes are added at the end.
805 So the gethostbyname2_r code will just ignore them. */
806 fct = __nss_lookup_function (nip, "gethostbyname2_r");
808 if (fct != NULL)
810 if (req->ai_family == AF_INET6
811 || req->ai_family == AF_UNSPEC)
813 gethosts (AF_INET6, struct in6_addr);
814 no_inet6_data = no_data;
815 inet6_status = status;
817 if (req->ai_family == AF_INET
818 || req->ai_family == AF_UNSPEC
819 || (req->ai_family == AF_INET6
820 && (req->ai_flags & AI_V4MAPPED)
821 /* Avoid generating the mapped addresses if we
822 know we are not going to need them. */
823 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
825 gethosts (AF_INET, struct in_addr);
827 if (req->ai_family == AF_INET)
829 no_inet6_data = no_data;
830 inet6_status = status;
834 /* If we found one address for AF_INET or AF_INET6,
835 don't continue the search. */
836 if (inet6_status == NSS_STATUS_SUCCESS
837 || status == NSS_STATUS_SUCCESS)
839 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
841 /* If we need the canonical name, get it
842 from the same service as the result. */
843 nss_getcanonname_r cfct;
844 int herrno;
846 cfct = __nss_lookup_function (nip, "getcanonname_r");
847 if (cfct != NULL)
849 const size_t max_fqdn_len = 256;
850 char *buf = alloca (max_fqdn_len);
851 char *s;
853 if (DL_CALL_FCT (cfct, (at->name ?: name, buf,
854 max_fqdn_len, &s, &rc,
855 &herrno))
856 == NSS_STATUS_SUCCESS)
857 canon = s;
858 else
859 /* Set to name now to avoid using
860 gethostbyaddr. */
861 canon = name;
865 break;
868 /* We can have different states for AF_INET and
869 AF_INET6. Try to find a useful one for both. */
870 if (inet6_status == NSS_STATUS_TRYAGAIN)
871 status = NSS_STATUS_TRYAGAIN;
872 else if (status == NSS_STATUS_UNAVAIL
873 && inet6_status != NSS_STATUS_UNAVAIL)
874 status = inet6_status;
877 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
878 break;
880 if (nip->next == NULL)
881 no_more = -1;
882 else
883 nip = nip->next;
886 _res.options = old_res_options;
888 if (no_data != 0 && no_inet6_data != 0)
890 /* If both requests timed out report this. */
891 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
892 return -EAI_AGAIN;
894 /* We made requests but they turned out no data. The name
895 is known, though. */
896 return (GAIH_OKIFUNSPEC | -EAI_NODATA);
900 process_list:
901 if (at->family == AF_UNSPEC)
902 return (GAIH_OKIFUNSPEC | -EAI_NONAME);
904 else
906 struct gaih_addrtuple *atr;
907 atr = at = __alloca (sizeof (struct gaih_addrtuple));
908 memset (at, '\0', sizeof (struct gaih_addrtuple));
910 if (req->ai_family == AF_UNSPEC)
912 at->next = __alloca (sizeof (struct gaih_addrtuple));
913 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
916 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
918 at->family = AF_INET6;
919 if ((req->ai_flags & AI_PASSIVE) == 0)
920 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
921 atr = at->next;
924 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
926 atr->family = AF_INET;
927 if ((req->ai_flags & AI_PASSIVE) == 0)
928 atr->addr[0] = htonl (INADDR_LOOPBACK);
932 if (pai == NULL)
933 return 0;
936 struct gaih_servtuple *st2;
937 struct gaih_addrtuple *at2 = at;
938 size_t socklen;
939 sa_family_t family;
942 buffer is the size of an unformatted IPv6 address in printable format.
944 while (at2 != NULL)
946 /* Only the first entry gets the canonical name. */
947 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
949 if (canon == NULL)
951 struct hostent *h = NULL;
952 int herrno;
953 struct hostent th;
954 size_t tmpbuflen = 512;
955 char *tmpbuf = NULL;
959 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
960 rc = __gethostbyaddr_r (at2->addr,
961 ((at2->family == AF_INET6)
962 ? sizeof (struct in6_addr)
963 : sizeof (struct in_addr)),
964 at2->family, &th, tmpbuf,
965 tmpbuflen, &h, &herrno);
967 while (rc == ERANGE && herrno == NETDB_INTERNAL);
969 if (rc != 0 && herrno == NETDB_INTERNAL)
971 __set_h_errno (herrno);
972 return -EAI_SYSTEM;
975 if (h != NULL)
976 canon = h->h_name;
977 else
979 assert (orig_name != NULL);
980 /* If the canonical name cannot be determined, use
981 the passed in string. */
982 canon = orig_name;
986 #ifdef HAVE_LIBIDN
987 if (req->ai_flags & AI_CANONIDN)
989 int idn_flags = 0;
990 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
991 idn_flags |= IDNA_ALLOW_UNASSIGNED;
992 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
993 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
995 char *out;
996 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
997 if (rc != IDNA_SUCCESS)
999 if (rc == IDNA_MALLOC_ERROR)
1000 return -EAI_MEMORY;
1001 if (rc == IDNA_DLOPEN_ERROR)
1002 return -EAI_SYSTEM;
1003 return -EAI_IDN_ENCODE;
1005 /* In case the output string is the same as the input
1006 string no new string has been allocated. Otherwise
1007 make a copy. */
1008 if (out == canon)
1009 goto make_copy;
1011 else
1012 #endif
1014 #ifdef HAVE_LIBIDN
1015 make_copy:
1016 #endif
1017 canon = strdup (canon);
1018 if (canon == NULL)
1019 return -EAI_MEMORY;
1023 family = at2->family;
1024 if (family == AF_INET6)
1026 socklen = sizeof (struct sockaddr_in6);
1028 /* If we looked up IPv4 mapped address discard them here if
1029 the caller isn't interested in all address and we have
1030 found at least one IPv6 address. */
1031 if (got_ipv6
1032 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1033 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1034 goto ignore;
1036 else
1037 socklen = sizeof (struct sockaddr_in);
1039 for (st2 = st; st2 != NULL; st2 = st2->next)
1041 struct addrinfo *ai;
1042 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1043 if (ai == NULL)
1044 return -EAI_MEMORY;
1046 ai->ai_flags = req->ai_flags;
1047 ai->ai_family = family;
1048 ai->ai_socktype = st2->socktype;
1049 ai->ai_protocol = st2->protocol;
1050 ai->ai_addrlen = socklen;
1051 ai->ai_addr = (void *) (ai + 1);
1053 /* We only add the canonical name once. */
1054 ai->ai_canonname = (char *) canon;
1055 canon = NULL;
1057 #ifdef _HAVE_SA_LEN
1058 ai->ai_addr->sa_len = socklen;
1059 #endif /* _HAVE_SA_LEN */
1060 ai->ai_addr->sa_family = family;
1062 if (family == AF_INET6)
1064 struct sockaddr_in6 *sin6p =
1065 (struct sockaddr_in6 *) ai->ai_addr;
1067 sin6p->sin6_port = st2->port;
1068 sin6p->sin6_flowinfo = 0;
1069 memcpy (&sin6p->sin6_addr,
1070 at2->addr, sizeof (struct in6_addr));
1071 sin6p->sin6_scope_id = at2->scopeid;
1073 else
1075 struct sockaddr_in *sinp =
1076 (struct sockaddr_in *) ai->ai_addr;
1077 sinp->sin_port = st2->port;
1078 memcpy (&sinp->sin_addr,
1079 at2->addr, sizeof (struct in_addr));
1080 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1083 pai = &(ai->ai_next);
1085 *pai = NULL;
1087 ++*naddrs;
1089 ignore:
1090 at2 = at2->next;
1093 return 0;
1096 static const struct gaih gaih[] =
1098 { PF_INET6, gaih_inet },
1099 { PF_INET, gaih_inet },
1100 #if 0
1101 { PF_LOCAL, gaih_local },
1102 #endif
1103 { PF_UNSPEC, NULL }
1106 struct sort_result
1108 struct addrinfo *dest_addr;
1109 struct sockaddr_storage source_addr;
1110 uint8_t source_addr_len;
1111 bool got_source_addr;
1115 static int
1116 get_scope (const struct sockaddr_storage *ss)
1118 int scope;
1119 if (ss->ss_family == PF_INET6)
1121 const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss;
1123 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1125 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
1126 scope = 2;
1127 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1128 scope = 5;
1129 else
1130 /* XXX Is this the correct default behavior? */
1131 scope = 14;
1133 else
1134 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1136 else if (ss->ss_family == PF_INET)
1138 const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
1139 const uint8_t *addr = (const uint8_t *) &in->sin_addr;
1141 /* RFC 3484 specifies how to map IPv6 addresses to scopes.
1142 169.254/16 and 127/8 are link-local. */
1143 if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
1144 scope = 2;
1145 else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16)
1146 || (addr[0] == 192 && addr[1] == 168))
1147 scope = 5;
1148 else
1149 scope = 14;
1151 else
1152 /* XXX What is a good default? */
1153 scope = 15;
1155 return scope;
1159 /* XXX The system administrator should be able to install other
1160 tables. We need to make this configurable. The problem is that
1161 the kernel is also involved since it needs the same table. */
1162 static const struct prefixlist
1164 struct in6_addr prefix;
1165 unsigned int bits;
1166 int val;
1167 } default_labels[] =
1169 /* See RFC 3484 for the details. */
1170 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1171 0x0000, 0x0000, 0x0000, 0x0001 } } },
1172 128, 0 },
1173 { { .in6_u = { .u6_addr16 = { 0x2002, 0x0000, 0x0000, 0x0000,
1174 0x0000, 0x0000, 0x0000, 0x0000 } } },
1175 16, 2 },
1176 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1177 0x0000, 0x0000, 0x0000, 0x0000 } } },
1178 96, 3 },
1179 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1180 0x0000, 0xffff, 0x0000, 0x0000 } } },
1181 96, 4 },
1182 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1183 0x0000, 0x0000, 0x0000, 0x0000 } } },
1184 0, 1 }
1188 static const struct prefixlist default_precedence[] =
1190 /* See RFC 3484 for the details. */
1191 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1192 0x0000, 0x0000, 0x0000, 0x0001 } } },
1193 128, 50 },
1194 { { .in6_u = { .u6_addr16 = { 0x2002, 0x0000, 0x0000, 0x0000,
1195 0x0000, 0x0000, 0x0000, 0x0000 } } },
1196 16, 30 },
1197 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1198 0x0000, 0x0000, 0x0000, 0x0000 } } },
1199 96, 20 },
1200 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1201 0x0000, 0xffff, 0x0000, 0x0000 } } },
1202 96, 100 },
1203 { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1204 0x0000, 0x0000, 0x0000, 0x0000 } } },
1205 0, 40 }
1209 static int
1210 match_prefix (const struct sockaddr_storage *ss, const struct prefixlist *list,
1211 int default_val)
1213 int idx;
1214 struct sockaddr_in6 in6_mem;
1215 const struct sockaddr_in6 *in6;
1217 if (ss->ss_family == PF_INET6)
1218 in6 = (const struct sockaddr_in6 *) ss;
1219 else if (ss->ss_family == PF_INET)
1221 const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
1223 /* Convert to IPv6 address. */
1224 in6_mem.sin6_family = PF_INET6;
1225 in6_mem.sin6_port = in->sin_port;
1226 in6_mem.sin6_flowinfo = 0;
1227 if (in->sin_addr.s_addr == htonl (0x7f000001))
1228 in6_mem.sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
1229 else
1231 /* Construct a V4-to-6 mapped address. */
1232 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1233 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1234 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1235 in6_mem.sin6_scope_id = 0;
1238 in6 = &in6_mem;
1240 else
1241 return default_val;
1243 for (idx = 0; ; ++idx)
1245 unsigned int bits = list[idx].bits;
1246 uint8_t *mask = list[idx].prefix.s6_addr;
1247 uint8_t *val = in6->sin6_addr.s6_addr;
1249 while (bits >= 8)
1251 if (*mask != *val)
1252 break;
1254 ++mask;
1255 ++val;
1256 bits -= 8;
1259 if (bits < 8)
1261 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1262 /* Match! */
1263 break;
1267 return list[idx].val;
1271 static int
1272 get_label (const struct sockaddr_storage *ss)
1274 /* XXX What is a good default value? */
1275 return match_prefix (ss, default_labels, INT_MAX);
1279 static int
1280 get_precedence (const struct sockaddr_storage *ss)
1282 /* XXX What is a good default value? */
1283 return match_prefix (ss, default_precedence, 0);
1287 /* Find last bit set in a word. */
1288 static int
1289 fls (uint32_t a)
1291 uint32_t mask;
1292 int n = 0;
1293 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1294 if ((a & mask) != 0)
1295 break;
1296 return n;
1300 static int
1301 rfc3484_sort (const void *p1, const void *p2)
1303 const struct sort_result *a1 = (const struct sort_result *) p1;
1304 const struct sort_result *a2 = (const struct sort_result *) p2;
1306 /* Rule 1: Avoid unusable destinations.
1307 We have the got_source_addr flag set if the destination is reachable. */
1308 if (a1->got_source_addr && ! a2->got_source_addr)
1309 return -1;
1310 if (! a1->got_source_addr && a2->got_source_addr)
1311 return 1;
1314 /* Rule 2: Prefer matching scope. Only interesting if both
1315 destination addresses are IPv6. */
1316 int a1_dst_scope
1317 = get_scope ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1319 int a2_dst_scope
1320 = get_scope ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1322 if (a1->got_source_addr)
1324 int a1_src_scope = get_scope (&a1->source_addr);
1325 int a2_src_scope = get_scope (&a2->source_addr);
1327 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1328 return -1;
1329 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1330 return 1;
1334 /* Rule 3: Avoid deprecated addresses.
1335 That's something only the kernel could decide. */
1337 /* Rule 4: Prefer home addresses.
1338 Another thing only the kernel can decide. */
1340 /* Rule 5: Prefer matching label. */
1341 if (a1->got_source_addr)
1343 int a1_dst_label
1344 = get_label ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1345 int a1_src_label = get_label (&a1->source_addr);
1347 int a2_dst_label
1348 = get_label ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1349 int a2_src_label = get_label (&a2->source_addr);
1351 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1352 return -1;
1353 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1354 return 1;
1358 /* Rule 6: Prefer higher precedence. */
1359 int a1_prec
1360 = get_precedence ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1361 int a2_prec
1362 = get_precedence ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1364 if (a1_prec > a2_prec)
1365 return -1;
1366 if (a1_prec < a2_prec)
1367 return 1;
1370 /* Rule 7: Prefer native transport.
1371 XXX How to recognize tunnels? */
1374 /* Rule 8: Prefer smaller scope. */
1375 if (a1_dst_scope < a2_dst_scope)
1376 return -1;
1377 if (a1_dst_scope > a2_dst_scope)
1378 return 1;
1381 /* Rule 9: Use longest matching prefix. */
1382 if (a1->got_source_addr
1383 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1385 int bit1 = 0;
1386 int bit2 = 0;
1388 if (a1->dest_addr->ai_family == PF_INET)
1390 assert (a1->source_addr.ss_family == PF_INET);
1391 assert (a2->source_addr.ss_family == PF_INET);
1393 struct sockaddr_in *in1_dst;
1394 struct sockaddr_in *in1_src;
1395 struct sockaddr_in *in2_dst;
1396 struct sockaddr_in *in2_src;
1398 in1_dst = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1399 in1_src = (struct sockaddr_in *) &a1->source_addr;
1400 in2_dst = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1401 in2_src = (struct sockaddr_in *) &a2->source_addr;
1403 bit1 = fls (ntohl (in1_dst->sin_addr.s_addr
1404 ^ in1_src->sin_addr.s_addr));
1405 bit2 = fls (ntohl (in2_dst->sin_addr.s_addr
1406 ^ in2_src->sin_addr.s_addr));
1408 else if (a1->dest_addr->ai_family == PF_INET6)
1410 assert (a1->source_addr.ss_family == PF_INET6);
1411 assert (a2->source_addr.ss_family == PF_INET6);
1413 struct sockaddr_in6 *in1_dst;
1414 struct sockaddr_in6 *in1_src;
1415 struct sockaddr_in6 *in2_dst;
1416 struct sockaddr_in6 *in2_src;
1418 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1419 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1420 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1421 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1423 int i;
1424 for (i = 0; i < 4; ++i)
1425 if (in1_dst->sin6_addr.s6_addr32[i]
1426 != in1_src->sin6_addr.s6_addr32[i]
1427 || (in2_dst->sin6_addr.s6_addr32[i]
1428 != in2_src->sin6_addr.s6_addr32[i]))
1429 break;
1431 if (i < 4)
1433 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1434 ^ in1_src->sin6_addr.s6_addr32[i]));
1435 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1436 ^ in2_src->sin6_addr.s6_addr32[i]));
1440 if (bit1 > bit2)
1441 return -1;
1442 if (bit1 < bit2)
1443 return 1;
1447 /* Rule 10: Otherwise, leave the order unchanged. */
1448 return 0;
1453 getaddrinfo (const char *name, const char *service,
1454 const struct addrinfo *hints, struct addrinfo **pai)
1456 int i = 0, j = 0, last_i = 0;
1457 int nresults = 0;
1458 struct addrinfo *p = NULL, **end;
1459 const struct gaih *g = gaih;
1460 const struct gaih *pg = NULL;
1461 struct gaih_service gaih_service, *pservice;
1462 struct addrinfo local_hints;
1464 if (name != NULL && name[0] == '*' && name[1] == 0)
1465 name = NULL;
1467 if (service != NULL && service[0] == '*' && service[1] == 0)
1468 service = NULL;
1470 if (name == NULL && service == NULL)
1471 return EAI_NONAME;
1473 if (hints == NULL)
1474 hints = &default_hints;
1476 if (hints->ai_flags
1477 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
1478 #ifdef HAVE_LIBIDN
1479 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
1480 |AI_IDN_USE_STD3_ASCII_RULES
1481 #endif
1482 |AI_NUMERICSERV|AI_ALL))
1483 return EAI_BADFLAGS;
1485 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
1486 return EAI_BADFLAGS;
1488 if (hints->ai_flags & AI_ADDRCONFIG)
1490 /* Determine whether we have IPv4 or IPv6 interfaces or both.
1491 We cannot cache the results since new interfaces could be
1492 added at any time. */
1493 bool seen_ipv4;
1494 bool seen_ipv6;
1495 __check_pf (&seen_ipv4, &seen_ipv6);
1497 /* Now make a decision on what we return, if anything. */
1498 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
1500 /* If we haven't seen both IPv4 and IPv6 interfaces we can
1501 narrow down the search. */
1502 if (! seen_ipv4 || ! seen_ipv6)
1504 local_hints = *hints;
1505 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
1506 hints = &local_hints;
1509 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
1510 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
1511 /* We cannot possibly return a valid answer. */
1512 return EAI_NONAME;
1515 if (service && service[0])
1517 char *c;
1518 gaih_service.name = service;
1519 gaih_service.num = strtoul (gaih_service.name, &c, 10);
1520 if (*c != '\0')
1522 if (hints->ai_flags & AI_NUMERICSERV)
1523 return EAI_NONAME;
1525 gaih_service.num = -1;
1528 pservice = &gaih_service;
1530 else
1531 pservice = NULL;
1533 if (pai)
1534 end = &p;
1535 else
1536 end = NULL;
1538 unsigned int naddrs = 0;
1539 while (g->gaih)
1541 if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
1543 j++;
1544 if (pg == NULL || pg->gaih != g->gaih)
1546 pg = g;
1547 i = g->gaih (name, pservice, hints, end, &naddrs);
1548 if (i != 0)
1550 /* EAI_NODATA is a more specific result as it says that
1551 we found a result but it is not usable. */
1552 if (last_i != (GAIH_OKIFUNSPEC | -EAI_NODATA))
1553 last_i = i;
1555 if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
1557 ++g;
1558 continue;
1561 freeaddrinfo (p);
1563 return -(i & GAIH_EAI);
1565 if (end)
1566 while (*end)
1568 end = &((*end)->ai_next);
1569 ++nresults;
1573 ++g;
1576 if (j == 0)
1577 return EAI_FAMILY;
1579 if (naddrs > 1)
1581 /* Sort results according to RFC 3484. */
1582 struct sort_result results[nresults];
1583 struct addrinfo *q;
1584 struct addrinfo *last = NULL;
1585 char *canonname = NULL;
1587 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
1589 results[i].dest_addr = q;
1590 results[i].got_source_addr = false;
1592 /* If we just looked up the address for a different
1593 protocol, reuse the result. */
1594 if (last != NULL && last->ai_addrlen == q->ai_addrlen
1595 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
1597 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
1598 results[i - 1].source_addr_len);
1599 results[i].source_addr_len = results[i - 1].source_addr_len;
1600 results[i].got_source_addr = results[i - 1].got_source_addr;
1602 else
1604 /* We overwrite the type with SOCK_DGRAM since we do not
1605 want connect() to connect to the other side. If we
1606 cannot determine the source address remember this
1607 fact. */
1608 int fd = __socket (q->ai_family, SOCK_DGRAM, IPPROTO_IP);
1609 socklen_t sl = sizeof (results[i].source_addr);
1610 if (fd != -1
1611 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
1612 && __getsockname (fd,
1613 (struct sockaddr *) &results[i].source_addr,
1614 &sl) == 0)
1616 results[i].source_addr_len = sl;
1617 results[i].got_source_addr = true;
1619 else
1620 /* Just make sure that if we have to process the same
1621 address again we do not copy any memory. */
1622 results[i].source_addr_len = 0;
1624 if (fd != -1)
1625 close_not_cancel_no_status (fd);
1628 /* Remember the canonical name. */
1629 if (q->ai_canonname != NULL)
1631 assert (canonname == NULL);
1632 canonname = q->ai_canonname;
1633 q->ai_canonname = NULL;
1637 /* We got all the source addresses we can get, now sort using
1638 the information. */
1639 qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
1641 /* Queue the results up as they come out of sorting. */
1642 q = p = results[0].dest_addr;
1643 for (i = 1; i < nresults; ++i)
1644 q = q->ai_next = results[i].dest_addr;
1645 q->ai_next = NULL;
1647 /* Fill in the canonical name into the new first entry. */
1648 p->ai_canonname = canonname;
1651 if (p)
1653 *pai = p;
1654 return 0;
1657 if (pai == NULL && last_i == 0)
1658 return 0;
1660 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
1662 libc_hidden_def (getaddrinfo)
1664 static_link_warning (getaddrinfo)
1666 void
1667 freeaddrinfo (struct addrinfo *ai)
1669 struct addrinfo *p;
1671 while (ai != NULL)
1673 p = ai;
1674 ai = ai->ai_next;
1675 free (p->ai_canonname);
1676 free (p);
1679 libc_hidden_def (freeaddrinfo)