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