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