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