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