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