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