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