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