Loading ares/CHANGES +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading ares/ares.h +7 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -164,6 +165,8 @@ typedef void (*ares_sock_state_cb)(void *data, int writable); #endif struct apattern; struct ares_options { int flags; int timeout; Loading @@ -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; Loading @@ -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, Loading ares/ares_destroy.c +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading ares/ares_init.c +94 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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 Loading
ares/CHANGES +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
ares/ares.h +7 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -164,6 +165,8 @@ typedef void (*ares_sock_state_cb)(void *data, int writable); #endif struct apattern; struct ares_options { int flags; int timeout; Loading @@ -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; Loading @@ -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, Loading
ares/ares_destroy.c +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
ares/ares_init.c +94 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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