diff --git a/CHANGES b/CHANGES index 2e18766996..0046e4e564 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2036. [bug] 'rndc recursing' could cause trigger a REQUIRE. + [RT #16075] + 2035. [func] Make falling back to TCP on UDP refresh failure optional. Default "try-tcp-refresh yes;" for BIND 8 compatibility. [RT #16123] diff --git a/bin/named/client.c b/bin/named/client.c index 336433f6cb..af518ff51a 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.236 2006/05/29 01:27:58 marka Exp $ */ +/* $Id: client.c,v 1.237 2006/06/04 23:59:33 marka Exp $ */ #include @@ -321,8 +321,17 @@ exit_check(ns_client_t *client) { } /* * I/O cancel is complete. Burn down all state - * related to the current request. + * related to the current request. Ensure that + * the client is on the active list and not the + * recursing list. */ + LOCK(&client->manager->lock); + if (client->list == &client->manager->recursing) { + ISC_LIST_UNLINK(*client->list, client, link); + ISC_LIST_APPEND(client->manager->active, client, link); + client->list = &client->manager->active; + } + UNLOCK(&client->manager->lock); ns_client_endrequest(client); client->state = NS_CLIENTSTATE_READING; @@ -2594,3 +2603,20 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { } UNLOCK(&manager->lock); } + +void +ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { + + if (client->manager != NULL) + LOCK(&client->manager->lock); + if (client->query.restarts > 0) { + /* + * client->query.qname was dynamically allocated. + */ + dns_message_puttempname(client->message, + &client->query.qname); + } + client->query.qname = name; + if (client->manager != NULL) + UNLOCK(&client->manager->lock); +} diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 44e25668a8..82881eb416 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.h,v 1.77 2005/08/15 01:21:04 marka Exp $ */ +/* $Id: client.h,v 1.78 2006/06/04 23:59:33 marka Exp $ */ #ifndef NAMED_CLIENT_H #define NAMED_CLIENT_H 1 @@ -344,6 +344,12 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); * Dump the outstanding recursive queries to 'f'. */ +void +ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); +/*% + * Replace the qname. + */ + isc_boolean_t ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, diff --git a/bin/named/query.c b/bin/named/query.c index b274d4377a..ddd91508de 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.287 2006/05/26 02:44:02 marka Exp $ */ +/* $Id: query.c,v 1.288 2006/06/04 23:59:33 marka Exp $ */ /*! \file */ @@ -179,18 +179,6 @@ query_next(ns_client_t *client, isc_result_t result) { ns_client_next(client, result); } -static inline void -query_maybeputqname(ns_client_t *client) { - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - client->query.qname = NULL; - } -} - static inline void query_freefreeversions(ns_client_t *client, isc_boolean_t everything) { ns_dbversion_t *dbversion, *dbversion_next; @@ -271,8 +259,14 @@ query_reset(ns_client_t *client, isc_boolean_t everything) { } } - query_maybeputqname(client); - + if (client->query.restarts > 0) { + /* + * client->query.qname was dynamically allocated. + */ + dns_message_puttempname(client->message, + &client->query.qname); + } + client->query.qname = NULL; client->query.attributes = (NS_QUERYATTR_RECURSIONOK | NS_QUERYATTR_CACHEOK | NS_QUERYATTR_SECURE); @@ -4004,8 +3998,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) goto cleanup; } dns_rdata_freestruct(&cname); - query_maybeputqname(client); - client->query.qname = tname; + ns_client_qnamereplace(client, tname); want_restart = ISC_TRUE; if (!WANTRECURSION(client)) options |= DNS_GETDB_NOLOG; @@ -4122,8 +4115,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * Switch to the new qname and restart. */ - query_maybeputqname(client); - client->query.qname = fname; + ns_client_qnamereplace(client, fname); fname = NULL; want_restart = ISC_TRUE; if (!WANTRECURSION(client))