int ares_set_servers_ports(ares_channel channel, struct ares_addr_port_node *servers) { struct ares_addr_port_node *srvr; int num_srvrs = 0; int i; if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ if (!channel) return ARES_ENODATA; if (!ares__is_list_empty(&channel->all_queries)) return ARES_ENOTIMP; ares__destroy_servers_state(channel); for (srvr = servers; srvr; srvr = srvr->next) { num_srvrs++; } if (num_srvrs > 0) { /* Allocate storage for servers state */ channel->servers = ares_malloc(num_srvrs * sizeof(struct server_state)); if (!channel->servers) { return ARES_ENOMEM; } channel->nservers = num_srvrs; /* Fill servers state address data */ for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) { channel->servers[i].addr.family = srvr->family; channel->servers[i].addr.udp_port = htons((unsigned short)srvr->udp_port); channel->servers[i].addr.tcp_port = htons((unsigned short)srvr->tcp_port); if (srvr->family == AF_INET) memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, sizeof(srvr->addrV4)); else memcpy(&channel->servers[i].addr.addrV6, &srvr->addrV6, sizeof(srvr->addrV6)); } /* Initialize servers state remaining data */ ares__init_servers_state(channel); } return ARES_SUCCESS; }
int ares_set_servers(ares_channel channel, struct ares_addr_node *servers) { struct ares_addr_node *srvr; int num_srvrs = 0; int i; if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; if (!channel) return ARES_ENODATA; ares__destroy_servers_state(channel); for (srvr = servers; srvr; srvr = srvr->next) { num_srvrs++; } if (num_srvrs > 0) { /* Allocate storage for servers state */ channel->servers = malloc(num_srvrs * sizeof(struct server_state)); if (!channel->servers) { return ARES_ENOMEM; } channel->nservers = num_srvrs; /* Fill servers state address data */ for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) { channel->servers[i].addr.family = srvr->family; if (srvr->family == AF_INET) memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, sizeof(srvr->addrV4)); else memcpy(&channel->servers[i].addr.addrV6, &srvr->addrV6, sizeof(srvr->addrV6)); } /* Initialize servers state remaining data */ ares__init_servers_state(channel); } return ARES_SUCCESS; }
int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask) { ares_channel channel; int i; int status = ARES_SUCCESS; struct timeval now; #ifdef CURLDEBUG const char *env = getenv("CARES_MEMDEBUG"); if (env) curl_memdebug(env); env = getenv("CARES_MEMLIMIT"); if (env) { char *endptr; long num = strtol(env, &endptr, 10); if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) curl_memlimit(num); } #endif if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; channel = malloc(sizeof(struct ares_channeldata)); if (!channel) { *channelptr = NULL; return ARES_ENOMEM; } now = ares__tvnow(); /* Set everything to distinguished values so we know they haven't * been set yet. */ channel->flags = -1; channel->timeout = -1; channel->tries = -1; channel->ndots = -1; channel->rotate = -1; channel->udp_port = -1; channel->tcp_port = -1; channel->socket_send_buffer_size = -1; channel->socket_receive_buffer_size = -1; channel->nservers = -1; channel->ndomains = -1; channel->nsort = -1; channel->tcp_connection_generation = 0; channel->lookups = NULL; channel->domains = NULL; channel->sortlist = NULL; channel->servers = NULL; channel->sock_state_cb = NULL; channel->sock_state_cb_data = NULL; channel->sock_create_cb = NULL; channel->sock_create_cb_data = NULL; channel->last_server = 0; channel->last_timeout_processed = (time_t)now.tv_sec; memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name)); channel->local_ip4 = 0; memset(&channel->local_ip6, 0, sizeof(channel->local_ip6)); /* Initialize our lists of queries */ ares__init_list_head(&(channel->all_queries)); for (i = 0; i < ARES_QID_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_qid[i])); } for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_timeout[i])); } /* Initialize configuration by each of the four sources, from highest * precedence to lowest. */ if (status == ARES_SUCCESS) { status = init_by_options(channel, options, optmask); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_environment(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_resolv_conf(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n", ares_strerror(status))); } /* * No matter what failed or succeeded, seed defaults to provide * useful behavior for things that we missed. */ status = init_by_defaults(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", ares_strerror(status))); /* Generate random key */ if (status == ARES_SUCCESS) { status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); if (status == ARES_SUCCESS) channel->next_id = ares__generate_new_id(&channel->id_key); else DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", ares_strerror(status))); } if (status != ARES_SUCCESS) { /* Something failed; clean up memory we may have allocated. */ if (channel->servers) free(channel->servers); if (channel->domains) { for (i = 0; i < channel->ndomains; i++) free(channel->domains[i]); free(channel->domains); } if (channel->sortlist) free(channel->sortlist); if(channel->lookups) free(channel->lookups); free(channel); return status; } /* Trim to one server if ARES_FLAG_PRIMARY is set. */ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) channel->nservers = 1; ares__init_servers_state(channel); *channelptr = channel; return ARES_SUCCESS; }