Move domain search state to evdns_request.

It doesn't seem to make sense to copy the state to each new request
in the search.
This commit is contained in:
Christopher Davis 2010-04-21 22:01:59 -07:00
parent 15bb82d690
commit beaa14a46f

81
evdns.c
View File

@ -148,6 +148,12 @@ typedef unsigned int uint;
/* persistent handle */ /* persistent handle */
struct evdns_request { struct evdns_request {
struct request *current_req; struct request *current_req;
/* elements used by the searching code */
int search_index;
struct search_state *search_state;
char *search_origname; /* needs to be free()ed */
int search_flags;
}; };
struct request { struct request {
@ -160,13 +166,6 @@ struct request {
evdns_callback_type user_callback; evdns_callback_type user_callback;
struct nameserver *ns; /* the server which we last sent it */ struct nameserver *ns; /* the server which we last sent it */
// XXX this could be moved to the evdns_request handle
/* elements used by the searching code */
int search_index;
struct search_state *search_state;
char *search_origname; /* needs to be free()ed */
int search_flags;
/* these objects are kept in a circular list */ /* these objects are kept in a circular list */
struct request *next, *prev; struct request *next, *prev;
@ -378,8 +377,8 @@ static void nameserver_ready_callback(evutil_socket_t fd, short events, void *ar
static int evdns_transmit(struct evdns_base *base); static int evdns_transmit(struct evdns_base *base);
static int evdns_request_transmit(struct request *req); static int evdns_request_transmit(struct request *req);
static void nameserver_send_probe(struct nameserver *const ns); static void nameserver_send_probe(struct nameserver *const ns);
static void search_request_finished(struct request *const); static void search_request_finished(struct evdns_request *const);
static int search_try_next(struct request *const req); static int search_try_next(struct evdns_request *const req);
static struct request *search_request_new(struct evdns_base *base, struct evdns_request *handle, int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg); static struct request *search_request_new(struct evdns_base *base, struct evdns_request *handle, int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg);
static void evdns_requests_pump_waiting_queue(struct evdns_base *base); static void evdns_requests_pump_waiting_queue(struct evdns_base *base);
static u16 transaction_id_pick(struct evdns_base *base); static u16 transaction_id_pick(struct evdns_base *base);
@ -660,7 +659,6 @@ request_finished(struct request *const req, struct request **head, int free_hand
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx", log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req); (unsigned long) req);
search_request_finished(req);
if (was_inflight) { if (was_inflight) {
evtimer_del(&req->timeout_event); evtimer_del(&req->timeout_event);
base->global_requests_inflight--; base->global_requests_inflight--;
@ -676,8 +674,10 @@ request_finished(struct request *const req, struct request **head, int free_hand
/* so everything gets free()ed when we: */ /* so everything gets free()ed when we: */
} }
if (free_handle && req->handle) if (free_handle && req->handle) {
search_request_finished(req->handle);
mm_free(req->handle); mm_free(req->handle);
}
mm_free(req); mm_free(req);
@ -864,10 +864,11 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
nameserver_up(req->ns); nameserver_up(req->ns);
} }
if (req->search_state && req->request_type != TYPE_PTR) { if (req->handle && req->handle->search_state
&& req->request_type != TYPE_PTR) {
/* if we have a list of domains to search in, /* if we have a list of domains to search in,
* try the next one */ * try the next one */
if (!search_try_next(req)) { if (!search_try_next(req->handle)) {
/* a new request was issued so this /* a new request was issued so this
* request is finished and */ * request is finished and */
/* the user callback will be made when /* the user callback will be made when
@ -2984,18 +2985,19 @@ search_request_new(struct evdns_base *base, struct evdns_request *handle,
if (string_num_dots(name) >= base->global_search_state->ndots) { if (string_num_dots(name) >= base->global_search_state->ndots) {
req = request_new(base, handle, type, name, flags, user_callback, user_arg); req = request_new(base, handle, type, name, flags, user_callback, user_arg);
if (!req) return NULL; if (!req) return NULL;
req->search_index = -1; handle->search_index = -1;
} else { } else {
char *const new_name = search_make_new(base->global_search_state, 0, name); char *const new_name = search_make_new(base->global_search_state, 0, name);
if (!new_name) return NULL; if (!new_name) return NULL;
req = request_new(base, handle, type, new_name, flags, user_callback, user_arg); req = request_new(base, handle, type, new_name, flags, user_callback, user_arg);
mm_free(new_name); mm_free(new_name);
if (!req) return NULL; if (!req) return NULL;
req->search_index = 0; handle->search_index = 0;
} }
req->search_origname = mm_strdup(name); EVUTIL_ASSERT(handle->search_origname == NULL);
req->search_state = base->global_search_state; handle->search_origname = mm_strdup(name);
req->search_flags = flags; handle->search_state = base->global_search_state;
handle->search_flags = flags;
base->global_search_state->refcount++; base->global_search_state->refcount++;
request_submit(req); request_submit(req);
return req; return req;
@ -3013,21 +3015,22 @@ search_request_new(struct evdns_base *base, struct evdns_request *handle,
/* 0 another request has been submitted */ /* 0 another request has been submitted */
/* 1 no more requests needed */ /* 1 no more requests needed */
static int static int
search_try_next(struct request *const req) { search_try_next(struct evdns_request *const handle) {
struct request *req = handle->current_req;
struct evdns_base *base = req->base; struct evdns_base *base = req->base;
ASSERT_LOCKED(base); ASSERT_LOCKED(base);
if (req->search_state) { if (handle->search_state) {
/* it is part of a search */ /* it is part of a search */
char *new_name; char *new_name;
struct request *newreq; struct request *newreq;
req->search_index++; handle->search_index++;
if (req->search_index >= req->search_state->num_domains) { if (handle->search_index >= handle->search_state->num_domains) {
/* no more postfixes to try, however we may need to try */ /* no more postfixes to try, however we may need to try */
/* this name without a postfix */ /* this name without a postfix */
if (string_num_dots(req->search_origname) < req->search_state->ndots) { if (string_num_dots(handle->search_origname) < handle->search_state->ndots) {
/* yep, we need to try it raw */ /* yep, we need to try it raw */
newreq = request_new(base, req->handle, req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer); newreq = request_new(base, req->handle, req->request_type, handle->search_origname, handle->search_flags, req->user_callback, req->user_pointer);
log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname); log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", handle->search_origname);
if (newreq) { if (newreq) {
request_submit(newreq); request_submit(newreq);
return 0; return 0;
@ -3036,18 +3039,12 @@ search_try_next(struct request *const req) {
return 1; return 1;
} }
new_name = search_make_new(req->search_state, req->search_index, req->search_origname); new_name = search_make_new(handle->search_state, handle->search_index, handle->search_origname);
if (!new_name) return 1; if (!new_name) return 1;
log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index); log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, handle->search_index);
newreq = request_new(base, req->handle, req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer); newreq = request_new(base, req->handle, req->request_type, new_name, handle->search_flags, req->user_callback, req->user_pointer);
mm_free(new_name); mm_free(new_name);
if (!newreq) return 1; if (!newreq) return 1;
newreq->search_origname = req->search_origname;
req->search_origname = NULL;
newreq->search_state = req->search_state;
newreq->search_flags = req->search_flags;
newreq->search_index = req->search_index;
newreq->search_state->refcount++;
request_submit(newreq); request_submit(newreq);
return 0; return 0;
} }
@ -3055,15 +3052,15 @@ search_try_next(struct request *const req) {
} }
static void static void
search_request_finished(struct request *const req) { search_request_finished(struct evdns_request *const handle) {
ASSERT_LOCKED(req->base); ASSERT_LOCKED(handle->current_req->base);
if (req->search_state) { if (handle->search_state) {
search_state_decref(req->search_state); search_state_decref(handle->search_state);
req->search_state = NULL; handle->search_state = NULL;
} }
if (req->search_origname) { if (handle->search_origname) {
mm_free(req->search_origname); mm_free(handle->search_origname);
req->search_origname = NULL; handle->search_origname = NULL;
} }
} }