diff options
author | dougb <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
---|---|---|
committer | dougb <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
commit | f5d31f05bda6a88f1513a06d3fd67e6fbaa0688e (patch) | |
tree | d7fa0e61cadfdb3b3752a55401049f2294a7cfaf /contrib/bind9/bin/dig/dighost.c | |
parent | 4a3a088a0b6ffaf0dd6b740dbe537d5a082825d5 (diff) | |
download | FreeBSD-src-f5d31f05bda6a88f1513a06d3fd67e6fbaa0688e.zip FreeBSD-src-f5d31f05bda6a88f1513a06d3fd67e6fbaa0688e.tar.gz |
Vendor import of BIND 9.3.3
Diffstat (limited to 'contrib/bind9/bin/dig/dighost.c')
-rw-r--r-- | contrib/bind9/bin/dig/dighost.c | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c index 6129fed..398711d 100644 --- a/contrib/bind9/bin/dig/dighost.c +++ b/contrib/bind9/bin/dig/dighost.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221.2.19.2.31 2005/10/14 01:38:40 marka Exp $ */ +/* $Id: dighost.c,v 1.221.2.19.2.36 2006/12/07 01:26:33 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -315,6 +315,9 @@ static void recv_done(isc_task_t *task, isc_event_t *event); static void +send_udp(dig_query_t *query); + +static void connect_timeout(isc_task_t *task, isc_event_t *event); static void @@ -945,9 +948,8 @@ setup_system(void) { if (lwresult != LWRES_R_SUCCESS) fatal("lwres_context_create failed"); - if (isc_file_exists(RESOLV_CONF)) - lwresult = lwres_conf_parse(lwctx, RESOLV_CONF); - if (lwresult != LWRES_R_SUCCESS) + lwresult = lwres_conf_parse(lwctx, RESOLV_CONF); + if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND) fatal("parse of %s failed", RESOLV_CONF); lwconf = lwres_conf_get(lwctx); @@ -1194,7 +1196,10 @@ clear_query(dig_query_t *query) { isc_mempool_put(commctx, query->recvspace); isc_buffer_invalidate(&query->recvbuf); isc_buffer_invalidate(&query->lengthbuf); - isc_mem_free(mctx, query); + if (query->waiting_senddone) + query->pending_free = ISC_TRUE; + else + isc_mem_free(mctx, query); } /* @@ -1219,9 +1224,10 @@ try_clear_lookup(dig_lookup_t *lookup) { debug("query to %s still pending", q->servname); q = ISC_LIST_NEXT(q, link); } - return (ISC_FALSE); } + return (ISC_FALSE); } + /* * At this point, we know there are no queries on the lookup, * so can make it go away also. @@ -1254,7 +1260,6 @@ try_clear_lookup(dig_lookup_t *lookup) { return (ISC_TRUE); } - /* * If we can, start the next lookup in the queue running. * This assumes that the lookup on the head of the queue hasn't been @@ -1784,9 +1789,9 @@ setup_lookup(dig_lookup_t *lookup) { check_result(result, "dns_compress_init"); debug("starting to render the message"); - isc_buffer_init(&lookup->sendbuf, lookup->sendspace, COMMSIZE); + isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE); result = dns_message_renderbegin(lookup->sendmsg, &cctx, - &lookup->sendbuf); + &lookup->renderbuf); check_result(result, "dns_message_renderbegin"); if (lookup->udpsize > 0 || lookup->dnssec) { if (lookup->udpsize == 0) @@ -1809,7 +1814,7 @@ setup_lookup(dig_lookup_t *lookup) { /* * Force TCP mode if the request is larger than 512 bytes. */ - if (isc_buffer_usedlength(&lookup->sendbuf) > 512) + if (isc_buffer_usedlength(&lookup->renderbuf) > 512) lookup->tcp_mode = ISC_TRUE; lookup->pending = ISC_FALSE; @@ -1825,6 +1830,8 @@ setup_lookup(dig_lookup_t *lookup) { query, lookup); query->lookup = lookup; query->waiting_connect = ISC_FALSE; + query->waiting_senddone = ISC_FALSE; + query->pending_free = ISC_FALSE; query->recv_made = ISC_FALSE; query->first_pass = ISC_TRUE; query->first_soa_rcvd = ISC_FALSE; @@ -1848,6 +1855,7 @@ setup_lookup(dig_lookup_t *lookup) { isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); isc_buffer_init(&query->slbuf, query->slspace, 2); + query->sendbuf = lookup->renderbuf; ISC_LINK_INIT(query, link); ISC_LIST_ENQUEUE(lookup->q, query, link); @@ -1865,18 +1873,43 @@ setup_lookup(dig_lookup_t *lookup) { */ static void send_done(isc_task_t *_task, isc_event_t *event) { + isc_socketevent_t *sevent = (isc_socketevent_t *)event; + isc_buffer_t *b = NULL; + dig_query_t *query, *next; + dig_lookup_t *l; + REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); UNUSED(_task); LOCK_LOOKUP; - isc_event_free(&event); - debug("send_done()"); sendcount--; debug("sendcount=%d", sendcount); INSIST(sendcount >= 0); + + for (b = ISC_LIST_HEAD(sevent->bufferlist); + b != NULL; + b = ISC_LIST_HEAD(sevent->bufferlist)) + ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); + + query = event->ev_arg; + query->waiting_senddone = ISC_FALSE; + l = query->lookup; + + if (l->ns_search_only && !l->trace_root) { + debug("sending next, since searching"); + next = ISC_LIST_NEXT(query, link); + if (next != NULL) + send_udp(next); + } + + isc_event_free(&event); + + if (query->pending_free) + isc_mem_free(mctx, query); + check_if_done(); UNLOCK_LOOKUP; } @@ -2020,7 +2053,6 @@ send_tcp_connect(dig_query_t *query) { static void send_udp(dig_query_t *query) { dig_lookup_t *l = NULL; - dig_query_t *next; isc_result_t result; debug("send_udp(%p)", query); @@ -2062,27 +2094,16 @@ send_udp(dig_query_t *query) { debug("recvcount=%d", recvcount); } ISC_LIST_INIT(query->sendlist); - ISC_LINK_INIT(&l->sendbuf, link); - ISC_LIST_ENQUEUE(query->sendlist, &l->sendbuf, - link); + ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); debug("sending a request"); TIME_NOW(&query->time_sent); INSIST(query->sock != NULL); + query->waiting_senddone = ISC_TRUE; result = isc_socket_sendtov(query->sock, &query->sendlist, global_task, send_done, query, &query->sockaddr, NULL); check_result(result, "isc_socket_sendtov"); sendcount++; - /* - * If we're at the endgame of a nameserver search, we need to - * immediately bring up all the queries. Do it here. - */ - if (l->ns_search_only && !l->trace_root) { - debug("sending next, since searching"); - next = ISC_LIST_NEXT(query, link); - if (next != NULL) - send_udp(next); - } } /* @@ -2171,6 +2192,10 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { recvcount--; INSIST(recvcount >= 0); + b = ISC_LIST_HEAD(sevent->bufferlist); + INSIST(b == &query->lengthbuf); + ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); + if (sevent->result == ISC_R_CANCELED) { isc_event_free(&event); l = query->lookup; @@ -2196,8 +2221,6 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { UNLOCK_LOOKUP; return; } - b = ISC_LIST_HEAD(sevent->bufferlist); - ISC_LIST_DEQUEUE(sevent->bufferlist, &query->lengthbuf, link); length = isc_buffer_getuint16(b); if (length == 0) { isc_event_free(&event); @@ -2254,16 +2277,12 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) { isc_buffer_clear(&query->slbuf); isc_buffer_clear(&query->lengthbuf); - isc_buffer_putuint16(&query->slbuf, - (isc_uint16_t) query->lookup->sendbuf.used); + isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used); ISC_LIST_INIT(query->sendlist); ISC_LINK_INIT(&query->slbuf, link); ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link); - if (include_question) { - ISC_LINK_INIT(&query->lookup->sendbuf, link); - ISC_LIST_ENQUEUE(query->sendlist, &query->lookup->sendbuf, - link); - } + if (include_question) + ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); ISC_LINK_INIT(&query->lengthbuf, link); ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); @@ -2275,6 +2294,7 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) { if (!query->first_soa_rcvd) { debug("sending a request in launch_next_query"); TIME_NOW(&query->time_sent); + query->waiting_senddone = ISC_TRUE; result = isc_socket_sendv(query->sock, &query->sendlist, global_task, send_done, query); check_result(result, "isc_socket_sendv"); @@ -2558,6 +2578,10 @@ recv_done(isc_task_t *task, isc_event_t *event) { REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); sevent = (isc_socketevent_t *)event; + b = ISC_LIST_HEAD(sevent->bufferlist); + INSIST(b == &query->recvbuf); + ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); + if ((l->tcp_mode) && (l->timer != NULL)) isc_timer_touch(l->timer); if ((!l->pending && !l->ns_search_only) || cancel_now) { @@ -2591,9 +2615,6 @@ recv_done(isc_task_t *task, isc_event_t *event) { return; } - b = ISC_LIST_HEAD(sevent->bufferlist); - ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); - if (!l->tcp_mode && !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) { char buf1[ISC_SOCKADDR_FORMATSIZE]; |