Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c7397b9cb | ||
|
|
a5ae37ad0b | ||
|
|
e081ab6ecf | ||
|
|
9604b13d00 | ||
|
|
d7a667d91b | ||
|
|
70470169a9 | ||
|
|
9bb834750d | ||
|
|
d17eda82e0 | ||
|
|
ca3e61a462 | ||
|
|
7f07c989b5 | ||
|
|
83115b931d | ||
|
|
184c7caff9 | ||
|
|
4199d2d5e4 | ||
|
|
6a5e60231f |
+15
-1
@@ -328,6 +328,7 @@ help(void) {
|
|||||||
" +[no]yaml (Present the results as "
|
" +[no]yaml (Present the results as "
|
||||||
"YAML)\n"
|
"YAML)\n"
|
||||||
" +[no]zflag (Set Z flag in query)\n"
|
" +[no]zflag (Set Z flag in query)\n"
|
||||||
|
" +[no]zoneversion (Request zone version)\n"
|
||||||
" global d-opts and servers (before host name) affect "
|
" global d-opts and servers (before host name) affect "
|
||||||
"all "
|
"all "
|
||||||
"queries.\n"
|
"queries.\n"
|
||||||
@@ -2574,10 +2575,23 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
|
|||||||
lookup->rrcomments = -1;
|
lookup->rrcomments = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'z': /* zflag */
|
case 'z':
|
||||||
|
switch (cmd[1]) {
|
||||||
|
case 'f': /* zflag */
|
||||||
FULLCHECK("zflag");
|
FULLCHECK("zflag");
|
||||||
lookup->zflag = state;
|
lookup->zflag = state;
|
||||||
break;
|
break;
|
||||||
|
case 'o': /* zoneversion */
|
||||||
|
FULLCHECK("zoneversion");
|
||||||
|
if (state && lookup->edns == -1) {
|
||||||
|
lookup->edns = DEFAULT_EDNS_VERSION;
|
||||||
|
}
|
||||||
|
lookup->zoneversion = state;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto invalid_option;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
invalid_option:
|
invalid_option:
|
||||||
need_value:
|
need_value:
|
||||||
|
|||||||
@@ -757,6 +757,10 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
|
|||||||
This option sets [or does not set] the last unassigned DNS header flag in a DNS query.
|
This option sets [or does not set] the last unassigned DNS header flag in a DNS query.
|
||||||
This flag is off by default.
|
This flag is off by default.
|
||||||
|
|
||||||
|
.. option:: +zoneversion, +nozoneversion
|
||||||
|
|
||||||
|
When enabled, this option includes an EDNS Zone Version request when sending a query.
|
||||||
|
|
||||||
Multiple Queries
|
Multiple Queries
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -705,6 +705,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
|
|||||||
looknew->opcode = lookold->opcode;
|
looknew->opcode = lookold->opcode;
|
||||||
looknew->expire = lookold->expire;
|
looknew->expire = lookold->expire;
|
||||||
looknew->nsid = lookold->nsid;
|
looknew->nsid = lookold->nsid;
|
||||||
|
looknew->zoneversion = lookold->zoneversion;
|
||||||
looknew->tcp_keepalive = lookold->tcp_keepalive;
|
looknew->tcp_keepalive = lookold->tcp_keepalive;
|
||||||
looknew->header_only = lookold->header_only;
|
looknew->header_only = lookold->header_only;
|
||||||
looknew->https_mode = lookold->https_mode;
|
looknew->https_mode = lookold->https_mode;
|
||||||
@@ -2591,6 +2592,14 @@ setup_lookup(dig_lookup_t *lookup) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lookup->zoneversion) {
|
||||||
|
INSIST(i < MAXOPTS);
|
||||||
|
opts[i].code = DNS_OPT_ZONEVERSION;
|
||||||
|
opts[i].length = 0;
|
||||||
|
opts[i].value = NULL;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
if (lookup->ednsoptscnt != 0) {
|
if (lookup->ednsoptscnt != 0) {
|
||||||
INSIST(i + lookup->ednsoptscnt <= MAXOPTS);
|
INSIST(i + lookup->ednsoptscnt <= MAXOPTS);
|
||||||
memmove(&opts[i], lookup->ednsopts,
|
memmove(&opts[i], lookup->ednsopts,
|
||||||
|
|||||||
+1
-1
@@ -121,7 +121,7 @@ struct dig_lookup {
|
|||||||
tcp_mode, tcp_mode_set, tls_mode, /*% connect using TLS */
|
tcp_mode, tcp_mode_set, tls_mode, /*% connect using TLS */
|
||||||
trace, /*% dig +trace */
|
trace, /*% dig +trace */
|
||||||
trace_root, /*% initial query for either +trace or +nssearch */
|
trace_root, /*% initial query for either +trace or +nssearch */
|
||||||
ttlunits, use_usec, waiting_connect, zflag;
|
ttlunits, use_usec, waiting_connect, zflag, zoneversion;
|
||||||
char textname[MXNAME]; /*% Name we're going to be looking up */
|
char textname[MXNAME]; /*% Name we're going to be looking up */
|
||||||
char cmdline[MXNAME];
|
char cmdline[MXNAME];
|
||||||
dns_rdatatype_t rdtype;
|
dns_rdatatype_t rdtype;
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ options {\n\
|
|||||||
recursing-file \"named.recursing\";\n\
|
recursing-file \"named.recursing\";\n\
|
||||||
recursive-clients 1000;\n\
|
recursive-clients 1000;\n\
|
||||||
request-nsid false;\n\
|
request-nsid false;\n\
|
||||||
|
request-zoneversion false;\n\
|
||||||
resolver-query-timeout 10;\n\
|
resolver-query-timeout 10;\n\
|
||||||
# responselog <boolean>;\n\
|
# responselog <boolean>;\n\
|
||||||
rrset-order { order random; };\n\
|
rrset-order { order random; };\n\
|
||||||
@@ -239,6 +240,7 @@ options {\n\
|
|||||||
notify yes;\n\
|
notify yes;\n\
|
||||||
notify-delay 5;\n\
|
notify-delay 5;\n\
|
||||||
notify-to-soa no;\n\
|
notify-to-soa no;\n\
|
||||||
|
provide-zoneversion yes;\n\
|
||||||
send-report-channel .;\n\
|
send-report-channel .;\n\
|
||||||
serial-update-method increment;\n\
|
serial-update-method increment;\n\
|
||||||
sig-signing-nodes 100;\n\
|
sig-signing-nodes 100;\n\
|
||||||
@@ -260,6 +262,7 @@ view \"_bind\" chaos {\n\
|
|||||||
notify no;\n\
|
notify no;\n\
|
||||||
allow-new-zones no;\n\
|
allow-new-zones no;\n\
|
||||||
max-cache-size 2M;\n\
|
max-cache-size 2M;\n\
|
||||||
|
provide-zoneversion no;\n\
|
||||||
\n\
|
\n\
|
||||||
# Prevent use of this zone in DNS amplified reflection DoS attacks\n\
|
# Prevent use of this zone in DNS amplified reflection DoS attacks\n\
|
||||||
rate-limit {\n\
|
rate-limit {\n\
|
||||||
|
|||||||
@@ -1391,6 +1391,13 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
|
|||||||
CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
|
CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
(void)cfg_map_get(cpeer, "request-zoneversion", &obj);
|
||||||
|
if (obj != NULL) {
|
||||||
|
CHECK(dns_peer_setrequestzoneversion(peer,
|
||||||
|
cfg_obj_asboolean(obj)));
|
||||||
|
}
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
(void)cfg_map_get(cpeer, "send-cookie", &obj);
|
(void)cfg_map_get(cpeer, "send-cookie", &obj);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
@@ -3246,6 +3253,7 @@ create_empty_zone(dns_zone_t *pzone, dns_name_t *name, dns_view_t *view,
|
|||||||
|
|
||||||
dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false);
|
dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false);
|
||||||
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true);
|
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true);
|
||||||
|
dns_zone_setoption(zone, DNS_ZONEOPT_ZONEVERSION, false);
|
||||||
dns_zone_setcheckdstype(zone, dns_checkdstype_no);
|
dns_zone_setcheckdstype(zone, dns_checkdstype_no);
|
||||||
dns_zone_setnotifytype(zone, dns_notifytype_no);
|
dns_zone_setnotifytype(zone, dns_notifytype_no);
|
||||||
dns_zone_setautomatic(zone, true);
|
dns_zone_setautomatic(zone, true);
|
||||||
@@ -5132,6 +5140,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
view->requestnsid = cfg_obj_asboolean(obj);
|
view->requestnsid = cfg_obj_asboolean(obj);
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
result = named_config_get(maps, "request-zoneversion", &obj);
|
||||||
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
view->requestzoneversion = cfg_obj_asboolean(obj);
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "send-cookie", &obj);
|
result = named_config_get(maps, "send-cookie", &obj);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
|||||||
@@ -358,6 +358,8 @@ init_desc(void) {
|
|||||||
SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt");
|
SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt");
|
||||||
SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received",
|
SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received",
|
||||||
"KeepAliveOpt");
|
"KeepAliveOpt");
|
||||||
|
SET_NSSTATDESC(zoneversionopt, "ZONEVERSION option received",
|
||||||
|
"ZoneVersionOpt");
|
||||||
SET_NSSTATDESC(padopt, "EDNS padding option received", "PadOpt");
|
SET_NSSTATDESC(padopt, "EDNS padding option received", "PadOpt");
|
||||||
SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt");
|
SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt");
|
||||||
SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn");
|
SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn");
|
||||||
|
|||||||
@@ -1227,6 +1227,12 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||||||
dns_zone_setkasp(zone, NULL);
|
dns_zone_setkasp(zone, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
result = named_config_get(maps, "provide-zoneversion", &obj);
|
||||||
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||||
|
dns_zone_setoption(zone, DNS_ZONEOPT_ZONEVERSION,
|
||||||
|
cfg_obj_asboolean(obj));
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "notify", &obj);
|
result = named_config_get(maps, "notify", &obj);
|
||||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ server 0.0.0.0 {
|
|||||||
request-ixfr no;
|
request-ixfr no;
|
||||||
request-ixfr-max-diffs 0;
|
request-ixfr-max-diffs 0;
|
||||||
request-nsid no;
|
request-nsid no;
|
||||||
|
request-zoneversion no;
|
||||||
require-cookie no;
|
require-cookie no;
|
||||||
send-cookie no;
|
send-cookie no;
|
||||||
tcp-keepalive no;
|
tcp-keepalive no;
|
||||||
@@ -55,6 +56,7 @@ server :: {
|
|||||||
request-ixfr no;
|
request-ixfr no;
|
||||||
request-ixfr-max-diffs 0;
|
request-ixfr-max-diffs 0;
|
||||||
request-nsid no;
|
request-nsid no;
|
||||||
|
request-zoneversion no;
|
||||||
require-cookie no;
|
require-cookie no;
|
||||||
send-cookie no;
|
send-cookie no;
|
||||||
tcp-keepalive no;
|
tcp-keepalive no;
|
||||||
|
|||||||
@@ -36,4 +36,5 @@ zone "example" {
|
|||||||
zone "example.tld" {
|
zone "example.tld" {
|
||||||
type primary;
|
type primary;
|
||||||
file "example.tld.db";
|
file "example.tld.db";
|
||||||
|
provide-zoneversion no;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -801,6 +801,73 @@ if [ -x "$DIG" ]; then
|
|||||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
status=$((status + ret))
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking dig +zoneversion to a authoritative server ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
|
||||||
|
pat="; ZONEVERSION: ZONE: example, SOA-SERIAL: 2000042407"
|
||||||
|
grep "$pat" dig.out.test$n >/dev/null || ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking dig +zoneversion to a authoritative server with zoneversion disabled ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +zoneversion a.example.tld >dig.out.test$n 2>&1 || ret=1
|
||||||
|
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
|
||||||
|
grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
if [ $HAS_PYYAML -ne 0 ]; then
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking dig +yaml +zoneversion to a authoritative server ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +yaml +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
|
||||||
|
$PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
|
||||||
|
read -r value <yamlget.out.test$n
|
||||||
|
expected="{'ZONE': 'example', 'SOA-SERIAL': 2000042407}"
|
||||||
|
[ "$value" = "$expected" ] || ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
fi
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking dig +ednsopt=ZONEVERSION:<answer> to a authoritative server ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
|
||||||
|
grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
|
||||||
|
grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking dig +zoneversion to a recursive server ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.3 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
|
||||||
|
grep '; ZONEVERSION:' dig.out.test$n >/dev/null && ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking display of non serial type zoneversion ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
|
||||||
|
grep '; ZONEVERSION: LABELS: 1, TYPE: 0, VALUE: 000007da ("....")' dig.out.test$n >/dev/null && ret=1
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
if [ $HAS_PYYAML -ne 0 ]; then
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "checking display of non serial type zoneversion +yaml ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example +yaml >dig.out.test$n 2>&1 || ret=1
|
||||||
|
$PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
|
||||||
|
expected="{'ZONE': 'example', 'TYPE': 1, 'VALUE': 000007da, PVALUE: '....'}"
|
||||||
|
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
fi
|
||||||
|
|
||||||
n=$((n + 1))
|
n=$((n + 1))
|
||||||
echo_i "check that dig gracefully handles bad escape in domain name ($n)"
|
echo_i "check that dig gracefully handles bad escape in domain name ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ use IO::Socket;
|
|||||||
use Net::DNS;
|
use Net::DNS;
|
||||||
use Net::DNS::Packet;
|
use Net::DNS::Packet;
|
||||||
|
|
||||||
|
print "Using Net::DNS $Net::DNS::VERSION\n";
|
||||||
|
|
||||||
my $localport = int($ENV{'PORT'});
|
my $localport = int($ENV{'PORT'});
|
||||||
if (!$localport) { $localport = 5300; }
|
if (!$localport) { $localport = 5300; }
|
||||||
|
|
||||||
@@ -170,6 +172,15 @@ for (;;) {
|
|||||||
$packet->push("authority",
|
$packet->push("authority",
|
||||||
new Net::DNS::RR($qname . " 300 SOA . . 0 0 0 0 0"));
|
new Net::DNS::RR($qname . " 300 SOA . . 0 0 0 0 0"));
|
||||||
}
|
}
|
||||||
|
} elsif ($qname eq "zoneversion") {
|
||||||
|
$packet->push("authority", new Net::DNS::RR(". 300 SOA . . 0 0 0 0 0"));
|
||||||
|
if ($Net::DNS::VERSION >= 1.49) {
|
||||||
|
$packet->edns->option('ZONEVERSION' => [0, 1, '01022304'] )
|
||||||
|
} elsif ($Net::DNS::VERSION >= 1.35) {
|
||||||
|
$packet->edns->option('19' => {'BASE16' => '000101022304'} )
|
||||||
|
} else {
|
||||||
|
$packet->edns->option('19' => pack 'H*', '000101022304')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
# Data for the "bogus referrals" test
|
# Data for the "bogus referrals" test
|
||||||
$packet->push("authority", new Net::DNS::RR("below.www.example.com 300 NS ns.below.www.example.com"));
|
$packet->push("authority", new Net::DNS::RR("below.www.example.com 300 NS ns.below.www.example.com"));
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ options {
|
|||||||
resolver-query-timeout 5000; # 5 seconds
|
resolver-query-timeout 5000; # 5 seconds
|
||||||
attach-cache "globalcache";
|
attach-cache "globalcache";
|
||||||
max-recursion-queries 100;
|
max-recursion-queries 100;
|
||||||
|
request-zoneversion yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
trust-anchors { };
|
trust-anchors { };
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ options {
|
|||||||
querylog yes;
|
querylog yes;
|
||||||
prefetch 4 10;
|
prefetch 4 10;
|
||||||
responselog yes;
|
responselog yes;
|
||||||
|
request-nsid yes;
|
||||||
|
request-zoneversion yes;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't break tests which depend on ans10 by requesting
|
||||||
|
// zoneversion or nsid
|
||||||
|
server 10.53.0.10 {
|
||||||
|
request-nsid no;
|
||||||
|
request-zoneversion no;
|
||||||
};
|
};
|
||||||
|
|
||||||
include "trusted.conf";
|
include "trusted.conf";
|
||||||
|
|||||||
@@ -901,6 +901,23 @@ test ${lines:-1} -ne 0 && ret=1
|
|||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=$((status + ret))
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "check that received ZONEVERSION is logged ($n)"
|
||||||
|
ret=0
|
||||||
|
pat="received ZONEVERSION serial 2010 from 10.53.0.4#[0-9]* for mixedttl.tld/TXT zone tld"
|
||||||
|
grep "$pat" ns5/named.run >/dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
|
n=$((n + 1))
|
||||||
|
echo_i "check that received ZONEVERSION is logged non serial ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts +tcp @10.53.0.1 zoneversion >dig.out.${n} || ret=1
|
||||||
|
pat='received ZONEVERSION type 1 value 01022304 (\.\.#\.) from 10.53.0.2#[0-9]* for zoneversion/A zone \.'
|
||||||
|
grep "$pat" ns1/named.run >/dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
n=$((n + 1))
|
n=$((n + 1))
|
||||||
echo_i "check resolver behavior when FORMERR for EDNS options happens (${n})"
|
echo_i "check resolver behavior when FORMERR for EDNS options happens (${n})"
|
||||||
ret=0
|
ret=0
|
||||||
|
|||||||
@@ -127,3 +127,7 @@
|
|||||||
|
|
||||||
``zoneload``
|
``zoneload``
|
||||||
Loading of zones and creation of automatic empty zones.
|
Loading of zones and creation of automatic empty zones.
|
||||||
|
|
||||||
|
``zoneversion``
|
||||||
|
ZONEVERSION options received from upstream servers.
|
||||||
|
|
||||||
|
|||||||
@@ -2165,6 +2165,14 @@ Boolean Options
|
|||||||
ultimate primary should be set to still send NOTIFY messages to all the name servers
|
ultimate primary should be set to still send NOTIFY messages to all the name servers
|
||||||
listed in the NS RRset.
|
listed in the NS RRset.
|
||||||
|
|
||||||
|
.. namedconf:statement:: provide-zoneversion
|
||||||
|
:tags: transfer
|
||||||
|
:short: Controls the return EDNS ZONEVERSION answers.
|
||||||
|
|
||||||
|
If ``yes`` EDNS ZONEVERSION answers will be returned otherwise
|
||||||
|
not for primary, secondary and mirror zones. The default is
|
||||||
|
``yes``.
|
||||||
|
|
||||||
.. namedconf:statement:: recursion
|
.. namedconf:statement:: recursion
|
||||||
:tags: query
|
:tags: query
|
||||||
:short: Defines whether recursion and caching are allowed.
|
:short: Defines whether recursion and caching are allowed.
|
||||||
@@ -2188,6 +2196,18 @@ Boolean Options
|
|||||||
option in its response, then its contents are logged in the ``nsid``
|
option in its response, then its contents are logged in the ``nsid``
|
||||||
category at level ``info``. The default is ``no``.
|
category at level ``info``. The default is ``no``.
|
||||||
|
|
||||||
|
.. namedconf:statement:: request-zoneversion
|
||||||
|
:tags: query
|
||||||
|
:short: Controls whether an empty EDNS(0) ZONEVERSION option is sent with all queries to authoritative name servers during iterative resolution.
|
||||||
|
|
||||||
|
If ``yes``, then an empty EDNS(0) ZONEVERSION option is sent
|
||||||
|
with all queries to authoritative name servers during iterative
|
||||||
|
resolution. If the authoritative server returns an ZONEVERSION
|
||||||
|
option in its response, then its contents are logged in the
|
||||||
|
``zoneversion`` category at level ``info``. If the NSID has
|
||||||
|
also been requested and it is returned then that is appended to
|
||||||
|
the log message. The default is ``no``.
|
||||||
|
|
||||||
.. namedconf:statement:: require-cookie
|
.. namedconf:statement:: require-cookie
|
||||||
:tags: query
|
:tags: query
|
||||||
:short: Controls whether responses without a server cookie are accepted.
|
:short: Controls whether responses without a server cookie are accepted.
|
||||||
@@ -5601,11 +5621,13 @@ and :namedconf:ref:`options` blocks:
|
|||||||
- :namedconf:ref:`notify-source-v6`
|
- :namedconf:ref:`notify-source-v6`
|
||||||
- :namedconf:ref:`notify-source`
|
- :namedconf:ref:`notify-source`
|
||||||
- :namedconf:ref:`provide-ixfr`
|
- :namedconf:ref:`provide-ixfr`
|
||||||
|
- :namedconf:ref:`provide-zoneversion`
|
||||||
- :namedconf:ref:`query-source-v6`
|
- :namedconf:ref:`query-source-v6`
|
||||||
- :namedconf:ref:`query-source`
|
- :namedconf:ref:`query-source`
|
||||||
- :namedconf:ref:`request-expire`
|
- :namedconf:ref:`request-expire`
|
||||||
- :namedconf:ref:`request-ixfr`
|
- :namedconf:ref:`request-ixfr`
|
||||||
- :namedconf:ref:`request-nsid`
|
- :namedconf:ref:`request-nsid`
|
||||||
|
- :namedconf:ref:`request-zoneversion`
|
||||||
- :namedconf:ref:`require-cookie`
|
- :namedconf:ref:`require-cookie`
|
||||||
- :namedconf:ref:`send-cookie`
|
- :namedconf:ref:`send-cookie`
|
||||||
- :namedconf:ref:`transfer-format`
|
- :namedconf:ref:`transfer-format`
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ zone <string> [ <class> ] {
|
|||||||
notify-source ( <ipv4_address> | * );
|
notify-source ( <ipv4_address> | * );
|
||||||
notify-source-v6 ( <ipv6_address> | * );
|
notify-source-v6 ( <ipv6_address> | * );
|
||||||
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
|
provide-zoneversion <boolean>;
|
||||||
request-expire <boolean>;
|
request-expire <boolean>;
|
||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ options {
|
|||||||
preferred-glue <string>;
|
preferred-glue <string>;
|
||||||
prefetch <integer> [ <integer> ];
|
prefetch <integer> [ <integer> ];
|
||||||
provide-ixfr <boolean>;
|
provide-ixfr <boolean>;
|
||||||
|
provide-zoneversion <boolean>;
|
||||||
qname-minimization ( strict | relaxed | disabled | off );
|
qname-minimization ( strict | relaxed | disabled | off );
|
||||||
query-source [ address ] ( <ipv4_address> | * | none );
|
query-source [ address ] ( <ipv4_address> | * | none );
|
||||||
query-source-v6 [ address ] ( <ipv6_address> | * | none );
|
query-source-v6 [ address ] ( <ipv6_address> | * | none );
|
||||||
@@ -254,6 +255,7 @@ options {
|
|||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
request-nsid <boolean>;
|
request-nsid <boolean>;
|
||||||
|
request-zoneversion <boolean>;
|
||||||
require-server-cookie <boolean>;
|
require-server-cookie <boolean>;
|
||||||
resolver-query-timeout <integer>;
|
resolver-query-timeout <integer>;
|
||||||
resolver-use-dns64 <boolean>;
|
resolver-use-dns64 <boolean>;
|
||||||
@@ -343,6 +345,7 @@ server <netprefix> {
|
|||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
request-nsid <boolean>;
|
request-nsid <boolean>;
|
||||||
|
request-zoneversion <boolean>;
|
||||||
require-cookie <boolean>;
|
require-cookie <boolean>;
|
||||||
send-cookie <boolean>;
|
send-cookie <boolean>;
|
||||||
tcp-keepalive <boolean>;
|
tcp-keepalive <boolean>;
|
||||||
@@ -509,6 +512,7 @@ view <string> [ <class> ] {
|
|||||||
preferred-glue <string>;
|
preferred-glue <string>;
|
||||||
prefetch <integer> [ <integer> ];
|
prefetch <integer> [ <integer> ];
|
||||||
provide-ixfr <boolean>;
|
provide-ixfr <boolean>;
|
||||||
|
provide-zoneversion <boolean>;
|
||||||
qname-minimization ( strict | relaxed | disabled | off );
|
qname-minimization ( strict | relaxed | disabled | off );
|
||||||
query-source [ address ] ( <ipv4_address> | * | none );
|
query-source [ address ] ( <ipv4_address> | * | none );
|
||||||
query-source-v6 [ address ] ( <ipv6_address> | * | none );
|
query-source-v6 [ address ] ( <ipv6_address> | * | none );
|
||||||
@@ -534,6 +538,7 @@ view <string> [ <class> ] {
|
|||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
request-nsid <boolean>;
|
request-nsid <boolean>;
|
||||||
|
request-zoneversion <boolean>;
|
||||||
require-server-cookie <boolean>;
|
require-server-cookie <boolean>;
|
||||||
resolver-query-timeout <integer>;
|
resolver-query-timeout <integer>;
|
||||||
resolver-use-dns64 <boolean>;
|
resolver-use-dns64 <boolean>;
|
||||||
@@ -561,6 +566,7 @@ view <string> [ <class> ] {
|
|||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
request-nsid <boolean>;
|
request-nsid <boolean>;
|
||||||
|
request-zoneversion <boolean>;
|
||||||
require-cookie <boolean>;
|
require-cookie <boolean>;
|
||||||
send-cookie <boolean>;
|
send-cookie <boolean>;
|
||||||
tcp-keepalive <boolean>;
|
tcp-keepalive <boolean>;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ zone <string> [ <class> ] {
|
|||||||
parental-agents [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
parental-agents [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
parental-source ( <ipv4_address> | * );
|
parental-source ( <ipv4_address> | * );
|
||||||
parental-source-v6 ( <ipv6_address> | * );
|
parental-source-v6 ( <ipv6_address> | * );
|
||||||
|
provide-zoneversion <boolean>;
|
||||||
send-report-channel <string>;
|
send-report-channel <string>;
|
||||||
serial-update-method ( date | increment | unixtime );
|
serial-update-method ( date | increment | unixtime );
|
||||||
sig-signing-nodes <integer>;
|
sig-signing-nodes <integer>;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ zone <string> [ <class> ] {
|
|||||||
parental-source ( <ipv4_address> | * );
|
parental-source ( <ipv4_address> | * );
|
||||||
parental-source-v6 ( <ipv6_address> | * );
|
parental-source-v6 ( <ipv6_address> | * );
|
||||||
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||||
|
provide-zoneversion <boolean>;
|
||||||
request-expire <boolean>;
|
request-expire <boolean>;
|
||||||
request-ixfr <boolean>;
|
request-ixfr <boolean>;
|
||||||
request-ixfr-max-diffs <integer>;
|
request-ixfr-max-diffs <integer>;
|
||||||
|
|||||||
@@ -1200,3 +1200,14 @@ dns__db_logtoomanyrecords(dns_db_t *db, const dns_name_t *name,
|
|||||||
(db->attributes & DNS_DBATTR_CACHE) != 0 ? "cache" : "zone",
|
(db->attributes & DNS_DBATTR_CACHE) != 0 ? "cache" : "zone",
|
||||||
isc_result_totext(DNS_R_TOOMANYRECORDS), limit);
|
isc_result_totext(DNS_R_TOOMANYRECORDS), limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_db_getzoneversion(dns_db_t *db, isc_buffer_t *b) {
|
||||||
|
REQUIRE(db != NULL);
|
||||||
|
REQUIRE(b != NULL);
|
||||||
|
|
||||||
|
if (db->methods->getzoneversion != NULL) {
|
||||||
|
return (db->methods->getzoneversion)(db, b);
|
||||||
|
}
|
||||||
|
return ISC_R_NOTIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ typedef struct dns_dbmethods {
|
|||||||
dns_name_t *name);
|
dns_name_t *name);
|
||||||
void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
|
void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
|
||||||
void (*setmaxtypepername)(dns_db_t *db, uint32_t value);
|
void (*setmaxtypepername)(dns_db_t *db, uint32_t value);
|
||||||
|
isc_result_t (*getzoneversion)(dns_db_t *db, isc_buffer_t *b);
|
||||||
} dns_dbmethods_t;
|
} dns_dbmethods_t;
|
||||||
|
|
||||||
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
|
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
|
||||||
@@ -1805,3 +1806,21 @@ dns_db_setmaxtypepername(dns_db_t *db, uint32_t value);
|
|||||||
* stored at a given node, then any subsequent attempt to add an rdataset
|
* stored at a given node, then any subsequent attempt to add an rdataset
|
||||||
* with a new RR type will return ISC_R_TOOMANYRECORDS.
|
* with a new RR type will return ISC_R_TOOMANYRECORDS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_db_getzoneversion(dns_db_t *db, isc_buffer_t *b);
|
||||||
|
/*%<
|
||||||
|
* Provides a database specific EDNS ZONEVERSION option.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li 'db' is a valid database
|
||||||
|
* \li 'b' is a valid buffer
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li ISC_R_SUCCESS when it has populated the buffer with the ZONEVERSION
|
||||||
|
* response (maybe empty implying no ZONEVERSION to be returned).
|
||||||
|
* \li ISC_R_NOSPACE if the buffer is too small.
|
||||||
|
* \li ISC_R_NOTIMPLEMENTED if there is not a database specific
|
||||||
|
* ZONEVERSION
|
||||||
|
* \li ISC_R_FAILURE other failures
|
||||||
|
*/
|
||||||
|
|||||||
@@ -102,7 +102,6 @@
|
|||||||
#define DNS_MESSAGEEXTFLAG_DO 0x8000U
|
#define DNS_MESSAGEEXTFLAG_DO 0x8000U
|
||||||
|
|
||||||
/*%< EDNS0 extended OPT codes */
|
/*%< EDNS0 extended OPT codes */
|
||||||
|
|
||||||
#define DNS_OPT_LLQ 1 /*%< LLQ opt code */
|
#define DNS_OPT_LLQ 1 /*%< LLQ opt code */
|
||||||
#define DNS_OPT_UL 2 /*%< UL opt code */
|
#define DNS_OPT_UL 2 /*%< UL opt code */
|
||||||
#define DNS_OPT_NSID 3 /*%< NSID opt code */
|
#define DNS_OPT_NSID 3 /*%< NSID opt code */
|
||||||
@@ -129,7 +128,7 @@
|
|||||||
* options we know about. Extended DNS Errors may occur multiple times, see
|
* options we know about. Extended DNS Errors may occur multiple times, see
|
||||||
* DNS_EDE_MAX_ERRORS.
|
* DNS_EDE_MAX_ERRORS.
|
||||||
*/
|
*/
|
||||||
#define DNS_EDNSOPTIONS 8 + DNS_EDE_MAX_ERRORS
|
#define DNS_EDNSOPTIONS 9 + DNS_EDE_MAX_ERRORS
|
||||||
|
|
||||||
#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_CD)
|
#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_CD)
|
||||||
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
|
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ dns_peer_setrequestnsid(dns_peer_t *peer, bool newval);
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval);
|
dns_peer_getrequestnsid(dns_peer_t *peer, bool *retval);
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_peer_setrequestzoneversion(dns_peer_t *peer, bool newval);
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_peer_getrequestzoneversion(dns_peer_t *peer, bool *retval);
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_peer_setsendcookie(dns_peer_t *peer, bool newval);
|
dns_peer_setsendcookie(dns_peer_t *peer, bool newval);
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ enum {
|
|||||||
DNS_FETCHOPT_NOFORWARD = 1 << 15, /*%< Do not use forwarders if
|
DNS_FETCHOPT_NOFORWARD = 1 << 15, /*%< Do not use forwarders if
|
||||||
* possible. */
|
* possible. */
|
||||||
DNS_FETCHOPT_QMINFETCH = 1 << 16, /*%< Qmin fetch */
|
DNS_FETCHOPT_QMINFETCH = 1 << 16, /*%< Qmin fetch */
|
||||||
|
DNS_FETCHOPT_WANTZONEVERSION = 1 << 17, /*%< Request ZONEVERSION */
|
||||||
|
|
||||||
/*% EDNS version bits: */
|
/*% EDNS version bits: */
|
||||||
DNS_FETCHOPT_EDNSVERSIONSET = 1 << 23,
|
DNS_FETCHOPT_EDNSVERSIONSET = 1 << 23,
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ struct dns_view {
|
|||||||
dns_rrl_t *rrl;
|
dns_rrl_t *rrl;
|
||||||
bool provideixfr;
|
bool provideixfr;
|
||||||
bool requestnsid;
|
bool requestnsid;
|
||||||
|
bool requestzoneversion;
|
||||||
bool sendcookie;
|
bool sendcookie;
|
||||||
dns_ttl_t maxcachettl;
|
dns_ttl_t maxcachettl;
|
||||||
dns_ttl_t maxncachettl;
|
dns_ttl_t maxncachettl;
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ typedef enum {
|
|||||||
DNS_ZONEOPT_CHECKTTL = 1 << 28, /*%< check max-zone-ttl */
|
DNS_ZONEOPT_CHECKTTL = 1 << 28, /*%< check max-zone-ttl */
|
||||||
DNS_ZONEOPT_AUTOEMPTY = 1 << 29, /*%< automatic empty zone */
|
DNS_ZONEOPT_AUTOEMPTY = 1 << 29, /*%< automatic empty zone */
|
||||||
DNS_ZONEOPT_CHECKSVCB = 1 << 30, /*%< check SVBC records */
|
DNS_ZONEOPT_CHECKSVCB = 1 << 30, /*%< check SVBC records */
|
||||||
|
DNS_ZONEOPT_ZONEVERSION = 1U << 31, /*%< enable zoneversion */
|
||||||
DNS_ZONEOPT___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
|
DNS_ZONEOPT___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
|
||||||
} dns_zoneopt_t;
|
} dns_zoneopt_t;
|
||||||
|
|
||||||
@@ -2785,6 +2786,24 @@ dns_zone_getrad(dns_zone_t *zone, dns_name_t *name);
|
|||||||
* \li 'name' is a valid name with a buffer.
|
* \li 'name' is a valid name with a buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_zone_getzoneversion(dns_zone_t *zone, isc_buffer_t *b);
|
||||||
|
/**<
|
||||||
|
* Return the EDNS ZONEVERSION for this zone.
|
||||||
|
*
|
||||||
|
* Note: For type SERIAL a buffer of at least 6 octets is required.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li 'zone' to be a valid zone.
|
||||||
|
* \li 'b' to be a valid buffer.
|
||||||
|
*
|
||||||
|
* Returns
|
||||||
|
* \li ISC_R_SUCCESS if the zone is loaded and supports ZONEVERSION.
|
||||||
|
* \li ISC_R_NOSPACE if the buffer is too small.
|
||||||
|
* \li DNS_R_NOTLOADED if the database is not loaded.
|
||||||
|
* \li ISC_R_FAILURE other failure.
|
||||||
|
*/
|
||||||
|
|
||||||
#if DNS_ZONE_TRACE
|
#if DNS_ZONE_TRACE
|
||||||
#define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__)
|
#define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__)
|
||||||
#define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__)
|
#define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__)
|
||||||
|
|||||||
@@ -3512,6 +3512,116 @@ static const char *option_names[] = {
|
|||||||
[DNS_OPT_ZONEVERSION] = "ZONEVERSION",
|
[DNS_OPT_ZONEVERSION] = "ZONEVERSION",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
render_zoneversion(dns_message_t *msg, isc_buffer_t *optbuf,
|
||||||
|
const dns_master_style_t *style, isc_buffer_t *target) {
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
unsigned int labels = isc_buffer_getuint8(optbuf);
|
||||||
|
unsigned int type = isc_buffer_getuint8(optbuf);
|
||||||
|
char buf[sizeof("4000000000")];
|
||||||
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
|
dns_name_t *name = ISC_LIST_HEAD(msg->sections[DNS_SECTION_QUESTION]);
|
||||||
|
dns_name_t suffix = DNS_NAME_INITEMPTY;
|
||||||
|
bool yaml = false, rawmode = false;
|
||||||
|
const char *sep1 = " ", *sep2 = ", ";
|
||||||
|
|
||||||
|
if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0) {
|
||||||
|
msg->indent.count++;
|
||||||
|
sep1 = sep2 = "\n";
|
||||||
|
yaml = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADD_STRING(target, sep1);
|
||||||
|
|
||||||
|
if (msg->counts[DNS_SECTION_QUESTION] != 1 || name == NULL ||
|
||||||
|
dns_name_countlabels(name) < labels + 1)
|
||||||
|
{
|
||||||
|
rawmode = true;
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "LABELS: ");
|
||||||
|
snprintf(buf, sizeof(buf), "%u", labels);
|
||||||
|
ADD_STRING(target, buf);
|
||||||
|
} else {
|
||||||
|
dns_name_split(name, labels + 1, NULL, &suffix);
|
||||||
|
dns_name_format(&suffix, namebuf, sizeof(namebuf));
|
||||||
|
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "ZONE: ");
|
||||||
|
if (yaml) {
|
||||||
|
char *s = namebuf;
|
||||||
|
ADD_STRING(target, "\"");
|
||||||
|
while (*s != 0) {
|
||||||
|
if (*s == '\\' || *s == '"') {
|
||||||
|
ADD_STRING(target, "\\");
|
||||||
|
}
|
||||||
|
if (isc_buffer_availablelength(target) < 1) {
|
||||||
|
result = ISC_R_NOSPACE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
isc_buffer_putmem(target, (unsigned char *)s,
|
||||||
|
1);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
ADD_STRING(target, "\"");
|
||||||
|
} else {
|
||||||
|
ADD_STRING(target, namebuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ADD_STRING(target, sep2);
|
||||||
|
|
||||||
|
if (!rawmode && type == 0 && isc_buffer_remaininglength(optbuf) == 4) {
|
||||||
|
uint32_t serial = isc_buffer_getuint32(optbuf);
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "SOA-SERIAL: ");
|
||||||
|
snprintf(buf, sizeof(buf), "%u", serial);
|
||||||
|
ADD_STRING(target, buf);
|
||||||
|
} else {
|
||||||
|
size_t len = isc_buffer_remaininglength(optbuf);
|
||||||
|
unsigned char *data = isc_buffer_current(optbuf);
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "TYPE: ");
|
||||||
|
snprintf(buf, sizeof(buf), "%u", type);
|
||||||
|
ADD_STRING(target, buf);
|
||||||
|
ADD_STRING(target, sep2);
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "VALUE: ");
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
snprintf(buf, sizeof(buf), "%02x", data[i]);
|
||||||
|
ADD_STRING(target, buf);
|
||||||
|
}
|
||||||
|
if (yaml) {
|
||||||
|
ADD_STRING(target, sep2);
|
||||||
|
INDENT(style);
|
||||||
|
ADD_STRING(target, "PVALUE: \"");
|
||||||
|
} else {
|
||||||
|
ADD_STRING(target, " (\"");
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
if (isprint(data[i])) {
|
||||||
|
if (yaml && (data[i] == '\\' || data[i] == '"'))
|
||||||
|
{
|
||||||
|
ADD_STRING(target, "\\");
|
||||||
|
}
|
||||||
|
if (isc_buffer_availablelength(target) < 1) {
|
||||||
|
result = ISC_R_NOSPACE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
isc_buffer_putmem(target, &data[i], 1);
|
||||||
|
} else {
|
||||||
|
ADD_STRING(target, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (yaml) {
|
||||||
|
ADD_STRING(target, "\"");
|
||||||
|
} else {
|
||||||
|
ADD_STRING(target, "\")");
|
||||||
|
}
|
||||||
|
isc_buffer_forward(optbuf, len);
|
||||||
|
}
|
||||||
|
cleanup:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
|
dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
|
||||||
const dns_master_style_t *style,
|
const dns_master_style_t *style,
|
||||||
@@ -3789,6 +3899,20 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
|
|||||||
optbuf = sb;
|
optbuf = sb;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DNS_OPT_ZONEVERSION:
|
||||||
|
if (optlen >= 2U) {
|
||||||
|
isc_buffer_t zonebuf = optbuf;
|
||||||
|
isc_buffer_setactive(&zonebuf, optlen);
|
||||||
|
result = render_zoneversion(
|
||||||
|
msg, &zonebuf, style, target);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
isc_buffer_forward(&optbuf, optlen);
|
||||||
|
ADD_STRING(target, "\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4208,6 +4332,20 @@ dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section,
|
|||||||
optbuf = sb;
|
optbuf = sb;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DNS_OPT_ZONEVERSION:
|
||||||
|
if (optlen >= 2U) {
|
||||||
|
isc_buffer_t zonebuf = optbuf;
|
||||||
|
isc_buffer_setactive(&zonebuf, optlen);
|
||||||
|
result = render_zoneversion(
|
||||||
|
msg, &zonebuf, style, target);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
ADD_STRING(target, "\n");
|
||||||
|
isc_buffer_forward(&optbuf, optlen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -57,6 +57,7 @@ struct dns_peer {
|
|||||||
bool request_ixfr;
|
bool request_ixfr;
|
||||||
bool support_edns;
|
bool support_edns;
|
||||||
bool request_nsid;
|
bool request_nsid;
|
||||||
|
bool request_zoneversion;
|
||||||
bool send_cookie;
|
bool send_cookie;
|
||||||
bool require_cookie;
|
bool require_cookie;
|
||||||
bool request_expire;
|
bool request_expire;
|
||||||
@@ -98,7 +99,8 @@ enum {
|
|||||||
SERVER_PADDING_BIT,
|
SERVER_PADDING_BIT,
|
||||||
REQUEST_TCP_KEEPALIVE_BIT,
|
REQUEST_TCP_KEEPALIVE_BIT,
|
||||||
REQUIRE_COOKIE_BIT,
|
REQUIRE_COOKIE_BIT,
|
||||||
DNS_PEER_FLAGS_COUNT
|
DNS_PEER_FLAGS_COUNT,
|
||||||
|
REQUEST_ZONEVERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC_ASSERT(DNS_PEER_FLAGS_COUNT <= CHAR_BIT * sizeof(uint32_t),
|
STATIC_ASSERT(DNS_PEER_FLAGS_COUNT <= CHAR_BIT * sizeof(uint32_t),
|
||||||
@@ -382,6 +384,8 @@ ACCESS_OPTION(requestixfr, REQUEST_IXFR_BIT, bool, request_ixfr)
|
|||||||
ACCESS_OPTION(requestixfrmaxdiffs, REQUEST_IXFRMAXDIFFS_BIT, uint32_t,
|
ACCESS_OPTION(requestixfrmaxdiffs, REQUEST_IXFRMAXDIFFS_BIT, uint32_t,
|
||||||
request_ixfr_maxdiffs)
|
request_ixfr_maxdiffs)
|
||||||
ACCESS_OPTION(requestnsid, REQUEST_NSID_BIT, bool, request_nsid)
|
ACCESS_OPTION(requestnsid, REQUEST_NSID_BIT, bool, request_nsid)
|
||||||
|
ACCESS_OPTION(requestzoneversion, REQUEST_ZONEVERSION, bool,
|
||||||
|
request_zoneversion)
|
||||||
ACCESS_OPTION(requirecookie, REQUIRE_COOKIE_BIT, bool, require_cookie)
|
ACCESS_OPTION(requirecookie, REQUIRE_COOKIE_BIT, bool, require_cookie)
|
||||||
ACCESS_OPTION(sendcookie, SEND_COOKIE_BIT, bool, send_cookie)
|
ACCESS_OPTION(sendcookie, SEND_COOKIE_BIT, bool, send_cookie)
|
||||||
ACCESS_OPTION(supportedns, SUPPORT_EDNS_BIT, bool, support_edns)
|
ACCESS_OPTION(supportedns, SUPPORT_EDNS_BIT, bool, support_edns)
|
||||||
|
|||||||
@@ -266,6 +266,21 @@ fromwire_opt(ARGS_FROMWIRE) {
|
|||||||
}
|
}
|
||||||
isc_region_consume(&sregion, length);
|
isc_region_consume(&sregion, length);
|
||||||
break;
|
break;
|
||||||
|
case DNS_OPT_ZONEVERSION:
|
||||||
|
if (length == 0) {
|
||||||
|
/* Request */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Labels and Type */
|
||||||
|
if (length < 2) {
|
||||||
|
return DNS_R_OPTERR;
|
||||||
|
}
|
||||||
|
/* Type 0 (serial), length is 6. */
|
||||||
|
if (sregion.base[1] == 0 && length != 6) {
|
||||||
|
return DNS_R_OPTERR;
|
||||||
|
}
|
||||||
|
isc_region_consume(&sregion, length);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
isc_region_consume(&sregion, length);
|
isc_region_consume(&sregion, length);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+171
-20
@@ -24,6 +24,7 @@
|
|||||||
#include <isc/counter.h>
|
#include <isc/counter.h>
|
||||||
#include <isc/hash.h>
|
#include <isc/hash.h>
|
||||||
#include <isc/hashmap.h>
|
#include <isc/hashmap.h>
|
||||||
|
#include <isc/hex.h>
|
||||||
#include <isc/log.h>
|
#include <isc/log.h>
|
||||||
#include <isc/loop.h>
|
#include <isc/loop.h>
|
||||||
#include <isc/mutex.h>
|
#include <isc/mutex.h>
|
||||||
@@ -2504,6 +2505,7 @@ resquery_send(resquery_t *query) {
|
|||||||
unsigned int flags = query->addrinfo->flags;
|
unsigned int flags = query->addrinfo->flags;
|
||||||
bool reqnsid = res->view->requestnsid;
|
bool reqnsid = res->view->requestnsid;
|
||||||
bool sendcookie = res->view->sendcookie;
|
bool sendcookie = res->view->sendcookie;
|
||||||
|
bool reqzoneversion = res->view->requestzoneversion;
|
||||||
bool tcpkeepalive = false;
|
bool tcpkeepalive = false;
|
||||||
unsigned char cookie[COOKIE_BUFFER_SIZE];
|
unsigned char cookie[COOKIE_BUFFER_SIZE];
|
||||||
uint16_t padding = 0;
|
uint16_t padding = 0;
|
||||||
@@ -2546,8 +2548,6 @@ resquery_send(resquery_t *query) {
|
|||||||
*/
|
*/
|
||||||
if (peer != NULL) {
|
if (peer != NULL) {
|
||||||
uint8_t ednsversion;
|
uint8_t ednsversion;
|
||||||
(void)dns_peer_getrequestnsid(peer, &reqnsid);
|
|
||||||
(void)dns_peer_getsendcookie(peer, &sendcookie);
|
|
||||||
result = dns_peer_getednsversion(peer,
|
result = dns_peer_getednsversion(peer,
|
||||||
&ednsversion);
|
&ednsversion);
|
||||||
if (result == ISC_R_SUCCESS &&
|
if (result == ISC_R_SUCCESS &&
|
||||||
@@ -2555,6 +2555,10 @@ resquery_send(resquery_t *query) {
|
|||||||
{
|
{
|
||||||
version = ednsversion;
|
version = ednsversion;
|
||||||
}
|
}
|
||||||
|
(void)dns_peer_getrequestnsid(peer, &reqnsid);
|
||||||
|
(void)dns_peer_getrequestzoneversion(
|
||||||
|
peer, &reqzoneversion);
|
||||||
|
(void)dns_peer_getsendcookie(peer, &sendcookie);
|
||||||
}
|
}
|
||||||
if (NOCOOKIE(query->addrinfo)) {
|
if (NOCOOKIE(query->addrinfo)) {
|
||||||
sendcookie = false;
|
sendcookie = false;
|
||||||
@@ -2566,6 +2570,13 @@ resquery_send(resquery_t *query) {
|
|||||||
ednsopts[ednsopt].value = NULL;
|
ednsopts[ednsopt].value = NULL;
|
||||||
ednsopt++;
|
ednsopt++;
|
||||||
}
|
}
|
||||||
|
if (reqzoneversion) {
|
||||||
|
INSIST(ednsopt < DNS_EDNSOPTIONS);
|
||||||
|
ednsopts[ednsopt].code = DNS_OPT_ZONEVERSION;
|
||||||
|
ednsopts[ednsopt].length = 0;
|
||||||
|
ednsopts[ednsopt].value = NULL;
|
||||||
|
ednsopt++;
|
||||||
|
}
|
||||||
if (sendcookie) {
|
if (sendcookie) {
|
||||||
INSIST(ednsopt < DNS_EDNSOPTIONS);
|
INSIST(ednsopt < DNS_EDNSOPTIONS);
|
||||||
ednsopts[ednsopt].code = DNS_OPT_COOKIE;
|
ednsopts[ednsopt].code = DNS_OPT_COOKIE;
|
||||||
@@ -2620,8 +2631,14 @@ resquery_send(resquery_t *query) {
|
|||||||
query->ednsversion = version;
|
query->ednsversion = version;
|
||||||
result = fctx_addopt(fctx->qmessage, version, udpsize,
|
result = fctx_addopt(fctx->qmessage, version, udpsize,
|
||||||
ednsopts, ednsopt);
|
ednsopts, ednsopt);
|
||||||
if (reqnsid && result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if (reqnsid) {
|
||||||
query->options |= DNS_FETCHOPT_WANTNSID;
|
query->options |= DNS_FETCHOPT_WANTNSID;
|
||||||
|
}
|
||||||
|
if (reqzoneversion) {
|
||||||
|
query->options |=
|
||||||
|
DNS_FETCHOPT_WANTZONEVERSION;
|
||||||
|
}
|
||||||
} else if (result != ISC_R_SUCCESS) {
|
} else if (result != ISC_R_SUCCESS) {
|
||||||
/*
|
/*
|
||||||
* We couldn't add the OPT, but we'll
|
* We couldn't add the OPT, but we'll
|
||||||
@@ -7387,17 +7404,38 @@ checknames(dns_message_t *message) {
|
|||||||
checknamessection(message, DNS_SECTION_ADDITIONAL);
|
checknamessection(message, DNS_SECTION_ADDITIONAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_hex(unsigned char *src, size_t srclen, char *buf, size_t buflen) {
|
||||||
|
isc_buffer_t b;
|
||||||
|
isc_region_t r;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
r.base = src;
|
||||||
|
r.length = srclen;
|
||||||
|
isc_buffer_init(&b, buf, buflen);
|
||||||
|
result = isc_hex_totext(&r, 0, "", &b);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
isc_buffer_putuint8(&b, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_printable(unsigned char *src, size_t srclen, char *buf, size_t buflen) {
|
||||||
|
INSIST(buflen > srclen);
|
||||||
|
while (srclen-- > 0) {
|
||||||
|
unsigned char c = *src++;
|
||||||
|
*buf++ = isprint(c) ? c : '.';
|
||||||
|
}
|
||||||
|
*buf = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log server NSID at log level 'level'
|
* Log server NSID at log level 'level'
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level,
|
log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level,
|
||||||
isc_mem_t *mctx) {
|
isc_mem_t *mctx) {
|
||||||
static const char hex[17] = "0123456789abcdef";
|
char addrbuf[ISC_SOCKADDR_FORMATSIZE], *buf = NULL, *pbuf = NULL;
|
||||||
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
unsigned char *p, *nsid;
|
|
||||||
unsigned char *buf = NULL, *pbuf = NULL;
|
|
||||||
|
|
||||||
REQUIRE(nsid_len <= UINT16_MAX);
|
REQUIRE(nsid_len <= UINT16_MAX);
|
||||||
|
|
||||||
@@ -7407,20 +7445,10 @@ log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level,
|
|||||||
pbuf = isc_mem_get(mctx, nsid_len + 1);
|
pbuf = isc_mem_get(mctx, nsid_len + 1);
|
||||||
|
|
||||||
/* Convert to hex */
|
/* Convert to hex */
|
||||||
p = buf;
|
make_hex(isc_buffer_current(opt), nsid_len, buf, buflen);
|
||||||
nsid = isc_buffer_current(opt);
|
|
||||||
for (size_t i = 0; i < nsid_len; i++) {
|
|
||||||
*p++ = hex[(nsid[i] >> 4) & 0xf];
|
|
||||||
*p++ = hex[nsid[i] & 0xf];
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
/* Make printable version */
|
/* Make printable version */
|
||||||
p = pbuf;
|
make_printable(isc_buffer_current(opt), nsid_len, pbuf, nsid_len + 1);
|
||||||
for (size_t i = 0; i < nsid_len; i++) {
|
|
||||||
*p++ = isprint(nsid[i]) ? nsid[i] : '.';
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
||||||
sizeof(addrbuf));
|
sizeof(addrbuf));
|
||||||
@@ -7431,6 +7459,108 @@ log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level,
|
|||||||
isc_mem_put(mctx, buf, buflen);
|
isc_mem_put(mctx, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_zoneversion(unsigned char *version, size_t version_len, unsigned char *nsid,
|
||||||
|
size_t nsid_len, resquery_t *query, int level,
|
||||||
|
isc_mem_t *mctx) {
|
||||||
|
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
|
size_t nsid_buflen = 0;
|
||||||
|
char *nsid_buf = NULL;
|
||||||
|
char *nsid_pbuf = NULL;
|
||||||
|
const char *nsid_hex = "";
|
||||||
|
const char *nsid_print = "";
|
||||||
|
const char *sep_1 = "";
|
||||||
|
const char *sep_2 = "";
|
||||||
|
const char *sep_3 = "";
|
||||||
|
dns_name_t suffix = DNS_NAME_INITEMPTY;
|
||||||
|
unsigned int labels;
|
||||||
|
|
||||||
|
REQUIRE(version_len <= UINT16_MAX);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't log reflected ZONEVERSION option.
|
||||||
|
*/
|
||||||
|
if (version_len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enforced by dns_rdata_fromwire. */
|
||||||
|
INSIST(version_len >= 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity check on label count.
|
||||||
|
*/
|
||||||
|
labels = version[0] + 1;
|
||||||
|
if (dns_name_countlabels(query->fctx->name) < labels) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get zone name.
|
||||||
|
*/
|
||||||
|
dns_name_split(query->fctx->name, labels, NULL, &suffix);
|
||||||
|
dns_name_format(&suffix, namebuf, sizeof(namebuf));
|
||||||
|
|
||||||
|
if (nsid != NULL) {
|
||||||
|
nsid_buflen = nsid_len * 2 + 1;
|
||||||
|
nsid_hex = nsid_buf = isc_mem_get(mctx, nsid_buflen);
|
||||||
|
nsid_print = nsid_pbuf = isc_mem_get(mctx, nsid_len + 1);
|
||||||
|
|
||||||
|
/* Convert to hex */
|
||||||
|
make_hex(nsid, nsid_len, nsid_buf, nsid_buflen);
|
||||||
|
|
||||||
|
/* Convert to printable */
|
||||||
|
make_printable(nsid, nsid_len, nsid_pbuf, nsid_len + 1);
|
||||||
|
|
||||||
|
sep_1 = " (NSID ";
|
||||||
|
sep_2 = " (";
|
||||||
|
sep_3 = "))";
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
||||||
|
sizeof(addrbuf));
|
||||||
|
if (version[1] == 0 && version_len == 6) {
|
||||||
|
uint32_t serial = version[2] << 24 | version[3] << 2 |
|
||||||
|
version[4] << 8 | version[5];
|
||||||
|
isc_log_write(DNS_LOGCATEGORY_ZONEVERSION,
|
||||||
|
DNS_LOGMODULE_RESOLVER, level,
|
||||||
|
"received ZONEVERSION serial %u from %s for %s "
|
||||||
|
"zone %s%s%s%s%s%s",
|
||||||
|
serial, addrbuf, query->fctx->info, namebuf,
|
||||||
|
sep_1, nsid_hex, sep_2, nsid_print, sep_3);
|
||||||
|
} else {
|
||||||
|
size_t version_buflen = version_len * 2 + 1;
|
||||||
|
char *version_hex = isc_mem_get(mctx, version_buflen);
|
||||||
|
char *version_pbuf = isc_mem_get(mctx, version_len - 1);
|
||||||
|
|
||||||
|
/* Convert to hex */
|
||||||
|
make_hex(version + 2, version_len - 2, version_hex,
|
||||||
|
version_buflen);
|
||||||
|
|
||||||
|
/* Convert to printable */
|
||||||
|
make_printable(version + 2, version_len - 2, version_pbuf,
|
||||||
|
version_len - 1);
|
||||||
|
|
||||||
|
isc_log_write(DNS_LOGCATEGORY_ZONEVERSION,
|
||||||
|
DNS_LOGMODULE_RESOLVER, level,
|
||||||
|
"received ZONEVERSION type %u value %s (%s) from "
|
||||||
|
"%s for %s zone %s%s%s%s%s%s",
|
||||||
|
version[1], version_hex, version_pbuf, addrbuf,
|
||||||
|
query->fctx->info, namebuf, sep_1, nsid_hex,
|
||||||
|
sep_2, nsid_print, sep_3);
|
||||||
|
isc_mem_put(mctx, version_hex, version_buflen);
|
||||||
|
isc_mem_put(mctx, version_pbuf, version_len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nsid_pbuf != NULL) {
|
||||||
|
isc_mem_put(mctx, nsid_pbuf, nsid_len + 1);
|
||||||
|
}
|
||||||
|
if (nsid_buf != NULL) {
|
||||||
|
isc_mem_put(mctx, nsid_buf, nsid_buflen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
betterreferral(respctx_t *rctx) {
|
betterreferral(respctx_t *rctx) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -8191,6 +8321,11 @@ rctx_opt(respctx_t *rctx) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
bool seen_cookie = false;
|
bool seen_cookie = false;
|
||||||
bool seen_nsid = false;
|
bool seen_nsid = false;
|
||||||
|
bool seen_zoneversion = false;
|
||||||
|
unsigned char *nsid = NULL;
|
||||||
|
uint16_t nsidlen = 0;
|
||||||
|
unsigned char *zoneversion = NULL;
|
||||||
|
uint16_t zoneversionlen = 0;
|
||||||
|
|
||||||
result = dns_rdataset_first(rctx->opt);
|
result = dns_rdataset_first(rctx->opt);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@@ -8216,7 +8351,8 @@ rctx_opt(respctx_t *rctx) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
seen_nsid = true;
|
seen_nsid = true;
|
||||||
|
nsid = isc_buffer_current(&optbuf);
|
||||||
|
nsidlen = optlen;
|
||||||
if ((query->options & DNS_FETCHOPT_WANTNSID) != 0) {
|
if ((query->options & DNS_FETCHOPT_WANTNSID) != 0) {
|
||||||
log_nsid(&optbuf, optlen, query, ISC_LOG_INFO,
|
log_nsid(&optbuf, optlen, query, ISC_LOG_INFO,
|
||||||
fctx->mctx);
|
fctx->mctx);
|
||||||
@@ -8254,12 +8390,27 @@ rctx_opt(respctx_t *rctx) {
|
|||||||
optvalue, optlen);
|
optvalue, optlen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DNS_OPT_ZONEVERSION:
|
||||||
|
if (seen_zoneversion) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
seen_zoneversion = true;
|
||||||
|
zoneversion = isc_buffer_current(&optbuf);
|
||||||
|
zoneversionlen = optlen;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
isc_buffer_forward(&optbuf, optlen);
|
isc_buffer_forward(&optbuf, optlen);
|
||||||
}
|
}
|
||||||
INSIST(isc_buffer_remaininglength(&optbuf) == 0U);
|
INSIST(isc_buffer_remaininglength(&optbuf) == 0U);
|
||||||
|
|
||||||
|
if ((query->options & DNS_FETCHOPT_WANTZONEVERSION) != 0 &&
|
||||||
|
zoneversion != NULL)
|
||||||
|
{
|
||||||
|
log_zoneversion(zoneversion, zoneversionlen, nsid, nsidlen,
|
||||||
|
query, ISC_LOG_INFO, fctx->mctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1497,6 +1497,56 @@ dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_zone_getzoneversion(dns_zone_t *zone, isc_buffer_t *b) {
|
||||||
|
isc_result_t result = DNS_R_NOTLOADED;
|
||||||
|
unsigned int soacount;
|
||||||
|
uint32_t serial;
|
||||||
|
dns_zone_t *mayberaw = zone;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
REQUIRE(b != NULL);
|
||||||
|
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
if (zone->raw != NULL) {
|
||||||
|
LOCK_ZONE(zone->raw);
|
||||||
|
mayberaw = zone->raw;
|
||||||
|
}
|
||||||
|
ZONEDB_LOCK(&mayberaw->dblock, isc_rwlocktype_read);
|
||||||
|
if (DNS_ZONE_OPTION(mayberaw, DNS_ZONEOPT_ZONEVERSION) &&
|
||||||
|
mayberaw->db != NULL)
|
||||||
|
{
|
||||||
|
result = dns_db_getzoneversion(mayberaw->db, b);
|
||||||
|
if (result == ISC_R_NOTIMPLEMENTED) {
|
||||||
|
result = zone_get_from_db(mayberaw, mayberaw->db, NULL,
|
||||||
|
&soacount, NULL, &serial,
|
||||||
|
NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (result == ISC_R_SUCCESS && soacount == 0) {
|
||||||
|
result = ISC_R_FAILURE;
|
||||||
|
}
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if (isc_buffer_availablelength(b) >= 6) {
|
||||||
|
isc_buffer_putuint8(
|
||||||
|
b, dns_name_countlabels(
|
||||||
|
&mayberaw->origin) -
|
||||||
|
1);
|
||||||
|
isc_buffer_putuint8(b, 0);
|
||||||
|
isc_buffer_putuint32(b, serial);
|
||||||
|
} else {
|
||||||
|
result = ISC_R_NOSPACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZONEDB_UNLOCK(&mayberaw->dblock, isc_rwlocktype_read);
|
||||||
|
if (zone->raw != NULL) {
|
||||||
|
UNLOCK_ZONE(zone->raw);
|
||||||
|
}
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Single shot.
|
* Single shot.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+22
-21
@@ -119,36 +119,37 @@ enum isc_logcategory {
|
|||||||
NAMED_LOGCATEGORY_GENERAL = ISC_LOGCATEGORY_GENERAL,
|
NAMED_LOGCATEGORY_GENERAL = ISC_LOGCATEGORY_GENERAL,
|
||||||
ISC_LOGCATEGORY_SSLKEYLOG,
|
ISC_LOGCATEGORY_SSLKEYLOG,
|
||||||
/* dns categories */
|
/* dns categories */
|
||||||
DNS_LOGCATEGORY_NOTIFY,
|
DNS_LOGCATEGORY_CNAME,
|
||||||
DNS_LOGCATEGORY_DATABASE,
|
DNS_LOGCATEGORY_DATABASE,
|
||||||
DNS_LOGCATEGORY_SECURITY,
|
DNS_LOGCATEGORY_DISPATCH,
|
||||||
DNS_LOGCATEGORY_DNSSEC,
|
DNS_LOGCATEGORY_DNSSEC,
|
||||||
|
DNS_LOGCATEGORY_DNSTAP,
|
||||||
|
DNS_LOGCATEGORY_EDNS_DISABLED,
|
||||||
|
DNS_LOGCATEGORY_LAME_SERVERS,
|
||||||
|
DNS_LOGCATEGORY_NOTIFY,
|
||||||
|
DNS_LOGCATEGORY_NSID,
|
||||||
DNS_LOGCATEGORY_RESOLVER,
|
DNS_LOGCATEGORY_RESOLVER,
|
||||||
|
DNS_LOGCATEGORY_RPZ,
|
||||||
|
DNS_LOGCATEGORY_RPZ_PASSTHRU,
|
||||||
|
DNS_LOGCATEGORY_RRL,
|
||||||
|
DNS_LOGCATEGORY_SECURITY,
|
||||||
|
DNS_LOGCATEGORY_SPILL,
|
||||||
|
DNS_LOGCATEGORY_UPDATE_POLICY,
|
||||||
DNS_LOGCATEGORY_XFER_IN,
|
DNS_LOGCATEGORY_XFER_IN,
|
||||||
DNS_LOGCATEGORY_XFER_OUT,
|
DNS_LOGCATEGORY_XFER_OUT,
|
||||||
DNS_LOGCATEGORY_DISPATCH,
|
|
||||||
DNS_LOGCATEGORY_LAME_SERVERS,
|
|
||||||
DNS_LOGCATEGORY_EDNS_DISABLED,
|
|
||||||
DNS_LOGCATEGORY_RPZ,
|
|
||||||
DNS_LOGCATEGORY_RRL,
|
|
||||||
DNS_LOGCATEGORY_CNAME,
|
|
||||||
DNS_LOGCATEGORY_SPILL,
|
|
||||||
DNS_LOGCATEGORY_DNSTAP,
|
|
||||||
DNS_LOGCATEGORY_ZONELOAD,
|
DNS_LOGCATEGORY_ZONELOAD,
|
||||||
DNS_LOGCATEGORY_NSID,
|
DNS_LOGCATEGORY_ZONEVERSION,
|
||||||
DNS_LOGCATEGORY_RPZ_PASSTHRU,
|
|
||||||
DNS_LOGCATEGORY_UPDATE_POLICY,
|
|
||||||
/* ns categories */
|
/* ns categories */
|
||||||
NS_LOGCATEGORY_CLIENT,
|
NS_LOGCATEGORY_CLIENT,
|
||||||
NS_LOGCATEGORY_NETWORK,
|
|
||||||
NS_LOGCATEGORY_UPDATE,
|
|
||||||
NS_LOGCATEGORY_QUERIES,
|
|
||||||
NS_LOGCATEGORY_UPDATE_SECURITY,
|
|
||||||
NS_LOGCATEGORY_QUERY_ERRORS,
|
|
||||||
NS_LOGCATEGORY_TAT,
|
|
||||||
NS_LOGCATEGORY_SERVE_STALE,
|
|
||||||
NS_LOGCATEGORY_RESPONSES,
|
|
||||||
NS_LOGCATEGORY_DRA,
|
NS_LOGCATEGORY_DRA,
|
||||||
|
NS_LOGCATEGORY_NETWORK,
|
||||||
|
NS_LOGCATEGORY_QUERIES,
|
||||||
|
NS_LOGCATEGORY_QUERY_ERRORS,
|
||||||
|
NS_LOGCATEGORY_RESPONSES,
|
||||||
|
NS_LOGCATEGORY_SERVE_STALE,
|
||||||
|
NS_LOGCATEGORY_TAT,
|
||||||
|
NS_LOGCATEGORY_UPDATE,
|
||||||
|
NS_LOGCATEGORY_UPDATE_SECURITY,
|
||||||
/* cfg categories */
|
/* cfg categories */
|
||||||
CFG_LOGCATEGORY_CONFIG,
|
CFG_LOGCATEGORY_CONFIG,
|
||||||
/* named categories */
|
/* named categories */
|
||||||
|
|||||||
+21
-20
@@ -170,36 +170,37 @@ static const char *categories_description[] = {
|
|||||||
[ISC_LOGCATEGORY_GENERAL] = "general",
|
[ISC_LOGCATEGORY_GENERAL] = "general",
|
||||||
[ISC_LOGCATEGORY_SSLKEYLOG] = "sslkeylog",
|
[ISC_LOGCATEGORY_SSLKEYLOG] = "sslkeylog",
|
||||||
/* dns categories */
|
/* dns categories */
|
||||||
[DNS_LOGCATEGORY_NOTIFY] = "notify",
|
[DNS_LOGCATEGORY_CNAME] = "cname",
|
||||||
[DNS_LOGCATEGORY_DATABASE] = "database",
|
[DNS_LOGCATEGORY_DATABASE] = "database",
|
||||||
[DNS_LOGCATEGORY_SECURITY] = "security",
|
[DNS_LOGCATEGORY_DISPATCH] = "dispatch",
|
||||||
[DNS_LOGCATEGORY_DNSSEC] = "dnssec",
|
[DNS_LOGCATEGORY_DNSSEC] = "dnssec",
|
||||||
|
[DNS_LOGCATEGORY_DNSTAP] = "dnstap",
|
||||||
|
[DNS_LOGCATEGORY_EDNS_DISABLED] = "edns-disabled",
|
||||||
|
[DNS_LOGCATEGORY_LAME_SERVERS] = "lame-servers",
|
||||||
|
[DNS_LOGCATEGORY_NOTIFY] = "notify",
|
||||||
|
[DNS_LOGCATEGORY_NSID] = "nsid",
|
||||||
[DNS_LOGCATEGORY_RESOLVER] = "resolver",
|
[DNS_LOGCATEGORY_RESOLVER] = "resolver",
|
||||||
|
[DNS_LOGCATEGORY_RPZ] = "rpz",
|
||||||
|
[DNS_LOGCATEGORY_RPZ_PASSTHRU] = "rpz-passthru",
|
||||||
|
[DNS_LOGCATEGORY_RRL] = "rate-limit",
|
||||||
|
[DNS_LOGCATEGORY_SECURITY] = "security",
|
||||||
|
[DNS_LOGCATEGORY_SPILL] = "spill",
|
||||||
|
[DNS_LOGCATEGORY_UPDATE_POLICY] = "update-policy",
|
||||||
[DNS_LOGCATEGORY_XFER_IN] = "xfer-in",
|
[DNS_LOGCATEGORY_XFER_IN] = "xfer-in",
|
||||||
[DNS_LOGCATEGORY_XFER_OUT] = "xfer-out",
|
[DNS_LOGCATEGORY_XFER_OUT] = "xfer-out",
|
||||||
[DNS_LOGCATEGORY_DISPATCH] = "dispatch",
|
|
||||||
[DNS_LOGCATEGORY_LAME_SERVERS] = "lame-servers",
|
|
||||||
[DNS_LOGCATEGORY_EDNS_DISABLED] = "edns-disabled",
|
|
||||||
[DNS_LOGCATEGORY_RPZ] = "rpz",
|
|
||||||
[DNS_LOGCATEGORY_RRL] = "rate-limit",
|
|
||||||
[DNS_LOGCATEGORY_CNAME] = "cname",
|
|
||||||
[DNS_LOGCATEGORY_SPILL] = "spill",
|
|
||||||
[DNS_LOGCATEGORY_DNSTAP] = "dnstap",
|
|
||||||
[DNS_LOGCATEGORY_ZONELOAD] = "zoneload",
|
[DNS_LOGCATEGORY_ZONELOAD] = "zoneload",
|
||||||
[DNS_LOGCATEGORY_NSID] = "nsid",
|
[DNS_LOGCATEGORY_ZONEVERSION] = "zoneversion",
|
||||||
[DNS_LOGCATEGORY_RPZ_PASSTHRU] = "rpz-passthru",
|
|
||||||
[DNS_LOGCATEGORY_UPDATE_POLICY] = "update-policy",
|
|
||||||
/* ns categories */
|
/* ns categories */
|
||||||
[NS_LOGCATEGORY_CLIENT] = "client",
|
[NS_LOGCATEGORY_CLIENT] = "client",
|
||||||
[NS_LOGCATEGORY_NETWORK] = "network",
|
|
||||||
[NS_LOGCATEGORY_UPDATE] = "update",
|
|
||||||
[NS_LOGCATEGORY_QUERIES] = "queries",
|
|
||||||
[NS_LOGCATEGORY_UPDATE_SECURITY] = "update-security",
|
|
||||||
[NS_LOGCATEGORY_QUERY_ERRORS] = "query-errors",
|
|
||||||
[NS_LOGCATEGORY_TAT] = "trust-anchor-telemetry",
|
|
||||||
[NS_LOGCATEGORY_DRA] = "dns-reporting-agent",
|
[NS_LOGCATEGORY_DRA] = "dns-reporting-agent",
|
||||||
[NS_LOGCATEGORY_SERVE_STALE] = "serve-stale",
|
[NS_LOGCATEGORY_NETWORK] = "network",
|
||||||
|
[NS_LOGCATEGORY_QUERIES] = "queries",
|
||||||
|
[NS_LOGCATEGORY_QUERY_ERRORS] = "query-errors",
|
||||||
[NS_LOGCATEGORY_RESPONSES] = "responses",
|
[NS_LOGCATEGORY_RESPONSES] = "responses",
|
||||||
|
[NS_LOGCATEGORY_SERVE_STALE] = "serve-stale",
|
||||||
|
[NS_LOGCATEGORY_TAT] = "trust-anchor-telemetry",
|
||||||
|
[NS_LOGCATEGORY_UPDATE] = "update",
|
||||||
|
[NS_LOGCATEGORY_UPDATE_SECURITY] = "update-security",
|
||||||
/* cfg categories */
|
/* cfg categories */
|
||||||
[CFG_LOGCATEGORY_CONFIG] = "config",
|
[CFG_LOGCATEGORY_CONFIG] = "config",
|
||||||
/* named categories */
|
/* named categories */
|
||||||
|
|||||||
@@ -4242,6 +4242,7 @@ static struct {
|
|||||||
{ "request-expire", dns_peer_setrequestexpire },
|
{ "request-expire", dns_peer_setrequestexpire },
|
||||||
{ "request-ixfr", dns_peer_setrequestixfr },
|
{ "request-ixfr", dns_peer_setrequestixfr },
|
||||||
{ "request-nsid", dns_peer_setrequestnsid },
|
{ "request-nsid", dns_peer_setrequestnsid },
|
||||||
|
{ "request-zoneversion", dns_peer_setrequestzoneversion },
|
||||||
{ "send-cookie", dns_peer_setsendcookie },
|
{ "send-cookie", dns_peer_setsendcookie },
|
||||||
{ "tcp-keepalive", dns_peer_settcpkeepalive },
|
{ "tcp-keepalive", dns_peer_settcpkeepalive },
|
||||||
{ "tcp-only", dns_peer_setforcetcp },
|
{ "tcp-only", dns_peer_setforcetcp },
|
||||||
|
|||||||
@@ -2110,6 +2110,7 @@ static cfg_clausedef_t view_clauses[] = {
|
|||||||
{ "recursion", &cfg_type_boolean, 0 },
|
{ "recursion", &cfg_type_boolean, 0 },
|
||||||
{ "request-nsid", &cfg_type_boolean, 0 },
|
{ "request-nsid", &cfg_type_boolean, 0 },
|
||||||
{ "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
{ "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
||||||
|
{ "request-zoneversion", &cfg_type_boolean, 0 },
|
||||||
{ "require-server-cookie", &cfg_type_boolean, 0 },
|
{ "require-server-cookie", &cfg_type_boolean, 0 },
|
||||||
{ "resolver-nonbackoff-tries", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
{ "resolver-nonbackoff-tries", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
||||||
{ "resolver-query-timeout", &cfg_type_uint32, 0 },
|
{ "resolver-query-timeout", &cfg_type_uint32, 0 },
|
||||||
@@ -2354,6 +2355,8 @@ static cfg_clausedef_t zone_clauses[] = {
|
|||||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
||||||
{ "parental-source-v6", &cfg_type_sockaddr6wild,
|
{ "parental-source-v6", &cfg_type_sockaddr6wild,
|
||||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
||||||
|
{ "provide-zoneversion", &cfg_type_boolean,
|
||||||
|
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
|
||||||
{ "send-report-channel", &cfg_type_astring,
|
{ "send-report-channel", &cfg_type_astring,
|
||||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
||||||
{ "request-expire", &cfg_type_boolean,
|
{ "request-expire", &cfg_type_boolean,
|
||||||
@@ -2603,6 +2606,7 @@ static cfg_clausedef_t server_clauses[] = {
|
|||||||
{ "request-ixfr", &cfg_type_boolean, 0 },
|
{ "request-ixfr", &cfg_type_boolean, 0 },
|
||||||
{ "request-ixfr-max-diffs", &cfg_type_uint32, 0 },
|
{ "request-ixfr-max-diffs", &cfg_type_uint32, 0 },
|
||||||
{ "request-nsid", &cfg_type_boolean, 0 },
|
{ "request-nsid", &cfg_type_boolean, 0 },
|
||||||
|
{ "request-zoneversion", &cfg_type_boolean, 0 },
|
||||||
{ "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
{ "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
|
||||||
{ "require-cookie", &cfg_type_boolean, 0 },
|
{ "require-cookie", &cfg_type_boolean, 0 },
|
||||||
{ "send-cookie", &cfg_type_boolean, 0 },
|
{ "send-cookie", &cfg_type_boolean, 0 },
|
||||||
|
|||||||
+47
-4
@@ -102,6 +102,8 @@
|
|||||||
#define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0)
|
#define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0)
|
||||||
#define WANTPAD(x) (((x)->attributes & NS_CLIENTATTR_WANTPAD) != 0)
|
#define WANTPAD(x) (((x)->attributes & NS_CLIENTATTR_WANTPAD) != 0)
|
||||||
#define WANTRC(x) (((x)->attributes & NS_CLIENTATTR_WANTRC) != 0)
|
#define WANTRC(x) (((x)->attributes & NS_CLIENTATTR_WANTRC) != 0)
|
||||||
|
#define WANTZONEVERSION(x) \
|
||||||
|
(((x)->attributes & NS_CLIENTATTR_WANTZONEVERSION) != 0)
|
||||||
|
|
||||||
#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm')
|
#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm')
|
||||||
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
|
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
|
||||||
@@ -218,6 +220,17 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
|
|||||||
/* XXXWPK TODO use netmgr to set timeout */
|
/* XXXWPK TODO use netmgr to set timeout */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_zoneversion_reset(ns_client_t *client) {
|
||||||
|
if (client->zoneversion == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isc_mem_put(client->manager->mctx, client->zoneversion,
|
||||||
|
client->zoneversionlength);
|
||||||
|
client->zoneversion = NULL;
|
||||||
|
client->zoneversionlength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ns_client_endrequest(ns_client_t *client) {
|
ns_client_endrequest(ns_client_t *client) {
|
||||||
INSIST(client->state == NS_CLIENTSTATE_WORKING ||
|
INSIST(client->state == NS_CLIENTSTATE_WORKING ||
|
||||||
@@ -258,6 +271,7 @@ ns_client_endrequest(ns_client_t *client) {
|
|||||||
dns_message_puttemprdataset(client->message, &client->opt);
|
dns_message_puttemprdataset(client->message, &client->opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_zoneversion_reset(client);
|
||||||
client->signer = NULL;
|
client->signer = NULL;
|
||||||
client->udpsize = 512;
|
client->udpsize = 512;
|
||||||
client->extflags = 0;
|
client->extflags = 0;
|
||||||
@@ -1192,6 +1206,13 @@ no_nsid:
|
|||||||
ednsopts[count].value = ede->value;
|
ednsopts[count].value = ede->value;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
if ((client->attributes & NS_CLIENTATTR_HAVEZONEVERSION) != 0) {
|
||||||
|
INSIST(count < DNS_EDNSOPTIONS);
|
||||||
|
ednsopts[count].code = DNS_OPT_ZONEVERSION;
|
||||||
|
ednsopts[count].length = client->zoneversionlength;
|
||||||
|
ednsopts[count].value = client->zoneversion;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
if (WANTRC(client)) {
|
if (WANTRC(client)) {
|
||||||
dns_name_t *rad = NULL;
|
dns_name_t *rad = NULL;
|
||||||
@@ -1609,8 +1630,7 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
|
|||||||
case DNS_OPT_CLIENT_SUBNET:
|
case DNS_OPT_CLIENT_SUBNET:
|
||||||
result = process_ecs(client, &optbuf, optlen);
|
result = process_ecs(client, &optbuf, optlen);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
ns_client_error(client, result);
|
goto formerr;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
ns_stats_increment(
|
ns_stats_increment(
|
||||||
client->manager->sctx->nsstats,
|
client->manager->sctx->nsstats,
|
||||||
@@ -1638,13 +1658,24 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
|
|||||||
result = process_keytag(client, &optbuf,
|
result = process_keytag(client, &optbuf,
|
||||||
optlen);
|
optlen);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
ns_client_error(client, result);
|
goto formerr;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
ns_stats_increment(
|
ns_stats_increment(
|
||||||
client->manager->sctx->nsstats,
|
client->manager->sctx->nsstats,
|
||||||
ns_statscounter_keytagopt);
|
ns_statscounter_keytagopt);
|
||||||
break;
|
break;
|
||||||
|
case DNS_OPT_ZONEVERSION:
|
||||||
|
if (optlen != 0 || WANTZONEVERSION(client)) {
|
||||||
|
result = DNS_R_FORMERR;
|
||||||
|
goto formerr;
|
||||||
|
}
|
||||||
|
ns_stats_increment(
|
||||||
|
client->manager->sctx->nsstats,
|
||||||
|
ns_statscounter_zoneversionopt);
|
||||||
|
client->attributes |=
|
||||||
|
NS_CLIENTATTR_WANTZONEVERSION;
|
||||||
|
isc_buffer_forward(&optbuf, optlen);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ns_stats_increment(
|
ns_stats_increment(
|
||||||
client->manager->sctx->nsstats,
|
client->manager->sctx->nsstats,
|
||||||
@@ -1660,6 +1691,17 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
|
|||||||
client->attributes |= NS_CLIENTATTR_WANTOPT;
|
client->attributes |= NS_CLIENTATTR_WANTOPT;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
formerr:
|
||||||
|
if (result == DNS_R_FORMERR || result == DNS_R_OPTERR) {
|
||||||
|
result = ns_client_addopt(client, client->message,
|
||||||
|
&client->opt);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
result = DNS_R_FORMERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns_client_error(client, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1724,6 +1766,7 @@ ns__client_put_cb(void *client0) {
|
|||||||
*/
|
*/
|
||||||
ns_query_free(client);
|
ns_query_free(client);
|
||||||
dns_ede_invalidate(&client->edectx);
|
dns_ede_invalidate(&client->edectx);
|
||||||
|
client_zoneversion_reset(client);
|
||||||
|
|
||||||
client->magic = 0;
|
client->magic = 0;
|
||||||
|
|
||||||
|
|||||||
+23
-19
@@ -224,6 +224,8 @@ struct ns_client {
|
|||||||
ISC_LINK(ns_client_t) rlink;
|
ISC_LINK(ns_client_t) rlink;
|
||||||
unsigned char cookie[8];
|
unsigned char cookie[8];
|
||||||
uint32_t expire;
|
uint32_t expire;
|
||||||
|
unsigned char *zoneversion;
|
||||||
|
uint32_t zoneversionlength;
|
||||||
unsigned char *keytag;
|
unsigned char *keytag;
|
||||||
uint16_t keytag_len;
|
uint16_t keytag_len;
|
||||||
|
|
||||||
@@ -241,26 +243,28 @@ struct ns_client {
|
|||||||
#define NS_CLIENT_MAGIC ISC_MAGIC('N', 'S', 'C', 'c')
|
#define NS_CLIENT_MAGIC ISC_MAGIC('N', 'S', 'C', 'c')
|
||||||
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
|
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
|
||||||
|
|
||||||
#define NS_CLIENTATTR_TCP 0x00001
|
#define NS_CLIENTATTR_TCP 0x000001
|
||||||
#define NS_CLIENTATTR_RA 0x00002 /*%< Client gets recursive service */
|
#define NS_CLIENTATTR_RA 0x000002 /*%< Client gets recursive service */
|
||||||
#define NS_CLIENTATTR_PKTINFO 0x00004 /*%< pktinfo is valid */
|
#define NS_CLIENTATTR_PKTINFO 0x000004 /*%< pktinfo is valid */
|
||||||
#define NS_CLIENTATTR_MULTICAST 0x00008 /*%< recv'd from multicast */
|
#define NS_CLIENTATTR_MULTICAST 0x000008 /*%< recv'd from multicast */
|
||||||
#define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */
|
#define NS_CLIENTATTR_WANTDNSSEC 0x000010 /*%< include dnssec records */
|
||||||
#define NS_CLIENTATTR_WANTNSID 0x00020 /*%< include nameserver ID */
|
#define NS_CLIENTATTR_WANTNSID 0x000020 /*%< include nameserver ID */
|
||||||
#define NS_CLIENTATTR_BADCOOKIE \
|
#define NS_CLIENTATTR_BADCOOKIE \
|
||||||
0x00040 /*%< Presented cookie is bad/out-of-date */
|
0x000040 /*%< Presented cookie is bad/out-of-date */
|
||||||
#define NS_CLIENTATTR_WANTRC 0x00080 /*%< include Report-Channel */
|
#define NS_CLIENTATTR_WANTRC 0x000080 /*%< include Report-Channel */
|
||||||
#define NS_CLIENTATTR_WANTAD 0x00100 /*%< want AD in response if possible */
|
#define NS_CLIENTATTR_WANTAD 0x000100 /*%< want AD in response if possible */
|
||||||
#define NS_CLIENTATTR_WANTCOOKIE 0x00200 /*%< return a COOKIE */
|
#define NS_CLIENTATTR_WANTCOOKIE 0x000200 /*%< return a COOKIE */
|
||||||
#define NS_CLIENTATTR_HAVECOOKIE 0x00400 /*%< has a valid COOKIE */
|
#define NS_CLIENTATTR_HAVECOOKIE 0x000400 /*%< has a valid COOKIE */
|
||||||
#define NS_CLIENTATTR_WANTEXPIRE 0x00800 /*%< return seconds to expire */
|
#define NS_CLIENTATTR_WANTEXPIRE 0x000800 /*%< return seconds to expire */
|
||||||
#define NS_CLIENTATTR_HAVEEXPIRE 0x01000 /*%< return seconds to expire */
|
#define NS_CLIENTATTR_HAVEEXPIRE 0x001000 /*%< return seconds to expire */
|
||||||
#define NS_CLIENTATTR_WANTOPT 0x02000 /*%< add opt to reply */
|
#define NS_CLIENTATTR_WANTOPT 0x002000 /*%< add opt to reply */
|
||||||
#define NS_CLIENTATTR_HAVEECS 0x04000 /*%< received an ECS option */
|
#define NS_CLIENTATTR_HAVEECS 0x004000 /*%< received an ECS option */
|
||||||
#define NS_CLIENTATTR_WANTPAD 0x08000 /*%< pad reply */
|
#define NS_CLIENTATTR_WANTPAD 0x008000 /*%< pad reply */
|
||||||
#define NS_CLIENTATTR_USEKEEPALIVE 0x10000 /*%< use TCP keepalive */
|
#define NS_CLIENTATTR_USEKEEPALIVE 0x010000 /*%< use TCP keepalive */
|
||||||
#define NS_CLIENTATTR_NOSETFC 0x20000 /*%< don't set servfail cache */
|
#define NS_CLIENTATTR_NOSETFC 0x020000 /*%< don't set servfail cache */
|
||||||
#define NS_CLIENTATTR_NEEDTCP 0x40000 /*%< send TC=1 */
|
#define NS_CLIENTATTR_NEEDTCP 0x040000 /*%< send TC=1 */
|
||||||
|
#define NS_CLIENTATTR_WANTZONEVERSION 0x100000 /*%< return zoneversion */
|
||||||
|
#define NS_CLIENTATTR_HAVEZONEVERSION 0x200000 /*%< return zoneversion */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flag to use with the SERVFAIL cache to indicate
|
* Flag to use with the SERVFAIL cache to indicate
|
||||||
|
|||||||
+32
-31
@@ -84,49 +84,50 @@ enum {
|
|||||||
ns_statscounter_ecsopt = 46,
|
ns_statscounter_ecsopt = 46,
|
||||||
ns_statscounter_padopt = 47,
|
ns_statscounter_padopt = 47,
|
||||||
ns_statscounter_keepaliveopt = 48,
|
ns_statscounter_keepaliveopt = 48,
|
||||||
|
ns_statscounter_zoneversionopt = 49,
|
||||||
|
|
||||||
ns_statscounter_nxdomainredirect = 49,
|
ns_statscounter_nxdomainredirect = 50,
|
||||||
ns_statscounter_nxdomainredirect_rlookup = 50,
|
ns_statscounter_nxdomainredirect_rlookup = 51,
|
||||||
|
|
||||||
ns_statscounter_cookiein = 51,
|
ns_statscounter_cookiein = 52,
|
||||||
ns_statscounter_cookiebadsize = 52,
|
ns_statscounter_cookiebadsize = 53,
|
||||||
ns_statscounter_cookiebadtime = 53,
|
ns_statscounter_cookiebadtime = 54,
|
||||||
ns_statscounter_cookienomatch = 54,
|
ns_statscounter_cookienomatch = 55,
|
||||||
ns_statscounter_cookiematch = 55,
|
ns_statscounter_cookiematch = 56,
|
||||||
ns_statscounter_cookienew = 56,
|
ns_statscounter_cookienew = 57,
|
||||||
ns_statscounter_badcookie = 57,
|
ns_statscounter_badcookie = 58,
|
||||||
|
|
||||||
ns_statscounter_nxdomainsynth = 58,
|
ns_statscounter_nxdomainsynth = 59,
|
||||||
ns_statscounter_nodatasynth = 59,
|
ns_statscounter_nodatasynth = 60,
|
||||||
ns_statscounter_wildcardsynth = 60,
|
ns_statscounter_wildcardsynth = 61,
|
||||||
|
|
||||||
ns_statscounter_trystale = 61,
|
ns_statscounter_trystale = 62,
|
||||||
ns_statscounter_usedstale = 62,
|
ns_statscounter_usedstale = 63,
|
||||||
|
|
||||||
ns_statscounter_prefetch = 63,
|
ns_statscounter_prefetch = 64,
|
||||||
ns_statscounter_keytagopt = 64,
|
ns_statscounter_keytagopt = 65,
|
||||||
|
|
||||||
ns_statscounter_tcphighwater = 65,
|
ns_statscounter_tcphighwater = 66,
|
||||||
|
|
||||||
ns_statscounter_reclimitdropped = 66,
|
ns_statscounter_reclimitdropped = 67,
|
||||||
|
|
||||||
ns_statscounter_updatequota = 67,
|
ns_statscounter_updatequota = 68,
|
||||||
|
|
||||||
ns_statscounter_recurshighwater = 68,
|
ns_statscounter_recurshighwater = 69,
|
||||||
|
|
||||||
ns_statscounter_dot = 69,
|
ns_statscounter_dot = 70,
|
||||||
ns_statscounter_doh = 70,
|
ns_statscounter_doh = 71,
|
||||||
ns_statscounter_dohplain = 71,
|
ns_statscounter_dohplain = 72,
|
||||||
|
|
||||||
ns_statscounter_proxyudp = 72,
|
ns_statscounter_proxyudp = 73,
|
||||||
ns_statscounter_proxytcp = 73,
|
ns_statscounter_proxytcp = 74,
|
||||||
ns_statscounter_proxydot = 74,
|
ns_statscounter_proxydot = 75,
|
||||||
ns_statscounter_proxydoh = 75,
|
ns_statscounter_proxydoh = 76,
|
||||||
ns_statscounter_proxydohplain = 76,
|
ns_statscounter_proxydohplain = 77,
|
||||||
ns_statscounter_encryptedproxydot = 77,
|
ns_statscounter_encryptedproxydot = 78,
|
||||||
ns_statscounter_encryptedproxydoh = 78,
|
ns_statscounter_encryptedproxydoh = 79,
|
||||||
|
|
||||||
ns_statscounter_max = 79,
|
ns_statscounter_max = 80,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -7938,6 +7938,55 @@ query_getexpire(query_ctx_t *qctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the zone version, if requested, when answering from a secondary,
|
||||||
|
* mirror, or primary zone.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
query_getzoneversion(query_ctx_t *qctx) {
|
||||||
|
CCTRACE(ISC_LOG_DEBUG(3), __func__);
|
||||||
|
|
||||||
|
if (qctx->zone == NULL || !qctx->is_zone ||
|
||||||
|
qctx->client->query.restarts != 0 ||
|
||||||
|
(qctx->client->attributes & NS_CLIENTATTR_WANTZONEVERSION) == 0 ||
|
||||||
|
(qctx->client->attributes & NS_CLIENTATTR_HAVEZONEVERSION) != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (dns_zone_gettype(qctx->zone)) {
|
||||||
|
case dns_zone_mirror:
|
||||||
|
case dns_zone_primary:
|
||||||
|
case dns_zone_secondary: {
|
||||||
|
isc_buffer_t b;
|
||||||
|
unsigned char buf[128];
|
||||||
|
isc_buffer_init(&b, buf, sizeof(buf));
|
||||||
|
isc_result_t result = dns_zone_getzoneversion(qctx->zone, &b);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
size_t len = isc_buffer_usedlength(&b);
|
||||||
|
/*
|
||||||
|
* Sanity check zone version from database
|
||||||
|
* implementations. Minimum length and type 0
|
||||||
|
* contraints.
|
||||||
|
*/
|
||||||
|
if (len < 2 || (buf[1] == 0 && len != 6)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qctx->client->attributes |=
|
||||||
|
NS_CLIENTATTR_HAVEZONEVERSION;
|
||||||
|
INSIST(qctx->client->zoneversion == NULL);
|
||||||
|
qctx->client->zoneversion =
|
||||||
|
isc_mem_get(qctx->client->manager->mctx, len);
|
||||||
|
qctx->client->zoneversionlength = len;
|
||||||
|
memmove(qctx->client->zoneversion, buf, len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Fill the ANSWER section of a positive response.
|
* Fill the ANSWER section of a positive response.
|
||||||
*/
|
*/
|
||||||
@@ -8101,6 +8150,11 @@ query_respond(query_ctx_t *qctx) {
|
|||||||
*/
|
*/
|
||||||
query_getexpire(qctx);
|
query_getexpire(qctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the zone version
|
||||||
|
*/
|
||||||
|
query_getzoneversion(qctx);
|
||||||
|
|
||||||
result = query_addanswer(qctx);
|
result = query_addanswer(qctx);
|
||||||
if (result != ISC_R_COMPLETE) {
|
if (result != ISC_R_COMPLETE) {
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user