]> granicus.if.org Git - libevent/commitdiff
Fix a crash in evdns related to shutting down evdns
authorNick Mathewson <nickm@torproject.org>
Fri, 21 Mar 2014 18:08:17 +0000 (14:08 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 26 Mar 2014 15:09:34 +0000 (11:09 -0400)
(Improved version to deal correctly with probe requests)

Patch from YASUOKA Masahiko; fix for libevent github issue #113.

evdns.c

diff --git a/evdns.c b/evdns.c
index ff60b098c67814c22493cd435d359e266fc52cf6..60b104851167b1b73ffc6d8017c0700920e30efd 100644 (file)
--- a/evdns.c
+++ b/evdns.c
@@ -3946,6 +3946,10 @@ evdns_nameserver_free(struct nameserver *server)
        event_debug_unassign(&server->event);
        if (server->state == 0)
                (void) event_del(&server->timeout_event);
+       if (server->probe_request) {
+               evdns_cancel_request(server->base, server->probe_request);
+               server->probe_request = NULL;
+       }
        event_debug_unassign(&server->timeout_event);
        mm_free(server);
 }
@@ -3961,13 +3965,6 @@ evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests)
 
        /* TODO(nickm) we might need to refcount here. */
 
-       for (i = 0; i < base->n_req_heads; ++i) {
-               while (base->req_heads[i]) {
-                       if (fail_requests)
-                               reply_schedule_callback(base->req_heads[i], 0, DNS_ERR_SHUTDOWN, NULL);
-                       request_finished(base->req_heads[i], &REQ_HEAD(base, base->req_heads[i]->trans_id), 1);
-               }
-       }
        for (server = base->server_head; server; server = server_next) {
                server_next = server->next;
                evdns_nameserver_free(server);
@@ -3976,6 +3973,14 @@ evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests)
        }
        base->server_head = NULL;
        base->global_good_nameservers = 0;
+
+       for (i = 0; i < base->n_req_heads; ++i) {
+               while (base->req_heads[i]) {
+                       if (fail_requests)
+                               reply_schedule_callback(base->req_heads[i], 0, DNS_ERR_SHUTDOWN, NULL);
+                       request_finished(base->req_heads[i], &REQ_HEAD(base, base->req_heads[i]->trans_id), 1);
+               }
+       }
        while (base->req_waiting_head) {
                if (fail_requests)
                        reply_schedule_callback(base->req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);