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