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