ares_init: fix gethostname error detection on winsock platforms
[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 <errno.h>
67 #include "ares.h"
68 #include "inet_net_pton.h"
69 #include "ares_library_init.h"
70 #include "ares_nowarn.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
709   if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
710      return ARES_SUCCESS;
711
712   if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
713   {
714     status = config_nameserver(&servers, &nservers, buf);
715     if (status == ARES_SUCCESS)
716       goto okay;
717   }
718
719   if (IS_NT())
720   {
721     if (RegOpenKeyEx(
722           HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
723           KEY_READ, &mykey
724           ) == ERROR_SUCCESS)
725     {
726       RegOpenKeyEx(mykey, "Interfaces", 0,
727                    KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
728       if (get_res_nt(mykey, NAMESERVER, &line))
729       {
730         status = config_nameserver(&servers, &nservers, line);
731         free(line);
732       }
733       else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
734       {
735         status = config_nameserver(&servers, &nservers, line);
736         free(line);
737       }
738       /* Try the interfaces */
739       else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
740       {
741         status = config_nameserver(&servers, &nservers, line);
742         free(line);
743       }
744       else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
745       {
746         status = config_nameserver(&servers, &nservers, line);
747         free(line);
748       }
749       RegCloseKey(subkey);
750       RegCloseKey(mykey);
751     }
752   }
753   else
754   {
755     if (RegOpenKeyEx(
756           HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
757           KEY_READ, &mykey
758           ) == ERROR_SUCCESS)
759     {
760       if ((result = RegQueryValueEx(
761              mykey, NAMESERVER, NULL, &data_type,
762              NULL, &bytes
763              )
764             ) == ERROR_SUCCESS ||
765           result == ERROR_MORE_DATA)
766       {
767         if (bytes)
768         {
769           line = malloc(bytes+1);
770           if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
771                               (unsigned char *)line, &bytes) ==
772               ERROR_SUCCESS)
773           {
774             status = config_nameserver(&servers, &nservers, line);
775           }
776           free(line);
777         }
778       }
779     }
780     RegCloseKey(mykey);
781   }
782
783   if (status == ARES_SUCCESS)
784     status = ARES_EOF;
785   else
786     /* Catch the case when all the above checks fail (which happens when there
787        is no network card or the cable is unplugged) */
788     status = ARES_EFILE;
789
790 #elif defined(__riscos__)
791
792   /* Under RISC OS, name servers are listed in the
793      system variable Inet$Resolvers, space separated. */
794
795   line = getenv("Inet$Resolvers");
796   status = ARES_EOF;
797   if (line) {
798     char *resolvers = strdup(line), *pos, *space;
799
800     if (!resolvers)
801       return ARES_ENOMEM;
802
803     pos = resolvers;
804     do {
805       space = strchr(pos, ' ');
806       if (space)
807         *space = '\0';
808       status = config_nameserver(&servers, &nservers, pos);
809       if (status != ARES_SUCCESS)
810         break;
811       pos = space + 1;
812     } while (space);
813
814     if (status == ARES_SUCCESS)
815       status = ARES_EOF;
816
817     free(resolvers);
818   }
819
820 #elif defined(WATT32)
821   int i;
822
823   sock_init();
824   for (i = 0; def_nameservers[i]; i++)
825       ;
826   if (i == 0)
827     return ARES_SUCCESS; /* use localhost DNS server */
828
829   nservers = i;
830   servers = calloc(i, sizeof(struct server_state));
831   if (!servers)
832      return ARES_ENOMEM;
833
834   for (i = 0; def_nameservers[i]; i++)
835   {
836     servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
837     servers[i].addr.family = AF_INET;
838   }
839   status = ARES_EOF;
840
841 #elif defined(ANDROID)
842   char value[PROP_VALUE_MAX]="";
843   __system_property_get("net.dns1", value);
844   status = config_nameserver(&servers, &nservers, value);
845   if (status == ARES_SUCCESS)
846     status = ARES_EOF;
847 #else
848   {
849     char *p;
850     FILE *fp;
851     size_t linesize;
852     int error;
853
854     /* Don't read resolv.conf and friends if we don't have to */
855     if (ARES_CONFIG_CHECK(channel))
856         return ARES_SUCCESS;
857
858     fp = fopen(PATH_RESOLV_CONF, "r");
859     if (fp) {
860       while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
861       {
862         if ((p = try_config(line, "domain", ';')))
863           status = config_domain(channel, p);
864         else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
865           status = config_lookup(channel, p, "bind", "file");
866         else if ((p = try_config(line, "search", ';')))
867           status = set_search(channel, p);
868         else if ((p = try_config(line, "nameserver", ';')) &&
869                  channel->nservers == -1)
870           status = config_nameserver(&servers, &nservers, p);
871         else if ((p = try_config(line, "sortlist", ';')) &&
872                  channel->nsort == -1)
873           status = config_sortlist(&sortlist, &nsort, p);
874         else if ((p = try_config(line, "options", ';')))
875           status = set_options(channel, p);
876         else
877           status = ARES_SUCCESS;
878         if (status != ARES_SUCCESS)
879           break;
880       }
881       fclose(fp);
882     }
883     else {
884       error = ERRNO;
885       switch(error) {
886       case ENOENT:
887       case ESRCH:
888         status = ARES_EOF;
889         break;
890       default:
891         DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
892                        error, strerror(error)));
893         DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
894         status = ARES_EFILE;
895       }
896     }
897
898     if ((status == ARES_EOF) && (!channel->lookups)) {
899       /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
900       fp = fopen("/etc/nsswitch.conf", "r");
901       if (fp) {
902         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
903         {
904           if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
905             /* ignore errors */
906             (void)config_lookup(channel, p, "dns", "files");
907         }
908         fclose(fp);
909       }
910       else {
911         error = ERRNO;
912         switch(error) {
913         case ENOENT:
914         case ESRCH:
915           status = ARES_EOF;
916           break;
917         default:
918           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
919                          error, strerror(error)));
920           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
921           status = ARES_EFILE;
922         }
923       }
924     }
925
926     if ((status == ARES_EOF) && (!channel->lookups)) {
927       /* Linux / GNU libc 2.x and possibly others have host.conf */
928       fp = fopen("/etc/host.conf", "r");
929       if (fp) {
930         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
931         {
932           if ((p = try_config(line, "order", '\0')) && !channel->lookups)
933             /* ignore errors */
934             (void)config_lookup(channel, p, "bind", "hosts");
935         }
936         fclose(fp);
937       }
938       else {
939         error = ERRNO;
940         switch(error) {
941         case ENOENT:
942         case ESRCH:
943           status = ARES_EOF;
944           break;
945         default:
946           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
947                          error, strerror(error)));
948           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
949           status = ARES_EFILE;
950         }
951       }
952     }
953
954     if ((status == ARES_EOF) && (!channel->lookups)) {
955       /* Tru64 uses /etc/svc.conf */
956       fp = fopen("/etc/svc.conf", "r");
957       if (fp) {
958         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
959         {
960           if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
961             /* ignore errors */
962             (void)config_lookup(channel, p, "bind", "local");
963         }
964         fclose(fp);
965       }
966       else {
967         error = ERRNO;
968         switch(error) {
969         case ENOENT:
970         case ESRCH:
971           status = ARES_EOF;
972           break;
973         default:
974           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
975                          error, strerror(error)));
976           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
977           status = ARES_EFILE;
978         }
979       }
980     }
981
982     if(line)
983       free(line);
984   }
985
986 #endif
987
988   /* Handle errors. */
989   if (status != ARES_EOF)
990     {
991       if (servers != NULL)
992         free(servers);
993       if (sortlist != NULL)
994         free(sortlist);
995       return status;
996     }
997
998   /* If we got any name server entries, fill them in. */
999 #ifdef WIN32
1000 okay:
1001 #endif
1002   if (servers)
1003     {
1004       channel->servers = servers;
1005       channel->nservers = nservers;
1006     }
1007
1008   /* If we got any sortlist entries, fill them in. */
1009   if (sortlist)
1010     {
1011       channel->sortlist = sortlist;
1012       channel->nsort = nsort;
1013     }
1014
1015   return ARES_SUCCESS;
1016 }
1017
1018 static int init_by_defaults(ares_channel channel)
1019 {
1020   char *hostname = NULL;
1021   int rc = ARES_SUCCESS;
1022 #ifdef HAVE_GETHOSTNAME
1023   char *dot;
1024 #endif
1025
1026   if (channel->flags == -1)
1027     channel->flags = 0;
1028   if (channel->timeout == -1)
1029     channel->timeout = DEFAULT_TIMEOUT;
1030   if (channel->tries == -1)
1031     channel->tries = DEFAULT_TRIES;
1032   if (channel->ndots == -1)
1033     channel->ndots = 1;
1034   if (channel->rotate == -1)
1035     channel->rotate = 0;
1036   if (channel->udp_port == -1)
1037     channel->udp_port = htons(NAMESERVER_PORT);
1038   if (channel->tcp_port == -1)
1039     channel->tcp_port = htons(NAMESERVER_PORT);
1040
1041   if (channel->nservers == -1) {
1042     /* If nobody specified servers, try a local named. */
1043     channel->servers = malloc(sizeof(struct server_state));
1044     if (!channel->servers) {
1045       rc = ARES_ENOMEM;
1046       goto error;
1047     }
1048     channel->servers[0].addr.family = AF_INET;
1049     channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1050     channel->nservers = 1;
1051   }
1052
1053 #if defined(USE_WINSOCK)
1054 #define toolong(x) (x == -1) &&  (SOCKERRNO == WSAEFAULT)
1055 #elif defined(ENAMETOOLONG)
1056 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1057                                  (SOCKERRNO == EINVAL))
1058 #else
1059 #define toolong(x) (x == -1) &&  (SOCKERRNO == EINVAL)
1060 #endif
1061
1062   if (channel->ndomains == -1) {
1063     /* Derive a default domain search list from the kernel hostname,
1064      * or set it to empty if the hostname isn't helpful.
1065      */
1066     size_t len = 64;
1067     int res;
1068     channel->ndomains = 0; /* default to none */
1069
1070 #ifdef HAVE_GETHOSTNAME
1071     hostname = malloc(len);
1072     if(!hostname) {
1073       rc = ARES_ENOMEM;
1074       goto error;
1075     }
1076
1077     do {
1078       res = gethostname(hostname, len);
1079
1080       if(toolong(res)) {
1081         char *p;
1082         len *= 2;
1083         p = realloc(hostname, len);
1084         if(!p) {
1085           rc = ARES_ENOMEM;
1086           goto error;
1087         }
1088         hostname = p;
1089         continue;
1090       }
1091       else if(res) {
1092         rc = ARES_EBADNAME;
1093         goto error;
1094       }
1095
1096     } while(0);
1097
1098     dot = strchr(hostname, '.');
1099     if (dot) {
1100       /* a dot was found */
1101       channel->domains = malloc(sizeof(char *));
1102       if (!channel->domains) {
1103         rc = ARES_ENOMEM;
1104         goto error;
1105       }
1106       channel->domains[0] = strdup(dot + 1);
1107       if (!channel->domains[0]) {
1108         rc = ARES_ENOMEM;
1109         goto error;
1110       }
1111       channel->ndomains = 1;
1112     }
1113 #endif
1114   }
1115
1116   if (channel->nsort == -1) {
1117     channel->sortlist = NULL;
1118     channel->nsort = 0;
1119   }
1120
1121   if (!channel->lookups) {
1122     channel->lookups = strdup("fb");
1123     if (!channel->lookups)
1124       rc = ARES_ENOMEM;
1125   }
1126
1127   error:
1128   if(rc) {
1129     if(channel->servers)
1130       free(channel->servers);
1131
1132     if(channel->domains && channel->domains[0])
1133       free(channel->domains[0]);
1134     if(channel->domains)
1135       free(channel->domains);
1136     if(channel->lookups)
1137       free(channel->lookups);
1138   }
1139
1140   if(hostname)
1141     free(hostname);
1142
1143   return rc;
1144 }
1145
1146 #if !defined(WIN32) && !defined(WATT32)
1147 static int config_domain(ares_channel channel, char *str)
1148 {
1149   char *q;
1150
1151   /* Set a single search domain. */
1152   q = str;
1153   while (*q && !ISSPACE(*q))
1154     q++;
1155   *q = '\0';
1156   return set_search(channel, str);
1157 }
1158
1159 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1160     defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
1161   /* workaround icc 9.1 optimizer issue */
1162 # define vqualifier volatile
1163 #else
1164 # define vqualifier
1165 #endif
1166
1167 static int config_lookup(ares_channel channel, const char *str,
1168                          const char *bindch, const char *filech)
1169 {
1170   char lookups[3], *l;
1171   const char *vqualifier p;
1172
1173   /* Set the lookup order.  Only the first letter of each work
1174    * is relevant, and it has to be "b" for DNS or "f" for the
1175    * host file.  Ignore everything else.
1176    */
1177   l = lookups;
1178   p = str;
1179   while (*p)
1180     {
1181       if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1182         if (*p == *bindch) *l++ = 'b';
1183         else *l++ = 'f';
1184       }
1185       while (*p && !ISSPACE(*p) && (*p != ','))
1186         p++;
1187       while (*p && (ISSPACE(*p) || (*p == ',')))
1188         p++;
1189     }
1190   *l = '\0';
1191   channel->lookups = strdup(lookups);
1192   return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1193 }
1194 #endif  /* !WIN32 & !WATT32 */
1195
1196 #ifndef WATT32
1197 static int config_nameserver(struct server_state **servers, int *nservers,
1198                              char *str)
1199 {
1200   struct ares_addr host;
1201   struct server_state *newserv;
1202   char *p, *txtaddr;
1203   /* On Windows, there may be more than one nameserver specified in the same
1204    * registry key, so we parse input as a space or comma seperated list.
1205    */
1206   for (p = str; p;)
1207     {
1208       /* Skip whitespace and commas. */
1209       while (*p && (ISSPACE(*p) || (*p == ',')))
1210         p++;
1211       if (!*p)
1212         /* No more input, done. */
1213         break;
1214
1215       /* Pointer to start of IPv4 or IPv6 address part. */
1216       txtaddr = p;
1217
1218       /* Advance past this address. */
1219       while (*p && !ISSPACE(*p) && (*p != ','))
1220         p++;
1221       if (*p)
1222         /* Null terminate this address. */
1223         *p++ = '\0';
1224       else
1225         /* Reached end of input, done when this address is processed. */
1226         p = NULL;
1227
1228       /* Convert textual address to binary format. */
1229       if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1230         host.family = AF_INET;
1231       else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1232         host.family = AF_INET6;
1233       else
1234         continue;
1235
1236       /* Resize servers state array. */
1237       newserv = realloc(*servers, (*nservers + 1) *
1238                         sizeof(struct server_state));
1239       if (!newserv)
1240         return ARES_ENOMEM;
1241
1242       /* Store address data. */
1243       newserv[*nservers].addr.family = host.family;
1244       if (host.family == AF_INET)
1245         memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1246                sizeof(host.addrV4));
1247       else
1248         memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1249                sizeof(host.addrV6));
1250
1251       /* Update arguments. */
1252       *servers = newserv;
1253       *nservers += 1;
1254     }
1255
1256   return ARES_SUCCESS;
1257 }
1258
1259 #ifndef WIN32
1260 static int config_sortlist(struct apattern **sortlist, int *nsort,
1261                            const char *str)
1262 {
1263   struct apattern pat;
1264   const char *q;
1265
1266   /* Add sortlist entries. */
1267   while (*str && *str != ';')
1268     {
1269       int bits;
1270       char ipbuf[16], ipbufpfx[32];
1271       /* Find just the IP */
1272       q = str;
1273       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1274         q++;
1275       memcpy(ipbuf, str, q-str);
1276       ipbuf[q-str] = '\0';
1277       /* Find the prefix */
1278       if (*q == '/')
1279         {
1280           const char *str2 = q+1;
1281           while (*q && *q != ';' && !ISSPACE(*q))
1282             q++;
1283           memcpy(ipbufpfx, str, q-str);
1284           ipbufpfx[q-str] = '\0';
1285           str = str2;
1286         }
1287       else
1288         ipbufpfx[0] = '\0';
1289       /* Lets see if it is CIDR */
1290       /* First we'll try IPv6 */
1291       if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1292                                      &pat.addrV6,
1293                                      sizeof(pat.addrV6))) > 0)
1294         {
1295           pat.type = PATTERN_CIDR;
1296           pat.mask.bits = (unsigned short)bits;
1297           pat.family = AF_INET6;
1298           if (!sortlist_alloc(sortlist, nsort, &pat))
1299             return ARES_ENOMEM;
1300         }
1301       else if (ipbufpfx[0] &&
1302                (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1303                                           sizeof(pat.addrV4))) > 0)
1304         {
1305           pat.type = PATTERN_CIDR;
1306           pat.mask.bits = (unsigned short)bits;
1307           pat.family = AF_INET;
1308           if (!sortlist_alloc(sortlist, nsort, &pat))
1309             return ARES_ENOMEM;
1310         }
1311       /* See if it is just a regular IP */
1312       else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1313         {
1314           if (ipbufpfx[0])
1315             {
1316               memcpy(ipbuf, str, q-str);
1317               ipbuf[q-str] = '\0';
1318               if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1319                 natural_mask(&pat);
1320             }
1321           else
1322             natural_mask(&pat);
1323           pat.family = AF_INET;
1324           pat.type = PATTERN_MASK;
1325           if (!sortlist_alloc(sortlist, nsort, &pat))
1326             return ARES_ENOMEM;
1327         }
1328       else
1329         {
1330           while (*q && *q != ';' && !ISSPACE(*q))
1331             q++;
1332         }
1333       str = q;
1334       while (ISSPACE(*str))
1335         str++;
1336     }
1337
1338   return ARES_SUCCESS;
1339 }
1340 #endif  /* !WIN32 */
1341 #endif  /* !WATT32 */
1342
1343 static int set_search(ares_channel channel, const char *str)
1344 {
1345   int n;
1346   const char *p, *q;
1347
1348   if(channel->ndomains != -1) {
1349     /* if we already have some domains present, free them first */
1350     for(n=0; n < channel->ndomains; n++)
1351       free(channel->domains[n]);
1352     free(channel->domains);
1353     channel->domains = NULL;
1354     channel->ndomains = -1;
1355   }
1356
1357   /* Count the domains given. */
1358   n = 0;
1359   p = str;
1360   while (*p)
1361     {
1362       while (*p && !ISSPACE(*p))
1363         p++;
1364       while (ISSPACE(*p))
1365         p++;
1366       n++;
1367     }
1368
1369   if (!n)
1370     {
1371       channel->ndomains = 0;
1372       return ARES_SUCCESS;
1373     }
1374
1375   channel->domains = malloc(n * sizeof(char *));
1376   if (!channel->domains)
1377     return ARES_ENOMEM;
1378
1379   /* Now copy the domains. */
1380   n = 0;
1381   p = str;
1382   while (*p)
1383     {
1384       channel->ndomains = n;
1385       q = p;
1386       while (*q && !ISSPACE(*q))
1387         q++;
1388       channel->domains[n] = malloc(q - p + 1);
1389       if (!channel->domains[n])
1390         return ARES_ENOMEM;
1391       memcpy(channel->domains[n], p, q - p);
1392       channel->domains[n][q - p] = 0;
1393       p = q;
1394       while (ISSPACE(*p))
1395         p++;
1396       n++;
1397     }
1398   channel->ndomains = n;
1399
1400   return ARES_SUCCESS;
1401 }
1402
1403 static int set_options(ares_channel channel, const char *str)
1404 {
1405   const char *p, *q, *val;
1406
1407   p = str;
1408   while (*p)
1409     {
1410       q = p;
1411       while (*q && !ISSPACE(*q))
1412         q++;
1413       val = try_option(p, q, "ndots:");
1414       if (val && channel->ndots == -1)
1415         channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1416       val = try_option(p, q, "retrans:");
1417       if (val && channel->timeout == -1)
1418         channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1419       val = try_option(p, q, "retry:");
1420       if (val && channel->tries == -1)
1421         channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1422       val = try_option(p, q, "rotate");
1423       if (val && channel->rotate == -1)
1424         channel->rotate = 1;
1425       p = q;
1426       while (ISSPACE(*p))
1427         p++;
1428     }
1429
1430   return ARES_SUCCESS;
1431 }
1432
1433 static const char *try_option(const char *p, const char *q, const char *opt)
1434 {
1435   size_t len = strlen(opt);
1436   return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1437 }
1438
1439 #if !defined(WIN32) && !defined(WATT32)
1440 static char *try_config(char *s, const char *opt, char scc)
1441 {
1442   size_t len;
1443   char *p;
1444   char *q;
1445
1446   if (!s || !opt)
1447     /* no line or no option */
1448     return NULL;
1449
1450   /* Hash '#' character is always used as primary comment char, additionally
1451      a not-NUL secondary comment char will be considered when specified. */
1452
1453   /* trim line comment */
1454   p = s;
1455   if(scc)
1456     while (*p && (*p != '#') && (*p != scc))
1457       p++;
1458   else
1459     while (*p && (*p != '#'))
1460       p++;
1461   *p = '\0';
1462
1463   /* trim trailing whitespace */
1464   q = p - 1;
1465   while ((q >= s) && ISSPACE(*q))
1466     q--;
1467   *++q = '\0';
1468
1469   /* skip leading whitespace */
1470   p = s;
1471   while (*p && ISSPACE(*p))
1472     p++;
1473
1474   if (!*p)
1475     /* empty line */
1476     return NULL;
1477
1478   if ((len = strlen(opt)) == 0)
1479     /* empty option */
1480     return NULL;
1481
1482   if (strncmp(p, opt, len) != 0)
1483     /* line and option do not match */
1484     return NULL;
1485
1486   /* skip over given option name */
1487   p += len;
1488
1489   if (!*p)
1490     /* no option value */
1491     return NULL;
1492
1493   if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1494     /* whitespace between option name and value is mandatory
1495        for given option names which do not end with ':' or '=' */
1496     return NULL;
1497
1498   /* skip over whitespace */
1499   while (*p && ISSPACE(*p))
1500     p++;
1501
1502   if (!*p)
1503     /* no option value */
1504     return NULL;
1505
1506   /* return pointer to option value */
1507   return p;
1508 }
1509
1510 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1511                           struct apattern *pat)
1512 {
1513   struct apattern *newsort;
1514   newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1515   if (!newsort)
1516     return 0;
1517   newsort[*nsort] = *pat;
1518   *sortlist = newsort;
1519   (*nsort)++;
1520   return 1;
1521 }
1522
1523 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1524 {
1525
1526   /* Four octets and three periods yields at most 15 characters. */
1527   if (len > 15)
1528     return -1;
1529
1530   addr->s_addr = inet_addr(ipbuf);
1531   if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1532     return -1;
1533   return 0;
1534 }
1535
1536 static void natural_mask(struct apattern *pat)
1537 {
1538   struct in_addr addr;
1539
1540   /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
1541    * but portable.
1542    */
1543   addr.s_addr = ntohl(pat->addrV4.s_addr);
1544
1545   /* This is out of date in the CIDR world, but some people might
1546    * still rely on it.
1547    */
1548   if (IN_CLASSA(addr.s_addr))
1549     pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1550   else if (IN_CLASSB(addr.s_addr))
1551     pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1552   else
1553     pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1554 }
1555 #endif /* !WIN32 && !WATT32 */
1556
1557 /* initialize an rc4 key. If possible a cryptographically secure random key
1558    is generated using a suitable function (for example win32's RtlGenRandom as
1559    described in
1560    http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1561    otherwise the code defaults to cross-platform albeit less secure mechanism
1562    using rand
1563 */
1564 static void randomize_key(unsigned char* key,int key_data_len)
1565 {
1566   int randomized = 0;
1567   int counter=0;
1568 #ifdef WIN32
1569   BOOLEAN res;
1570   if (ares_fpSystemFunction036)
1571     {
1572       res = (*ares_fpSystemFunction036) (key, key_data_len);
1573       if (res)
1574         randomized = 1;
1575     }
1576 #else /* !WIN32 */
1577 #ifdef RANDOM_FILE
1578   FILE *f = fopen(RANDOM_FILE, "rb");
1579   if(f) {
1580     counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1581     fclose(f);
1582   }
1583 #endif
1584 #endif /* WIN32 */
1585
1586   if ( !randomized ) {
1587     for (;counter<key_data_len;counter++)
1588       key[counter]=(unsigned char)(rand() % 256);
1589   }
1590 }
1591
1592 static int init_id_key(rc4_key* key,int key_data_len)
1593 {
1594   unsigned char index1;
1595   unsigned char index2;
1596   unsigned char* state;
1597   short counter;
1598   unsigned char *key_data_ptr = 0;
1599
1600   key_data_ptr = calloc(1,key_data_len);
1601   if (!key_data_ptr)
1602     return ARES_ENOMEM;
1603
1604   state = &key->state[0];
1605   for(counter = 0; counter < 256; counter++)
1606     /* unnecessary AND but it keeps some compilers happier */
1607     state[counter] = (unsigned char)(counter & 0xff);
1608   randomize_key(key->state,key_data_len);
1609   key->x = 0;
1610   key->y = 0;
1611   index1 = 0;
1612   index2 = 0;
1613   for(counter = 0; counter < 256; counter++)
1614   {
1615     index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1616                               index2) % 256);
1617     ARES_SWAP_BYTE(&state[counter], &state[index2]);
1618
1619     index1 = (unsigned char)((index1 + 1) % key_data_len);
1620   }
1621   free(key_data_ptr);
1622   return ARES_SUCCESS;
1623 }
1624
1625 unsigned short ares__generate_new_id(rc4_key* key)
1626 {
1627   unsigned short r=0;
1628   ares__rc4(key, (unsigned char *)&r, sizeof(r));
1629   return r;
1630 }
1631
1632 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1633 {
1634   channel->local_ip4 = local_ip;
1635 }
1636
1637 /* local_ip6 should be 16 bytes in length */
1638 void ares_set_local_ip6(ares_channel channel,
1639                         const unsigned char* local_ip6)
1640 {
1641   memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1642 }
1643
1644 /* local_dev_name should be null terminated. */
1645 void ares_set_local_dev(ares_channel channel,
1646                         const char* local_dev_name)
1647 {
1648   strncpy(channel->local_dev_name, local_dev_name,
1649           sizeof(channel->local_dev_name));
1650   channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1651 }
1652
1653
1654 void ares_set_socket_callback(ares_channel channel,
1655                               ares_sock_create_callback cb,
1656                               void *data)
1657 {
1658   channel->sock_create_cb = cb;
1659   channel->sock_create_cb_data = data;
1660 }
1661
1662 void ares__init_servers_state(ares_channel channel)
1663 {
1664   struct server_state *server;
1665   int i;
1666
1667   for (i = 0; i < channel->nservers; i++)
1668     {
1669       server = &channel->servers[i];
1670       server->udp_socket = ARES_SOCKET_BAD;
1671       server->tcp_socket = ARES_SOCKET_BAD;
1672       server->tcp_connection_generation = ++channel->tcp_connection_generation;
1673       server->tcp_lenbuf_pos = 0;
1674       server->tcp_buffer_pos = 0;
1675       server->tcp_buffer = NULL;
1676       server->tcp_length = 0;
1677       server->qhead = NULL;
1678       server->qtail = NULL;
1679       ares__init_list_head(&server->queries_to_server);
1680       server->channel = channel;
1681       server->is_broken = 0;
1682     }
1683 }