Brad House added ares_save_options() and ares_destroy_options() that can be
used to keep options for later re-usal when ares_init_options() is used.
This commit is contained in:
parent
a49e78d9b7
commit
79d59ec97b
19
ares/CHANGES
19
ares/CHANGES
@ -2,6 +2,25 @@
|
||||
|
||||
* May 30 2007
|
||||
|
||||
- Brad House added ares_save_options() and ares_destroy_options() that can be
|
||||
used to keep options for later re-usal when ares_init_options() is used.
|
||||
|
||||
Problem: Calling ares_init() for each lookup can be unnecessarily resource
|
||||
intensive. On windows, it must LoadLibrary() or search the registry
|
||||
on each call to ares_init(). On unix, it must read and parse
|
||||
multiple files to obtain the necessary configuration information. In
|
||||
a single-threaded environment, it would make sense to only
|
||||
ares_init() once, but in a heavily multi-threaded environment, it is
|
||||
undesirable to ares_init() and ares_destroy() for each thread created
|
||||
and track that.
|
||||
|
||||
Solution: Create ares_save_options() and ares_destroy_options() functions to
|
||||
retrieve and free options obtained from an initialized channel. The
|
||||
options populated can be used to pass back into ares_init_options(),
|
||||
it should populate all needed fields and not retrieve any information
|
||||
from the system. Probably wise to destroy the cache every minute or
|
||||
so to prevent the data from becoming stale.
|
||||
|
||||
- Daniel S added ares_process_fd() to allow applications to ask for processing
|
||||
on specific sockets and thus avoiding select() and associated
|
||||
functions/macros. This function will be used by upcoming libcurl releases
|
||||
|
@ -94,6 +94,7 @@ extern "C" {
|
||||
#define ARES_OPT_DOMAINS (1 << 7)
|
||||
#define ARES_OPT_LOOKUPS (1 << 8)
|
||||
#define ARES_OPT_SOCK_STATE_CB (1 << 9)
|
||||
#define ARES_OPT_SORTLIST (1 << 10)
|
||||
|
||||
/* Nameinfo flag values */
|
||||
#define ARES_NI_NOFQDN (1 << 0)
|
||||
@ -164,6 +165,8 @@ typedef void (*ares_sock_state_cb)(void *data,
|
||||
int writable);
|
||||
#endif
|
||||
|
||||
struct apattern;
|
||||
|
||||
struct ares_options {
|
||||
int flags;
|
||||
int timeout;
|
||||
@ -178,6 +181,8 @@ struct ares_options {
|
||||
char *lookups;
|
||||
ares_sock_state_cb sock_state_cb;
|
||||
void *sock_state_cb_data;
|
||||
struct apattern *sortlist;
|
||||
int nsort;
|
||||
};
|
||||
|
||||
struct hostent;
|
||||
@ -195,6 +200,8 @@ typedef void (*ares_nameinfo_callback)(void *arg, int status,
|
||||
int ares_init(ares_channel *channelptr);
|
||||
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
int optmask);
|
||||
int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask);
|
||||
void ares_destroy_options(struct ares_options *options);
|
||||
void ares_destroy(ares_channel channel);
|
||||
void ares_cancel(ares_channel channel);
|
||||
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
||||
|
@ -20,6 +20,19 @@
|
||||
#include "ares.h"
|
||||
#include "ares_private.h"
|
||||
|
||||
void ares_destroy_options(struct ares_options *options)
|
||||
{
|
||||
int i;
|
||||
|
||||
free(options->servers);
|
||||
for (i = 0; i < options->ndomains; i++)
|
||||
free(options->domains[i]);
|
||||
free(options->domains);
|
||||
if(options->sortlist)
|
||||
free(options->sortlist);
|
||||
free(options->lookups);
|
||||
}
|
||||
|
||||
void ares_destroy(ares_channel channel)
|
||||
{
|
||||
int i;
|
||||
|
@ -61,7 +61,7 @@
|
||||
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
||||
#endif
|
||||
|
||||
static int init_by_options(ares_channel channel, struct ares_options *options,
|
||||
static int init_by_options(ares_channel channel, const struct ares_options *options,
|
||||
int optmask);
|
||||
static int init_by_environment(ares_channel channel);
|
||||
static int init_by_resolv_conf(ares_channel channel);
|
||||
@ -84,6 +84,12 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
static char *try_config(char *s, const char *opt);
|
||||
#endif
|
||||
|
||||
#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
|
||||
x->nservers > -1 && \
|
||||
x->ndomains > -1 && \
|
||||
x->ndots > -1 && x->timeout > -1 && \
|
||||
x->tries > -1)
|
||||
|
||||
int ares_init(ares_channel *channelptr)
|
||||
{
|
||||
return ares_init_options(channelptr, NULL, 0);
|
||||
@ -212,7 +218,76 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
static int init_by_options(ares_channel channel, struct ares_options *options,
|
||||
/* Save options from initialized channel */
|
||||
int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||
int *optmask)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Zero everything out */
|
||||
memset(options, 0, sizeof(struct ares_options));
|
||||
|
||||
if (!ARES_CONFIG_CHECK(channel))
|
||||
return ARES_ENODATA;
|
||||
|
||||
(*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TIMEOUT|ARES_OPT_TRIES|ARES_OPT_NDOTS|
|
||||
ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
|
||||
ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
|
||||
ARES_OPT_SORTLIST);
|
||||
|
||||
/* Copy easy stuff */
|
||||
options->flags = channel->flags;
|
||||
options->timeout = channel->timeout;
|
||||
options->tries = channel->tries;
|
||||
options->ndots = channel->ndots;
|
||||
options->udp_port = channel->udp_port;
|
||||
options->tcp_port = channel->tcp_port;
|
||||
options->sock_state_cb = channel->sock_state_cb;
|
||||
options->sock_state_cb_data = channel->sock_state_cb_data;
|
||||
|
||||
/* Copy servers */
|
||||
options->servers =
|
||||
malloc(channel->nservers * sizeof(struct server_state));
|
||||
if (!options->servers && channel->nservers != 0)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < channel->nservers; i++)
|
||||
options->servers[i] = channel->servers[i].addr;
|
||||
options->nservers = channel->nservers;
|
||||
|
||||
/* copy domains */
|
||||
options->domains = malloc(channel->ndomains * sizeof(char *));
|
||||
if (!options->domains)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < channel->ndomains; i++)
|
||||
{
|
||||
options->ndomains = i;
|
||||
options->domains[i] = strdup(channel->domains[i]);
|
||||
if (!options->domains[i])
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
options->ndomains = channel->ndomains;
|
||||
|
||||
/* copy lookups */
|
||||
options->lookups = strdup(channel->lookups);
|
||||
if (!options->lookups)
|
||||
return ARES_ENOMEM;
|
||||
|
||||
/* copy sortlist */
|
||||
options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
|
||||
if (!options->sortlist)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < channel->nsort; i++)
|
||||
{
|
||||
memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
|
||||
sizeof(struct apattern));
|
||||
}
|
||||
options->nsort = channel->nsort;
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
static int init_by_options(ares_channel channel,
|
||||
const struct ares_options *options,
|
||||
int optmask)
|
||||
{
|
||||
int i;
|
||||
@ -282,6 +357,19 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
|
||||
/* copy sortlist */
|
||||
if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
|
||||
{
|
||||
channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
|
||||
if (!channel->sortlist)
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->nsort; i++)
|
||||
{
|
||||
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]), sizeof(struct apattern));
|
||||
}
|
||||
channel->nsort = options->nsort;
|
||||
}
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
@ -615,6 +703,10 @@ DhcpNameServer
|
||||
int linesize;
|
||||
int error;
|
||||
|
||||
/* Don't read resolv.conf and friends if we don't have to */
|
||||
if (ARES_CONFIG_CHECK(channel))
|
||||
return ARES_SUCCESS;
|
||||
|
||||
fp = fopen(PATH_RESOLV_CONF, "r");
|
||||
if (fp) {
|
||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||
|
Loading…
x
Reference in New Issue
Block a user