Android: small changes to dns property part.
[platform/upstream/c-ares.git] / ares_init.c
1
2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3  * Copyright (C) 2007-2012 by Daniel Stenberg
4  *
5  * Permission to use, copy, modify, and distribute this
6  * software and its documentation for any purpose and without
7  * fee is hereby granted, provided that the above copyright
8  * notice appear in all copies and that both that copyright
9  * notice and this permission notice appear in supporting
10  * documentation, and that the name of M.I.T. not be used in
11  * advertising or publicity pertaining to distribution of the
12  * software without specific, written prior permission.
13  * M.I.T. makes no representations about the suitability of
14  * this software for any purpose.  It is provided "as is"
15  * without express or implied warranty.
16  */
17
18 #include "ares_setup.h"
19
20 #ifdef HAVE_SYS_PARAM_H
21 #include <sys/param.h>
22 #endif
23
24 #ifdef HAVE_SYS_TIME_H
25 #include <sys/time.h>
26 #endif
27
28 #ifdef HAVE_SYS_SOCKET_H
29 #include <sys/socket.h>
30 #endif
31
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
34 #endif
35
36 #ifdef HAVE_NETDB_H
37 #include <netdb.h>
38 #endif
39
40 #ifdef HAVE_ARPA_INET_H
41 #include <arpa/inet.h>
42 #endif
43
44 #ifdef HAVE_ARPA_NAMESER_H
45 #  include <arpa/nameser.h>
46 #else
47 #  include "nameser.h"
48 #endif
49 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
50 #  include <arpa/nameser_compat.h>
51 #endif
52
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <ctype.h>
61 #include <time.h>
62
63 #if defined(ANDROID) || defined(__ANDROID__)
64 #include <sys/system_properties.h>
65 /* From the Bionic sources */
66 #define DNS_PROP_NAME_PREFIX  "net.dns"
67 #define MAX_DNS_PROPERTIES    8
68 #endif
69
70 #include "ares.h"
71 #include "inet_ntop.h"
72 #include "inet_net_pton.h"
73 #include "ares_library_init.h"
74 #include "ares_nowarn.h"
75 #include "ares_platform.h"
76 #include "ares_private.h"
77
78 #ifdef WATT32
79 #undef WIN32  /* Redefined in MingW/MSVC headers */
80 #endif
81
82 static int init_by_options(ares_channel channel,
83                            const struct ares_options *options,
84                            int optmask);
85 static int init_by_environment(ares_channel channel);
86 static int init_by_resolv_conf(ares_channel channel);
87 static int init_by_defaults(ares_channel channel);
88
89 #ifndef WATT32
90 static int config_nameserver(struct server_state **servers, int *nservers,
91                              char *str);
92 #endif
93 static int set_search(ares_channel channel, const char *str);
94 static int set_options(ares_channel channel, const char *str);
95 static const char *try_option(const char *p, const char *q, const char *opt);
96 static int init_id_key(rc4_key* key,int key_data_len);
97
98 #if !defined(WIN32) && !defined(WATT32) && \
99     !defined(ANDROID) && !defined(__ANDROID__)
100 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
101                           struct apattern *pat);
102 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
103 static void natural_mask(struct apattern *pat);
104 static int config_domain(ares_channel channel, char *str);
105 static int config_lookup(ares_channel channel, const char *str,
106                          const char *bindch, const char *filech);
107 static int config_sortlist(struct apattern **sortlist, int *nsort,
108                            const char *str);
109 static char *try_config(char *s, const char *opt, char scc);
110 #endif
111
112 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
113                              x->nservers > -1 && \
114                              x->ndomains > -1 && \
115                              x->ndots > -1 && x->timeout > -1 && \
116                              x->tries > -1)
117
118 int ares_init(ares_channel *channelptr)
119 {
120   return ares_init_options(channelptr, NULL, 0);
121 }
122
123 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
124                       int optmask)
125 {
126   ares_channel channel;
127   int i;
128   int status = ARES_SUCCESS;
129   struct timeval now;
130
131 #ifdef CURLDEBUG
132   const char *env = getenv("CARES_MEMDEBUG");
133
134   if (env)
135     curl_memdebug(env);
136   env = getenv("CARES_MEMLIMIT");
137   if (env) {
138     char *endptr;
139     long num = strtol(env, &endptr, 10);
140     if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
141       curl_memlimit(num);
142   }
143 #endif
144
145   if (ares_library_initialized() != ARES_SUCCESS)
146     return ARES_ENOTINITIALIZED;
147
148   channel = malloc(sizeof(struct ares_channeldata));
149   if (!channel) {
150     *channelptr = NULL;
151     return ARES_ENOMEM;
152   }
153
154   now = ares__tvnow();
155
156   /* Set everything to distinguished values so we know they haven't
157    * been set yet.
158    */
159   channel->flags = -1;
160   channel->timeout = -1;
161   channel->tries = -1;
162   channel->ndots = -1;
163   channel->rotate = -1;
164   channel->udp_port = -1;
165   channel->tcp_port = -1;
166   channel->socket_send_buffer_size = -1;
167   channel->socket_receive_buffer_size = -1;
168   channel->nservers = -1;
169   channel->ndomains = -1;
170   channel->nsort = -1;
171   channel->tcp_connection_generation = 0;
172   channel->lookups = NULL;
173   channel->domains = NULL;
174   channel->sortlist = NULL;
175   channel->servers = NULL;
176   channel->sock_state_cb = NULL;
177   channel->sock_state_cb_data = NULL;
178   channel->sock_create_cb = NULL;
179   channel->sock_create_cb_data = NULL;
180
181   channel->last_server = 0;
182   channel->last_timeout_processed = (time_t)now.tv_sec;
183
184   memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
185   channel->local_ip4 = 0;
186   memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
187
188   /* Initialize our lists of queries */
189   ares__init_list_head(&(channel->all_queries));
190   for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
191     {
192       ares__init_list_head(&(channel->queries_by_qid[i]));
193     }
194   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
195     {
196       ares__init_list_head(&(channel->queries_by_timeout[i]));
197     }
198
199   /* Initialize configuration by each of the four sources, from highest
200    * precedence to lowest.
201    */
202
203   if (status == ARES_SUCCESS) {
204     status = init_by_options(channel, options, optmask);
205     if (status != ARES_SUCCESS)
206       DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
207                      ares_strerror(status)));
208   }
209   if (status == ARES_SUCCESS) {
210     status = init_by_environment(channel);
211     if (status != ARES_SUCCESS)
212       DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
213                      ares_strerror(status)));
214   }
215   if (status == ARES_SUCCESS) {
216     status = init_by_resolv_conf(channel);
217     if (status != ARES_SUCCESS)
218       DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
219                      ares_strerror(status)));
220   }
221
222   /*
223    * No matter what failed or succeeded, seed defaults to provide
224    * useful behavior for things that we missed.
225    */
226   status = init_by_defaults(channel);
227   if (status != ARES_SUCCESS)
228     DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
229                    ares_strerror(status)));
230
231   /* Generate random key */
232
233   if (status == ARES_SUCCESS) {
234     status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
235     if (status == ARES_SUCCESS)
236       channel->next_id = ares__generate_new_id(&channel->id_key);
237     else
238       DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
239                      ares_strerror(status)));
240   }
241
242   if (status != ARES_SUCCESS)
243     {
244       /* Something failed; clean up memory we may have allocated. */
245       if (channel->servers)
246         free(channel->servers);
247       if (channel->domains)
248         {
249           for (i = 0; i < channel->ndomains; i++)
250             free(channel->domains[i]);
251           free(channel->domains);
252         }
253       if (channel->sortlist)
254         free(channel->sortlist);
255       if(channel->lookups)
256         free(channel->lookups);
257       free(channel);
258       return status;
259     }
260
261   /* Trim to one server if ARES_FLAG_PRIMARY is set. */
262   if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
263     channel->nservers = 1;
264
265   ares__init_servers_state(channel);
266
267   *channelptr = channel;
268   return ARES_SUCCESS;
269 }
270
271 /* ares_dup() duplicates a channel handle with all its options and returns a
272    new channel handle */
273 int ares_dup(ares_channel *dest, ares_channel src)
274 {
275   struct ares_options opts;
276   struct ares_addr_node *servers;
277   int ipv6_nservers = 0;
278   int i, rc;
279   int optmask;
280
281   *dest = NULL; /* in case of failure return NULL explicitly */
282
283   /* First get the options supported by the old ares_save_options() function,
284      which is most of them */
285   rc = ares_save_options(src, &opts, &optmask);
286   if(rc)
287     return rc;
288
289   /* Then create the new channel with those options */
290   rc = ares_init_options(dest, &opts, optmask);
291
292   /* destroy the options copy to not leak any memory */
293   ares_destroy_options(&opts);
294
295   if(rc)
296     return rc;
297
298   /* Now clone the options that ares_save_options() doesn't support. */
299   (*dest)->sock_create_cb      = src->sock_create_cb;
300   (*dest)->sock_create_cb_data = src->sock_create_cb_data;
301
302   strncpy((*dest)->local_dev_name, src->local_dev_name,
303           sizeof(src->local_dev_name));
304   (*dest)->local_ip4 = src->local_ip4;
305   memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
306
307   /* Full name server cloning required when not all are IPv4 */
308   for (i = 0; i < src->nservers; i++)
309     {
310       if (src->servers[i].addr.family != AF_INET) {
311         ipv6_nservers++;
312         break;
313       }
314     }
315   if (ipv6_nservers) {
316     rc = ares_get_servers(src, &servers);
317     if (rc != ARES_SUCCESS)
318       return rc;
319     rc = ares_set_servers(*dest, servers);
320     ares_free_data(servers);
321     if (rc != ARES_SUCCESS)
322       return rc;
323   }
324
325   return ARES_SUCCESS; /* everything went fine */
326 }
327
328 /* Save options from initialized channel */
329 int ares_save_options(ares_channel channel, struct ares_options *options,
330                       int *optmask)
331 {
332   int i, j;
333   int ipv4_nservers = 0;
334
335   /* Zero everything out */
336   memset(options, 0, sizeof(struct ares_options));
337
338   if (!ARES_CONFIG_CHECK(channel))
339     return ARES_ENODATA;
340
341   /* Traditionally the optmask wasn't saved in the channel struct so it was
342      recreated here. ROTATE is the first option that has no struct field of
343      its own in the public config struct */
344   (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
345                 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
346                 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
347                 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
348     (channel->optmask & ARES_OPT_ROTATE);
349
350   /* Copy easy stuff */
351   options->flags   = channel->flags;
352
353   /* We return full millisecond resolution but that's only because we don't
354      set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
355   options->timeout = channel->timeout;
356   options->tries   = channel->tries;
357   options->ndots   = channel->ndots;
358   options->udp_port = (unsigned short)channel->udp_port;
359   options->tcp_port = (unsigned short)channel->tcp_port;
360   options->sock_state_cb     = channel->sock_state_cb;
361   options->sock_state_cb_data = channel->sock_state_cb_data;
362
363   /* Copy IPv4 servers */
364   if (channel->nservers) {
365     for (i = 0; i < channel->nservers; i++)
366     {
367       if (channel->servers[i].addr.family == AF_INET)
368         ipv4_nservers++;
369     }
370     if (ipv4_nservers) {
371       options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
372       if (!options->servers)
373         return ARES_ENOMEM;
374       for (i = j = 0; i < channel->nservers; i++)
375       {
376         if (channel->servers[i].addr.family == AF_INET)
377           memcpy(&options->servers[j++],
378                  &channel->servers[i].addr.addrV4,
379                  sizeof(channel->servers[i].addr.addrV4));
380       }
381     }
382   }
383   options->nservers = ipv4_nservers;
384
385   /* copy domains */
386   if (channel->ndomains) {
387     options->domains = malloc(channel->ndomains * sizeof(char *));
388     if (!options->domains)
389       return ARES_ENOMEM;
390
391     for (i = 0; i < channel->ndomains; i++)
392     {
393       options->ndomains = i;
394       options->domains[i] = strdup(channel->domains[i]);
395       if (!options->domains[i])
396         return ARES_ENOMEM;
397     }
398   }
399   options->ndomains = channel->ndomains;
400
401   /* copy lookups */
402   if (channel->lookups) {
403     options->lookups = strdup(channel->lookups);
404     if (!options->lookups && channel->lookups)
405       return ARES_ENOMEM;
406   }
407
408   /* copy sortlist */
409   if (channel->nsort) {
410     options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
411     if (!options->sortlist)
412       return ARES_ENOMEM;
413     for (i = 0; i < channel->nsort; i++)
414       options->sortlist[i] = channel->sortlist[i];
415   }
416   options->nsort = channel->nsort;
417
418   return ARES_SUCCESS;
419 }
420
421 static int init_by_options(ares_channel channel,
422                            const struct ares_options *options,
423                            int optmask)
424 {
425   int i;
426
427   /* Easy stuff. */
428   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
429     channel->flags = options->flags;
430   if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
431     channel->timeout = options->timeout;
432   else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
433     channel->timeout = options->timeout * 1000;
434   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
435     channel->tries = options->tries;
436   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
437     channel->ndots = options->ndots;
438   if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
439     channel->rotate = 1;
440   if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
441     channel->udp_port = htons(options->udp_port);
442   if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
443     channel->tcp_port = htons(options->tcp_port);
444   if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
445     {
446       channel->sock_state_cb = options->sock_state_cb;
447       channel->sock_state_cb_data = options->sock_state_cb_data;
448     }
449   if ((optmask & ARES_OPT_SOCK_SNDBUF)
450       && channel->socket_send_buffer_size == -1)
451     channel->socket_send_buffer_size = options->socket_send_buffer_size;
452   if ((optmask & ARES_OPT_SOCK_RCVBUF)
453       && channel->socket_receive_buffer_size == -1)
454     channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
455
456   /* Copy the IPv4 servers, if given. */
457   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
458     {
459       /* Avoid zero size allocations at any cost */
460       if (options->nservers > 0)
461         {
462           channel->servers =
463             malloc(options->nservers * sizeof(struct server_state));
464           if (!channel->servers)
465             return ARES_ENOMEM;
466           for (i = 0; i < options->nservers; i++)
467             {
468               channel->servers[i].addr.family = AF_INET;
469               memcpy(&channel->servers[i].addr.addrV4,
470                      &options->servers[i],
471                      sizeof(channel->servers[i].addr.addrV4));
472             }
473         }
474       channel->nservers = options->nservers;
475     }
476
477   /* Copy the domains, if given.  Keep channel->ndomains consistent so
478    * we can clean up in case of error.
479    */
480   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
481     {
482       /* Avoid zero size allocations at any cost */
483       if (options->ndomains > 0)
484       {
485         channel->domains = malloc(options->ndomains * sizeof(char *));
486         if (!channel->domains)
487           return ARES_ENOMEM;
488         for (i = 0; i < options->ndomains; i++)
489           {
490             channel->ndomains = i;
491             channel->domains[i] = strdup(options->domains[i]);
492             if (!channel->domains[i])
493               return ARES_ENOMEM;
494           }
495       }
496       channel->ndomains = options->ndomains;
497     }
498
499   /* Set lookups, if given. */
500   if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
501     {
502       channel->lookups = strdup(options->lookups);
503       if (!channel->lookups)
504         return ARES_ENOMEM;
505     }
506
507   /* copy sortlist */
508   if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
509       (options->nsort>0)) {
510     channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
511     if (!channel->sortlist)
512       return ARES_ENOMEM;
513     for (i = 0; i < options->nsort; i++)
514       channel->sortlist[i] = options->sortlist[i];
515     channel->nsort = options->nsort;
516   }
517
518   channel->optmask = optmask;
519
520   return ARES_SUCCESS;
521 }
522
523 static int init_by_environment(ares_channel channel)
524 {
525   const char *localdomain, *res_options;
526   int status;
527
528   localdomain = getenv("LOCALDOMAIN");
529   if (localdomain && channel->ndomains == -1)
530     {
531       status = set_search(channel, localdomain);
532       if (status != ARES_SUCCESS)
533         return status;
534     }
535
536   res_options = getenv("RES_OPTIONS");
537   if (res_options)
538     {
539       status = set_options(channel, res_options);
540       if (status != ARES_SUCCESS)
541         return status;
542     }
543
544   return ARES_SUCCESS;
545 }
546
547 #ifdef WIN32
548 /*
549  * Warning: returns a dynamically allocated buffer, the user MUST
550  * use free() if the function returns 1
551  */
552 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
553 {
554   /* Test for the size we need */
555   DWORD size = 0;
556   int result;
557
558   result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
559   if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
560     return 0;
561   *obuf = malloc(size+1);
562   if (!*obuf)
563     return 0;
564
565   if (RegQueryValueEx(hKey, subkey, 0, NULL,
566                       (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
567   {
568     free(*obuf);
569     return 0;
570   }
571   if (size == 1)
572   {
573     free(*obuf);
574     return 0;
575   }
576   return 1;
577 }
578
579 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
580 {
581   char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
582   DWORD enum_size = 39;
583   int idx = 0;
584   HKEY hVal;
585
586   while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
587                       NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
588   {
589     int rc;
590
591     enum_size = 39;
592     if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
593         ERROR_SUCCESS)
594       continue;
595     rc = get_res_nt(hVal, subkey, obuf);
596       RegCloseKey(hVal);
597     if (rc)
598       return 1;
599     }
600   return 0;
601 }
602
603 /* get_iphlpapi_dns_classic() is supported on W98 and newer */
604 static int get_iphlpapi_dns_classic(char *ret_buf, size_t ret_size)
605 {
606   FIXED_INFO       *fi, *newfi;
607   struct ares_addr namesrvr;
608   char             *txtaddr;
609   IP_ADDR_STRING   *ipAddr;
610   size_t           txtlen;
611   HRESULT          res;
612   DWORD            size = sizeof (*fi);
613   char             *endptr = ret_buf;
614   int              count = 0;
615
616   *endptr = '\0';
617
618   fi = malloc(size);
619   if (!fi)
620     return 0;
621
622   res = (*ares_fpGetNetworkParams) (fi, &size);
623   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
624     goto quit;
625
626   newfi = realloc(fi, size);
627   if (!newfi)
628     goto quit;
629
630   fi = newfi;
631   res = (*ares_fpGetNetworkParams) (fi, &size);
632   if (res != ERROR_SUCCESS)
633     goto quit;
634
635   for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
636   {
637     txtaddr = &ipAddr->IpAddress.String[0];
638
639     /* Validate converting textual address to binary format. */
640     if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
641     {
642       if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
643           (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
644         continue;
645     }
646     else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
647     {
648       if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
649                  sizeof(namesrvr.addrV6)) == 0)
650         continue;
651     }
652     else
653       continue;
654
655     txtlen = strlen(txtaddr);
656     if (ret_size >= strlen(ret_buf) + txtlen + 2)
657     {
658       sprintf(endptr, "%s,", txtaddr);
659       endptr += txtlen + 1;
660       count++;
661     }
662   }
663
664 quit:
665   if (fi)
666     free(fi);
667
668   if (endptr != ret_buf)
669     *(endptr - 1) = '\0';
670
671   return count;
672 }
673
674 #define IPAA_INITIAL_BUF_SZ 15 * 1024
675 #define IPAA_MAX_TRIES 3
676
677 static int get_iphlpapi_dns_info(char *ret_buf, size_t ret_size)
678 {
679   IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
680   IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
681   ULONG res;
682   ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
683   ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
684   ULONG AddrFlags = 0;
685   char *endptr = ret_buf;
686   int trying = IPAA_MAX_TRIES;
687   int count = 0;
688
689   union {
690     struct sockaddr     *sa;
691     struct sockaddr_in  *sa4;
692     struct sockaddr_in6 *sa6;
693   } namesrvr;
694
695   char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
696   size_t txtlen;
697
698   /* Unless GetAdaptersAddresses is available, use GetNetworkParams */
699   if (ares_fpGetAdaptersAddresses == ZERO_NULL)
700     return get_iphlpapi_dns_classic(ret_buf, ret_size);
701
702   *endptr = '\0';
703
704   ipaa = malloc(Bufsz);
705   if (!ipaa)
706     return 0;
707
708   /* Usually this call suceeds with initial buffer size */
709   res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
710                                         ipaa, &ReqBufsz);
711   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
712     goto quit;
713
714   while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
715   {
716     if (Bufsz < ReqBufsz)
717     {
718       newipaa = realloc(ipaa, ReqBufsz);
719       if (!newipaa)
720         goto quit;
721       Bufsz = ReqBufsz;
722       ipaa = newipaa;
723     }
724     res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
725                                           ipaa, &ReqBufsz);
726     if (res == ERROR_SUCCESS)
727       break;
728   }
729   if (res != ERROR_SUCCESS)
730     goto quit;
731
732   for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
733   {
734     for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
735          ipaDNSAddr;
736          ipaDNSAddr = ipaDNSAddr->Next)
737     {
738       namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
739
740       if (namesrvr.sa->sa_family == AF_INET)
741       {
742         if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
743             (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
744           continue;
745         if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
746                              txtaddr, sizeof(txtaddr)))
747           continue;
748       }
749       else if (namesrvr.sa->sa_family == AF_INET6)
750       {
751         if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
752                    sizeof(namesrvr.sa6->sin6_addr)) == 0)
753           continue;
754         if (! ares_inet_ntop(AF_INET, &namesrvr.sa6->sin6_addr,
755                              txtaddr, sizeof(txtaddr)))
756           continue;
757       }
758       else
759         continue;
760
761       txtlen = strlen(txtaddr);
762       if (ret_size >= strlen(ret_buf) + txtlen + 2)
763       {
764         sprintf(endptr, "%s,", txtaddr);
765         endptr += txtlen + 1;
766         count++;
767       }
768     }
769   }
770
771 quit:
772   if (ipaa)
773     free(ipaa);
774
775   if (endptr != ret_buf)
776     *(endptr - 1) = '\0';
777
778   return count;
779 }
780 #endif
781
782 static int init_by_resolv_conf(ares_channel channel)
783 {
784 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
785   char *line = NULL;
786 #endif
787   int status = -1, nservers = 0, nsort = 0;
788   struct server_state *servers = NULL;
789   struct apattern *sortlist = NULL;
790
791 #ifdef WIN32
792
793     /*
794   NameServer info via IPHLPAPI (IP helper API):
795     GetNetworkParams() should be the trusted source for this.
796     Available in Win-98/2000 and later. If that fail, fall-back to
797     registry information.
798
799   NameServer Registry:
800
801    On Windows 9X, the DNS server can be found in:
802 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
803
804         On Windows NT/2000/XP/2003:
805 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
806         or
807 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
808         or
809 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
810 NameServer
811         or
812 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
813 DhcpNameServer
814    */
815
816   HKEY mykey;
817   HKEY subkey;
818   DWORD data_type;
819   DWORD bytes;
820   DWORD result;
821   char  buf[512];
822   win_platform platform;
823
824   if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
825      return ARES_SUCCESS;
826
827   if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
828   {
829     status = config_nameserver(&servers, &nservers, buf);
830     if (status == ARES_SUCCESS)
831       goto okay;
832   }
833
834   platform = ares__getplatform();
835
836   if (platform == WIN_NT)
837   {
838     if (RegOpenKeyEx(
839           HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
840           KEY_READ, &mykey
841          ) == ERROR_SUCCESS)
842     {
843       RegOpenKeyEx(mykey, "Interfaces", 0,
844                    KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
845       if (get_res_nt(mykey, NAMESERVER, &line))
846       {
847         status = config_nameserver(&servers, &nservers, line);
848         free(line);
849       }
850       else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
851       {
852         status = config_nameserver(&servers, &nservers, line);
853         free(line);
854       }
855       /* Try the interfaces */
856       else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
857       {
858         status = config_nameserver(&servers, &nservers, line);
859         free(line);
860       }
861       else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
862       {
863         status = config_nameserver(&servers, &nservers, line);
864         free(line);
865       }
866       RegCloseKey(subkey);
867       RegCloseKey(mykey);
868     }
869   }
870   else if (platform == WIN_9X)
871   {
872     if (RegOpenKeyEx(
873           HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
874           KEY_READ, &mykey
875          ) == ERROR_SUCCESS)
876     {
877       if ((result = RegQueryValueEx(
878              mykey, NAMESERVER, NULL, &data_type,
879              NULL, &bytes
880             )
881            ) == ERROR_SUCCESS ||
882           result == ERROR_MORE_DATA)
883       {
884         if (bytes)
885         {
886           line = malloc(bytes+1);
887           if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
888                               (unsigned char *)line, &bytes) ==
889               ERROR_SUCCESS)
890           {
891             status = config_nameserver(&servers, &nservers, line);
892           }
893           free(line);
894         }
895       }
896     }
897     RegCloseKey(mykey);
898   }
899
900   if (status == ARES_SUCCESS)
901     status = ARES_EOF;
902   else
903     /* Catch the case when all the above checks fail (which happens when there
904        is no network card or the cable is unplugged) */
905     status = ARES_EFILE;
906
907 #elif defined(__riscos__)
908
909   /* Under RISC OS, name servers are listed in the
910      system variable Inet$Resolvers, space separated. */
911
912   line = getenv("Inet$Resolvers");
913   status = ARES_EOF;
914   if (line) {
915     char *resolvers = strdup(line), *pos, *space;
916
917     if (!resolvers)
918       return ARES_ENOMEM;
919
920     pos = resolvers;
921     do {
922       space = strchr(pos, ' ');
923       if (space)
924         *space = '\0';
925       status = config_nameserver(&servers, &nservers, pos);
926       if (status != ARES_SUCCESS)
927         break;
928       pos = space + 1;
929     } while (space);
930
931     if (status == ARES_SUCCESS)
932       status = ARES_EOF;
933
934     free(resolvers);
935   }
936
937 #elif defined(WATT32)
938   int i;
939
940   sock_init();
941   for (i = 0; def_nameservers[i]; i++)
942       ;
943   if (i == 0)
944     return ARES_SUCCESS; /* use localhost DNS server */
945
946   nservers = i;
947   servers = calloc(i, sizeof(struct server_state));
948   if (!servers)
949      return ARES_ENOMEM;
950
951   for (i = 0; def_nameservers[i]; i++)
952   {
953     servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
954     servers[i].addr.family = AF_INET;
955   }
956   status = ARES_EOF;
957
958 #elif defined(ANDROID) || defined(__ANDROID__)
959   unsigned int i;
960   char propname[PROP_NAME_MAX];
961   char propvalue[PROP_VALUE_MAX]="";
962
963   for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
964     snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
965     if (__system_property_get(propname, propvalue) < 1) {
966       status = ARES_EOF;
967       break;
968     }
969     status = config_nameserver(&servers, &nservers, propvalue);
970     if (status != ARES_SUCCESS)
971       break;
972     status = ARES_EOF;
973   }
974 #else
975   {
976     char *p;
977     FILE *fp;
978     size_t linesize;
979     int error;
980
981     /* Don't read resolv.conf and friends if we don't have to */
982     if (ARES_CONFIG_CHECK(channel))
983         return ARES_SUCCESS;
984
985     fp = fopen(PATH_RESOLV_CONF, "r");
986     if (fp) {
987       while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
988       {
989         if ((p = try_config(line, "domain", ';')))
990           status = config_domain(channel, p);
991         else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
992           status = config_lookup(channel, p, "bind", "file");
993         else if ((p = try_config(line, "search", ';')))
994           status = set_search(channel, p);
995         else if ((p = try_config(line, "nameserver", ';')) &&
996                  channel->nservers == -1)
997           status = config_nameserver(&servers, &nservers, p);
998         else if ((p = try_config(line, "sortlist", ';')) &&
999                  channel->nsort == -1)
1000           status = config_sortlist(&sortlist, &nsort, p);
1001         else if ((p = try_config(line, "options", ';')))
1002           status = set_options(channel, p);
1003         else
1004           status = ARES_SUCCESS;
1005         if (status != ARES_SUCCESS)
1006           break;
1007       }
1008       fclose(fp);
1009     }
1010     else {
1011       error = ERRNO;
1012       switch(error) {
1013       case ENOENT:
1014       case ESRCH:
1015         status = ARES_EOF;
1016         break;
1017       default:
1018         DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1019                        error, strerror(error)));
1020         DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1021         status = ARES_EFILE;
1022       }
1023     }
1024
1025     if ((status == ARES_EOF) && (!channel->lookups)) {
1026       /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1027       fp = fopen("/etc/nsswitch.conf", "r");
1028       if (fp) {
1029         while ((status = ares__read_line(fp, &line, &linesize)) ==
1030                ARES_SUCCESS)
1031         {
1032           if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1033             /* ignore errors */
1034             (void)config_lookup(channel, p, "dns", "files");
1035         }
1036         fclose(fp);
1037       }
1038       else {
1039         error = ERRNO;
1040         switch(error) {
1041         case ENOENT:
1042         case ESRCH:
1043           status = ARES_EOF;
1044           break;
1045         default:
1046           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1047                          error, strerror(error)));
1048           DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1049                          "/etc/nsswitch.conf"));
1050           status = ARES_EFILE;
1051         }
1052       }
1053     }
1054
1055     if ((status == ARES_EOF) && (!channel->lookups)) {
1056       /* Linux / GNU libc 2.x and possibly others have host.conf */
1057       fp = fopen("/etc/host.conf", "r");
1058       if (fp) {
1059         while ((status = ares__read_line(fp, &line, &linesize)) ==
1060                ARES_SUCCESS)
1061         {
1062           if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1063             /* ignore errors */
1064             (void)config_lookup(channel, p, "bind", "hosts");
1065         }
1066         fclose(fp);
1067       }
1068       else {
1069         error = ERRNO;
1070         switch(error) {
1071         case ENOENT:
1072         case ESRCH:
1073           status = ARES_EOF;
1074           break;
1075         default:
1076           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1077                          error, strerror(error)));
1078           DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1079                          "/etc/host.conf"));
1080           status = ARES_EFILE;
1081         }
1082       }
1083     }
1084
1085     if ((status == ARES_EOF) && (!channel->lookups)) {
1086       /* Tru64 uses /etc/svc.conf */
1087       fp = fopen("/etc/svc.conf", "r");
1088       if (fp) {
1089         while ((status = ares__read_line(fp, &line, &linesize)) ==
1090                ARES_SUCCESS)
1091         {
1092           if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1093             /* ignore errors */
1094             (void)config_lookup(channel, p, "bind", "local");
1095         }
1096         fclose(fp);
1097       }
1098       else {
1099         error = ERRNO;
1100         switch(error) {
1101         case ENOENT:
1102         case ESRCH:
1103           status = ARES_EOF;
1104           break;
1105         default:
1106           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1107                          error, strerror(error)));
1108           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1109           status = ARES_EFILE;
1110         }
1111       }
1112     }
1113
1114     if(line)
1115       free(line);
1116   }
1117
1118 #endif
1119
1120   /* Handle errors. */
1121   if (status != ARES_EOF)
1122     {
1123       if (servers != NULL)
1124         free(servers);
1125       if (sortlist != NULL)
1126         free(sortlist);
1127       return status;
1128     }
1129
1130   /* If we got any name server entries, fill them in. */
1131 #ifdef WIN32
1132 okay:
1133 #endif
1134   if (servers)
1135     {
1136       channel->servers = servers;
1137       channel->nservers = nservers;
1138     }
1139
1140   /* If we got any sortlist entries, fill them in. */
1141   if (sortlist)
1142     {
1143       channel->sortlist = sortlist;
1144       channel->nsort = nsort;
1145     }
1146
1147   return ARES_SUCCESS;
1148 }
1149
1150 static int init_by_defaults(ares_channel channel)
1151 {
1152   char *hostname = NULL;
1153   int rc = ARES_SUCCESS;
1154 #ifdef HAVE_GETHOSTNAME
1155   char *dot;
1156 #endif
1157
1158   if (channel->flags == -1)
1159     channel->flags = 0;
1160   if (channel->timeout == -1)
1161     channel->timeout = DEFAULT_TIMEOUT;
1162   if (channel->tries == -1)
1163     channel->tries = DEFAULT_TRIES;
1164   if (channel->ndots == -1)
1165     channel->ndots = 1;
1166   if (channel->rotate == -1)
1167     channel->rotate = 0;
1168   if (channel->udp_port == -1)
1169     channel->udp_port = htons(NAMESERVER_PORT);
1170   if (channel->tcp_port == -1)
1171     channel->tcp_port = htons(NAMESERVER_PORT);
1172
1173   if (channel->nservers == -1) {
1174     /* If nobody specified servers, try a local named. */
1175     channel->servers = malloc(sizeof(struct server_state));
1176     if (!channel->servers) {
1177       rc = ARES_ENOMEM;
1178       goto error;
1179     }
1180     channel->servers[0].addr.family = AF_INET;
1181     channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1182     channel->nservers = 1;
1183   }
1184
1185 #if defined(USE_WINSOCK)
1186 #define toolong(x) (x == -1) &&  (SOCKERRNO == WSAEFAULT)
1187 #elif defined(ENAMETOOLONG)
1188 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1189                                  (SOCKERRNO == EINVAL))
1190 #else
1191 #define toolong(x) (x == -1) &&  (SOCKERRNO == EINVAL)
1192 #endif
1193
1194   if (channel->ndomains == -1) {
1195     /* Derive a default domain search list from the kernel hostname,
1196      * or set it to empty if the hostname isn't helpful.
1197      */
1198 #ifndef HAVE_GETHOSTNAME
1199     channel->ndomains = 0; /* default to none */
1200 #else
1201     GETHOSTNAME_TYPE_ARG2 lenv = 64;
1202     size_t len = 64;
1203     int res;
1204     channel->ndomains = 0; /* default to none */
1205
1206     hostname = malloc(len);
1207     if(!hostname) {
1208       rc = ARES_ENOMEM;
1209       goto error;
1210     }
1211
1212     do {
1213       res = gethostname(hostname, lenv);
1214
1215       if(toolong(res)) {
1216         char *p;
1217         len *= 2;
1218         lenv *= 2;
1219         p = realloc(hostname, len);
1220         if(!p) {
1221           rc = ARES_ENOMEM;
1222           goto error;
1223         }
1224         hostname = p;
1225         continue;
1226       }
1227       else if(res) {
1228         rc = ARES_EBADNAME;
1229         goto error;
1230       }
1231
1232     } WHILE_FALSE;
1233
1234     dot = strchr(hostname, '.');
1235     if (dot) {
1236       /* a dot was found */
1237       channel->domains = malloc(sizeof(char *));
1238       if (!channel->domains) {
1239         rc = ARES_ENOMEM;
1240         goto error;
1241       }
1242       channel->domains[0] = strdup(dot + 1);
1243       if (!channel->domains[0]) {
1244         rc = ARES_ENOMEM;
1245         goto error;
1246       }
1247       channel->ndomains = 1;
1248     }
1249 #endif
1250   }
1251
1252   if (channel->nsort == -1) {
1253     channel->sortlist = NULL;
1254     channel->nsort = 0;
1255   }
1256
1257   if (!channel->lookups) {
1258     channel->lookups = strdup("fb");
1259     if (!channel->lookups)
1260       rc = ARES_ENOMEM;
1261   }
1262
1263   error:
1264   if(rc) {
1265     if(channel->servers) {
1266       free(channel->servers);
1267       channel->servers = NULL;
1268     }
1269
1270     if(channel->domains && channel->domains[0])
1271       free(channel->domains[0]);
1272     if(channel->domains) {
1273       free(channel->domains);
1274       channel->domains = NULL;
1275     }
1276
1277     if(channel->lookups) {
1278       free(channel->lookups);
1279       channel->lookups = NULL;
1280     }
1281   }
1282
1283   if(hostname)
1284     free(hostname);
1285
1286   return rc;
1287 }
1288
1289 #if !defined(WIN32) && !defined(WATT32) && \
1290     !defined(ANDROID) && !defined(__ANDROID__)
1291 static int config_domain(ares_channel channel, char *str)
1292 {
1293   char *q;
1294
1295   /* Set a single search domain. */
1296   q = str;
1297   while (*q && !ISSPACE(*q))
1298     q++;
1299   *q = '\0';
1300   return set_search(channel, str);
1301 }
1302
1303 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1304     defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
1305   /* workaround icc 9.1 optimizer issue */
1306 # define vqualifier volatile
1307 #else
1308 # define vqualifier
1309 #endif
1310
1311 static int config_lookup(ares_channel channel, const char *str,
1312                          const char *bindch, const char *filech)
1313 {
1314   char lookups[3], *l;
1315   const char *vqualifier p;
1316
1317   /* Set the lookup order.  Only the first letter of each work
1318    * is relevant, and it has to be "b" for DNS or "f" for the
1319    * host file.  Ignore everything else.
1320    */
1321   l = lookups;
1322   p = str;
1323   while (*p)
1324     {
1325       if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1326         if (*p == *bindch) *l++ = 'b';
1327         else *l++ = 'f';
1328       }
1329       while (*p && !ISSPACE(*p) && (*p != ','))
1330         p++;
1331       while (*p && (ISSPACE(*p) || (*p == ',')))
1332         p++;
1333     }
1334   *l = '\0';
1335   channel->lookups = strdup(lookups);
1336   return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1337 }
1338 #endif  /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1339
1340 #ifndef WATT32
1341 static int config_nameserver(struct server_state **servers, int *nservers,
1342                              char *str)
1343 {
1344   struct ares_addr host;
1345   struct server_state *newserv;
1346   char *p, *txtaddr;
1347   /* On Windows, there may be more than one nameserver specified in the same
1348    * registry key, so we parse input as a space or comma seperated list.
1349    */
1350   for (p = str; p;)
1351     {
1352       /* Skip whitespace and commas. */
1353       while (*p && (ISSPACE(*p) || (*p == ',')))
1354         p++;
1355       if (!*p)
1356         /* No more input, done. */
1357         break;
1358
1359       /* Pointer to start of IPv4 or IPv6 address part. */
1360       txtaddr = p;
1361
1362       /* Advance past this address. */
1363       while (*p && !ISSPACE(*p) && (*p != ','))
1364         p++;
1365       if (*p)
1366         /* Null terminate this address. */
1367         *p++ = '\0';
1368       else
1369         /* Reached end of input, done when this address is processed. */
1370         p = NULL;
1371
1372       /* Convert textual address to binary format. */
1373       if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1374         host.family = AF_INET;
1375       else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1376         host.family = AF_INET6;
1377       else
1378         continue;
1379
1380       /* Resize servers state array. */
1381       newserv = realloc(*servers, (*nservers + 1) *
1382                         sizeof(struct server_state));
1383       if (!newserv)
1384         return ARES_ENOMEM;
1385
1386       /* Store address data. */
1387       newserv[*nservers].addr.family = host.family;
1388       if (host.family == AF_INET)
1389         memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1390                sizeof(host.addrV4));
1391       else
1392         memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1393                sizeof(host.addrV6));
1394
1395       /* Update arguments. */
1396       *servers = newserv;
1397       *nservers += 1;
1398     }
1399
1400   return ARES_SUCCESS;
1401 }
1402
1403 #if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
1404 static int config_sortlist(struct apattern **sortlist, int *nsort,
1405                            const char *str)
1406 {
1407   struct apattern pat;
1408   const char *q;
1409
1410   /* Add sortlist entries. */
1411   while (*str && *str != ';')
1412     {
1413       int bits;
1414       char ipbuf[16], ipbufpfx[32];
1415       /* Find just the IP */
1416       q = str;
1417       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1418         q++;
1419       memcpy(ipbuf, str, q-str);
1420       ipbuf[q-str] = '\0';
1421       /* Find the prefix */
1422       if (*q == '/')
1423         {
1424           const char *str2 = q+1;
1425           while (*q && *q != ';' && !ISSPACE(*q))
1426             q++;
1427           memcpy(ipbufpfx, str, q-str);
1428           ipbufpfx[q-str] = '\0';
1429           str = str2;
1430         }
1431       else
1432         ipbufpfx[0] = '\0';
1433       /* Lets see if it is CIDR */
1434       /* First we'll try IPv6 */
1435       if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1436                                      &pat.addrV6,
1437                                      sizeof(pat.addrV6))) > 0)
1438         {
1439           pat.type = PATTERN_CIDR;
1440           pat.mask.bits = (unsigned short)bits;
1441           pat.family = AF_INET6;
1442           if (!sortlist_alloc(sortlist, nsort, &pat))
1443             return ARES_ENOMEM;
1444         }
1445       else if (ipbufpfx[0] &&
1446                (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1447                                           sizeof(pat.addrV4))) > 0)
1448         {
1449           pat.type = PATTERN_CIDR;
1450           pat.mask.bits = (unsigned short)bits;
1451           pat.family = AF_INET;
1452           if (!sortlist_alloc(sortlist, nsort, &pat))
1453             return ARES_ENOMEM;
1454         }
1455       /* See if it is just a regular IP */
1456       else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1457         {
1458           if (ipbufpfx[0])
1459             {
1460               memcpy(ipbuf, str, q-str);
1461               ipbuf[q-str] = '\0';
1462               if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1463                 natural_mask(&pat);
1464             }
1465           else
1466             natural_mask(&pat);
1467           pat.family = AF_INET;
1468           pat.type = PATTERN_MASK;
1469           if (!sortlist_alloc(sortlist, nsort, &pat))
1470             return ARES_ENOMEM;
1471         }
1472       else
1473         {
1474           while (*q && *q != ';' && !ISSPACE(*q))
1475             q++;
1476         }
1477       str = q;
1478       while (ISSPACE(*str))
1479         str++;
1480     }
1481
1482   return ARES_SUCCESS;
1483 }
1484 #endif  /* !WIN32 & !ANDROID & !__ANDROID__ */
1485 #endif  /* !WATT32 */
1486
1487 static int set_search(ares_channel channel, const char *str)
1488 {
1489   int n;
1490   const char *p, *q;
1491
1492   if(channel->ndomains != -1) {
1493     /* if we already have some domains present, free them first */
1494     for(n=0; n < channel->ndomains; n++)
1495       free(channel->domains[n]);
1496     free(channel->domains);
1497     channel->domains = NULL;
1498     channel->ndomains = -1;
1499   }
1500
1501   /* Count the domains given. */
1502   n = 0;
1503   p = str;
1504   while (*p)
1505     {
1506       while (*p && !ISSPACE(*p))
1507         p++;
1508       while (ISSPACE(*p))
1509         p++;
1510       n++;
1511     }
1512
1513   if (!n)
1514     {
1515       channel->ndomains = 0;
1516       return ARES_SUCCESS;
1517     }
1518
1519   channel->domains = malloc(n * sizeof(char *));
1520   if (!channel->domains)
1521     return ARES_ENOMEM;
1522
1523   /* Now copy the domains. */
1524   n = 0;
1525   p = str;
1526   while (*p)
1527     {
1528       channel->ndomains = n;
1529       q = p;
1530       while (*q && !ISSPACE(*q))
1531         q++;
1532       channel->domains[n] = malloc(q - p + 1);
1533       if (!channel->domains[n])
1534         return ARES_ENOMEM;
1535       memcpy(channel->domains[n], p, q - p);
1536       channel->domains[n][q - p] = 0;
1537       p = q;
1538       while (ISSPACE(*p))
1539         p++;
1540       n++;
1541     }
1542   channel->ndomains = n;
1543
1544   return ARES_SUCCESS;
1545 }
1546
1547 static int set_options(ares_channel channel, const char *str)
1548 {
1549   const char *p, *q, *val;
1550
1551   p = str;
1552   while (*p)
1553     {
1554       q = p;
1555       while (*q && !ISSPACE(*q))
1556         q++;
1557       val = try_option(p, q, "ndots:");
1558       if (val && channel->ndots == -1)
1559         channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1560       val = try_option(p, q, "retrans:");
1561       if (val && channel->timeout == -1)
1562         channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1563       val = try_option(p, q, "retry:");
1564       if (val && channel->tries == -1)
1565         channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1566       val = try_option(p, q, "rotate");
1567       if (val && channel->rotate == -1)
1568         channel->rotate = 1;
1569       p = q;
1570       while (ISSPACE(*p))
1571         p++;
1572     }
1573
1574   return ARES_SUCCESS;
1575 }
1576
1577 static const char *try_option(const char *p, const char *q, const char *opt)
1578 {
1579   size_t len = strlen(opt);
1580   return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1581 }
1582
1583 #if !defined(WIN32) && !defined(WATT32) && \
1584     !defined(ANDROID) && !defined(__ANDROID__)
1585 static char *try_config(char *s, const char *opt, char scc)
1586 {
1587   size_t len;
1588   char *p;
1589   char *q;
1590
1591   if (!s || !opt)
1592     /* no line or no option */
1593     return NULL;
1594
1595   /* Hash '#' character is always used as primary comment char, additionally
1596      a not-NUL secondary comment char will be considered when specified. */
1597
1598   /* trim line comment */
1599   p = s;
1600   if(scc)
1601     while (*p && (*p != '#') && (*p != scc))
1602       p++;
1603   else
1604     while (*p && (*p != '#'))
1605       p++;
1606   *p = '\0';
1607
1608   /* trim trailing whitespace */
1609   q = p - 1;
1610   while ((q >= s) && ISSPACE(*q))
1611     q--;
1612   *++q = '\0';
1613
1614   /* skip leading whitespace */
1615   p = s;
1616   while (*p && ISSPACE(*p))
1617     p++;
1618
1619   if (!*p)
1620     /* empty line */
1621     return NULL;
1622
1623   if ((len = strlen(opt)) == 0)
1624     /* empty option */
1625     return NULL;
1626
1627   if (strncmp(p, opt, len) != 0)
1628     /* line and option do not match */
1629     return NULL;
1630
1631   /* skip over given option name */
1632   p += len;
1633
1634   if (!*p)
1635     /* no option value */
1636     return NULL;
1637
1638   if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1639     /* whitespace between option name and value is mandatory
1640        for given option names which do not end with ':' or '=' */
1641     return NULL;
1642
1643   /* skip over whitespace */
1644   while (*p && ISSPACE(*p))
1645     p++;
1646
1647   if (!*p)
1648     /* no option value */
1649     return NULL;
1650
1651   /* return pointer to option value */
1652   return p;
1653 }
1654
1655 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1656                           struct apattern *pat)
1657 {
1658   struct apattern *newsort;
1659   newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1660   if (!newsort)
1661     return 0;
1662   newsort[*nsort] = *pat;
1663   *sortlist = newsort;
1664   (*nsort)++;
1665   return 1;
1666 }
1667
1668 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1669 {
1670
1671   /* Four octets and three periods yields at most 15 characters. */
1672   if (len > 15)
1673     return -1;
1674
1675   addr->s_addr = inet_addr(ipbuf);
1676   if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1677     return -1;
1678   return 0;
1679 }
1680
1681 static void natural_mask(struct apattern *pat)
1682 {
1683   struct in_addr addr;
1684
1685   /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
1686    * but portable.
1687    */
1688   addr.s_addr = ntohl(pat->addrV4.s_addr);
1689
1690   /* This is out of date in the CIDR world, but some people might
1691    * still rely on it.
1692    */
1693   if (IN_CLASSA(addr.s_addr))
1694     pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1695   else if (IN_CLASSB(addr.s_addr))
1696     pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1697   else
1698     pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1699 }
1700 #endif  /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1701
1702 /* initialize an rc4 key. If possible a cryptographically secure random key
1703    is generated using a suitable function (for example win32's RtlGenRandom as
1704    described in
1705    http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1706    otherwise the code defaults to cross-platform albeit less secure mechanism
1707    using rand
1708 */
1709 static void randomize_key(unsigned char* key,int key_data_len)
1710 {
1711   int randomized = 0;
1712   int counter=0;
1713 #ifdef WIN32
1714   BOOLEAN res;
1715   if (ares_fpSystemFunction036)
1716     {
1717       res = (*ares_fpSystemFunction036) (key, key_data_len);
1718       if (res)
1719         randomized = 1;
1720     }
1721 #else /* !WIN32 */
1722 #ifdef RANDOM_FILE
1723   FILE *f = fopen(RANDOM_FILE, "rb");
1724   if(f) {
1725     counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1726     fclose(f);
1727   }
1728 #endif
1729 #endif /* WIN32 */
1730
1731   if (!randomized) {
1732     for (;counter<key_data_len;counter++)
1733       key[counter]=(unsigned char)(rand() % 256);
1734   }
1735 }
1736
1737 static int init_id_key(rc4_key* key,int key_data_len)
1738 {
1739   unsigned char index1;
1740   unsigned char index2;
1741   unsigned char* state;
1742   short counter;
1743   unsigned char *key_data_ptr = 0;
1744
1745   key_data_ptr = calloc(1,key_data_len);
1746   if (!key_data_ptr)
1747     return ARES_ENOMEM;
1748
1749   state = &key->state[0];
1750   for(counter = 0; counter < 256; counter++)
1751     /* unnecessary AND but it keeps some compilers happier */
1752     state[counter] = (unsigned char)(counter & 0xff);
1753   randomize_key(key->state,key_data_len);
1754   key->x = 0;
1755   key->y = 0;
1756   index1 = 0;
1757   index2 = 0;
1758   for(counter = 0; counter < 256; counter++)
1759   {
1760     index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1761                               index2) % 256);
1762     ARES_SWAP_BYTE(&state[counter], &state[index2]);
1763
1764     index1 = (unsigned char)((index1 + 1) % key_data_len);
1765   }
1766   free(key_data_ptr);
1767   return ARES_SUCCESS;
1768 }
1769
1770 unsigned short ares__generate_new_id(rc4_key* key)
1771 {
1772   unsigned short r=0;
1773   ares__rc4(key, (unsigned char *)&r, sizeof(r));
1774   return r;
1775 }
1776
1777 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1778 {
1779   channel->local_ip4 = local_ip;
1780 }
1781
1782 /* local_ip6 should be 16 bytes in length */
1783 void ares_set_local_ip6(ares_channel channel,
1784                         const unsigned char* local_ip6)
1785 {
1786   memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1787 }
1788
1789 /* local_dev_name should be null terminated. */
1790 void ares_set_local_dev(ares_channel channel,
1791                         const char* local_dev_name)
1792 {
1793   strncpy(channel->local_dev_name, local_dev_name,
1794           sizeof(channel->local_dev_name));
1795   channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1796 }
1797
1798
1799 void ares_set_socket_callback(ares_channel channel,
1800                               ares_sock_create_callback cb,
1801                               void *data)
1802 {
1803   channel->sock_create_cb = cb;
1804   channel->sock_create_cb_data = data;
1805 }
1806
1807 void ares__init_servers_state(ares_channel channel)
1808 {
1809   struct server_state *server;
1810   int i;
1811
1812   for (i = 0; i < channel->nservers; i++)
1813     {
1814       server = &channel->servers[i];
1815       server->udp_socket = ARES_SOCKET_BAD;
1816       server->tcp_socket = ARES_SOCKET_BAD;
1817       server->tcp_connection_generation = ++channel->tcp_connection_generation;
1818       server->tcp_lenbuf_pos = 0;
1819       server->tcp_buffer_pos = 0;
1820       server->tcp_buffer = NULL;
1821       server->tcp_length = 0;
1822       server->qhead = NULL;
1823       server->qtail = NULL;
1824       ares__init_list_head(&server->queries_to_server);
1825       server->channel = channel;
1826       server->is_broken = 0;
1827     }
1828 }