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