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