From d680c5e7d5a10feb6208a5582ca0dbd30ec69fb9 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Sun, 17 Oct 1999 19:27:04 +0000 Subject: [PATCH] Do not free client->query.qname prematurely. Detach from our fetch as soon as it is done. (Not doing this meant we couldn't recurse again when restarting.) Fix some bugs in the multiple question code that were causing qtype to be set incorrectly when restarting after recursion. --- bin/named/query.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/bin/named/query.c b/bin/named/query.c index 7179b90782..62267da15a 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -75,12 +75,11 @@ query_maybeputqname(ns_client_t *client) { if (client->query.restarts > 0) { /* * client->query.qname was dynamically allocated. - * We must free it before we set it. */ dns_message_puttempname(client->message, &client->query.qname); - } else client->query.qname = NULL; + } } static inline void @@ -150,6 +149,7 @@ query_reset(ns_client_t *client, isc_boolean_t everything) { NS_QUERYATTR_CACHEOK); client->query.restarts = 0; client->query.origqname = NULL; + client->query.qname = NULL; client->query.qrdataset = NULL; client->query.dboptions = 0; client->query.gluedb = NULL; @@ -1339,6 +1339,10 @@ query_resume(isc_task_t *task, isc_event_t *event) { REQUIRE(task == client->task); REQUIRE(RECURSING(client)); + client->query.attributes &= ~NS_QUERYATTR_RECURSING; + dns_resolver_destroyfetch(client->view->resolver, + &client->query.fetch); + client->waiting--; /* @@ -1450,7 +1454,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) { zdb = NULL; version = NULL; zone = NULL; - qcount = 0; if (event != NULL) { /* @@ -1463,8 +1466,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) { clear_fname = ISC_FALSE; is_zone = ISC_FALSE; - client->query.attributes &= ~NS_QUERYATTR_RECURSING; - qtype = event->qtype; if (qtype == dns_rdatatype_sig) type = dns_rdatatype_any; @@ -1557,7 +1558,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) { /* * Find the first unanswered type in the question section. */ - qtype = dns_rdatatype_null; + qtype = 0; + qcount = 0; + client->query.qrdataset = NULL; for (trdataset = ISC_LIST_HEAD(client->query.origqname->list); trdataset != NULL; trdataset = ISC_LIST_NEXT(trdataset, link)) { @@ -1573,16 +1576,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) { * We had better have found something! */ INSIST(client->query.qrdataset != NULL && qcount > 0); + /* - * If there's more than one question, we'll retrieve the node and - * iterate it, trying to find answers. + * If there's more than one question, we'll eventually retrieve the + * node and iterate it, trying to find answers. For now, we simply + * refuse requests with more than one question. */ if (qcount == 1) type = qtype; else { - type = dns_rdatatype_any; - /* XXXRTH */ - QUERY_ERROR(DNS_R_NOTIMP); + QUERY_ERROR(DNS_R_REFUSED); goto cleanup; } @@ -2189,11 +2192,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) { goto restart; } - /* - * Cleanup qname? - */ - query_maybeputqname(client); - if (eresult != ISC_R_SUCCESS && !PARTIALANSWER(client)) ns_client_error(client, eresult); else if (!RECURSING(client))