ares_init.c (16632B)
1 /* MIT License 2 * 3 * Copyright (c) 1998 Massachusetts Institute of Technology 4 * Copyright (c) 2007 Daniel Stenberg 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * SPDX-License-Identifier: MIT 26 */ 27 28 #include "ares_private.h" 29 30 #ifdef HAVE_SYS_PARAM_H 31 # include <sys/param.h> 32 #endif 33 34 #ifdef HAVE_NETINET_IN_H 35 # include <netinet/in.h> 36 #endif 37 38 #ifdef HAVE_NETDB_H 39 # include <netdb.h> 40 #endif 41 42 #ifdef HAVE_ARPA_INET_H 43 # include <arpa/inet.h> 44 #endif 45 46 #include "ares_nameser.h" 47 48 #if defined(ANDROID) || defined(__ANDROID__) 49 # include <sys/system_properties.h> 50 # include "ares_android.h" 51 /* From the Bionic sources */ 52 # define DNS_PROP_NAME_PREFIX "net.dns" 53 # define MAX_DNS_PROPERTIES 8 54 #endif 55 56 #if defined(CARES_USE_LIBRESOLV) 57 # include <resolv.h> 58 #endif 59 60 #if defined(USE_WINSOCK) && defined(HAVE_IPHLPAPI_H) 61 # include <iphlpapi.h> 62 #endif 63 64 #include "ares_inet_net_pton.h" 65 #include "event/ares_event.h" 66 67 int ares_init(ares_channel_t **channelptr) 68 { 69 return ares_init_options(channelptr, NULL, 0); 70 } 71 72 static int ares_query_timeout_cmp_cb(const void *arg1, const void *arg2) 73 { 74 const ares_query_t *q1 = arg1; 75 const ares_query_t *q2 = arg2; 76 77 if (q1->timeout.sec > q2->timeout.sec) { 78 return 1; 79 } 80 if (q1->timeout.sec < q2->timeout.sec) { 81 return -1; 82 } 83 84 if (q1->timeout.usec > q2->timeout.usec) { 85 return 1; 86 } 87 if (q1->timeout.usec < q2->timeout.usec) { 88 return -1; 89 } 90 91 return 0; 92 } 93 94 static int server_sort_cb(const void *data1, const void *data2) 95 { 96 const ares_server_t *s1 = data1; 97 const ares_server_t *s2 = data2; 98 99 if (s1->consec_failures < s2->consec_failures) { 100 return -1; 101 } 102 if (s1->consec_failures > s2->consec_failures) { 103 return 1; 104 } 105 if (s1->idx < s2->idx) { 106 return -1; 107 } 108 if (s1->idx > s2->idx) { 109 return 1; 110 } 111 return 0; 112 } 113 114 static void server_destroy_cb(void *data) 115 { 116 if (data == NULL) { 117 return; /* LCOV_EXCL_LINE: DefensiveCoding */ 118 } 119 ares_destroy_server(data); 120 } 121 122 static ares_status_t init_by_defaults(ares_channel_t *channel) 123 { 124 char *hostname = NULL; 125 ares_status_t rc = ARES_SUCCESS; 126 #ifdef HAVE_GETHOSTNAME 127 const char *dot; 128 #endif 129 struct ares_addr addr; 130 ares_llist_t *sconfig = NULL; 131 132 /* Enable EDNS by default */ 133 if (!(channel->optmask & ARES_OPT_FLAGS)) { 134 channel->flags = ARES_FLAG_EDNS; 135 } 136 if (channel->ednspsz == 0) { 137 channel->ednspsz = EDNSPACKETSZ; 138 } 139 140 if (channel->timeout == 0) { 141 channel->timeout = DEFAULT_TIMEOUT; 142 } 143 144 if (channel->tries == 0) { 145 channel->tries = DEFAULT_TRIES; 146 } 147 148 if (ares_slist_len(channel->servers) == 0) { 149 /* Add a default local named server to the channel unless configured not 150 * to (in which case return an error). 151 */ 152 if (channel->flags & ARES_FLAG_NO_DFLT_SVR) { 153 rc = ARES_ENOSERVER; 154 goto error; 155 } 156 157 addr.family = AF_INET; 158 addr.addr.addr4.s_addr = htonl(INADDR_LOOPBACK); 159 160 rc = ares_sconfig_append(channel, &sconfig, &addr, 0, 0, NULL); 161 if (rc != ARES_SUCCESS) { 162 goto error; /* LCOV_EXCL_LINE: OutOfMemory */ 163 } 164 165 rc = ares_servers_update(channel, sconfig, ARES_FALSE); 166 ares_llist_destroy(sconfig); 167 168 if (rc != ARES_SUCCESS) { 169 goto error; 170 } 171 } 172 173 if (channel->ndomains == 0) { 174 /* Derive a default domain search list from the kernel hostname, 175 * or set it to empty if the hostname isn't helpful. 176 */ 177 #ifndef HAVE_GETHOSTNAME 178 channel->ndomains = 0; /* default to none */ 179 #else 180 size_t len = 256; 181 channel->ndomains = 0; /* default to none */ 182 183 hostname = ares_malloc(len); 184 if (!hostname) { 185 rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ 186 goto error; /* LCOV_EXCL_LINE: OutOfMemory */ 187 } 188 189 if (gethostname(hostname, (GETHOSTNAME_TYPE_ARG2)len) != 0) { 190 /* Lets not treat a gethostname failure as critical, since we 191 * are ok if gethostname doesn't even exist */ 192 *hostname = '\0'; 193 } 194 195 dot = strchr(hostname, '.'); 196 if (dot) { 197 /* a dot was found */ 198 channel->domains = ares_malloc(sizeof(char *)); 199 if (!channel->domains) { 200 rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ 201 goto error; /* LCOV_EXCL_LINE: OutOfMemory */ 202 } 203 channel->domains[0] = ares_strdup(dot + 1); 204 if (!channel->domains[0]) { 205 rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ 206 goto error; /* LCOV_EXCL_LINE: OutOfMemory */ 207 } 208 channel->ndomains = 1; 209 } 210 #endif 211 } 212 213 if (channel->nsort == 0) { 214 channel->sortlist = NULL; 215 } 216 217 if (!channel->lookups) { 218 channel->lookups = ares_strdup("fb"); 219 if (!channel->lookups) { 220 rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ 221 } 222 } 223 224 /* Set default fields for server failover behavior */ 225 if (!(channel->optmask & ARES_OPT_SERVER_FAILOVER)) { 226 channel->server_retry_chance = DEFAULT_SERVER_RETRY_CHANCE; 227 channel->server_retry_delay = DEFAULT_SERVER_RETRY_DELAY; 228 } 229 230 error: 231 if (hostname) { 232 ares_free(hostname); 233 } 234 235 return rc; 236 } 237 238 int ares_init_options(ares_channel_t **channelptr, 239 const struct ares_options *options, int optmask) 240 { 241 ares_channel_t *channel; 242 ares_status_t status = ARES_SUCCESS; 243 244 if (ares_library_initialized() != ARES_SUCCESS) { 245 return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ 246 } 247 248 channel = ares_malloc_zero(sizeof(*channel)); 249 if (!channel) { 250 *channelptr = NULL; 251 return ARES_ENOMEM; 252 } 253 254 /* We are in a good state */ 255 channel->sys_up = ARES_TRUE; 256 257 /* One option where zero is valid, so set default value here */ 258 channel->ndots = 1; 259 260 status = ares_channel_threading_init(channel); 261 if (status != ARES_SUCCESS) { 262 goto done; 263 } 264 265 /* Generate random key */ 266 channel->rand_state = ares_init_rand_state(); 267 if (channel->rand_state == NULL) { 268 status = ARES_ENOMEM; 269 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", 270 ares_strerror(status))); 271 goto done; 272 } 273 274 /* Initialize Server List */ 275 channel->servers = 276 ares_slist_create(channel->rand_state, server_sort_cb, server_destroy_cb); 277 if (channel->servers == NULL) { 278 status = ARES_ENOMEM; 279 goto done; 280 } 281 282 /* Initialize our lists of queries */ 283 channel->all_queries = ares_llist_create(NULL); 284 if (channel->all_queries == NULL) { 285 status = ARES_ENOMEM; 286 goto done; 287 } 288 289 channel->queries_by_qid = ares_htable_szvp_create(NULL); 290 if (channel->queries_by_qid == NULL) { 291 status = ARES_ENOMEM; 292 goto done; 293 } 294 295 channel->queries_by_timeout = 296 ares_slist_create(channel->rand_state, ares_query_timeout_cmp_cb, NULL); 297 if (channel->queries_by_timeout == NULL) { 298 status = ARES_ENOMEM; 299 goto done; 300 } 301 302 channel->connnode_by_socket = ares_htable_asvp_create(NULL); 303 if (channel->connnode_by_socket == NULL) { 304 status = ARES_ENOMEM; 305 goto done; 306 } 307 308 /* Initialize configuration by each of the four sources, from highest 309 * precedence to lowest. 310 */ 311 312 status = ares_init_by_options(channel, options, optmask); 313 if (status != ARES_SUCCESS) { 314 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", 315 ares_strerror(status))); 316 /* If we fail to apply user-specified options, fail the whole init process 317 */ 318 goto done; 319 } 320 321 /* Go ahead and let it initialize the query cache even if the ttl is 0 and 322 * completely unused. This reduces the number of different code paths that 323 * might be followed even if there is a minor performance hit. */ 324 status = ares_qcache_create(channel->rand_state, channel->qcache_max_ttl, 325 &channel->qcache); 326 if (status != ARES_SUCCESS) { 327 goto done; /* LCOV_EXCL_LINE: OutOfMemory */ 328 } 329 330 if (status == ARES_SUCCESS) { 331 status = ares_init_by_sysconfig(channel); 332 if (status != ARES_SUCCESS) { 333 DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n", 334 ares_strerror(status))); 335 } 336 } 337 338 /* 339 * No matter what failed or succeeded, seed defaults to provide 340 * useful behavior for things that we missed. 341 */ 342 status = init_by_defaults(channel); 343 if (status != ARES_SUCCESS) { 344 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", 345 ares_strerror(status))); 346 goto done; 347 } 348 349 ares_set_socket_functions_def(channel); 350 351 /* Initialize the event thread */ 352 if (channel->optmask & ARES_OPT_EVENT_THREAD) { 353 ares_event_thread_t *e = NULL; 354 355 status = ares_event_thread_init(channel); 356 if (status != ARES_SUCCESS) { 357 goto done; /* LCOV_EXCL_LINE: UntestablePath */ 358 } 359 360 /* Initialize monitor for configuration changes. In some rare cases, 361 * ARES_ENOTIMP may occur (OpenWatcom), ignore this. */ 362 e = channel->sock_state_cb_data; 363 status = ares_event_configchg_init(&e->configchg, e); 364 if (status != ARES_SUCCESS && status != ARES_ENOTIMP) { 365 goto done; /* LCOV_EXCL_LINE: UntestablePath */ 366 } 367 status = ARES_SUCCESS; 368 } 369 370 done: 371 if (status != ARES_SUCCESS) { 372 ares_destroy(channel); 373 return (int)status; 374 } 375 376 *channelptr = channel; 377 return ARES_SUCCESS; 378 } 379 380 static void *ares_reinit_thread(void *arg) 381 { 382 ares_channel_t *channel = arg; 383 ares_status_t status; 384 385 /* ares_init_by_sysconfig() will lock when applying the config, but not 386 * when retrieving. */ 387 status = ares_init_by_sysconfig(channel); 388 if (status != ARES_SUCCESS) { 389 DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n", 390 ares_strerror(status))); 391 } 392 393 ares_channel_lock(channel); 394 395 /* Flush cached queries on reinit */ 396 if (status == ARES_SUCCESS && channel->qcache) { 397 ares_qcache_flush(channel->qcache); 398 } 399 400 channel->reinit_pending = ARES_FALSE; 401 ares_channel_unlock(channel); 402 403 return NULL; 404 } 405 406 ares_status_t ares_reinit(ares_channel_t *channel) 407 { 408 ares_status_t status = ARES_SUCCESS; 409 410 if (channel == NULL) { 411 return ARES_EFORMERR; 412 } 413 414 ares_channel_lock(channel); 415 416 /* If a reinit is already in process, lets not do it again. Or if we are 417 * shutting down, skip. */ 418 if (!channel->sys_up || channel->reinit_pending) { 419 ares_channel_unlock(channel); 420 return ARES_SUCCESS; 421 } 422 channel->reinit_pending = ARES_TRUE; 423 ares_channel_unlock(channel); 424 425 if (ares_threadsafety()) { 426 /* clean up the prior reinit process's thread. We know the thread isn't 427 * running since reinit_pending was false */ 428 if (channel->reinit_thread != NULL) { 429 void *rv; 430 ares_thread_join(channel->reinit_thread, &rv); 431 channel->reinit_thread = NULL; 432 } 433 434 /* Spawn a new thread */ 435 status = 436 ares_thread_create(&channel->reinit_thread, ares_reinit_thread, channel); 437 if (status != ARES_SUCCESS) { 438 /* LCOV_EXCL_START: UntestablePath */ 439 ares_channel_lock(channel); 440 channel->reinit_pending = ARES_FALSE; 441 ares_channel_unlock(channel); 442 /* LCOV_EXCL_STOP */ 443 } 444 } else { 445 /* Threading support not available, call directly */ 446 ares_reinit_thread(channel); 447 } 448 449 return status; 450 } 451 452 /* ares_dup() duplicates a channel handle with all its options and returns a 453 new channel handle */ 454 int ares_dup(ares_channel_t **dest, const ares_channel_t *src) 455 { 456 struct ares_options opts; 457 ares_status_t rc; 458 int optmask; 459 460 if (dest == NULL || src == NULL) { 461 return ARES_EFORMERR; 462 } 463 464 *dest = NULL; /* in case of failure return NULL explicitly */ 465 466 /* First get the options supported by the old ares_save_options() function, 467 which is most of them */ 468 rc = (ares_status_t)ares_save_options(src, &opts, &optmask); 469 if (rc != ARES_SUCCESS) { 470 ares_destroy_options(&opts); 471 goto done; 472 } 473 474 /* Then create the new channel with those options */ 475 rc = (ares_status_t)ares_init_options(dest, &opts, optmask); 476 477 /* destroy the options copy to not leak any memory */ 478 ares_destroy_options(&opts); 479 480 if (rc != ARES_SUCCESS) { 481 goto done; 482 } 483 484 ares_channel_lock(src); 485 /* Now clone the options that ares_save_options() doesn't support, but are 486 * user-provided */ 487 (*dest)->sock_create_cb = src->sock_create_cb; 488 (*dest)->sock_create_cb_data = src->sock_create_cb_data; 489 (*dest)->sock_config_cb = src->sock_config_cb; 490 (*dest)->sock_config_cb_data = src->sock_config_cb_data; 491 memcpy(&(*dest)->sock_funcs, &(src->sock_funcs), sizeof((*dest)->sock_funcs)); 492 (*dest)->sock_func_cb_data = src->sock_func_cb_data; 493 (*dest)->legacy_sock_funcs = src->legacy_sock_funcs; 494 (*dest)->legacy_sock_funcs_cb_data = src->legacy_sock_funcs_cb_data; 495 (*dest)->server_state_cb = src->server_state_cb; 496 (*dest)->server_state_cb_data = src->server_state_cb_data; 497 498 ares_strcpy((*dest)->local_dev_name, src->local_dev_name, 499 sizeof((*dest)->local_dev_name)); 500 (*dest)->local_ip4 = src->local_ip4; 501 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); 502 ares_channel_unlock(src); 503 504 /* Servers are a bit unique as ares_init_options() only allows ipv4 servers 505 * and not a port per server, but there are other user specified ways, that 506 * too will toggle the optmask ARES_OPT_SERVERS to let us know. If that's 507 * the case, pull them in. 508 * 509 * We don't want to clone system-configuration servers though. 510 * 511 * We must use the "csv" format to get things like link-local address support 512 */ 513 514 if (optmask & ARES_OPT_SERVERS) { 515 char *csv = ares_get_servers_csv(src); 516 if (csv == NULL) { 517 /* LCOV_EXCL_START: OutOfMemory */ 518 ares_destroy(*dest); 519 *dest = NULL; 520 rc = ARES_ENOMEM; 521 goto done; 522 /* LCOV_EXCL_STOP */ 523 } 524 525 rc = (ares_status_t)ares_set_servers_ports_csv(*dest, csv); 526 ares_free_string(csv); 527 if (rc != ARES_SUCCESS) { 528 /* LCOV_EXCL_START: OutOfMemory */ 529 ares_destroy(*dest); 530 *dest = NULL; 531 goto done; 532 /* LCOV_EXCL_STOP */ 533 } 534 } 535 536 rc = ARES_SUCCESS; 537 done: 538 return (int)rc; /* everything went fine */ 539 } 540 541 void ares_set_local_ip4(ares_channel_t *channel, unsigned int local_ip) 542 { 543 if (channel == NULL) { 544 return; 545 } 546 ares_channel_lock(channel); 547 channel->local_ip4 = local_ip; 548 ares_channel_unlock(channel); 549 } 550 551 /* local_ip6 should be 16 bytes in length */ 552 void ares_set_local_ip6(ares_channel_t *channel, const unsigned char *local_ip6) 553 { 554 if (channel == NULL) { 555 return; 556 } 557 ares_channel_lock(channel); 558 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6)); 559 ares_channel_unlock(channel); 560 } 561 562 /* local_dev_name should be null terminated. */ 563 void ares_set_local_dev(ares_channel_t *channel, const char *local_dev_name) 564 { 565 if (channel == NULL) { 566 return; 567 } 568 569 ares_channel_lock(channel); 570 ares_strcpy(channel->local_dev_name, local_dev_name, 571 sizeof(channel->local_dev_name)); 572 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0; 573 ares_channel_unlock(channel); 574 } 575 576 int ares_set_sortlist(ares_channel_t *channel, const char *sortstr) 577 { 578 size_t nsort = 0; 579 struct apattern *sortlist = NULL; 580 ares_status_t status; 581 582 if (!channel) { 583 return ARES_ENODATA; 584 } 585 ares_channel_lock(channel); 586 587 status = ares_parse_sortlist(&sortlist, &nsort, sortstr); 588 if (status == ARES_SUCCESS && sortlist) { 589 if (channel->sortlist) { 590 ares_free(channel->sortlist); 591 } 592 channel->sortlist = sortlist; 593 channel->nsort = nsort; 594 595 /* Save sortlist as if it was passed in as an option */ 596 channel->optmask |= ARES_OPT_SORTLIST; 597 } 598 ares_channel_unlock(channel); 599 return (int)status; 600 }