/* persistent handle */
struct evdns_request {
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 {
evdns_callback_type user_callback;
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 */
struct request *next, *prev;
static int evdns_transmit(struct evdns_base *base);
static int evdns_request_transmit(struct request *req);
static void nameserver_send_probe(struct nameserver *const ns);
-static void search_request_finished(struct request *const);
-static int search_try_next(struct request *const req);
+static void search_request_finished(struct evdns_request *const);
+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 void evdns_requests_pump_waiting_queue(struct evdns_base *base);
static u16 transaction_id_pick(struct evdns_base *base);
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
- search_request_finished(req);
if (was_inflight) {
evtimer_del(&req->timeout_event);
base->global_requests_inflight--;
/* 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);
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,
* try the next one */
- if (!search_try_next(req)) {
+ if (!search_try_next(req->handle)) {
/* a new request was issued so this
* request is finished and */
/* the user callback will be made when
if (string_num_dots(name) >= base->global_search_state->ndots) {
req = request_new(base, handle, type, name, flags, user_callback, user_arg);
if (!req) return NULL;
- req->search_index = -1;
+ handle->search_index = -1;
} else {
char *const new_name = search_make_new(base->global_search_state, 0, name);
if (!new_name) return NULL;
req = request_new(base, handle, type, new_name, flags, user_callback, user_arg);
mm_free(new_name);
if (!req) return NULL;
- req->search_index = 0;
+ handle->search_index = 0;
}
- req->search_origname = mm_strdup(name);
- req->search_state = base->global_search_state;
- req->search_flags = flags;
+ EVUTIL_ASSERT(handle->search_origname == NULL);
+ handle->search_origname = mm_strdup(name);
+ handle->search_state = base->global_search_state;
+ handle->search_flags = flags;
base->global_search_state->refcount++;
request_submit(req);
return req;
/* 0 another request has been submitted */
/* 1 no more requests needed */
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;
ASSERT_LOCKED(base);
- if (req->search_state) {
+ if (handle->search_state) {
/* it is part of a search */
char *new_name;
struct request *newreq;
- req->search_index++;
- if (req->search_index >= req->search_state->num_domains) {
+ handle->search_index++;
+ if (handle->search_index >= handle->search_state->num_domains) {
/* no more postfixes to try, however we may need to try */
/* 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 */
- newreq = request_new(base, req->handle, req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
- log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
+ 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", handle->search_origname);
if (newreq) {
request_submit(newreq);
return 0;
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;
- log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
- newreq = request_new(base, req->handle, req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer);
+ 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, handle->search_flags, req->user_callback, req->user_pointer);
mm_free(new_name);
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);
return 0;
}
}
static void
-search_request_finished(struct request *const req) {
- ASSERT_LOCKED(req->base);
- if (req->search_state) {
- search_state_decref(req->search_state);
- req->search_state = NULL;
- }
- if (req->search_origname) {
- mm_free(req->search_origname);
- req->search_origname = NULL;
+search_request_finished(struct evdns_request *const handle) {
+ ASSERT_LOCKED(handle->current_req->base);
+ if (handle->search_state) {
+ search_state_decref(handle->search_state);
+ handle->search_state = NULL;
+ }
+ if (handle->search_origname) {
+ mm_free(handle->search_origname);
+ handle->search_origname = NULL;
}
}