1
0
mirror of https://gitlab.isc.org/isc-projects/bind9.git synced 2025-04-18 09:44:09 +03:00

fix: usr: Return DNS COOKIE and NSID with BADVERS

This change allows the client to identify the server that returns the
BADVERS and to provide a DNS SERVER COOKIE to be included in the
resend of the request.

Closes #5235

Merge branch '5235-return-the-server-cookie-when-returning-badvers' into 'main'

See merge request isc-projects/bind9!10334
This commit is contained in:
Mark Andrews 2025-04-15 03:11:01 +00:00
commit 79c50d4538
4 changed files with 39 additions and 12 deletions

View File

@ -4269,6 +4269,12 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
dighost_comments(l, "BADVERS, retrying with EDNS version %u.",
(unsigned int)newedns);
l->edns = newedns;
/*
* Extract the server cookie so it can be sent in the retry.
*/
if (l->cookie == NULL && l->sendcookie) {
process_opt(l, msg);
}
n = requeue_lookup(l, true);
if (l->trace && l->trace_root) {
n->rdtype = l->qrdtype;

View File

@ -21,6 +21,7 @@ options {
listen-on-v6 { none; };
recursion no;
dnssec-validation no;
server-id "ns1";
};
zone "." {

View File

@ -57,7 +57,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "Unknown EDNS version ($n)"
ret=0 reason=
$DIG $DIGOPTS @10.53.0.1 +edns=100 +noednsnegotiation soa $zone >dig.out$n || ret=1
$DIG $DIGOPTS @10.53.0.1 +edns=100 +nsid +noednsnegotiation soa $zone >dig.out$n || ret=1
grep "status: BADVERS," dig.out$n >/dev/null || {
ret=1
reason="status"
@ -66,6 +66,14 @@ grep "EDNS: version: 0," dig.out$n >/dev/null || {
ret=1
reason="version"
}
grep "; COOKIE: .* (good)" dig.out$n >/dev/null || {
ret=1
reason="cookie missing"
}
grep '; NSID: 6e 73 31 ("ns1")' dig.out$n >/dev/null || {
ret=1
reason="nsid missing"
}
grep "IN.SOA." dig.out$n >/dev/null && {
ret=1
reason="soa"

View File

@ -1580,17 +1580,6 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
* XXXRTH need library support for this!
*/
client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
if (client->ednsversion > DNS_EDNS_VERSION) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_badednsver);
result = ns_client_addopt(client, client->message,
&client->opt);
if (result == ISC_R_SUCCESS) {
result = DNS_R_BADVERS;
}
ns_client_error(client, result);
return result;
}
/* Check for NSID request */
result = dns_rdataset_first(opt);
@ -1602,6 +1591,17 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
while (isc_buffer_remaininglength(&optbuf) >= 4) {
optcode = isc_buffer_getuint16(&optbuf);
optlen = isc_buffer_getuint16(&optbuf);
/*
* When returning BADVERSION, only process
* DNS_OPT_NSID or DNS_OPT_COOKIE options.
*/
if (client->ednsversion > DNS_EDNS_VERSION &&
optcode != DNS_OPT_NSID &&
optcode != DNS_OPT_COOKIE)
{
isc_buffer_forward(&optbuf, optlen);
continue;
}
switch (optcode) {
case DNS_OPT_NSID:
if (!WANTNSID(client)) {
@ -1683,6 +1683,18 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
}
}
if (client->ednsversion > DNS_EDNS_VERSION) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_badednsver);
result = ns_client_addopt(client, client->message,
&client->opt);
if (result == ISC_R_SUCCESS) {
result = DNS_R_BADVERS;
}
ns_client_error(client, result);
return result;
}
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_edns0in);
client->attributes |= NS_CLIENTATTR_WANTOPT;