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