* the GLUEOK flag. Glue will be looked for later, but not
* necessarily in the same database.
*/
- node = NULL;
result = dns_db_findext(db, name, version, type,
client->query.dboptions,
client->now, &node, fname, &cm, &ci,
dbuf, DNS_SECTION_AUTHORITY);
}
+static void
+free_devent(ns_client_t *client, isc_event_t **eventp,
+ dns_fetchevent_t **deventp)
+{
+ dns_fetchevent_t *devent = *deventp;
+
+ REQUIRE((void*)(*eventp) == (void *)(*deventp));
+
+ if (devent->fetch != NULL)
+ dns_resolver_destroyfetch(&devent->fetch);
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ dns_db_detach(&devent->db);
+ if (devent->rdataset != NULL)
+ query_putrdataset(client, &devent->rdataset);
+ if (devent->rdataset != NULL)
+ query_putrdataset(client, &devent->sigrdataset);
+ /*
+ * If the two pointers are the same then leave the setting of
+ * (*deventp) to NULL to isc_event_free.
+ */
+ if ((void *)eventp != (void *)deventp)
+ (*deventp) = NULL;
+ isc_event_free(eventp);
+}
+
static void
query_resume(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
- dns_fetch_t *fetch;
+ dns_fetch_t *fetch = NULL;
ns_client_t *client;
isc_boolean_t fetch_canceled, client_shuttingdown;
isc_result_t result;
INSIST(client->query.fetch == NULL);
client->query.attributes &= ~NS_QUERYATTR_RECURSING;
- fetch = devent->fetch;
- devent->fetch = NULL;
+ SAVE(fetch, devent->fetch);
/*
* If this client is shutting down, or this transaction
*/
client_shuttingdown = ns_client_shuttingdown(client);
if (fetch_canceled || client_shuttingdown) {
- if (devent->node != NULL)
- dns_db_detachnode(devent->db, &devent->node);
- if (devent->db != NULL)
- dns_db_detach(&devent->db);
- query_putrdataset(client, &devent->rdataset);
- if (devent->sigrdataset != NULL)
- query_putrdataset(client, &devent->sigrdataset);
- isc_event_free(&event);
+ free_devent(client, &event, &devent);
if (fetch_canceled) {
CTRACE(ISC_LOG_ERROR, "fetch cancelled");
query_error(client, DNS_R_SERVFAIL, __LINE__);
client->query.prefetch = NULL;
}
UNLOCK(&client->query.fetchlock);
- if (devent->fetch != NULL)
- dns_resolver_destroyfetch(&devent->fetch);
- if (devent->node != NULL)
- dns_db_detachnode(devent->db, &devent->node);
- if (devent->db != NULL)
- dns_db_detach(&devent->db);
- query_putrdataset(client, &devent->rdataset);
- isc_event_free(&event);
+ free_devent(client, &event, &devent);
ns_client_detach(&client);
}
INSIST(dns_name_equal(name, st->r_name));
INSIST(*rdatasetp == NULL ||
!dns_rdataset_isassociated(*rdatasetp));
- INSIST(*dbp == NULL);
st->state &= ~DNS_RPZ_RECURSING;
- *dbp = st->r.db;
- st->r.db = NULL;
+ RESTORE(*dbp, st->r.db);
if (*rdatasetp != NULL)
query_putrdataset(client, rdatasetp);
- *rdatasetp = st->r.r_rdataset;
- st->r.r_rdataset = NULL;
+ RESTORE(*rdatasetp, st->r.r_rdataset);
result = st->r.r_result;
if (result == DNS_R_DELEGATION) {
CTRACE(ISC_LOG_ERROR, "RPZ recursing");
RESTORE(sigrdataset, rpz_st->q.sigrdataset);
qtype = rpz_st->q.qtype;
- rpz_st->r.db = event->db;
if (event->node != NULL)
dns_db_detachnode(event->db, &event->node);
+ SAVE(rpz_st->r.db, event->db);
rpz_st->r.r_type = event->qtype;
- rpz_st->r.r_rdataset = event->rdataset;
+ SAVE(rpz_st->r.r_rdataset, event->rdataset);
query_putrdataset(client, &event->sigrdataset);
} else if (REDIRECT(client)) {
/*
authoritative = ISC_FALSE;
qtype = event->qtype;
- db = event->db;
- node = event->node;
- rdataset = event->rdataset;
- sigrdataset = event->sigrdataset;
+ SAVE(db, event->db);
+ SAVE(node, event->node);
+ SAVE(rdataset, event->rdataset);
+ SAVE(sigrdataset, event->sigrdataset);
}
INSIST(rdataset != NULL);
(rpz_st->state & DNS_RPZ_RECURSING) != 0) {
rpz_st->r.r_result = event->result;
result = rpz_st->q.result;
- isc_event_free(ISC_EVENT_PTR(&event));
+ free_devent(client, ISC_EVENT_PTR(&event), &event);
} else if (REDIRECT(client)) {
result = client->query.redirect.result;
is_zone = client->query.redirect.is_zone;
* We're authoritative for an ancestor of QNAME.
*/
if (!USECACHE(client) || !RECURSIONOK(client)) {
+ isc_boolean_t detach = ISC_FALSE;
+
dns_fixedname_init(&fixed);
dns_name_copy(fname,
dns_fixedname_name(&fixed), NULL);
* We enable the retrieval of glue for this
* database by setting client->query.gluedb.
*/
- client->query.gluedb = db;
+ if (db != NULL &&
+ client->query.gluedb == NULL) {
+ dns_db_attach(db,
+ &client->query.gluedb);
+ detach = ISC_TRUE;
+ }
client->query.isreferral = ISC_TRUE;
/*
* We must ensure NOADDITIONAL is off,
query_addrrset(client, &fname,
&rdataset, sigrdatasetp,
dbuf, DNS_SECTION_AUTHORITY);
- client->query.gluedb = NULL;
+ if (detach) {
+ dns_db_detach(&client->query.gluedb);
+ }
if (WANTDNSSEC(client))
query_addds(client, db, node, version,
dns_fixedname_name(&fixed));
else
RECURSE_ERROR(result);
} else {
+ isc_boolean_t detach = ISC_FALSE;
+
dns_fixedname_init(&fixed);
dns_name_copy(fname,
dns_fixedname_name(&fixed), NULL);
*/
client->query.attributes |=
NS_QUERYATTR_CACHEGLUEOK;
- client->query.gluedb = zdb;
client->query.isreferral = ISC_TRUE;
+
+ if (zdb != NULL &&
+ client->query.gluedb == NULL) {
+ dns_db_attach(zdb,
+ &client->query.gluedb);
+ detach = ISC_TRUE;
+ }
+
/*
* We must ensure NOADDITIONAL is off,
* because the generation of
query_addrrset(client, &fname,
&rdataset, sigrdatasetp,
dbuf, DNS_SECTION_AUTHORITY);
- client->query.gluedb = NULL;
client->query.attributes &=
~NS_QUERYATTR_CACHEGLUEOK;
+ if (detach) {
+ dns_db_detach(&client->query.gluedb);
+ }
+
if (WANTDNSSEC(client))
query_addds(client, db, node, version,
dns_fixedname_name(&fixed));
query_releasename(client, &zfname);
dns_db_detach(&zdb);
}
- if (event != NULL)
- isc_event_free(ISC_EVENT_PTR(&event));
+ if (event != NULL) {
+ free_devent(client, ISC_EVENT_PTR(&event), &event);
+ }
/*
* AA bit.