]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3397. [bug] dig crashed when using +nssearch with +tcp. [RT #25298]
authorckb <ckb@isc.org>
Thu, 18 Oct 2012 22:50:07 +0000 (17:50 -0500)
committerckb <ckb@isc.org>
Thu, 18 Oct 2012 22:50:07 +0000 (17:50 -0500)
CHANGES
bin/dig/dighost.c
bin/dig/include/dig/dig.h

diff --git a/CHANGES b/CHANGES
index c8d52260f81bf7e8b5b2e5f3321eaaad7f710ad5..eac40a08004827ddcafe8fbe4958d9bfd11ce219 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+3397.  [bug]           dig crashed when using +nssearch with +tcp. [RT #25298]
+                       
 3396.  [bug]           OPT records were incorrectly removed from signed,
                        truncated responses. [RT #31439]
 
index c07cc4c8eed1329923e9ac8c7784e22f2debb545..c506da4a762ea1c4a1894063f88ea6395e5f4324 100644 (file)
@@ -791,6 +791,7 @@ make_empty_lookup(void) {
        looknew->need_search = ISC_FALSE;
        ISC_LINK_INIT(looknew, link);
        ISC_LIST_INIT(looknew->q);
+       ISC_LIST_INIT(looknew->connecting);
        ISC_LIST_INIT(looknew->my_server_list);
        return (looknew);
 }
@@ -1468,7 +1469,10 @@ clear_query(dig_query_t *query) {
        if (lookup->current_query == query)
                lookup->current_query = NULL;
 
-       ISC_LIST_UNLINK(lookup->q, query, link);
+       if (ISC_LINK_LINKED(query, link))
+               ISC_LIST_UNLINK(lookup->q, query, link);
+       if (ISC_LINK_LINKED(query, clink))
+               ISC_LIST_UNLINK(lookup->connecting, query, clink);
        if (ISC_LINK_LINKED(&query->recvbuf, link))
                ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
                                 link);
@@ -1476,6 +1480,7 @@ clear_query(dig_query_t *query) {
                ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
                                 link);
        INSIST(query->recvspace != NULL);
+
        if (query->sock != NULL) {
                isc_socket_detach(&query->sock);
                sockcount--;
@@ -1503,13 +1508,22 @@ try_clear_lookup(dig_lookup_t *lookup) {
 
        debug("try_clear_lookup(%p)", lookup);
 
-       if (ISC_LIST_HEAD(lookup->q) != NULL) {
+       if (ISC_LIST_HEAD(lookup->q) != NULL ||
+           ISC_LIST_HEAD(lookup->connecting) != NULL)
+       {
                if (debugging) {
                        q = ISC_LIST_HEAD(lookup->q);
                        while (q != NULL) {
                                debug("query to %s still pending", q->servname);
                                q = ISC_LIST_NEXT(q, link);
                        }
+
+                       q = ISC_LIST_HEAD(lookup->connecting);
+                       while (q != NULL) {
+                               debug("query to %s still connecting",
+                                     q->servname);
+                               q = ISC_LIST_NEXT(q, clink);
+                       }
                }
                return (ISC_FALSE);
        }
@@ -2286,7 +2300,6 @@ setup_lookup(dig_lookup_t *lookup) {
                query->rr_count = 0;
                query->msg_count = 0;
                query->byte_count = 0;
-               ISC_LINK_INIT(query, link);
                ISC_LIST_INIT(query->recvlist);
                ISC_LIST_INIT(query->lengthlist);
                query->sock = NULL;
@@ -2299,6 +2312,7 @@ setup_lookup(dig_lookup_t *lookup) {
                isc_buffer_init(&query->slbuf, query->slspace, 2);
                query->sendbuf = lookup->renderbuf;
 
+               ISC_LINK_INIT(query, clink);
                ISC_LINK_INIT(query, link);
                ISC_LIST_ENQUEUE(lookup->q, query, link);
        }
@@ -2341,7 +2355,7 @@ send_done(isc_task_t *_task, isc_event_t *event) {
        query->waiting_senddone = ISC_FALSE;
        l = query->lookup;
 
-       if (l->ns_search_only && !l->trace_root) {
+       if (l->ns_search_only && !l->trace_root && !l->tcp_mode) {
                debug("sending next, since searching");
                next = ISC_LIST_NEXT(query, link);
                if (next != NULL)
@@ -2420,6 +2434,7 @@ static void
 force_timeout(dig_lookup_t *l, dig_query_t *query) {
        isc_event_t *event;
 
+       debug("force_timeout ()");
        event = isc_event_allocate(mctx, query, ISC_TIMEREVENT_IDLE,
                                   connect_timeout, l,
                                   sizeof(isc_event_t));
@@ -2487,6 +2502,7 @@ send_tcp_connect(dig_query_t *query) {
                send_tcp_connect(next);
                return;
        }
+       
        INSIST(query->sock == NULL);
        result = isc_socket_create(socketmgr,
                                   isc_sockaddr_pf(&query->sockaddr),
@@ -2517,6 +2533,9 @@ send_tcp_connect(dig_query_t *query) {
        if (l->ns_search_only && !l->trace_root) {
                debug("sending next, since searching");
                next = ISC_LIST_NEXT(query, link);
+               if (ISC_LINK_LINKED(query, link))
+                       ISC_LIST_DEQUEUE(l->q, query, link);
+               ISC_LIST_ENQUEUE(l->connecting, query, clink);
                if (next != NULL)
                        send_tcp_connect(next);
        }
@@ -2866,9 +2885,8 @@ connect_done(isc_task_t *task, isc_event_t *event) {
                if (next != NULL) {
                        bringup_timer(next, TCP_TIMEOUT);
                        send_tcp_connect(next);
-               } else {
+               } else
                        check_next_lookup(l);
-               }
                UNLOCK_LOOKUP;
                return;
        }
@@ -3082,7 +3100,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
                UNLOCK_LOOKUP;
                return;
        }
-
+       
        if (sevent->result != ISC_R_SUCCESS) {
                if (sevent->result == ISC_R_CANCELED) {
                        debug("in recv cancel handler");
index b34542e30cda89cdad692feaa9e439bfb6aa3b80..8aca3d65fcebca7071d1e9f0eac30f25a1000630 100644 (file)
@@ -168,6 +168,7 @@ isc_boolean_t       sigchase;
        dns_name_t *oname;
        ISC_LINK(dig_lookup_t) link;
        ISC_LIST(dig_query_t) q;
+       ISC_LIST(dig_query_t) connecting;
        dig_query_t *current_query;
        dig_serverlist_t my_server_list;
        dig_searchlist_t *origin;
@@ -214,6 +215,7 @@ struct dig_query {
                slspace[4];
        isc_socket_t *sock;
        ISC_LINK(dig_query_t) link;
+       ISC_LINK(dig_query_t) clink;
        isc_sockaddr_t sockaddr;
        isc_time_t time_sent;
        isc_uint64_t byte_count;