Alien-cares
view release on metacpan or search on metacpan
libcares/ares_init.c view on Meta::CPAN
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->ednspsz = -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->sock_config_cb = NULL;
channel->sock_config_cb_data = NULL;
channel->sock_funcs = NULL;
channel->sock_func_cb_data = NULL;
channel->resolvconf_path = 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.
*/
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 we fail to apply user-specified options, fail the whole init process */
goto done;
}
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)));
}
done:
if (status != ARES_SUCCESS)
{
/* Something failed; clean up memory we may have allocated. */
if (channel->servers)
ares_free(channel->servers);
if (channel->ndomains != -1)
ares_strsplit_free(channel->domains, channel->ndomains);
if (channel->sortlist)
ares_free(channel->sortlist);
if(channel->lookups)
ares_free(channel->lookups);
if(channel->resolvconf_path)
ares_free(channel->resolvconf_path);
ares_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;
}
/* ares_dup() duplicates a channel handle with all its options and returns a
new channel handle */
int ares_dup(ares_channel *dest, ares_channel src)
{
struct ares_options opts;
struct ares_addr_port_node *servers;
int non_v4_default_port = 0;
int i, rc;
int optmask;
*dest = NULL; /* in case of failure return NULL explicitly */
/* First get the options supported by the old ares_save_options() function,
which is most of them */
rc = ares_save_options(src, &opts, &optmask);
if(rc)
{
ares_destroy_options(&opts);
return rc;
}
/* Then create the new channel with those options */
rc = ares_init_options(dest, &opts, optmask);
/* destroy the options copy to not leak any memory */
ares_destroy_options(&opts);
if(rc)
return rc;
libcares/ares_init.c view on Meta::CPAN
channel->timeout = res.retrans * 1000;
res_ndestroy(&res);
}
#else
{
char *p;
FILE *fp;
size_t linesize;
int error;
int update_domains;
const char *resolvconf_path;
/* Don't read resolv.conf and friends if we don't have to */
if (ARES_CONFIG_CHECK(channel))
return ARES_SUCCESS;
/* Only update search domains if they're not already specified */
update_domains = (channel->ndomains == -1);
/* Support path for resolvconf filename set by ares_init_options */
if(channel->resolvconf_path) {
resolvconf_path = channel->resolvconf_path;
} else {
resolvconf_path = PATH_RESOLV_CONF;
}
fp = fopen(resolvconf_path, "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
if ((p = try_config(line, "domain", ';')) && update_domains)
status = config_domain(channel, p);
else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
status = config_lookup(channel, p, "bind", NULL, "file");
else if ((p = try_config(line, "search", ';')) && update_domains)
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver", ';')) &&
channel->nservers == -1)
status = config_nameserver(&servers, &nservers, p);
else if ((p = try_config(line, "sortlist", ';')) &&
channel->nsort == -1)
status = config_sortlist(&sortlist, &nsort, p);
else if ((p = try_config(line, "options", ';')))
status = set_options(channel, p);
else
status = ARES_SUCCESS;
if (status != ARES_SUCCESS)
break;
}
fclose(fp);
}
else {
error = ERRNO;
switch(error) {
case ENOENT:
case ESRCH:
status = ARES_EOF;
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
status = ARES_EFILE;
}
}
if ((status == ARES_EOF) && (!channel->lookups)) {
/* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
fp = fopen("/etc/nsswitch.conf", "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) ==
ARES_SUCCESS)
{
if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
(void)config_lookup(channel, p, "dns", "resolve", "files");
}
fclose(fp);
}
else {
error = ERRNO;
switch(error) {
case ENOENT:
case ESRCH:
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n",
"/etc/nsswitch.conf"));
}
/* ignore error, maybe we will get luck in next if clause */
status = ARES_EOF;
}
}
if ((status == ARES_EOF) && (!channel->lookups)) {
/* Linux / GNU libc 2.x and possibly others have host.conf */
fp = fopen("/etc/host.conf", "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) ==
ARES_SUCCESS)
{
if ((p = try_config(line, "order", '\0')) && !channel->lookups)
/* ignore errors */
(void)config_lookup(channel, p, "bind", NULL, "hosts");
}
fclose(fp);
}
else {
error = ERRNO;
switch(error) {
case ENOENT:
case ESRCH:
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n",
"/etc/host.conf"));
}
/* ignore error, maybe we will get luck in next if clause */
status = ARES_EOF;
}
}
if ((status == ARES_EOF) && (!channel->lookups)) {
/* Tru64 uses /etc/svc.conf */
fp = fopen("/etc/svc.conf", "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) ==
ARES_SUCCESS)
{
if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
/* ignore errors */
(void)config_lookup(channel, p, "bind", NULL, "local");
}
fclose(fp);
}
else {
error = ERRNO;
switch(error) {
case ENOENT:
case ESRCH:
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
}
/* ignore error, default value will be chosen for `channel->lookups` */
status = ARES_EOF;
}
}
if(line)
ares_free(line);
}
#endif
/* Handle errors. */
if (status != ARES_EOF)
{
if (servers != NULL)
ares_free(servers);
if (sortlist != NULL)
ares_free(sortlist);
return status;
}
/* If we got any name server entries, fill them in. */
if (servers)
{
channel->servers = servers;
channel->nservers = nservers;
}
/* If we got any sortlist entries, fill them in. */
if (sortlist)
{
channel->sortlist = sortlist;
channel->nsort = nsort;
}
return ARES_SUCCESS;
}
static int init_by_defaults(ares_channel channel)
{
char *hostname = NULL;
int rc = ARES_SUCCESS;
#ifdef HAVE_GETHOSTNAME
char *dot;
#endif
if (channel->flags == -1)
channel->flags = 0;
if (channel->timeout == -1)
channel->timeout = DEFAULT_TIMEOUT;
if (channel->tries == -1)
channel->tries = DEFAULT_TRIES;
if (channel->ndots == -1)
channel->ndots = 1;
if (channel->rotate == -1)
channel->rotate = 0;
if (channel->udp_port == -1)
channel->udp_port = htons(NAMESERVER_PORT);
( run in 0.929 second using v1.01-cache-2.11-cpan-2398b32b56e )