]> granicus.if.org Git - libevent/commitdiff
Assert for valid requests as necessary.
authorChristopher Davis <chrisd@mangrin.org>
Fri, 23 Apr 2010 04:46:05 +0000 (21:46 -0700)
committerChristopher Davis <chrisd@mangrin.org>
Fri, 23 Apr 2010 04:46:05 +0000 (21:46 -0700)
A valid request has an associated handle, and the handle must point
to the request.

evdns.c

diff --git a/evdns.c b/evdns.c
index abeeb25e27bd0257ced14004bcff48c9db5445e6..3dbe7bea0165b5addb89d977f7dec71715c8a0f4 100644 (file)
--- a/evdns.c
+++ b/evdns.c
 #undef MIN
 #define MIN(a,b) ((a)<(b)?(a):(b))
 
+#define ASSERT_VALID_REQUEST(req) \
+       EVUTIL_ASSERT((req)->handle && (req)->handle->current_req == (req))
+
 #ifdef __USE_ISOC99B
 /* libevent doesn't work without this */
 typedef unsigned int uint;
@@ -654,6 +657,8 @@ request_finished(struct request *const req, struct request **head, int free_hand
        struct evdns_base *base = req->base;
        int was_inflight = (head != &base->req_waiting_head);
        EVDNS_LOCK(base);
+       ASSERT_VALID_REQUEST(req);
+
        if (head)
                evdns_request_remove(req, head);
 
@@ -674,9 +679,13 @@ request_finished(struct request *const req, struct request **head, int free_hand
                /* so everything gets free()ed when we: */
        }
 
-       if (free_handle && req->handle) {
-               search_request_finished(req->handle);
-               mm_free(req->handle);
+       if (req->handle) {
+               EVUTIL_ASSERT(req->handle->current_req == req);
+               if (free_handle) {
+                       search_request_finished(req->handle);
+                       mm_free(req->handle);
+               } else
+                       req->handle->current_req = NULL;
        }
 
        mm_free(req);
@@ -695,6 +704,7 @@ static int
 request_reissue(struct request *req) {
        const struct nameserver *const last_ns = req->ns;
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
        /* the last nameserver should have been marked as failing */
        /* by the caller of this function, therefore pick will try */
        /* not to return it */
@@ -823,6 +833,7 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
        };
 
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
 
        if (flags & 0x020f || !reply || !reply->have_answer) {
                /* there was an error */
@@ -864,8 +875,8 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
                        nameserver_up(req->ns);
                }
 
-               if (req->handle && req->handle->search_state
-                   && req->request_type != TYPE_PTR) {
+               if (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->handle)) {
@@ -874,7 +885,6 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
                                /* the user callback will be made when
                                 * that request (or a */
                                /* child of it) finishes. */
-                               request_finished(req, &REQ_HEAD(req->base, req->trans_id), 0);
                                return;
                        }
                }
@@ -2088,6 +2098,7 @@ static int
 evdns_request_transmit_to(struct request *req, struct nameserver *server) {
        int r;
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
        r = sendto(server->socket, req->request, req->request_len, 0,
            (struct sockaddr *)&server->address, server->addrlen);
        if (r < 0) {
@@ -2114,6 +2125,7 @@ evdns_request_transmit(struct request *req) {
        int retcode = 0, r;
 
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
        /* if we fail to send this packet then this flag marks it */
        /* for evdns_transmit */
        req->transmit_me = 1;
@@ -2495,6 +2507,7 @@ static void
 evdns_request_remove(struct request *req, struct request **head)
 {
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
 
 #if 0
        {
@@ -2531,6 +2544,7 @@ evdns_request_remove(struct request *req, struct request **head)
 static void
 evdns_request_insert(struct request *req, struct request **head) {
        ASSERT_LOCKED(req->base);
+       ASSERT_VALID_REQUEST(req);
        if (!*head) {
                *head = req;
                req->next = req->prev = req;
@@ -2619,7 +2633,8 @@ request_new(struct evdns_base *base, struct evdns_request *handle, int type,
        req->ns = issuing_now ? nameserver_pick(base) : NULL;
        req->next = req->prev = NULL;
        req->handle = handle;
-       handle->current_req = req;
+       if (handle)
+               handle->current_req = req;
 
        return req;
 err1:
@@ -2631,6 +2646,7 @@ static void
 request_submit(struct request *const req) {
        struct evdns_base *base = req->base;
        ASSERT_LOCKED(base);
+       ASSERT_VALID_REQUEST(req);
        if (req->ns) {
                /* if it has a nameserver assigned then this is going */
                /* straight into the inflight queue */
@@ -2649,6 +2665,8 @@ evdns_cancel_request(struct evdns_base *base, struct evdns_request *handle)
 {
        struct request *req = handle->current_req;
 
+       ASSERT_VALID_REQUEST(req);
+
        if (!base)
                base = req->base;
 
@@ -2977,6 +2995,7 @@ search_request_new(struct evdns_base *base, struct evdns_request *handle,
                   evdns_callback_type user_callback, void *user_arg) {
        ASSERT_LOCKED(base);
        EVUTIL_ASSERT(type == TYPE_A || type == TYPE_AAAA);
+       EVUTIL_ASSERT(handle->current_req == NULL);
        if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
             base->global_search_state &&
                 base->global_search_state->num_domains) {
@@ -3018,23 +3037,22 @@ static int
 search_try_next(struct evdns_request *const handle) {
        struct request *req = handle->current_req;
        struct evdns_base *base = req->base;
+       struct request *newreq;
        ASSERT_LOCKED(base);
        if (handle->search_state) {
                /* it is part of a search */
                char *new_name;
-               struct request *newreq;
                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(handle->search_origname) < handle->search_state->ndots) {
                                /* yep, we need to try it raw */
-                               newreq = request_new(base, req->handle, req->request_type, handle->search_origname, handle->search_flags, req->user_callback, req->user_pointer);
+                               newreq = request_new(base, NULL, 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) {
                                        search_request_finished(handle);
-                                       request_submit(newreq);
-                                       return 0;
+                                       goto submit_next;
                                }
                        }
                        return 1;
@@ -3043,13 +3061,19 @@ search_try_next(struct evdns_request *const handle) {
                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, handle->search_index);
-               newreq = request_new(base, req->handle, req->request_type, new_name, handle->search_flags, req->user_callback, req->user_pointer);
+               newreq = request_new(base, NULL, req->request_type, new_name, handle->search_flags, req->user_callback, req->user_pointer);
                mm_free(new_name);
                if (!newreq) return 1;
-               request_submit(newreq);
-               return 0;
+               goto submit_next;
        }
        return 1;
+
+submit_next:
+       request_finished(req, &REQ_HEAD(req->base, req->trans_id), 0);
+       handle->current_req = newreq;
+       newreq->handle = handle;
+       request_submit(newreq);
+       return 0;
 }
 
 static void