mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-05 09:05:40 +00:00
[master] add better servfail logging
3937. [func] Added some debug logging to better indicate the conditions causing SERVFAILs when resolving. [RT #35538]
This commit is contained in:
@@ -80,11 +80,13 @@
|
||||
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, \
|
||||
@@ -92,6 +94,22 @@
|
||||
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, \
|
||||
@@ -1268,6 +1286,9 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
|
||||
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.
|
||||
@@ -1279,6 +1300,10 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
|
||||
break;
|
||||
|
||||
default:
|
||||
FCTXTRACE3("query canceled in sendevent() due to "
|
||||
"unexpected event result; responding",
|
||||
sevent->result);
|
||||
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||
break;
|
||||
}
|
||||
@@ -2359,6 +2384,9 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
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;
|
||||
@@ -2395,6 +2423,9 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
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__);
|
||||
}
|
||||
@@ -2406,6 +2437,10 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
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.
|
||||
*/
|
||||
@@ -2415,6 +2450,10 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
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;
|
||||
@@ -2495,11 +2534,12 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
||||
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);
|
||||
@@ -3479,6 +3519,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
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
|
||||
@@ -3490,10 +3531,13 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
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.
|
||||
@@ -3777,7 +3821,6 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
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;
|
||||
|
||||
/*
|
||||
@@ -3789,6 +3832,11 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
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 */
|
||||
@@ -3798,6 +3846,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup_fetch;
|
||||
}
|
||||
|
||||
FCTXTRACE("create");
|
||||
dns_name_init(&fctx->name, NULL);
|
||||
result = dns_name_dup(name, mctx, &fctx->name);
|
||||
@@ -3870,10 +3919,12 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
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) {
|
||||
@@ -3882,6 +3933,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
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,
|
||||
@@ -7170,6 +7223,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
if (fctx->res->exiting) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
FCTXTRACE("resolver shutting down");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7224,6 +7278,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
no_response = ISC_TRUE;
|
||||
}
|
||||
}
|
||||
FCTXTRACE3("dispatcher failure", devent->result);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7231,14 +7286,18 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
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) {
|
||||
@@ -7250,6 +7309,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
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 ||
|
||||
@@ -7338,6 +7398,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
resend = ISC_TRUE;
|
||||
/* XXXMPA log it */
|
||||
FCTXTRACE("bad sit");
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
@@ -7348,8 +7409,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
* 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.
|
||||
@@ -7453,6 +7516,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
options |= DNS_FETCHOPT_TCP;
|
||||
resend = ISC_TRUE;
|
||||
}
|
||||
FCTXTRACE3("message truncated", result);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7463,6 +7527,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
/* XXXRTH Log */
|
||||
broken_server = DNS_R_UNEXPECTEDOPCODE;
|
||||
keep_trying = ISC_TRUE;
|
||||
FCTXTRACE("invalid message opcode");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7497,6 +7562,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
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];
|
||||
|
||||
@@ -7623,6 +7690,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -7634,6 +7706,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
/* XXXRTH Log */
|
||||
if (result == DNS_R_FORMERR)
|
||||
keep_trying = ISC_TRUE;
|
||||
FCTXTRACE3("response did not match question", result);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7654,6 +7727,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_totext(result));
|
||||
broken_server = DNS_R_LAME;
|
||||
keep_trying = ISC_TRUE;
|
||||
FCTXTRACE("lame server");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7706,22 +7780,32 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
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) {
|
||||
/*
|
||||
@@ -7734,6 +7818,9 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
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
|
||||
@@ -7749,6 +7836,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
result = noanswer_response(fctx, NULL,
|
||||
LOOK_FOR_GLUE_IN_ANSWER);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
FCTXTRACE3("noanswer_response", result);
|
||||
}
|
||||
if (result != DNS_R_DELEGATION) {
|
||||
/*
|
||||
@@ -7813,6 +7902,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
if (result == DNS_R_FORMERR)
|
||||
keep_trying = ISC_TRUE;
|
||||
FCTXTRACE3("noanswer_response", result);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
@@ -7822,6 +7912,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
/* XXXRTH Log */
|
||||
broken_server = DNS_R_UNEXPECTEDRCODE;
|
||||
keep_trying = ISC_TRUE;
|
||||
FCTXTRACE("broken server: unexpected rcode");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -7836,8 +7927,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -7855,6 +7948,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
* 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:
|
||||
@@ -7864,6 +7959,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
addrinfo = query->addrinfo;
|
||||
|
||||
FCTXTRACE4("query canceled in response(); ",
|
||||
no_response ? "no response" : "responding",
|
||||
result);
|
||||
|
||||
/*
|
||||
* Cancel the query.
|
||||
*
|
||||
@@ -8616,6 +8715,10 @@ log_fetch(dns_name_t *name, dns_rdatatype_t type) {
|
||||
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;
|
||||
|
||||
@@ -9022,6 +9125,11 @@ dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
|
||||
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);
|
||||
@@ -9066,6 +9174,8 @@ dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name) {
|
||||
isc_time_t now;
|
||||
isc_result_t result;
|
||||
|
||||
/* Drop all expired entries from the badcache. */
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
REQUIRE(name != NULL);
|
||||
|
||||
@@ -9105,6 +9215,13 @@ resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
|
||||
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
|
||||
@@ -9115,6 +9232,13 @@ resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
|
||||
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;
|
||||
@@ -9143,6 +9267,18 @@ dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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);
|
||||
@@ -9167,6 +9303,7 @@ dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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;
|
||||
@@ -9179,6 +9316,12 @@ dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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)
|
||||
@@ -9337,6 +9480,12 @@ dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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);
|
||||
@@ -9358,7 +9507,17 @@ dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
|
||||
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;
|
||||
@@ -9368,8 +9527,10 @@ dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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);
|
||||
@@ -9451,6 +9612,11 @@ dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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);
|
||||
@@ -9472,7 +9638,14 @@ dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name,
|
||||
|
||||
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;
|
||||
@@ -9482,8 +9655,10 @@ dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name,
|
||||
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);
|
||||
|
Reference in New Issue
Block a user