(gaih_inet): Recognize all the IPv4 numeric address formats inet_addr knows.
[kopensolaris-gnu/glibc.git] / sysdeps / posix / getaddrinfo.c
1 /* The Inner Net License, Version 2.00
2
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:
6
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.
22
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.
33
34   If these license terms cause you a real problem, contact the author.  */
35
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved.  */
37
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
58 #ifdef HAVE_LIBIDN
59 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
60 extern int __idna_to_unicode_lzlz (const char *input, char **output,
61                                    int flags);
62 # include <libidn/idna.h>
63 #endif
64
65 #define GAIH_OKIFUNSPEC 0x0100
66 #define GAIH_EAI        ~(GAIH_OKIFUNSPEC)
67
68 #ifndef UNIX_PATH_MAX
69 #define UNIX_PATH_MAX  108
70 #endif
71
72 struct gaih_service
73   {
74     const char *name;
75     int num;
76   };
77
78 struct gaih_servtuple
79   {
80     struct gaih_servtuple *next;
81     int socktype;
82     int protocol;
83     int port;
84   };
85
86 static const struct gaih_servtuple nullserv;
87
88 struct gaih_addrtuple
89   {
90     struct gaih_addrtuple *next;
91     int family;
92     char addr[16];
93     uint32_t scopeid;
94   };
95
96 struct gaih_typeproto
97   {
98     int socktype;
99     int protocol;
100     char name[4];
101     int protoflag;
102   };
103
104 /* Values for `protoflag'.  */
105 #define GAI_PROTO_NOSERVICE     1
106 #define GAI_PROTO_PROTOANY      2
107
108 static const struct gaih_typeproto gaih_inet_typeproto[] =
109 {
110   { 0, 0, "", 0 },
111   { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 },
112   { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 },
113   { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
114   { 0, 0, "", 0 }
115 };
116
117 struct gaih
118   {
119     int family;
120     int (*gaih)(const char *name, const struct gaih_service *service,
121                 const struct addrinfo *req, struct addrinfo **pai);
122   };
123
124 static const struct addrinfo default_hints =
125   {
126     .ai_flags = AI_DEFAULT,
127     .ai_family = PF_UNSPEC,
128     .ai_socktype = 0,
129     .ai_protocol = 0,
130     .ai_addrlen = 0,
131     .ai_addr = NULL,
132     .ai_canonname = NULL,
133     .ai_next = NULL
134   };
135
136
137 #if 0
138 /* Using Unix sockets this way is a security risk.  */
139 static int
140 gaih_local (const char *name, const struct gaih_service *service,
141             const struct addrinfo *req, struct addrinfo **pai)
142 {
143   struct utsname utsname;
144
145   if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
146     return GAIH_OKIFUNSPEC | -EAI_NONAME;
147
148   if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
149     if (uname (&utsname) < 0)
150       return -EAI_SYSTEM;
151
152   if (name != NULL)
153     {
154       if (strcmp(name, "localhost") &&
155           strcmp(name, "local") &&
156           strcmp(name, "unix") &&
157           strcmp(name, utsname.nodename))
158         return GAIH_OKIFUNSPEC | -EAI_NONAME;
159     }
160
161   if (req->ai_protocol || req->ai_socktype)
162     {
163       const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
164
165       while (tp->name[0]
166              && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
167                  || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
168                  || (req->ai_protocol != 0
169                      && !(tp->protoflag & GAI_PROTO_PROTOANY)
170                      && req->ai_protocol != tp->protocol)))
171         ++tp;
172
173       if (! tp->name[0])
174         {
175           if (req->ai_socktype)
176             return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
177           else
178             return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
179         }
180     }
181
182   *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un)
183                  + ((req->ai_flags & AI_CANONNAME)
184                     ? (strlen(utsname.nodename) + 1): 0));
185   if (*pai == NULL)
186     return -EAI_MEMORY;
187
188   (*pai)->ai_next = NULL;
189   (*pai)->ai_flags = req->ai_flags;
190   (*pai)->ai_family = AF_LOCAL;
191   (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
192   (*pai)->ai_protocol = req->ai_protocol;
193   (*pai)->ai_addrlen = sizeof (struct sockaddr_un);
194   (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
195
196 #if SALEN
197   ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len =
198     sizeof (struct sockaddr_un);
199 #endif /* SALEN */
200
201   ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
202   memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
203
204   if (service)
205     {
206       struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr;
207
208       if (strchr (service->name, '/') != NULL)
209         {
210           if (strlen (service->name) >= sizeof (sunp->sun_path))
211             return GAIH_OKIFUNSPEC | -EAI_SERVICE;
212
213           strcpy (sunp->sun_path, service->name);
214         }
215       else
216         {
217           if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >=
218               sizeof (sunp->sun_path))
219             return GAIH_OKIFUNSPEC | -EAI_SERVICE;
220
221           __stpcpy (__stpcpy (sunp->sun_path, P_tmpdir "/"), service->name);
222         }
223     }
224   else
225     {
226       /* This is a dangerous use of the interface since there is a time
227          window between the test for the file and the actual creation
228          (done by the caller) in which a file with the same name could
229          be created.  */
230       char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path;
231
232       if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0),
233                             0) != 0
234           || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0)
235         return -EAI_SYSTEM;
236     }
237
238   if (req->ai_flags & AI_CANONNAME)
239     (*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo)
240                                    + sizeof (struct sockaddr_un),
241                                    utsname.nodename);
242   else
243     (*pai)->ai_canonname = NULL;
244   return 0;
245 }
246 #endif  /* 0 */
247
248 static int
249 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
250                const struct addrinfo *req, struct gaih_servtuple *st)
251 {
252   struct servent *s;
253   size_t tmpbuflen = 1024;
254   struct servent ts;
255   char *tmpbuf;
256   int r;
257
258   do
259     {
260       tmpbuf = __alloca (tmpbuflen);
261
262       r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
263                              &s);
264       if (r != 0 || s == NULL)
265         {
266           if (r == ERANGE)
267             tmpbuflen *= 2;
268           else
269             return GAIH_OKIFUNSPEC | -EAI_SERVICE;
270         }
271     }
272   while (r);
273
274   st->next = NULL;
275   st->socktype = tp->socktype;
276   st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
277                   ? req->ai_protocol : tp->protocol);
278   st->port = s->s_port;
279
280   return 0;
281 }
282
283 #define gethosts(_family, _type) \
284  {                                                                            \
285   int i, herrno;                                                              \
286   size_t tmpbuflen;                                                           \
287   struct hostent th;                                                          \
288   char *tmpbuf = NULL;                                                        \
289   tmpbuflen = 512;                                                            \
290   no_data = 0;                                                                \
291   do {                                                                        \
292     tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);                \
293     rc = __gethostbyname2_r (name, _family, &th, tmpbuf,                      \
294          tmpbuflen, &h, &herrno);                                             \
295   } while (rc == ERANGE && herrno == NETDB_INTERNAL);                         \
296   if (rc != 0)                                                                \
297     {                                                                         \
298       if (herrno == NETDB_INTERNAL)                                           \
299         {                                                                     \
300           __set_h_errno (herrno);                                             \
301           return -EAI_SYSTEM;                                                 \
302         }                                                                     \
303       if (herrno == TRY_AGAIN)                                                \
304         no_data = EAI_AGAIN;                                                  \
305       else                                                                    \
306         no_data = herrno == NO_DATA;                                          \
307     }                                                                         \
308   else if (h != NULL)                                                         \
309     {                                                                         \
310       for (i = 0; h->h_addr_list[i]; i++)                                     \
311         {                                                                     \
312           if (*pat == NULL) {                                                 \
313             *pat = __alloca (sizeof (struct gaih_addrtuple));                 \
314             (*pat)->scopeid = 0;                                              \
315           }                                                                   \
316           (*pat)->next = NULL;                                                \
317           (*pat)->family = _family;                                           \
318           memcpy ((*pat)->addr, h->h_addr_list[i],                            \
319                  sizeof(_type));                                              \
320           pat = &((*pat)->next);                                              \
321         }                                                                     \
322       if (_family == AF_INET6)                                                \
323         got_ipv6 = true;                                                      \
324     }                                                                         \
325   else if (_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))              \
326     {                                                                         \
327       /* We have to add V4 mapped addresses.  Maybe we discard them           \
328          later again but we get them anyhow for now.  */                      \
329       while ((rc = __gethostbyname2_r (name, AF_INET6, &th, tmpbuf,           \
330                                        tmpbuflen, &h, &herrno)) == ERANGE     \
331              && herrno == NETDB_INTERNAL)                                     \
332         tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);            \
333                                                                               \
334       if (rc != 0)                                                            \
335         {                                                                     \
336           if (herrno == NETDB_INTERNAL)                                       \
337             {                                                                 \
338               __set_h_errno (herrno);                                         \
339               return -EAI_SYSTEM;                                             \
340             }                                                                 \
341           if (herrno == TRY_AGAIN)                                            \
342             no_data = EAI_AGAIN;                                              \
343           else                                                                \
344             no_data = herrno == NO_DATA;                                      \
345         }                                                                     \
346       else if (h != NULL)                                                     \
347         {                                                                     \
348           for (i = 0; h->h_addr_list[i]; ++i)                                 \
349             {                                                                 \
350               if (*pat == NULL)                                               \
351                 {                                                             \
352                   *pat = __alloca (sizeof (struct gaih_addrtuple));           \
353                   (*pat)->scopeid = 0;                                        \
354                 }                                                             \
355               uint32_t *addr = (uint32_t *) (*pat)->addr;                     \
356               (*pat)->next = NULL;                                            \
357               (*pat)->family = _family;                                       \
358               addr[3] = *(uint32_t *) h->h_addr_list[i];                      \
359               addr[2] = htonl (0xffff);                                       \
360               addr[1] = 0;                                                    \
361               addr[0] = 0;                                                    \
362               pat = &((*pat)->next);                                          \
363             }                                                                 \
364         }                                                                     \
365     }                                                                         \
366  }
367
368
369 #define gethosts2(_family, _type) \
370  {                                                                            \
371   int i, herrno;                                                              \
372   size_t tmpbuflen;                                                           \
373   struct hostent th;                                                          \
374   char *tmpbuf = NULL;                                                        \
375   tmpbuflen = 512;                                                            \
376   no_data = 0;                                                                \
377   do {                                                                        \
378     tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);                \
379     rc = 0;                                                                   \
380     status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf,                   \
381            tmpbuflen, &rc, &herrno));                                         \
382   } while (rc == ERANGE && herrno == NETDB_INTERNAL);                         \
383   if (status == NSS_STATUS_SUCCESS && rc == 0)                                \
384     h = &th;                                                                  \
385   else                                                                        \
386     h = NULL;                                                                 \
387   if (rc != 0)                                                                \
388     {                                                                         \
389       if (herrno == NETDB_INTERNAL)                                           \
390         {                                                                     \
391           __set_h_errno (herrno);                                             \
392           return -EAI_SYSTEM;                                                 \
393         }                                                                     \
394       if (herrno == TRY_AGAIN)                                                \
395         no_data = EAI_AGAIN;                                                  \
396       else                                                                    \
397         no_data = herrno == NO_DATA;                                          \
398     }                                                                         \
399   else if (h != NULL)                                                         \
400     {                                                                         \
401       for (i = 0; h->h_addr_list[i]; i++)                                     \
402         {                                                                     \
403           if (*pat == NULL) {                                                 \
404             *pat = __alloca (sizeof (struct gaih_addrtuple));                 \
405             (*pat)->scopeid = 0;                                              \
406           }                                                                   \
407           (*pat)->next = NULL;                                                \
408           (*pat)->family = _family;                                           \
409           memcpy ((*pat)->addr, h->h_addr_list[i],                            \
410                  sizeof(_type));                                              \
411           pat = &((*pat)->next);                                              \
412         }                                                                     \
413     }                                                                         \
414  }
415
416 typedef enum nss_status (*nss_gethostbyname2_r)
417   (const char *name, int af, struct hostent *host,
418    char *buffer, size_t buflen, int *errnop,
419    int *h_errnop);
420 extern service_user *__nss_hosts_database attribute_hidden;
421
422 static int
423 gaih_inet (const char *name, const struct gaih_service *service,
424            const struct addrinfo *req, struct addrinfo **pai)
425 {
426   const struct gaih_typeproto *tp = gaih_inet_typeproto;
427   struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
428   struct gaih_addrtuple *at = NULL;
429   int rc;
430   bool got_ipv6 = false;
431
432   if (req->ai_protocol || req->ai_socktype)
433     {
434       ++tp;
435
436       while (tp->name[0]
437              && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
438                  || (req->ai_protocol != 0
439                      && !(tp->protoflag & GAI_PROTO_PROTOANY)
440                      && req->ai_protocol != tp->protocol)))
441         ++tp;
442
443       if (! tp->name[0])
444         {
445           if (req->ai_socktype)
446             return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
447           else
448             return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
449         }
450     }
451
452   if (service != NULL)
453     {
454       if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
455         return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
456
457       if (service->num < 0)
458         {
459           if (tp->name[0])
460             {
461               st = (struct gaih_servtuple *)
462                 __alloca (sizeof (struct gaih_servtuple));
463
464               if ((rc = gaih_inet_serv (service->name, tp, req, st)))
465                 return rc;
466             }
467           else
468             {
469               struct gaih_servtuple **pst = &st;
470               for (tp++; tp->name[0]; tp++)
471                 {
472                   struct gaih_servtuple *newp;
473
474                   if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
475                     continue;
476
477                   if (req->ai_socktype != 0
478                       && req->ai_socktype != tp->socktype)
479                     continue;
480                   if (req->ai_protocol != 0
481                       && !(tp->protoflag & GAI_PROTO_PROTOANY)
482                       && req->ai_protocol != tp->protocol)
483                     continue;
484
485                   newp = (struct gaih_servtuple *)
486                     __alloca (sizeof (struct gaih_servtuple));
487
488                   if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
489                     {
490                       if (rc & GAIH_OKIFUNSPEC)
491                         continue;
492                       return rc;
493                     }
494
495                   *pst = newp;
496                   pst = &(newp->next);
497                 }
498               if (st == (struct gaih_servtuple *) &nullserv)
499                 return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
500             }
501         }
502       else
503         {
504           st = __alloca (sizeof (struct gaih_servtuple));
505           st->next = NULL;
506           st->socktype = tp->socktype;
507           st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
508                           ? req->ai_protocol : tp->protocol);
509           st->port = htons (service->num);
510         }
511     }
512   else if (req->ai_socktype || req->ai_protocol)
513     {
514       st = __alloca (sizeof (struct gaih_servtuple));
515       st->next = NULL;
516       st->socktype = tp->socktype;
517       st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
518                       ? req->ai_protocol : tp->protocol);
519       st->port = 0;
520     }
521   else
522     {
523       /* Neither socket type nor protocol is set.  Return all socket types
524          we know about.  */
525       struct gaih_servtuple **lastp = &st;
526       for (++tp; tp->name[0]; ++tp)
527         {
528           struct gaih_servtuple *newp;
529
530           newp = __alloca (sizeof (struct gaih_servtuple));
531           newp->next = NULL;
532           newp->socktype = tp->socktype;
533           newp->protocol = tp->protocol;
534           newp->port = 0;
535
536           *lastp = newp;
537           lastp = &newp->next;
538         }
539     }
540
541   if (name != NULL)
542     {
543       at = __alloca (sizeof (struct gaih_addrtuple));
544
545       at->family = AF_UNSPEC;
546       at->scopeid = 0;
547       at->next = NULL;
548
549 #ifdef HAVE_LIBIDN
550       if (req->ai_flags & AI_IDN)
551         {
552           int idn_flags = 0;
553           if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
554             idn_flags |= IDNA_ALLOW_UNASSIGNED;
555           if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
556             idn_flags |= IDNA_USE_STD3_ASCII_RULES;
557
558           char *p = NULL;
559           rc = __idna_to_ascii_lz (name, &p, idn_flags);
560           if (rc != IDNA_SUCCESS)
561             {
562               if (rc == IDNA_MALLOC_ERROR)
563                 return -EAI_MEMORY;
564               if (rc == IDNA_DLOPEN_ERROR)
565                 return -EAI_SYSTEM;
566               return -EAI_IDN_ENCODE;
567             }
568           /* In case the output string is the same as the input string
569              no new string has been allocated.  */
570           if (p != name)
571             {
572               name = strdupa (p);
573               free (p);
574             }
575         }
576 #endif
577
578       if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
579         {
580           if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
581             at->family = AF_INET;
582           else if (req->ai_family == AF_INET6 && req->ai_flags & AI_V4MAPPED)
583             {
584               ((uint32_t *) at->addr)[3] = *(uint32_t *) at->addr;
585               ((uint32_t *) at->addr)[2] = htonl (0xffff);
586               ((uint32_t *) at->addr)[1] = 0;
587               ((uint32_t *) at->addr)[0] = 0;
588               at->family = AF_INET6;
589             }
590           else
591             return -EAI_ADDRFAMILY;
592         }
593
594       if (at->family == AF_UNSPEC)
595         {
596           char *namebuf = strdupa (name);
597           char *scope_delim;
598
599           scope_delim = strchr (namebuf, SCOPE_DELIMITER);
600           if (scope_delim != NULL)
601             *scope_delim = '\0';
602
603           if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
604             {
605               if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
606                 at->family = AF_INET6;
607               else if (IN6_IS_ADDR_V4MAPPED (at->addr))
608                 *(uint32_t *) at->addr = ((uint32_t *) at->addr)[3];
609               else
610                 return -EAI_ADDRFAMILY;
611
612               if (scope_delim != NULL)
613                 {
614                   int try_numericscope = 0;
615                   if (IN6_IS_ADDR_LINKLOCAL (at->addr)
616                       || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
617                     {
618                       at->scopeid = if_nametoindex (scope_delim + 1);
619                       if (at->scopeid == 0)
620                         try_numericscope = 1;
621                     }
622                   else
623                     try_numericscope = 1;
624
625                   if (try_numericscope != 0)
626                     {
627                       char *end;
628                       assert (sizeof (uint32_t) <= sizeof (unsigned long));
629                       at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
630                                                         10);
631                       if (*end != '\0')
632                         return GAIH_OKIFUNSPEC | -EAI_NONAME;
633                     }
634                 }
635             }
636         }
637
638       if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
639         {
640           struct hostent *h;
641           struct gaih_addrtuple **pat = &at;
642           int no_data = 0;
643           int no_inet6_data = 0;
644           /* If we are looking for both IPv4 and IPv6 address we don't
645              want the lookup functions to automatically promote IPv4
646              addresses to IPv6 addresses.  Currently this is decided
647              by setting the RES_USE_INET6 bit in _res.options.  */
648           if (req->ai_family == AF_UNSPEC)
649             {
650               service_user *nip = NULL;
651               enum nss_status inet6_status, status = NSS_STATUS_UNAVAIL;
652               int no_more;
653               nss_gethostbyname2_r fct;
654               int old_res_options;
655
656               if (__nss_hosts_database != NULL)
657                 {
658                   no_more = 0;
659                   nip = __nss_hosts_database;
660                 }
661               else
662                 no_more = __nss_database_lookup ("hosts", NULL,
663                                                  "dns [!UNAVAIL=return] files", &nip);
664
665               if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1)
666                 no_more = 1;
667               old_res_options = _res.options;
668               _res.options &= ~RES_USE_INET6;
669
670               while (!no_more)
671                 {
672                   fct = __nss_lookup_function (nip, "gethostbyname2_r");
673
674                   if (fct != NULL)
675                     {
676                       gethosts2 (AF_INET6, struct in6_addr);
677                       no_inet6_data = no_data;
678                       inet6_status = status;
679                       gethosts2 (AF_INET, struct in_addr);
680
681                       /* If we found one address for AF_INET or AF_INET6,
682                          don't continue the search.  */
683                       if (inet6_status == NSS_STATUS_SUCCESS ||
684                           status == NSS_STATUS_SUCCESS)
685                         break;
686
687                       /* We can have different states for AF_INET
688                          and AF_INET6. Try to find a usefull one for
689                          both.  */
690                       if (inet6_status == NSS_STATUS_TRYAGAIN)
691                         status = NSS_STATUS_TRYAGAIN;
692                       else if (status == NSS_STATUS_UNAVAIL &&
693                                inet6_status != NSS_STATUS_UNAVAIL)
694                         status = inet6_status;
695                     }
696
697                   if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
698                     break;
699
700                   if (nip->next == NULL)
701                     no_more = -1;
702                   else
703                     nip = nip->next;
704                 }
705
706               _res.options = old_res_options;
707             }
708           else if (req->ai_family == AF_INET6)
709             {
710               gethosts (AF_INET6, struct in6_addr);
711               no_inet6_data = no_data;
712             }
713           else if (req->ai_family == AF_INET)
714             {
715               gethosts (AF_INET, struct in_addr);
716               no_inet6_data = no_data;
717             }
718
719           if (no_data != 0 && no_inet6_data != 0)
720             {
721               /* If both requests timed out report this.  */
722               if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
723                 return -EAI_AGAIN;
724
725               /* We made requests but they turned out no data.  The name
726                  is known, though.  */
727               return (GAIH_OKIFUNSPEC | -EAI_NODATA);
728             }
729         }
730
731       if (at->family == AF_UNSPEC)
732         return (GAIH_OKIFUNSPEC | -EAI_NONAME);
733     }
734   else
735     {
736       struct gaih_addrtuple *atr;
737       atr = at = __alloca (sizeof (struct gaih_addrtuple));
738       memset (at, '\0', sizeof (struct gaih_addrtuple));
739
740       if (req->ai_family == 0)
741         {
742           at->next = __alloca (sizeof (struct gaih_addrtuple));
743           memset (at->next, '\0', sizeof (struct gaih_addrtuple));
744         }
745
746       if (req->ai_family == 0 || req->ai_family == AF_INET6)
747         {
748           at->family = AF_INET6;
749           if ((req->ai_flags & AI_PASSIVE) == 0)
750             memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
751           atr = at->next;
752         }
753
754       if (req->ai_family == 0 || req->ai_family == AF_INET)
755         {
756           atr->family = AF_INET;
757           if ((req->ai_flags & AI_PASSIVE) == 0)
758             *(uint32_t *) atr->addr = htonl (INADDR_LOOPBACK);
759         }
760     }
761
762   if (pai == NULL)
763     return 0;
764
765   {
766     struct gaih_servtuple *st2;
767     struct gaih_addrtuple *at2 = at;
768     size_t socklen, namelen;
769     sa_family_t family;
770
771     /*
772       buffer is the size of an unformatted IPv6 address in printable format.
773      */
774     while (at2 != NULL)
775       {
776         const char *c = NULL;
777
778         /* Only the first entry gets the canonical name.  */
779         if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
780           {
781             struct hostent *h = NULL;
782
783             int herrno;
784             struct hostent th;
785             size_t tmpbuflen = 512;
786             char *tmpbuf = NULL;
787
788             do
789               {
790                 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
791                 rc = __gethostbyaddr_r (at2->addr,
792                                         ((at2->family == AF_INET6)
793                                          ? sizeof(struct in6_addr)
794                                          : sizeof(struct in_addr)),
795                                         at2->family, &th, tmpbuf, tmpbuflen,
796                                         &h, &herrno);
797
798               }
799             while (rc == ERANGE && herrno == NETDB_INTERNAL);
800
801             if (rc != 0 && herrno == NETDB_INTERNAL)
802               {
803                 __set_h_errno (herrno);
804                 return -EAI_SYSTEM;
805               }
806
807             if (h != NULL)
808               c = h->h_name;
809             else
810               {
811                 /* We have to try to get the canonical in some other
812                    way.  If we are looking for either AF_INET or
813                    AF_INET6 try the other line.  */
814                 if (req->ai_family == AF_UNSPEC)
815                   {
816                     struct addrinfo *p = NULL;
817                     struct addrinfo **end = &p;
818                     struct addrinfo localreq = *req;
819                     struct addrinfo *runp;
820
821                     localreq.ai_family = AF_INET + AF_INET6 - at2->family;
822                     (void) gaih_inet (name, service, &localreq, end);
823
824                     runp = p;
825                     while (runp != NULL)
826                       {
827                         if (p->ai_canonname != name)
828                           {
829                             c = strdupa (p->ai_canonname);
830                             break;
831                           }
832                         runp = runp->ai_next;
833                       }
834
835                     freeaddrinfo (p);
836                   }
837
838                 /* If this code is used the missing canonical name is
839                    substituted with the name passed in by the user.  */
840                 if (c == NULL)
841                   c = name;
842               }
843
844             if (c == NULL)
845               return GAIH_OKIFUNSPEC | -EAI_NONAME;
846
847 #ifdef HAVE_LIBIDN
848             if (req->ai_flags & AI_CANONIDN)
849               {
850                 int idn_flags = 0;
851                 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
852                   idn_flags |= IDNA_ALLOW_UNASSIGNED;
853                 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
854                   idn_flags |= IDNA_USE_STD3_ASCII_RULES;
855
856                 char *out;
857                 int rc = __idna_to_unicode_lzlz (c, &out, idn_flags);
858                 if (rc != IDNA_SUCCESS)
859                   {
860                     if (rc == IDNA_MALLOC_ERROR)
861                       return -EAI_MEMORY;
862                     if (rc == IDNA_DLOPEN_ERROR)
863                       return -EAI_SYSTEM;
864                     return -EAI_IDN_ENCODE;
865                   }
866                 /* In case the output string is the same as the input
867                    string no new string has been allocated.  */
868                 if (out != c)
869                   {
870                     c = strdupa (out);
871                     free (out);
872                   }
873               }
874 #endif
875
876             namelen = strlen (c) + 1;
877           }
878         else
879           namelen = 0;
880
881         if (at2->family == AF_INET6)
882           {
883             family = AF_INET6;
884             socklen = sizeof (struct sockaddr_in6);
885
886             /* If we looked up IPv4 mapped address discard them here if
887                the caller isn't interested in all address and we have
888                found at least one IPv6 address.  */
889             if (! got_ipv6
890                 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
891                 && IN6_IS_ADDR_V4MAPPED (at2->addr))
892               goto ignore;
893           }
894         else
895           {
896             family = AF_INET;
897             socklen = sizeof (struct sockaddr_in);
898           }
899
900         for (st2 = st; st2 != NULL; st2 = st2->next)
901           {
902             *pai = malloc (sizeof (struct addrinfo) + socklen + namelen);
903             if (*pai == NULL)
904               return -EAI_MEMORY;
905
906             (*pai)->ai_flags = req->ai_flags;
907             (*pai)->ai_family = family;
908             (*pai)->ai_socktype = st2->socktype;
909             (*pai)->ai_protocol = st2->protocol;
910             (*pai)->ai_addrlen = socklen;
911             (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
912 #if SALEN
913             (*pai)->ai_addr->sa_len = socklen;
914 #endif /* SALEN */
915             (*pai)->ai_addr->sa_family = family;
916
917             if (family == AF_INET6)
918               {
919                 struct sockaddr_in6 *sin6p =
920                   (struct sockaddr_in6 *) (*pai)->ai_addr;
921
922                 sin6p->sin6_flowinfo = 0;
923                 memcpy (&sin6p->sin6_addr,
924                         at2->addr, sizeof (struct in6_addr));
925                 sin6p->sin6_port = st2->port;
926                 sin6p->sin6_scope_id = at2->scopeid;
927               }
928             else
929               {
930                 struct sockaddr_in *sinp =
931                   (struct sockaddr_in *) (*pai)->ai_addr;
932                 memcpy (&sinp->sin_addr,
933                         at2->addr, sizeof (struct in_addr));
934                 sinp->sin_port = st2->port;
935                 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
936               }
937
938             if (c)
939               {
940                 (*pai)->ai_canonname = ((void *) (*pai) +
941                                         sizeof (struct addrinfo) + socklen);
942                 strcpy ((*pai)->ai_canonname, c);
943               }
944             else
945               (*pai)->ai_canonname = NULL;
946
947             (*pai)->ai_next = NULL;
948             pai = &((*pai)->ai_next);
949           }
950
951       ignore:
952         at2 = at2->next;
953       }
954   }
955   return 0;
956 }
957
958 static struct gaih gaih[] =
959   {
960     { PF_INET6, gaih_inet },
961     { PF_INET, gaih_inet },
962 #if 0
963     { PF_LOCAL, gaih_local },
964 #endif
965     { PF_UNSPEC, NULL }
966   };
967
968 struct sort_result
969 {
970   struct addrinfo *dest_addr;
971   struct sockaddr_storage source_addr;
972   bool got_source_addr;
973 };
974
975
976 static int
977 get_scope (const struct sockaddr_storage *ss)
978 {
979   int scope;
980   if (ss->ss_family == PF_INET6)
981     {
982       const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss;
983
984       if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
985         {
986           if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
987             scope = 2;
988           else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
989             scope = 5;
990           else
991             /* XXX Is this the correct default behavior?  */
992             scope = 14;
993         }
994       else
995         scope = in6->sin6_addr.s6_addr[1] & 0xf;
996     }
997   else if (ss->ss_family == PF_INET)
998     {
999       const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
1000       const uint8_t *addr = (const uint8_t *) &in->sin_addr;
1001
1002       /* RFC 3484 specifies how to map IPv6 addresses to scopes.
1003          169.254/16 and 127/8 are link-local.  */
1004       if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
1005         scope = 2;
1006       else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16)
1007                || (addr[0] == 192 && addr[1] == 168))
1008         scope = 5;
1009       else
1010         scope = 14;
1011     }
1012   else
1013     /* XXX What is a good default?  */
1014     scope = 15;
1015
1016   return scope;
1017 }
1018
1019
1020 /* XXX The system administrator should be able to install other
1021    tables.  We need to make this configurable.  The problem is that
1022    the kernel is also involved since it needs the same table.  */
1023 static const struct prefixlist
1024 {
1025   struct in6_addr prefix;
1026   unsigned int bits;
1027   int val;
1028 } default_labels[] =
1029   {
1030     /* See RFC 3484 for the details.  */
1031     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1032                                   0x0000, 0x0000, 0x0000, 0x0001 } } },
1033       128, 0 },
1034     { { .in6_u = { .u6_addr16 = { 0x2002, 0x0000, 0x0000, 0x0000,
1035                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1036       16, 2 },
1037     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1038                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1039       96, 3 },
1040     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1041                                   0x0000, 0xffff, 0x0000, 0x0000 } } },
1042       96, 4 },
1043     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1044                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1045       0, 1 }
1046   };
1047
1048
1049 static const struct prefixlist default_precedence[] =
1050   {
1051     /* See RFC 3484 for the details.  */
1052     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1053                                   0x0000, 0x0000, 0x0000, 0x0001 } } },
1054       128, 50 },
1055     { { .in6_u = { .u6_addr16 = { 0x2002, 0x0000, 0x0000, 0x0000,
1056                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1057       16, 30 },
1058     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1059                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1060       96, 20 },
1061     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1062                                   0x0000, 0xffff, 0x0000, 0x0000 } } },
1063       96, 10 },
1064     { { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
1065                                   0x0000, 0x0000, 0x0000, 0x0000 } } },
1066       0, 40 }
1067   };
1068
1069
1070 static int
1071 match_prefix (const struct sockaddr_storage *ss, const struct prefixlist *list,
1072               int default_val)
1073 {
1074   int idx;
1075   struct sockaddr_in6 in6_mem;
1076   const struct sockaddr_in6 *in6;
1077
1078   if (ss->ss_family == PF_INET6)
1079     in6 = (const struct sockaddr_in6 *) ss;
1080   else if (ss->ss_family == PF_INET)
1081     {
1082       const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
1083
1084       /* Convert to IPv6 address.  */
1085       in6_mem.sin6_family = PF_INET6;
1086       in6_mem.sin6_port = in->sin_port;
1087       in6_mem.sin6_flowinfo = 0;
1088       if (in->sin_addr.s_addr == htonl (0x7f000001))
1089         in6_mem.sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
1090       else
1091         {
1092           /* Construct a V4-to-6 mapped address.  */
1093           memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1094           in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1095           in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1096           in6_mem.sin6_scope_id = 0;
1097         }
1098
1099       in6 = &in6_mem;
1100     }
1101   else
1102     return default_val;
1103
1104   for (idx = 0; ; ++idx)
1105     {
1106       unsigned int bits = list[idx].bits;
1107       uint8_t *mask = list[idx].prefix.s6_addr;
1108       uint8_t *val = in6->sin6_addr.s6_addr;
1109
1110       while (bits > 8)
1111         {
1112           if (*mask != *val)
1113             break;
1114
1115           ++mask;
1116           ++val;
1117           bits -= 8;
1118         }
1119
1120       if (bits < 8)
1121         {
1122           if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1123             /* Match!  */
1124             break;
1125         }
1126     }
1127
1128   return list[idx].val;
1129 }
1130
1131
1132 static int
1133 get_label (const struct sockaddr_storage *ss)
1134 {
1135   /* XXX What is a good default value?  */
1136   return match_prefix (ss, default_labels, INT_MAX);
1137 }
1138
1139
1140 static int
1141 get_precedence (const struct sockaddr_storage *ss)
1142 {
1143   /* XXX What is a good default value?  */
1144   return match_prefix (ss, default_precedence, 0);
1145 }
1146
1147
1148 static int
1149 rfc3484_sort (const void *p1, const void *p2)
1150 {
1151   const struct sort_result *a1 = (const struct sort_result *) p1;
1152   const struct sort_result *a2 = (const struct sort_result *) p2;
1153
1154   /* Rule 1: Avoid unusable destinations.
1155      We have the got_source_addr flag set if the destination is reachable.  */
1156   if (a1->got_source_addr && ! a2->got_source_addr)
1157     return -1;
1158   if (! a1->got_source_addr && a2->got_source_addr)
1159     return 1;
1160
1161
1162   /* Rule 2: Prefer matching scope.  Only interesting if both
1163      destination addresses are IPv6.  */
1164   int a1_dst_scope
1165     = get_scope ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1166
1167   int a2_dst_scope
1168     = get_scope ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1169
1170   if (a1->got_source_addr)
1171     {
1172       int a1_src_scope = get_scope (&a1->source_addr);
1173       int a2_src_scope = get_scope (&a2->source_addr);
1174
1175       if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1176         return -1;
1177       if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1178         return 1;
1179     }
1180
1181
1182   /* Rule 3: Avoid deprecated addresses.
1183      That's something only the kernel could decide.  */
1184
1185   /* Rule 4: Prefer home addresses.
1186      Another thing only the kernel can decide.  */
1187
1188   /* Rule 5: Prefer matching label.  */
1189   if (a1->got_source_addr)
1190     {
1191       int a1_dst_label
1192         = get_label ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1193       int a1_src_label = get_label (&a1->source_addr);
1194
1195       int a2_dst_label
1196         = get_label ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1197       int a2_src_label = get_label (&a2->source_addr);
1198
1199       if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1200         return -1;
1201       if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1202         return 1;
1203     }
1204
1205
1206   /* Rule 6: Prefer higher precedence.  */
1207   int a1_prec
1208     = get_precedence ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
1209   int a2_prec
1210     = get_precedence ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
1211
1212   if (a1_prec > a2_prec)
1213     return -1;
1214   if (a1_prec < a2_prec)
1215     return 1;
1216
1217
1218   /* Rule 7: Prefer native transport.
1219      XXX How to recognize tunnels?  */
1220
1221
1222   /* Rule 8: Prefer smaller scope.  */
1223   if (a1_dst_scope < a2_dst_scope)
1224     return -1;
1225   if (a1_dst_scope > a2_dst_scope)
1226     return 1;
1227
1228
1229   /* Rule 9: Use longest matching prefix.  */
1230   if (a1->got_source_addr
1231       && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1232     {
1233       int bit1 = 0;
1234       int bit2 = 0;
1235
1236       if (a1->dest_addr->ai_family == PF_INET)
1237         {
1238           assert (a1->source_addr.ss_family == PF_INET);
1239           assert (a2->source_addr.ss_family == PF_INET);
1240
1241           struct sockaddr_in *in1_dst;
1242           struct sockaddr_in *in1_src;
1243           struct sockaddr_in *in2_dst;
1244           struct sockaddr_in *in2_src;
1245
1246           in1_dst = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1247           in1_src = (struct sockaddr_in *) &a1->source_addr;
1248           in2_dst = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1249           in2_src = (struct sockaddr_in *) &a2->source_addr;
1250
1251           bit1 = ffs (in1_dst->sin_addr.s_addr ^ in1_src->sin_addr.s_addr);
1252           bit2 = ffs (in2_dst->sin_addr.s_addr ^ in2_src->sin_addr.s_addr);
1253         }
1254       else if (a1->dest_addr->ai_family == PF_INET6)
1255         {
1256           assert (a1->source_addr.ss_family == PF_INET6);
1257           assert (a2->source_addr.ss_family == PF_INET6);
1258
1259           struct sockaddr_in6 *in1_dst;
1260           struct sockaddr_in6 *in1_src;
1261           struct sockaddr_in6 *in2_dst;
1262           struct sockaddr_in6 *in2_src;
1263
1264           in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1265           in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1266           in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1267           in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1268
1269           int i;
1270           for (i = 0; i < 4; ++i)
1271             if (in1_dst->sin6_addr.s6_addr32[i]
1272                 != in1_src->sin6_addr.s6_addr32[i]
1273                 || (in2_dst->sin6_addr.s6_addr32[i]
1274                     != in2_src->sin6_addr.s6_addr32[i]))
1275               break;
1276
1277           if (i < 4)
1278             {
1279               bit1 = ffs (in1_dst->sin6_addr.s6_addr32[i]
1280                           ^ in1_src->sin6_addr.s6_addr32[i]);
1281               bit2 = ffs (in2_dst->sin6_addr.s6_addr32[i]
1282                           ^ in2_src->sin6_addr.s6_addr32[i]);
1283             }
1284         }
1285
1286       if (bit1 > bit2)
1287         return -1;
1288       if (bit1 < bit2)
1289         return 1;
1290     }
1291
1292
1293   /* Rule 10: Otherwise, leave the order unchanged.  */
1294   return 0;
1295 }
1296
1297
1298 int
1299 getaddrinfo (const char *name, const char *service,
1300              const struct addrinfo *hints, struct addrinfo **pai)
1301 {
1302   int i = 0, j = 0, last_i = 0;
1303   int nresults = 0;
1304   struct addrinfo *p = NULL, **end;
1305   struct gaih *g = gaih, *pg = NULL;
1306   struct gaih_service gaih_service, *pservice;
1307   struct addrinfo local_hints;
1308
1309   if (name != NULL && name[0] == '*' && name[1] == 0)
1310     name = NULL;
1311
1312   if (service != NULL && service[0] == '*' && service[1] == 0)
1313     service = NULL;
1314
1315   if (name == NULL && service == NULL)
1316     return EAI_NONAME;
1317
1318   if (hints == NULL)
1319     hints = &default_hints;
1320
1321   if (hints->ai_flags
1322       & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
1323 #ifdef HAVE_LIBIDN
1324           |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
1325           |AI_IDN_USE_STD3_ASCII_RULES
1326 #endif
1327           |AI_NUMERICSERV|AI_ALL))
1328     return EAI_BADFLAGS;
1329
1330   if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
1331     return EAI_BADFLAGS;
1332
1333   if (hints->ai_flags & AI_ADDRCONFIG)
1334     {
1335       /* Determine whether we have IPv4 or IPv6 interfaces or both.
1336          We cannot cache the results since new interfaces could be
1337          added at any time.  */
1338       bool seen_ipv4;
1339       bool seen_ipv6;
1340       __check_pf (&seen_ipv4, &seen_ipv6);
1341
1342       /* Now make a decision on what we return, if anything.  */
1343       if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
1344         {
1345           /* If we haven't seen both IPv4 and IPv6 interfaces we can
1346              narrow down the search.  */
1347           if (! seen_ipv4 || ! seen_ipv6)
1348             {
1349               local_hints = *hints;
1350               local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
1351               hints = &local_hints;
1352             }
1353         }
1354       else if ((hints->ai_family == PF_INET && ! seen_ipv4)
1355                || (hints->ai_family == PF_INET6 && ! seen_ipv6))
1356         /* We cannot possibly return a valid answer.  */
1357         return EAI_NONAME;
1358     }
1359
1360   if (service && service[0])
1361     {
1362       char *c;
1363       gaih_service.name = service;
1364       gaih_service.num = strtoul (gaih_service.name, &c, 10);
1365       if (*c != '\0')
1366         {
1367           if (hints->ai_flags & AI_NUMERICSERV)
1368             return EAI_NONAME;
1369
1370           gaih_service.num = -1;
1371         }
1372       else
1373         /* Can't specify a numerical socket unless a protocol family was
1374            given. */
1375         if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
1376           return EAI_SERVICE;
1377       pservice = &gaih_service;
1378     }
1379   else
1380     pservice = NULL;
1381
1382   if (pai)
1383     end = &p;
1384   else
1385     end = NULL;
1386
1387   while (g->gaih)
1388     {
1389       if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
1390         {
1391           j++;
1392           if (pg == NULL || pg->gaih != g->gaih)
1393             {
1394               pg = g;
1395               i = g->gaih (name, pservice, hints, end);
1396               if (i != 0)
1397                 {
1398                   /* EAI_NODATA is a more specific result as it says that
1399                      we found a result but it is not usable.  */
1400                   if (last_i != (GAIH_OKIFUNSPEC | -EAI_NODATA))
1401                     last_i = i;
1402
1403                   if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
1404                     {
1405                       ++g;
1406                       continue;
1407                     }
1408
1409                   freeaddrinfo (p);
1410
1411                   return -(i & GAIH_EAI);
1412                 }
1413               if (end)
1414                 while (*end)
1415                   {
1416                     end = &((*end)->ai_next);
1417                     ++nresults;
1418                   }
1419             }
1420         }
1421       ++g;
1422     }
1423
1424   if (j == 0)
1425     return EAI_FAMILY;
1426
1427   if (nresults > 1)
1428     {
1429       /* Sort results according to RFC 3484.  */
1430       struct sort_result results[nresults];
1431       struct addrinfo *q;
1432
1433       for (i = 0, q = p; q != NULL; ++i, q = q->ai_next)
1434         {
1435           results[i].dest_addr = q;
1436           results[i].got_source_addr = false;
1437
1438           /* We overwrite the type with SOCK_DGRAM since we do not
1439              want connect() to connect to the other side.  If we
1440              cannot determine the source address remember this
1441              fact.  */
1442           int fd = __socket (q->ai_family, SOCK_DGRAM, IPPROTO_IP);
1443           if (fd != -1)
1444             {
1445               socklen_t sl = sizeof (results[i].source_addr);
1446               if (__connect (fd, q->ai_addr, q->ai_addrlen) == 0
1447                   && __getsockname (fd,
1448                                     (struct sockaddr *) &results[i].source_addr,
1449                                     &sl) == 0)
1450                 results[i].got_source_addr = true;
1451
1452               close_not_cancel_no_status (fd);
1453             }
1454         }
1455
1456       /* We got all the source addresses we can get, now sort using
1457          the information.  */
1458       qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
1459
1460       /* Queue the results up as they come out of sorting.  */
1461       q = p = results[0].dest_addr;
1462       for (i = 1; i < nresults; ++i)
1463         q = q->ai_next = results[i].dest_addr;
1464       q->ai_next = NULL;
1465     }
1466
1467   if (p)
1468     {
1469       *pai = p;
1470       return 0;
1471     }
1472
1473   if (pai == NULL && last_i == 0)
1474     return 0;
1475
1476   return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
1477 }
1478 libc_hidden_def (getaddrinfo)
1479
1480 static_link_warning (getaddrinfo)
1481
1482 void
1483 freeaddrinfo (struct addrinfo *ai)
1484 {
1485   struct addrinfo *p;
1486
1487   while (ai != NULL)
1488     {
1489       p = ai;
1490       ai = ai->ai_next;
1491       free (p);
1492     }
1493 }
1494 libc_hidden_def (freeaddrinfo)