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