DNS_RDATASETATTR_NOQNAME) != 0)
#if 0
-#define CTRACE(m) isc_log_write(ns_g_lctx, \
- NS_LOGCATEGORY_CLIENT, \
- NS_LOGMODULE_QUERY, \
- ISC_LOG_DEBUG(3), \
- "client %p: %s", client, (m))
-#define QTRACE(m) isc_log_write(ns_g_lctx, \
- NS_LOGCATEGORY_GENERAL, \
- NS_LOGMODULE_QUERY, \
- ISC_LOG_DEBUG(3), \
- "query %p: %s", query, (m))
+#define CTRACE(l,m) do { \
+ if (client != NULL && client->query.qname != NULL) { \
+ char qbuf[DNS_NAME_FORMATSIZE]; \
+ dns_name_format(client->query.qname, qbuf, sizeof(qbuf)); \
+ isc_log_write(ns_g_lctx, \
+ NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, \
+ l, "client %p (%s): %s", client, qbuf, (m)); \
+ } else { \
+ isc_log_write(ns_g_lctx, \
+ NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, \
+ l, "client %p (<unknown-name>): %s", \
+ client, (m)); \
+ } \
+} while(0)
#else
-#define CTRACE(m) ((void)m)
-#define QTRACE(m) ((void)m)
+#define CTRACE(l,m) ((void)m)
#endif
+
#define DNS_GETDB_NOEXACT 0x01U
#define DNS_GETDB_NOLOG 0x02U
#define DNS_GETDB_PARTIAL 0x04U
query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
dns_rdataset_t *rdataset = *rdatasetp;
- CTRACE("query_putrdataset");
+ CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset");
if (rdataset != NULL) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(client->message, rdatasetp);
}
- CTRACE("query_putrdataset: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_putrdataset: done");
}
static inline void
isc_buffer_t *dbuf;
isc_result_t result;
- CTRACE("query_newnamebuf");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf");
/*%
* Allocate a name buffer.
*/
dbuf = NULL;
result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_newnamebuf: isc_buffer_allocate failed: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_newnamebuf: isc_buffer_allocate failed: done");
return (result);
}
ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
- CTRACE("query_newnamebuf: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newnamebuf: done");
return (ISC_R_SUCCESS);
}
isc_result_t result;
isc_region_t r;
- CTRACE("query_getnamebuf");
+ CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf");
/*%
* Return a name buffer with space for a maximal name, allocating
* a new one if necessary.
if (ISC_LIST_EMPTY(client->query.namebufs)) {
result = query_newnamebuf(client);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_getnamebuf: query_newnamebuf failed: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_getnamebuf: query_newnamebuf failed: done");
return (NULL);
}
}
if (r.length < 255) {
result = query_newnamebuf(client);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_getnamebuf: query_newnamebuf failed: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_getnamebuf: query_newnamebuf failed: done");
return (NULL);
}
isc_buffer_availableregion(dbuf, &r);
INSIST(r.length >= 255);
}
- CTRACE("query_getnamebuf: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_getnamebuf: done");
return (dbuf);
}
query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
isc_region_t r;
- CTRACE("query_keepname");
+ CTRACE(ISC_LOG_DEBUG(3), "query_keepname");
/*%
* 'name' is using space in 'dbuf', but 'dbuf' has not yet been
* adjusted to take account of that. We do the adjustment.
* rights on the buffer.
*/
- CTRACE("query_releasename");
+ CTRACE(ISC_LOG_DEBUG(3), "query_releasename");
if (dns_name_hasbuffer(name)) {
INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
!= 0);
client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
}
dns_message_puttempname(client->message, namep);
- CTRACE("query_releasename: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_releasename: done");
}
static inline dns_name_t *
REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
- CTRACE("query_newname");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newname");
name = NULL;
result = dns_message_gettempname(client->message, &name);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_newname: dns_message_gettempname failed: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_newname: dns_message_gettempname failed: done");
return (NULL);
}
isc_buffer_availableregion(dbuf, &r);
dns_name_setbuffer(name, nbuf);
client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
- CTRACE("query_newname: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newname: done");
return (name);
}
dns_rdataset_t *rdataset;
isc_result_t result;
- CTRACE("query_newrdataset");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset");
rdataset = NULL;
result = dns_message_gettemprdataset(client->message, &rdataset);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_newrdataset: "
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_newrdataset: "
"dns_message_gettemprdataset failed: done");
return (NULL);
}
dns_rdataset_init(rdataset);
- CTRACE("query_newrdataset: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_newrdataset: done");
return (rdataset);
}
* Get the current version of this database.
*/
dbversion = query_findversion(client, db);
- if (dbversion == NULL)
+ if (dbversion == NULL) {
+ CTRACE(ISC_LOG_ERROR, "unable to get db version");
return (DNS_R_SERVFAIL);
+ }
if ((options & DNS_GETDB_IGNOREACL) != 0)
goto approved;
dns_name_t *mname = NULL;
isc_result_t result;
- CTRACE("query_isduplicate");
+ CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate");
for (section = DNS_SECTION_ANSWER;
section <= DNS_SECTION_ADDITIONAL;
/*
* We've already got this RRset in the response.
*/
- CTRACE("query_isduplicate: true: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_isduplicate: true: done");
return (ISC_TRUE);
} else if (result == DNS_R_NXRRSET) {
/*
if (mnamep != NULL)
*mnamep = mname;
- CTRACE("query_isduplicate: false: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done");
return (ISC_FALSE);
}
if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype))
return (ISC_R_SUCCESS);
- CTRACE("query_addadditional");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional");
/*
* Initialization.
if (result != ISC_R_SUCCESS)
goto try_cache;
- CTRACE("query_addadditional: db_find");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: db_find");
/*
* Since we are looking for authoritative data, we do not set
}
addname:
- CTRACE("query_addadditional: addname");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: addname");
/*
* If we haven't added anything, then we're done.
*/
}
cleanup:
- CTRACE("query_addadditional: cleanup");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: cleanup");
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (zone != NULL)
dns_zone_detach(&zone);
- CTRACE("query_addadditional: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional: done");
return (eresult);
}
dns_clientinfomethods_init(&cm, ns_client_sourceip);
dns_clientinfo_init(&ci, client, NULL);
- CTRACE("query_addadditional2");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2");
/*
* We treat type A additional section processing as if it
if (result != ISC_R_SUCCESS)
goto findauthdb;
if (zone == NULL) {
- CTRACE("query_addadditional2: auth zone not found");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: auth zone not found");
goto try_cache;
}
/* Is the cached DB up-to-date? */
result = query_iscachevalid(zone, cdb, NULL, cversion);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_addadditional2: old auth additional cache");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: old auth additional cache");
query_discardcache(client, rdataset_base, additionaltype,
type, &zone, &cdb, &cversion, &cnode,
&cfname);
* ACL, since the result (not using this zone) would be same
* regardless of the result.
*/
- CTRACE("query_addadditional2: negative auth additional cache");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: negative auth additional cache");
dns_db_closeversion(cdb, &cversion, ISC_FALSE);
dns_db_detach(&cdb);
dns_zone_detach(&zone);
}
/* We've got an active cache. */
- CTRACE("query_addadditional2: auth additional cache");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: auth additional cache");
dns_db_closeversion(cdb, &cversion, ISC_FALSE);
db = cdb;
node = cnode;
goto try_cache;
}
- CTRACE("query_addadditional2: db_find");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: db_find");
/*
* Since we are looking for authoritative data, we do not set
result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_addadditional2: old glue additional cache");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: old glue additional cache");
query_discardcache(client, rdataset_base, additionaltype,
type, &zone, &cdb, &cversion, &cnode,
&cfname);
if (cnode == NULL) {
/* We have a negative cache. */
- CTRACE("query_addadditional2: negative glue additional cache");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addadditional2: negative glue additional cache");
dns_db_closeversion(cdb, &cversion, ISC_FALSE);
dns_db_detach(&cdb);
goto cleanup;
}
/* Cache hit. */
- CTRACE("query_addadditional2: glue additional cache");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: glue additional cache");
dns_db_closeversion(cdb, &cversion, ISC_FALSE);
db = cdb;
node = cnode;
}
}
- CTRACE("query_addadditional2: addname");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: addname");
/*
* If we haven't added anything, then we're done.
fname = NULL;
cleanup:
- CTRACE("query_addadditional2: cleanup");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: cleanup");
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (zone != NULL)
dns_zone_detach(&zone);
- CTRACE("query_addadditional2: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addadditional2: done");
return (eresult);
}
* 'fname', a name in the response message for 'client'.
*/
- CTRACE("query_addrdataset");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset");
ISC_LIST_APPEND(fname->list, rdataset, link);
additionalctx.rdataset = rdataset;
(void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
&additionalctx);
- CTRACE("query_addrdataset: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addrdataset: done");
}
static isc_result_t
* stored in 'dbuf'. In this case, query_addrrset() guarantees that
* when it returns the name will either have been kept or released.
*/
- CTRACE("query_dns64");
+ CTRACE(ISC_LOG_DEBUG(3), "query_dns64");
name = *namep;
mname = NULL;
mrdataset = NULL;
* We've already got an RRset of the given name and type.
* There's nothing else to do;
*/
- CTRACE("query_dns64: dns_message_findname succeeded: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_dns64: dns_message_findname succeeded: done");
if (dbuf != NULL)
query_releasename(client, namep);
return (ISC_R_SUCCESS);
dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
}
- CTRACE("query_dns64: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done");
return (result);
}
isc_result_t result;
unsigned int i;
- CTRACE("query_filter64");
+ CTRACE(ISC_LOG_DEBUG(3), "query_filter64");
INSIST(client->query.dns64_aaaaok != NULL);
INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
* We've already got an RRset of the given name and type.
* There's nothing else to do;
*/
- CTRACE("query_filter64: dns_message_findname succeeded: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_filter64: dns_message_findname succeeded: done");
if (dbuf != NULL)
query_releasename(client, namep);
return;
if (dbuf != NULL)
query_releasename(client, &name);
- CTRACE("query_filter64: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done");
}
static void
* stored in 'dbuf'. In this case, query_addrrset() guarantees that
* when it returns the name will either have been kept or released.
*/
- CTRACE("query_addrrset");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addrrset");
name = *namep;
rdataset = *rdatasetp;
if (sigrdatasetp != NULL)
/*
* We've already got an RRset of the given name and type.
*/
- CTRACE("query_addrrset: dns_message_findname succeeded: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addrrset: dns_message_findname succeeded: done");
if (dbuf != NULL)
query_releasename(client, namep);
if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0)
ISC_LIST_APPEND(mname->list, sigrdataset, link);
*sigrdatasetp = NULL;
}
- CTRACE("query_addrrset: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done");
}
static inline isc_result_t
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
- CTRACE("query_addsoa");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addsoa");
/*
* Initialization.
*/
dns_name_clone(dns_db_origin(db), name);
rdataset = query_newrdataset(client);
if (rdataset == NULL) {
+ CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset");
eresult = DNS_R_SERVFAIL;
goto cleanup;
}
if (WANTDNSSEC(client) && dns_db_issecure(db)) {
sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) {
+ CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset");
eresult = DNS_R_SERVFAIL;
goto cleanup;
}
* This is bad. We tried to get the SOA RR at the zone top
* and it didn't work!
*/
+ CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex");
eresult = DNS_R_SERVFAIL;
} else {
/*
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
- CTRACE("query_addns");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addns");
/*
* Initialization.
*/
*/
result = dns_message_gettempname(client->message, &name);
if (result != ISC_R_SUCCESS) {
- CTRACE("query_addns: dns_message_gettempname failed: done");
+ CTRACE(ISC_LOG_DEBUG(3),
+ "query_addns: dns_message_gettempname failed: done");
return (result);
}
dns_name_init(name, NULL);
dns_name_clone(dns_db_origin(db), name);
rdataset = query_newrdataset(client);
if (rdataset == NULL) {
- CTRACE("query_addns: query_newrdataset failed");
+ CTRACE(ISC_LOG_ERROR,
+ "query_addns: query_newrdataset failed");
eresult = DNS_R_SERVFAIL;
goto cleanup;
}
if (WANTDNSSEC(client) && dns_db_issecure(db)) {
sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) {
- CTRACE("query_addns: query_newrdataset failed");
+ CTRACE(ISC_LOG_ERROR,
+ "query_addns: query_newrdataset failed");
eresult = DNS_R_SERVFAIL;
goto cleanup;
}
dns_rdatatype_ns, 0, client->now,
rdataset, sigrdataset);
} else {
- CTRACE("query_addns: calling dns_db_find");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find");
result = dns_db_findext(db, name, NULL, dns_rdatatype_ns,
client->query.dboptions, 0, &node,
fname, &cm, &ci, rdataset, sigrdataset);
- CTRACE("query_addns: dns_db_find complete");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete");
}
if (result != ISC_R_SUCCESS) {
- CTRACE("query_addns: "
+ CTRACE(ISC_LOG_ERROR,
+ "query_addns: "
"dns_db_findrdataset or dns_db_find failed");
/*
* This is bad. We tried to get the NS rdataset at the zone
}
cleanup:
- CTRACE("query_addns: cleanup");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup");
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
- CTRACE("query_addns: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addns: done");
return (eresult);
}
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
- CTRACE("query_addbestns");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addbestns");
fname = NULL;
zfname = NULL;
rdataset = NULL;
isc_result_t result;
unsigned int count;
- CTRACE("query_addds");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addds");
rname = NULL;
rdataset = NULL;
sigrdataset = NULL;
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
- CTRACE("query_addwildcardproof");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof");
fname = NULL;
rdataset = NULL;
sigrdataset = NULL;
if (devent->sigrdataset != NULL)
query_putrdataset(client, &devent->sigrdataset);
isc_event_free(&event);
- if (fetch_canceled)
+ if (fetch_canceled) {
+ CTRACE(ISC_LOG_ERROR, "fetch cancelled");
query_error(client, DNS_R_SERVFAIL, __LINE__);
- else
+ } else
query_next(client, ISC_R_CANCELED);
/*
* This may destroy the client.
if (*rdatasetp == NULL) {
*rdatasetp = query_newrdataset(client);
- if (*rdatasetp == NULL)
+ if (*rdatasetp == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "rpz_ready: query_newrdataset failed");
return (DNS_R_SERVFAIL);
+ }
} else if (dns_rdataset_isassociated(*rdatasetp)) {
dns_rdataset_disassociate(*rdatasetp);
}
st->r.r_rdataset = NULL;
result = st->r.r_result;
if (result == DNS_R_DELEGATION) {
+ CTRACE(ISC_LOG_ERROR, "RPZ recursing");
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
rpz_type, " rpz_rrset_find(1)", result);
st->m.policy = DNS_RPZ_POLICY_ERROR;
*/
rpz_clean(zonep, dbp, nodep, rdatasetp);
result = rpz_ready(client, rdatasetp);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ CTRACE(ISC_LOG_ERROR, "rpz_ready() failed");
return (DNS_R_SERVFAIL);
+ }
*versionp = NULL;
result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
rpz_type, " allrdatasets()", result);
+ CTRACE(ISC_LOG_ERROR,
+ "rpz_find_p: allrdatasets failed");
return (DNS_R_SERVFAIL);
}
for (result = dns_rdatasetiter_first(rdsiter);
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
p_name, rpz_type,
" rdatasetiter", result);
+ CTRACE(ISC_LOG_ERROR,
+ "rpz_find_p: rdatasetiter_destroy "
+ "failed");
return (DNS_R_SERVFAIL);
}
/*
default:
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
"", result);
+ CTRACE(ISC_LOG_ERROR,
+ "rpz_find_p: unexpected result");
return (DNS_R_SERVFAIL);
}
}
rpz_type, " NS address rewrite rrset",
result);
}
+ CTRACE(ISC_LOG_ERROR,
+ "rpz_rewrite_ip_rrset: unexpected result");
return (DNS_R_SERVFAIL);
}
rpz_match_clear(st);
}
if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
+ CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy");
st->m.type = DNS_RPZ_TYPE_BAD;
result = DNS_R_SERVFAIL;
}
dns_rdataset_t *neg, *negsig;
isc_result_t result = ISC_R_NOMEMORY;
- CTRACE("query_addnoqnameproof");
+ CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof");
fname = NULL;
neg = NULL;
dns_clientinfo_t ci;
ns_dbversion_t *dbversion;
- CTRACE("redirect");
+ CTRACE(ISC_LOG_DEBUG(3), "redirect");
if (client->view->redirect == NULL)
return (ISC_FALSE);
dns_db_detach(&db);
return (ISC_FALSE);
}
- CTRACE("redirect: found data: done");
+ CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
dns_name_copy(found, name, NULL);
if (dns_rdataset_isassociated(rdataset))
isc_boolean_t nxrewrite = ISC_FALSE;
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
+ char errmsg[256];
isc_boolean_t associated;
dns_section_t section;
dns_ttl_t ttl;
- CTRACE("query_find");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find");
/*
* One-time initialization.
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_getnamebuf failed (1)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
fname = query_newname(client, dbuf, &b);
if (fname == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_newname failed (1)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
}
result = dns_name_copy(tname, fname, NULL);
if (result != ISC_R_SUCCESS) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: dns_name_copy failed");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
type = qtype;
restart:
- CTRACE("query_find: restart");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: restart");
want_restart = ISC_FALSE;
authoritative = ISC_FALSE;
version = NULL;
inc_stats(client, dns_nsstatscounter_authrej);
if (!PARTIALANSWER(client))
QUERY_ERROR(DNS_R_REFUSED);
- } else
+ } else {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_getdb failed");
QUERY_ERROR(DNS_R_SERVFAIL);
+ }
goto cleanup;
}
}
db_find:
- CTRACE("query_find: db_find");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: db_find");
/*
* We'll need some resources...
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_getnamebuf failed (2)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_newname failed (2)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) {
sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: query_newrdataset failed (2)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
dns_cache_updatestats(client->view->cache, result);
resume:
- CTRACE("query_find: resume");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: resume");
/*
* Rate limit these responses to this client.
goto cleanup;
} else {
/* Unable to give root server referral. */
+ CTRACE(ISC_LOG_ERROR,
+ "unable to give root server referral");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
if (fname == NULL) {
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: "
+ "query_getnamebuf failed (3)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
fname = query_newname(client, dbuf, &b);
if (fname == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: "
+ "query_newname failed (3)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
if (fname == NULL ||
rdataset == NULL ||
sigrdataset == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: "
+ "failure getting "
+ "closest encloser");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
if (fname == NULL) {
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: "
+ "query_getnamebuf failed (4)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
fname = query_newname(client, dbuf, &b);
if (fname == NULL) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: "
+ "query_newname failed (4)");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
/*
* Something has gone wrong.
*/
+ snprintf(errmsg, sizeof(errmsg) - 1,
+ "query_find: unexpected error after resuming: %s",
+ isc_result_totext(result));
+ CTRACE(ISC_LOG_ERROR, errmsg);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
rdsiter = NULL;
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
if (result != ISC_R_SUCCESS) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: type any; allrdatasets failed");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
dns_rdatasetiter_destroy(&rdsiter);
fname = query_newname(client, dbuf, &b);
goto nxrrset_rrsig;
- } else
+ } else {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: no matching rdatasets "
+ "in cache");
result = DNS_R_SERVFAIL;
+ }
}
dns_rdatasetiter_destroy(&rdsiter);
if (result != ISC_R_NOMORE) {
+ CTRACE(ISC_LOG_ERROR,
+ "query_find: dns_rdatasetiter_destroy failed");
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
}
addauth:
- CTRACE("query_find: addauth");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: addauth");
/*
* Add NS records to the authority section (if we haven't already
* added them to the answer section).
dns_fixedname_name(&wildcardname),
ISC_TRUE, ISC_FALSE);
cleanup:
- CTRACE("query_find: cleanup");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: cleanup");
/*
* General cleanup.
*/
query_send(client);
ns_client_detach(&client);
}
- CTRACE("query_find: done");
+ CTRACE(ISC_LOG_DEBUG(3), "query_find: done");
return (eresult);
}
unsigned int saved_extflags = client->extflags;
unsigned int saved_flags = client->message->flags;
- CTRACE("ns_query_start");
+ CTRACE(ISC_LOG_DEBUG(3), "ns_query_start");
/*
* Test only.
DNS_LOGMODULE_RESOLVER, \
ISC_LOG_DEBUG(3), \
"res %p: %s", (r), (m))
-#define FCTXTRACE(m) isc_log_write(dns_lctx, \
+#define FCTXTRACE(m) \
+ isc_log_write(dns_lctx, \
DNS_LOGCATEGORY_RESOLVER, \
DNS_LOGMODULE_RESOLVER, \
ISC_LOG_DEBUG(3), \
- "fctx %p(%s): %s", fctx, fctx->info, (m))
+ "fctx %p(%s): %s", \
+ fctx, fctx->info, (m))
#define FCTXTRACE2(m1, m2) \
isc_log_write(dns_lctx, \
DNS_LOGCATEGORY_RESOLVER, \
ISC_LOG_DEBUG(3), \
"fctx %p(%s): %s %s", \
fctx, fctx->info, (m1), (m2))
+#define FCTXTRACE3(m, res) \
+ isc_log_write(dns_lctx, \
+ DNS_LOGCATEGORY_RESOLVER, \
+ DNS_LOGMODULE_RESOLVER, \
+ ISC_LOG_DEBUG(3), \
+ "fctx %p(%s): [result: %s] %s", \
+ fctx, fctx->info, \
+ isc_result_totext(res), (m))
+#define FCTXTRACE4(m1, m2, res) \
+ isc_log_write(dns_lctx, \
+ DNS_LOGCATEGORY_RESOLVER, \
+ DNS_LOGMODULE_RESOLVER, \
+ ISC_LOG_DEBUG(3), \
+ "fctx %p(%s): [result: %s] %s %s", \
+ fctx, fctx->info, \
+ isc_result_totext(res), (m1), (m2))
#define FTRACE(m) isc_log_write(dns_lctx, \
DNS_LOGCATEGORY_RESOLVER, \
DNS_LOGMODULE_RESOLVER, \
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNREFUSED:
+ FCTXTRACE3("query canceled in sendevent(): "
+ "no route to host; no response",
+ sevent->result);
/*
* No route to remote.
break;
default:
+ FCTXTRACE3("query canceled in sendevent() due to "
+ "unexpected event result; responding",
+ sevent->result);
+
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
break;
}
isc_interval_set(&interval, 20, 0);
result = fctx_startidletimer(query->fctx, &interval);
if (result != ISC_R_SUCCESS) {
+ FCTXTRACE("query canceled: idle timer failed; "
+ "responding");
+
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
fctx_done(fctx, result, __LINE__);
break;
result = resquery_send(query);
if (result != ISC_R_SUCCESS) {
+ FCTXTRACE("query canceled: "
+ "resquery_send() failed; responding");
+
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
fctx_done(fctx, result, __LINE__);
}
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNECTIONRESET:
+ FCTXTRACE3("query canceled in connected(): "
+ "no route to host; no response",
+ sevent->result);
+
/*
* No route to remote.
*/
break;
default:
+ FCTXTRACE3("query canceled in connected() due to "
+ "unexpected event result; responding",
+ sevent->result);
+
isc_socket_detach(&query->tcpsocket);
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
break;
isc_event_free(&event);
dns_adb_destroyfind(&find);
- if (want_try)
+ if (want_try) {
fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- else if (want_done)
+ } else if (want_done) {
+ FCTXTRACE("fetch failed in finddone(); return ISC_R_FAILURE");
fctx_done(fctx, ISC_R_FAILURE, __LINE__);
- else if (destroy) {
+ } else if (destroy) {
fctx_destroy(fctx);
if (bucket_empty)
empty_bucket(res);
fctx->timeouts++;
fctx->timeout = ISC_TRUE;
+
/*
* We could cancel the running queries here, or we could let
* them keep going. Since we normally use separate sockets for
*/
query = ISC_LIST_HEAD(fctx->queries);
if (query != NULL &&
- isc_time_compare(&tevent->due, &query->start) >= 0) {
+ isc_time_compare(&tevent->due, &query->start) >= 0)
+ {
+ FCTXTRACE("query timed out; no response");
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
}
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
+
/*
* Our timer has triggered. Reestablish the fctx lifetime
* timer.
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
- dns_name_t suffix;
isc_mem_t *mctx;
/*
fctx = isc_mem_get(mctx, sizeof(*fctx));
if (fctx == NULL)
return (ISC_R_NOMEMORY);
+
+ /*
+ * Make fctx->info point to a copy of a formatted string
+ * "name/type".
+ */
dns_name_format(name, buf, sizeof(buf));
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
strcat(buf, "/"); /* checked */
result = ISC_R_NOMEMORY;
goto cleanup_fetch;
}
+
FCTXTRACE("create");
dns_name_init(&fctx->name, NULL);
result = dns_name_dup(name, mctx, &fctx->name);
dns_forwarders_t *forwarders = NULL;
unsigned int labels;
dns_name_t *fwdname = name;
+ dns_name_t suffix;
/*
- * DS records are found in the parent server.
- * Strip label to get the correct forwarder (if any).
+ * DS records are found in the parent server. Strip one
+ * leading label from the name (to be used in finding
+ * the forwarder).
*/
if (dns_rdatatype_atparent(fctx->type) &&
dns_name_countlabels(name) > 1) {
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
fwdname = &suffix;
}
+
+ /* Find the forwarder for this name. */
dns_fixedname_init(&fixed);
domain = dns_fixedname_name(&fixed);
result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
if (fctx->res->exiting) {
result = ISC_R_SHUTTINGDOWN;
+ FCTXTRACE("resolver shutting down");
goto done;
}
no_response = ISC_TRUE;
}
}
+ FCTXTRACE3("dispatcher failure", devent->result);
goto done;
}
if (query->tsig != NULL) {
result = dns_message_setquerytsig(message, query->tsig);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ FCTXTRACE3("unable to set query tsig", result);
goto done;
+ }
}
if (query->tsigkey) {
result = dns_message_settsigkey(message, query->tsigkey);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ FCTXTRACE3("unable to set tsig key", result);
goto done;
+ }
}
if ((options & DNS_FETCHOPT_TCP) == 0) {
}
result = dns_message_parse(message, &devent->buffer, 0);
if (result != ISC_R_SUCCESS) {
+ FCTXTRACE3("message failed to parse", result);
switch (result) {
case ISC_R_UNEXPECTEDEND:
if (!message->question_ok ||
*/
resend = ISC_TRUE;
/* XXXMPA log it */
+ FCTXTRACE("bad sit");
goto done;
}
#endif
* returns success anyway.
*/
result = dns_message_checksig(message, fctx->res->view);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ FCTXTRACE3("signature check failed", result);
goto done;
+ }
/*
* The dispatcher should ensure we only get responses with QR set.
options |= DNS_FETCHOPT_TCP;
resend = ISC_TRUE;
}
+ FCTXTRACE3("message truncated", result);
goto done;
}
/* XXXRTH Log */
broken_server = DNS_R_UNEXPECTEDOPCODE;
keep_trying = ISC_TRUE;
+ FCTXTRACE("invalid message opcode");
goto done;
}
*/
if (message->rcode != dns_rcode_noerror &&
message->rcode != dns_rcode_nxdomain) {
+ isc_buffer_t b;
+ char code[64];
#ifdef ISC_PLATFORM_USESIT
unsigned char sit[64];
INSIST(broken_server != ISC_R_SUCCESS);
keep_trying = ISC_TRUE;
}
+
+ isc_buffer_init(&b, code, sizeof(code) - 1);
+ dns_rcode_totext(fctx->rmessage->rcode, &b);
+ code[isc_buffer_usedlength(&b)] = '\0';
+ FCTXTRACE2("remote server broken: returned ", code);
goto done;
}
/* XXXRTH Log */
if (result == DNS_R_FORMERR)
keep_trying = ISC_TRUE;
+ FCTXTRACE3("response did not match question", result);
goto done;
}
isc_result_totext(result));
broken_server = DNS_R_LAME;
keep_trying = ISC_TRUE;
+ FCTXTRACE("lame server");
goto done;
}
*/
if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 ||
ISFORWARDER(query->addrinfo))
+ {
result = answer_response(fctx);
- else if (iscname(fctx) &&
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE3("answer_response (AA/fwd)", result);
+ } else if (iscname(fctx) &&
fctx->type != dns_rdatatype_any &&
- fctx->type != dns_rdatatype_cname) {
+ fctx->type != dns_rdatatype_cname)
+ {
/*
* A BIND8 server could return a non-authoritative
* answer when a CNAME is followed. We should treat
* it as a valid answer.
*/
result = answer_response(fctx);
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE3("answer_response (!ANY/!CNAME)",
+ result);
} else if (fctx->type != dns_rdatatype_ns &&
!betterreferral(fctx)) {
/*
* Lame response !!!.
*/
result = answer_response(fctx);
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE("answer_response (!NS)");
+ FCTXTRACE3("answer_response (!NS)", result);
} else {
if (fctx->type == dns_rdatatype_ns) {
/*
*/
result = noanswer_response(fctx, NULL,
LOOK_FOR_NS_IN_ANSWER);
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE3("noanswer_response (NS)",
+ result);
} else {
/*
* Some other servers may still somehow include
*/
result = noanswer_response(fctx, NULL,
LOOK_FOR_GLUE_IN_ANSWER);
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE3("noanswer_response", result);
}
if (result != DNS_R_DELEGATION) {
/*
*/
if (result == DNS_R_FORMERR)
keep_trying = ISC_TRUE;
+ FCTXTRACE3("noanswer_response", result);
goto done;
}
} else {
/* XXXRTH Log */
broken_server = DNS_R_UNEXPECTEDRCODE;
keep_trying = ISC_TRUE;
+ FCTXTRACE("broken server: unexpected rcode");
goto done;
}
*/
if (WANTCACHE(fctx)) {
result = cache_message(fctx, query->addrinfo, now);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ FCTXTRACE3("cache_message complete", result);
goto done;
+ }
}
/*
* Cache any negative cache entries in the message.
*/
result = ncache_message(fctx, query->addrinfo, covers, now);
+ if (result != ISC_R_SUCCESS)
+ FCTXTRACE3("ncache_message complete", result);
}
done:
*/
addrinfo = query->addrinfo;
+ FCTXTRACE4("query canceled in response(); ",
+ no_response ? "no response" : "responding",
+ result);
+
/*
* Cancel the query.
*
char typebuf[DNS_RDATATYPE_FORMATSIZE];
int level = ISC_LOG_DEBUG(1);
+ /*
+ * If there's no chance of logging it, don't render (format) the
+ * name and RDATA type (further below), and return early.
+ */
if (! isc_log_wouldlog(dns_lctx, level))
return;
unsigned int i;
dns_badcache_t *bad, *prev, *next;
+ /*
+ * Drop all entries that match the name, and also all expired
+ * entries from the badcache.
+ */
+
REQUIRE(VALID_RESOLVER(resolver));
LOCK(&resolver->lock);
isc_time_t now;
isc_result_t result;
+ /* Drop all expired entries from the badcache. */
+
REQUIRE(VALID_RESOLVER(resolver));
REQUIRE(name != NULL);
dns_badcache_t **new, *bad, *next;
unsigned int i;
+ /*
+ * The number of buckets in the hashtable is modified in this
+ * function. Afterwards, all the entries are remapped into the
+ * corresponding new slot. Rehashing (hash computation) is
+ * unnecessary as the hash values had been saved.
+ */
+
if (grow)
newsize = resolver->badhash * 2 + 1;
else
if (new == NULL)
return;
memset(new, 0, sizeof(*resolver->badcache) * newsize);
+
+ /*
+ * Because the hashtable implements a simple modulus mapping
+ * from hash to bucket (no extendible hashing is used), every
+ * name in the hashtable has to be remapped to its new slot.
+ * Entries that have expired (time) are dropped.
+ */
for (i = 0; i < resolver->badhash; i++) {
for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
next = bad->next;
unsigned int i, hashval;
dns_badcache_t *bad, *prev, *next;
+ /*
+ * The badcache is implemented as a hashtable keyed on the name,
+ * and each bucket slot points to a linked list (separate
+ * chaining).
+ *
+ * To avoid long list chains, if the number of entries in the
+ * hashtable goes over number-of-buckets * 8, the
+ * number-of-buckets is doubled. Similarly, if the number of
+ * entries goes below number-of-buckets * 2, the number-of-buckets
+ * is halved. See resizehash().
+ */
+
REQUIRE(VALID_RESOLVER(resolver));
LOCK(&resolver->lock);
next = bad->next;
if (bad->type == type && dns_name_equal(name, &bad->name))
break;
+ /* Drop expired entries when walking the chain. */
if (isc_time_compare(&bad->expire, &now) < 0) {
if (prev == NULL)
resolver->badcache[i] = bad->next;
prev = bad;
}
if (bad == NULL) {
+ /*
+ * Insert the name into the badcache hashtable at the
+ * head of the linked list at the appropriate slot. The
+ * name data follows right after the allocation for the
+ * linked list node.
+ */
isc_buffer_t buffer;
bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length);
if (bad == NULL)
isc_result_t result;
dns_rbtnode_t *node = NULL;
+ /*
+ * Whether an algorithm is disabled (or not) is stored in a
+ * per-name bitfield that is stored as the node data of an
+ * RBT.
+ */
+
REQUIRE(VALID_RESOLVER(resolver));
if (alg > 255)
return (ISC_R_RANGE);
if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
algorithms = node->data;
+ /*
+ * If algorithms is set, algorithms[0] contains its
+ * length.
+ */
if (algorithms == NULL || len > *algorithms) {
+ /*
+ * If no bitfield exists in the node data, or if
+ * it is not long enough, allocate a new
+ * bitfield and copy the old (smaller) bitfield
+ * into it if one exists.
+ */
new = isc_mem_get(resolver->mctx, len);
if (new == NULL) {
result = ISC_R_NOMEMORY;
if (algorithms != NULL)
memmove(new, algorithms, *algorithms);
new[len-1] |= mask;
+ /* new[0] should contain the length of new. */
*new = len;
node->data = new;
+ /* Free the older bitfield. */
if (algorithms != NULL)
isc_mem_put(resolver->mctx, algorithms,
*algorithms);
isc_result_t result;
dns_rbtnode_t *node = NULL;
+ /*
+ * Whether a digest is disabled (or not) is stored in a per-name
+ * bitfield that is stored as the node data of an RBT.
+ */
+
REQUIRE(VALID_RESOLVER(resolver));
if (digest_type > 255)
return (ISC_R_RANGE);
if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
digests = node->data;
+ /* If digests is set, digests[0] contains its length. */
if (digests == NULL || len > *digests) {
+ /*
+ * If no bitfield exists in the node data, or if
+ * it is not long enough, allocate a new
+ * bitfield and copy the old (smaller) bitfield
+ * into it if one exists.
+ */
new = isc_mem_get(resolver->mctx, len);
if (new == NULL) {
result = ISC_R_NOMEMORY;
if (digests != NULL)
memmove(new, digests, *digests);
new[len-1] |= mask;
+ /* new[0] should contain the length of new. */
*new = len;
node->data = new;
+ /* Free the older bitfield. */
if (digests != NULL)
isc_mem_put(resolver->mctx, digests,
*digests);