add debug messages for initialization failures
[platform/upstream/c-ares.git] / ares_init.c
1 /* $Id$ */
2
3 /* Copyright 1998 by the Massachusetts Institute of Technology.
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 "setup.h"
19 #include <sys/types.h>
20
21 #if defined(WIN32) && !defined(WATT32)
22 #include "nameser.h"
23 #include <iphlpapi.h>
24 #include <malloc.h>
25
26 #else
27 #include <sys/param.h>
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 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #include <netdb.h>
39 #include <arpa/nameser.h>
40 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
41 #include <arpa/nameser_compat.h>
42 #endif
43 #ifdef HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46 #endif
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <ctype.h>
52 #include <time.h>
53 #include <errno.h>
54 #include "ares.h"
55 #include "ares_private.h"
56 #include "inet_net_pton.h"
57
58 #ifdef WATT32
59 #undef WIN32  /* Redefined in MingW/MSVC headers */
60 #endif
61
62 static int init_by_options(ares_channel channel, struct ares_options *options,
63                            int optmask);
64 static int init_by_environment(ares_channel channel);
65 static int init_by_resolv_conf(ares_channel channel);
66 static int init_by_defaults(ares_channel channel);
67
68 static int config_nameserver(struct server_state **servers, int *nservers,
69                              char *str);
70 static int set_search(ares_channel channel, const char *str);
71 static int set_options(ares_channel channel, const char *str);
72 static const char *try_option(const char *p, const char *q, const char *opt);
73 #ifndef WIN32
74 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
75 static int ip_addr(const char *s, int len, struct in_addr *addr);
76 static void natural_mask(struct apattern *pat);
77 static int config_domain(ares_channel channel, char *str);
78 static int config_lookup(ares_channel channel, const char *str,
79                          const char *bindch, const char *filech);
80 static int config_sortlist(struct apattern **sortlist, int *nsort,
81                            const char *str);
82 static char *try_config(char *s, const char *opt);
83 #endif
84
85 int ares_init(ares_channel *channelptr)
86 {
87   return ares_init_options(channelptr, NULL, 0);
88 }
89
90 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
91                       int optmask)
92 {
93   ares_channel channel;
94   int i;
95   int status = ARES_SUCCESS;
96   struct server_state *server;
97   struct timeval tv;
98
99 #ifdef CURLDEBUG
100   const char *env = getenv("CARES_MEMDEBUG");
101
102   if (env)
103     curl_memdebug(env);
104   env = getenv("CARES_MEMLIMIT");
105   if (env)
106     curl_memlimit(atoi(env));
107 #endif
108
109   channel = malloc(sizeof(struct ares_channeldata));
110   if (!channel) {
111     *channelptr = NULL;
112     return ARES_ENOMEM;
113   }
114
115   /* Set everything to distinguished values so we know they haven't
116    * been set yet.
117    */
118   channel->flags = -1;
119   channel->timeout = -1;
120   channel->tries = -1;
121   channel->ndots = -1;
122   channel->udp_port = -1;
123   channel->tcp_port = -1;
124   channel->nservers = -1;
125   channel->ndomains = -1;
126   channel->nsort = -1;
127   channel->lookups = NULL;
128   channel->queries = NULL;
129   channel->domains = NULL;
130   channel->sortlist = NULL;
131   channel->servers = NULL;
132   channel->sock_state_cb = NULL;
133   channel->sock_state_cb_data = NULL;
134
135   /* Initialize configuration by each of the four sources, from highest
136    * precedence to lowest.
137    */
138
139   if (status == ARES_SUCCESS) {
140   status = init_by_options(channel, options, optmask);
141     if (status != ARES_SUCCESS)
142       DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
143                      ares_strerror(status)));
144   }
145   if (status == ARES_SUCCESS) {
146     status = init_by_environment(channel);
147     if (status != ARES_SUCCESS)
148       DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
149                      ares_strerror(status)));
150   }
151   if (status == ARES_SUCCESS) {
152     status = init_by_resolv_conf(channel);
153     if (status != ARES_SUCCESS)
154       DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
155                      ares_strerror(status)));
156   }
157   if (status == ARES_SUCCESS) {
158     status = init_by_defaults(channel);
159     if (status != ARES_SUCCESS)
160       DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
161                      ares_strerror(status)));
162   }
163   if (status != ARES_SUCCESS)
164     {
165       /* Something failed; clean up memory we may have allocated. */
166       if (channel->servers)
167         free(channel->servers);
168       if (channel->domains)
169         {
170           for (i = 0; i < channel->ndomains; i++)
171             free(channel->domains[i]);
172           free(channel->domains);
173         }
174       if (channel->sortlist)
175         free(channel->sortlist);
176       if(channel->lookups)
177         free(channel->lookups);
178       free(channel);
179       return status;
180     }
181
182   /* Trim to one server if ARES_FLAG_PRIMARY is set. */
183   if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
184     channel->nservers = 1;
185
186   /* Initialize server states. */
187   for (i = 0; i < channel->nservers; i++)
188     {
189       server = &channel->servers[i];
190       server->udp_socket = ARES_SOCKET_BAD;
191       server->tcp_socket = ARES_SOCKET_BAD;
192       server->tcp_lenbuf_pos = 0;
193       server->tcp_buffer = NULL;
194       server->qhead = NULL;
195       server->qtail = NULL;
196     }
197
198   /* Choose a somewhat random query ID.  The main point is to avoid
199    * collisions with stale queries.  An attacker trying to spoof a DNS
200    * answer also has to guess the query ID, but it's only a 16-bit
201    * field, so there's not much to be done about that.
202    */
203   gettimeofday(&tv, NULL);
204   channel->next_id = (unsigned short)
205     ((tv.tv_sec ^ tv.tv_usec ^ getpid()) & 0xffff);
206
207   channel->queries = NULL;
208
209   *channelptr = channel;
210   return ARES_SUCCESS;
211 }
212
213 static int init_by_options(ares_channel channel, struct ares_options *options,
214                            int optmask)
215 {
216   int i;
217
218   /* Easy stuff. */
219   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
220     channel->flags = options->flags;
221   if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
222     channel->timeout = options->timeout;
223   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
224     channel->tries = options->tries;
225   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
226     channel->ndots = options->ndots;
227   if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
228     channel->udp_port = options->udp_port;
229   if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
230     channel->tcp_port = options->tcp_port;
231   if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
232     {
233       channel->sock_state_cb = options->sock_state_cb;
234       channel->sock_state_cb_data = options->sock_state_cb_data;
235     }
236
237   /* Copy the servers, if given. */
238   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
239     {
240       /* Avoid zero size allocations at any cost */
241       if (options->nservers > 0)
242         {
243           channel->servers =
244             malloc(options->nservers * sizeof(struct server_state));
245           if (!channel->servers)
246             return ARES_ENOMEM;
247           for (i = 0; i < options->nservers; i++)
248             channel->servers[i].addr = options->servers[i];
249         }
250       channel->nservers = options->nservers;
251     }
252
253   /* Copy the domains, if given.  Keep channel->ndomains consistent so
254    * we can clean up in case of error.
255    */
256   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
257     {
258       /* Avoid zero size allocations at any cost */
259       if (options->ndomains > 0)
260       {
261         channel->domains = malloc(options->ndomains * sizeof(char *));
262         if (!channel->domains)
263           return ARES_ENOMEM;
264         for (i = 0; i < options->ndomains; i++)
265           {
266             channel->ndomains = i;
267             channel->domains[i] = strdup(options->domains[i]);
268             if (!channel->domains[i])
269               return ARES_ENOMEM;
270           }
271       }
272       channel->ndomains = options->ndomains;
273     }
274
275   /* Set lookups, if given. */
276   if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
277     {
278       channel->lookups = strdup(options->lookups);
279       if (!channel->lookups)
280         return ARES_ENOMEM;
281     }
282
283   return ARES_SUCCESS;
284 }
285
286 static int init_by_environment(ares_channel channel)
287 {
288   const char *localdomain, *res_options;
289   int status;
290
291   localdomain = getenv("LOCALDOMAIN");
292   if (localdomain && channel->ndomains == -1)
293     {
294       status = set_search(channel, localdomain);
295       if (status != ARES_SUCCESS)
296         return status;
297     }
298
299   res_options = getenv("RES_OPTIONS");
300   if (res_options)
301     {
302       status = set_options(channel, res_options);
303       if (status != ARES_SUCCESS)
304         return status;
305     }
306
307   return ARES_SUCCESS;
308 }
309
310 #ifdef WIN32
311 /*
312  * Warning: returns a dynamically allocated buffer, the user MUST
313  * use free() if the function returns 1
314  */
315 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
316 {
317   /* Test for the size we need */
318   DWORD size = 0;
319   int result;
320
321   result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
322   if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
323     return 0;
324   *obuf = malloc(size+1);
325   if (!*obuf)
326     return 0;
327
328   if (RegQueryValueEx(hKey, subkey, 0, NULL,
329                       (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
330   {
331     free(*obuf);
332     return 0;
333   }
334   if (size == 1)
335   {
336     free(*obuf);
337     return 0;
338   }
339   return 1;
340 }
341
342 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
343 {
344   char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
345   DWORD enum_size = 39;
346   int idx = 0;
347   HKEY hVal;
348
349   while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
350                       NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
351   {
352     int rc;
353
354     enum_size = 39;
355     if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
356         ERROR_SUCCESS)
357       continue;
358     rc = get_res_nt(hVal, subkey, obuf);
359       RegCloseKey(hVal);
360     if (rc)
361       return 1;
362     }
363   return 0;
364 }
365
366 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
367 {
368   FIXED_INFO    *fi   = alloca (sizeof(*fi));
369   DWORD          size = sizeof (*fi);
370   typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
371   get_net_param_func GetNetworkParams;  /* available only on Win-98/2000+ */
372   HMODULE        handle;
373   IP_ADDR_STRING *ipAddr;
374   int            i, count = 0;
375   int            debug  = 0;
376   size_t         ip_size = sizeof("255.255.255.255,")-1;
377   size_t         left = ret_size;
378   char          *ret = ret_buf;
379   HRESULT        res;
380
381   if (!fi)
382      return (0);
383
384   handle = LoadLibrary ("iphlpapi.dll");
385   if (!handle)
386      return (0);
387
388   GetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
389   if (!GetNetworkParams)
390      goto quit;
391
392   res = (*GetNetworkParams) (fi, &size);
393   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
394      goto quit;
395
396   fi = alloca (size);
397   if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS)
398      goto quit;
399
400   if (debug)
401   {
402     printf ("Host Name: %s\n", fi->HostName);
403     printf ("Domain Name: %s\n", fi->DomainName);
404     printf ("DNS Servers:\n"
405             "    %s (primary)\n", fi->DnsServerList.IpAddress.String);
406   }
407   if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
408       inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
409       left > ip_size)
410   {
411     ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
412     left -= ret - ret_buf;
413     count++;
414   }
415
416   for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
417        ipAddr = ipAddr->Next, i++)
418   {
419     if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
420     {
421        ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
422        left -= ret - ret_buf;
423        count++;
424     }
425     if (debug)
426        printf ("    %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
427   }
428
429 quit:
430   if (handle)
431      FreeLibrary (handle);
432
433   if (debug && left <= ip_size)
434      printf ("Too many nameservers. Truncating to %d addressess", count);
435   if (ret > ret_buf)
436      ret[-1] = '\0';
437   return (count);
438 }
439 #endif
440
441 static int init_by_resolv_conf(ares_channel channel)
442 {
443   char *line = NULL;
444   int status = -1, nservers = 0, nsort = 0;
445   struct server_state *servers = NULL;
446   struct apattern *sortlist = NULL;
447
448 #ifdef WIN32
449
450     /*
451   NameServer info via IPHLPAPI (IP helper API):
452     GetNetworkParams() should be the trusted source for this.
453     Available in Win-98/2000 and later. If that fail, fall-back to
454     registry information.
455
456   NameServer Registry:
457
458    On Windows 9X, the DNS server can be found in:
459 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
460
461         On Windows NT/2000/XP/2003:
462 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
463         or
464 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
465         or
466 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
467 NameServer
468         or
469 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
470 DhcpNameServer
471    */
472
473   HKEY mykey;
474   HKEY subkey;
475   DWORD data_type;
476   DWORD bytes;
477   DWORD result;
478   char  buf[256];
479
480   if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
481      return ARES_SUCCESS;
482
483   if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
484   {
485     status = config_nameserver(&servers, &nservers, buf);
486     if (status == ARES_SUCCESS)
487       goto okay;
488   }
489
490   if (IS_NT())
491   {
492     if (RegOpenKeyEx(
493           HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
494           KEY_READ, &mykey
495           ) == ERROR_SUCCESS)
496     {
497       RegOpenKeyEx(mykey, "Interfaces", 0,
498                    KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
499       if (get_res_nt(mykey, NAMESERVER, &line))
500       {
501         status = config_nameserver(&servers, &nservers, line);
502         free(line);
503       }
504       else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
505       {
506         status = config_nameserver(&servers, &nservers, line);
507         free(line);
508       }
509       /* Try the interfaces */
510       else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
511       {
512         status = config_nameserver(&servers, &nservers, line);
513         free(line);
514       }
515       else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
516       {
517         status = config_nameserver(&servers, &nservers, line);
518         free(line);
519       }
520       RegCloseKey(subkey);
521       RegCloseKey(mykey);
522     }
523   }
524   else
525   {
526     if (RegOpenKeyEx(
527           HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
528           KEY_READ, &mykey
529           ) == ERROR_SUCCESS)
530     {
531       if ((result = RegQueryValueEx(
532              mykey, NAMESERVER, NULL, &data_type,
533              NULL, &bytes
534              )
535             ) == ERROR_SUCCESS ||
536           result == ERROR_MORE_DATA)
537       {
538         if (bytes)
539         {
540           line = (char *)malloc(bytes+1);
541           if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
542                               (unsigned char *)line, &bytes) ==
543               ERROR_SUCCESS)
544           {
545             status = config_nameserver(&servers, &nservers, line);
546           }
547           free(line);
548         }
549       }
550     }
551     RegCloseKey(mykey);
552   }
553
554   if (status == ARES_SUCCESS)
555     status = ARES_EOF;
556
557 #elif defined(__riscos__)
558
559   /* Under RISC OS, name servers are listed in the
560      system variable Inet$Resolvers, space separated. */
561
562   line = getenv("Inet$Resolvers");
563   status = ARES_EOF;
564   if (line) {
565     char *resolvers = strdup(line), *pos, *space;
566
567     if (!resolvers)
568       return ARES_ENOMEM;
569
570     pos = resolvers;
571     do {
572       space = strchr(pos, ' ');
573       if (space)
574         *space = 0;
575       status = config_nameserver(&servers, &nservers, pos);
576       if (status != ARES_SUCCESS)
577         break;
578       pos = space + 1;
579     } while (space);
580
581     if (status == ARES_SUCCESS)
582       status = ARES_EOF;
583
584     free(resolvers);
585   }
586
587 #elif defined(WATT32)
588   int i;
589
590   sock_init();
591   for (i = 0; def_nameservers[i]; i++)
592       ;
593   if (i == 0)
594     return ARES_SUCCESS; /* use localhost DNS server */
595
596   nservers = i;
597   servers = calloc(sizeof(*servers), i);
598   if (!servers)
599      return ARES_ENOMEM;
600
601   for (i = 0; def_nameservers[i]; i++)
602       servers[i].addr.s_addr = htonl(def_nameservers[i]);
603   status = ARES_EOF;
604
605 #else
606   {
607     char *p;
608     FILE *fp;
609     int linesize;
610
611     fp = fopen(PATH_RESOLV_CONF, "r");
612     if (!fp)
613       return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
614     while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
615     {
616       if ((p = try_config(line, "domain")) && channel->ndomains == -1)
617         status = config_domain(channel, p);
618       else if ((p = try_config(line, "lookup")) && !channel->lookups)
619         status = config_lookup(channel, p, "bind", "file");
620       else if ((p = try_config(line, "search")) && channel->ndomains == -1)
621         status = set_search(channel, p);
622       else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
623         status = config_nameserver(&servers, &nservers, p);
624       else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
625         status = config_sortlist(&sortlist, &nsort, p);
626       else if ((p = try_config(line, "options")))
627         status = set_options(channel, p);
628       else
629         status = ARES_SUCCESS;
630       if (status != ARES_SUCCESS)
631         break;
632     }
633     fclose(fp);
634
635     if (!channel->lookups) {
636       /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
637       fp = fopen("/etc/nsswitch.conf", "r");
638       if (fp) {
639         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
640         {
641           if ((p = try_config(line, "hosts:")) && !channel->lookups)
642             status = config_lookup(channel, p, "dns", "files");
643         }
644         fclose(fp);
645       }
646     }
647
648     if (!channel->lookups) {
649       /* Linux / GNU libc 2.x and possibly others have host.conf */
650       fp = fopen("/etc/host.conf", "r");
651       if (fp) {
652         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
653         {
654           if ((p = try_config(line, "order")) && !channel->lookups)
655             status = config_lookup(channel, p, "bind", "hosts");
656         }
657         fclose(fp);
658       }
659     }
660
661     if (!channel->lookups) {
662       /* Tru64 uses /etc/svc.conf */
663       fp = fopen("/etc/svc.conf", "r");
664       if (fp) {
665         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
666         {
667           if ((p = try_config(line, "hosts=")) && !channel->lookups)
668             status = config_lookup(channel, p, "bind", "local");
669         }
670         fclose(fp);
671       }
672     }
673
674     if(line)
675       free(line);
676   }
677
678 #endif
679
680   /* Handle errors. */
681   if (status != ARES_EOF)
682     {
683       if (servers != NULL)
684         free(servers);
685       if (sortlist != NULL)
686         free(sortlist);
687       return status;
688     }
689
690   /* If we got any name server entries, fill them in. */
691 #ifdef WIN32
692 okay:
693 #endif
694   if (servers)
695     {
696       channel->servers = servers;
697       channel->nservers = nservers;
698     }
699
700   /* If we got any sortlist entries, fill them in. */
701   if (sortlist)
702     {
703       channel->sortlist = sortlist;
704       channel->nsort = nsort;
705     }
706
707   return ARES_SUCCESS;
708 }
709
710 static int init_by_defaults(ares_channel channel)
711 {
712   char hostname[MAXHOSTNAMELEN + 1];
713
714   if (channel->flags == -1)
715     channel->flags = 0;
716   if (channel->timeout == -1)
717     channel->timeout = DEFAULT_TIMEOUT;
718   if (channel->tries == -1)
719     channel->tries = DEFAULT_TRIES;
720   if (channel->ndots == -1)
721     channel->ndots = 1;
722   if (channel->udp_port == -1)
723     channel->udp_port = htons(NAMESERVER_PORT);
724   if (channel->tcp_port == -1)
725     channel->tcp_port = htons(NAMESERVER_PORT);
726
727   if (channel->nservers == -1)
728     {
729       /* If nobody specified servers, try a local named. */
730       channel->servers = malloc(sizeof(struct server_state));
731       if (!channel->servers)
732         return ARES_ENOMEM;
733       channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
734       channel->nservers = 1;
735     }
736
737   if (channel->ndomains == -1)
738     {
739       /* Derive a default domain search list from the kernel hostname,
740        * or set it to empty if the hostname isn't helpful.
741        */
742       if (gethostname(hostname, sizeof(hostname)) == -1
743           || !strchr(hostname, '.'))
744         {
745           channel->ndomains = 0;
746         }
747       else
748         {
749           channel->domains = malloc(sizeof(char *));
750           if (!channel->domains)
751             return ARES_ENOMEM;
752           channel->ndomains = 0;
753           channel->domains[0] = strdup(strchr(hostname, '.') + 1);
754           if (!channel->domains[0])
755             return ARES_ENOMEM;
756           channel->ndomains = 1;
757         }
758     }
759
760   if (channel->nsort == -1)
761     {
762       channel->sortlist = NULL;
763       channel->nsort = 0;
764     }
765
766   if (!channel->lookups)
767     {
768       channel->lookups = strdup("fb");
769       if (!channel->lookups)
770         return ARES_ENOMEM;
771     }
772
773   return ARES_SUCCESS;
774 }
775
776 #ifndef WIN32
777 static int config_domain(ares_channel channel, char *str)
778 {
779   char *q;
780
781   /* Set a single search domain. */
782   q = str;
783   while (*q && !ISSPACE(*q))
784     q++;
785   *q = 0;
786   return set_search(channel, str);
787 }
788
789 static int config_lookup(ares_channel channel, const char *str,
790                          const char *bindch, const char *filech)
791 {
792   char lookups[3], *l;
793   const char *p;
794
795   /* Set the lookup order.  Only the first letter of each work
796    * is relevant, and it has to be "b" for DNS or "f" for the
797    * host file.  Ignore everything else.
798    */
799   l = lookups;
800   p = str;
801   while (*p)
802     {
803       if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
804         if (*p == *bindch) *l++ = 'b';
805         else *l++ = 'f';
806       }
807       while (*p && !ISSPACE(*p) && (*p != ','))
808         p++;
809       while (*p && (ISSPACE(*p) || (*p == ',')))
810         p++;
811     }
812   *l = 0;
813   channel->lookups = strdup(lookups);
814   return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
815 }
816
817 #endif
818
819 static int config_nameserver(struct server_state **servers, int *nservers,
820                              char *str)
821 {
822   struct in_addr addr;
823   struct server_state *newserv;
824   /* On Windows, there may be more than one nameserver specified in the same
825    * registry key, so we parse it as a space or comma seperated list.
826    */
827 #ifdef WIN32
828   char *p = str;
829   char *begin = str;
830   int more = 1;
831   while (more)
832   {
833     more = 0;
834     while (*p && !ISSPACE(*p) && *p != ',')
835       p++;
836
837     if (*p)
838     {
839       *p = 0;
840       more = 1;
841     }
842
843     /* Skip multiple spaces or trailing spaces */
844     if (!*begin)
845     {
846       begin = ++p;
847       continue;
848     }
849
850     /* This is the part that actually sets the nameserver */
851     addr.s_addr = inet_addr(begin);
852     if (addr.s_addr == INADDR_NONE)
853       continue;
854     newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
855     if (!newserv)
856       return ARES_ENOMEM;
857     newserv[*nservers].addr = addr;
858     *servers = newserv;
859     (*nservers)++;
860
861     if (!more)
862       break;
863     begin = ++p;
864   }
865 #else
866   /* Add a nameserver entry, if this is a valid address. */
867   addr.s_addr = inet_addr(str);
868   if (addr.s_addr == INADDR_NONE)
869     return ARES_SUCCESS;
870   newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
871   if (!newserv)
872     return ARES_ENOMEM;
873   newserv[*nservers].addr = addr;
874   *servers = newserv;
875   (*nservers)++;
876 #endif
877   return ARES_SUCCESS;
878 }
879
880 #ifndef WIN32
881 static int config_sortlist(struct apattern **sortlist, int *nsort,
882                            const char *str)
883 {
884   struct apattern pat;
885   const char *q;
886
887   /* Add sortlist entries. */
888   while (*str && *str != ';')
889     {
890       int bits;
891       char ipbuf[16], ipbufpfx[32];
892       /* Find just the IP */
893       q = str;
894       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
895         q++;
896       memcpy(ipbuf, str, (int)(q-str));
897       ipbuf[(int)(q-str)] = 0;
898       /* Find the prefix */
899       if (*q == '/')
900         {
901           const char *str2 = q+1;
902           while (*q && *q != ';' && !ISSPACE(*q))
903             q++;
904           memcpy(ipbufpfx, str, (int)(q-str));
905           ipbufpfx[(int)(q-str)] = 0;
906           str = str2;
907         }
908       else
909         ipbufpfx[0] = 0;
910       /* Lets see if it is CIDR */
911       /* First we'll try IPv6 */
912       if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf,
913                                      &pat.addr.addr6,
914                                      sizeof(pat.addr.addr6))) > 0)
915         {
916           pat.type = PATTERN_CIDR;
917           pat.mask.bits = (unsigned short)bits;
918           pat.family = AF_INET6;
919           if (!sortlist_alloc(sortlist, nsort, &pat))
920             return ARES_ENOMEM;
921         }
922       if (ipbufpfx &&
923           (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
924                                      sizeof(pat.addr.addr4))) > 0)
925         {
926           pat.type = PATTERN_CIDR;
927           pat.mask.bits = (unsigned short)bits;
928           pat.family = AF_INET;
929           if (!sortlist_alloc(sortlist, nsort, &pat))
930             return ARES_ENOMEM;
931         }
932       /* See if it is just a regular IP */
933       else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
934         {
935           if (ipbufpfx)
936             {
937               memcpy(ipbuf, str, (int)(q-str));
938               ipbuf[(int)(q-str)] = 0;
939               if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
940                 natural_mask(&pat);
941             }
942           else
943             natural_mask(&pat);
944           pat.family = AF_INET;
945           pat.type = PATTERN_MASK;
946           if (!sortlist_alloc(sortlist, nsort, &pat))
947             return ARES_ENOMEM;
948         }
949       else
950         {
951           while (*q && *q != ';' && !ISSPACE(*q))
952             q++;
953         }
954       str = q;
955       while (ISSPACE(*str))
956         str++;
957     }
958
959   return ARES_SUCCESS;
960 }
961 #endif
962
963 static int set_search(ares_channel channel, const char *str)
964 {
965   int n;
966   const char *p, *q;
967
968   if(channel->ndomains != -1) {
969     /* if we already have some domains present, free them first */
970     for(n=0; n < channel->ndomains; n++)
971       free(channel->domains[n]);
972     free(channel->domains);
973     channel->domains = NULL;
974     channel->ndomains = -1;
975   }
976
977   /* Count the domains given. */
978   n = 0;
979   p = str;
980   while (*p)
981     {
982       while (*p && !ISSPACE(*p))
983         p++;
984       while (ISSPACE(*p))
985         p++;
986       n++;
987     }
988
989   if (!n)
990     {
991       channel->ndomains = 0;
992       return ARES_SUCCESS;
993     }
994
995   channel->domains = malloc(n * sizeof(char *));
996   if (!channel->domains)
997     return ARES_ENOMEM;
998
999   /* Now copy the domains. */
1000   n = 0;
1001   p = str;
1002   while (*p)
1003     {
1004       channel->ndomains = n;
1005       q = p;
1006       while (*q && !ISSPACE(*q))
1007         q++;
1008       channel->domains[n] = malloc(q - p + 1);
1009       if (!channel->domains[n])
1010         return ARES_ENOMEM;
1011       memcpy(channel->domains[n], p, q - p);
1012       channel->domains[n][q - p] = 0;
1013       p = q;
1014       while (ISSPACE(*p))
1015         p++;
1016       n++;
1017     }
1018   channel->ndomains = n;
1019
1020   return ARES_SUCCESS;
1021 }
1022
1023 static int set_options(ares_channel channel, const char *str)
1024 {
1025   const char *p, *q, *val;
1026
1027   p = str;
1028   while (*p)
1029     {
1030       q = p;
1031       while (*q && !ISSPACE(*q))
1032         q++;
1033       val = try_option(p, q, "ndots:");
1034       if (val && channel->ndots == -1)
1035         channel->ndots = atoi(val);
1036       val = try_option(p, q, "retrans:");
1037       if (val && channel->timeout == -1)
1038         channel->timeout = atoi(val);
1039       val = try_option(p, q, "retry:");
1040       if (val && channel->tries == -1)
1041         channel->tries = atoi(val);
1042       p = q;
1043       while (ISSPACE(*p))
1044         p++;
1045     }
1046
1047   return ARES_SUCCESS;
1048 }
1049
1050 #ifndef WIN32
1051 static char *try_config(char *s, const char *opt)
1052 {
1053   size_t len;
1054
1055   len = strlen(opt);
1056   if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len]))
1057     return NULL;
1058   s += len;
1059   while (ISSPACE(*s))
1060     s++;
1061   return s;
1062 }
1063
1064 #endif
1065
1066 static const char *try_option(const char *p, const char *q, const char *opt)
1067 {
1068   size_t len = strlen(opt);
1069   return ((size_t)(q - p) > len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1070 }
1071
1072 #ifndef WIN32
1073 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1074                           struct apattern *pat)
1075 {
1076   struct apattern *newsort;
1077   newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1078   if (!newsort)
1079     return 0;
1080   newsort[*nsort] = *pat;
1081   *sortlist = newsort;
1082   (*nsort)++;
1083   return 1;
1084 }
1085
1086 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1087 {
1088
1089   /* Four octets and three periods yields at most 15 characters. */
1090   if (len > 15)
1091     return -1;
1092
1093   addr->s_addr = inet_addr(ipbuf);
1094   if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1095     return -1;
1096   return 0;
1097 }
1098
1099 static void natural_mask(struct apattern *pat)
1100 {
1101   struct in_addr addr;
1102
1103   /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
1104    * but portable.
1105    */
1106   addr.s_addr = ntohl(pat->addr.addr4.s_addr);
1107
1108   /* This is out of date in the CIDR world, but some people might
1109    * still rely on it.
1110    */
1111   if (IN_CLASSA(addr.s_addr))
1112     pat->mask.addr.addr4.s_addr = htonl(IN_CLASSA_NET);
1113   else if (IN_CLASSB(addr.s_addr))
1114     pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
1115   else
1116     pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
1117 }
1118 #endif