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