2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Allow EDNS to be used when making requests in xfrin

This allow for the EDNS options EXPIRE and NSID to be sent when
when making requests.  The existing controls controlling whether
EDNS is used and whether EXPIRE or NSID are sent are honoured.

Adjust the expected byte counts in the xfer system test to reflect
the EDNS overhead.  Adjust the dig call to match named's behavior
(don't set +expire as we are talking to a secondary).
This commit is contained in:
Mark Andrews
2023-06-29 17:25:15 +10:00
parent 87912e4bb8
commit 690fd050a0
6 changed files with 66 additions and 8 deletions

View File

@@ -1,3 +1,3 @@
messages=1
records=5
bytes=204
bytes=223

View File

@@ -0,0 +1,3 @@
messages=1
records=5
bytes=215

View File

@@ -388,9 +388,9 @@ status=$((status+ret))
n=$((n+1))
echo_i "checking whether dig calculates IXFR statistics correctly ($n)"
ret=0
$DIG $DIGOPTS +noedns +stat -b 10.53.0.4 @10.53.0.4 test. ixfr=2 > dig.out1.test$n
$DIG $DIGOPTS +expire +nocookie +stat -b 10.53.0.4 @10.53.0.4 test. ixfr=2 > dig.out1.test$n
get_dig_xfer_stats dig.out1.test$n > stats.dig
diff ixfr-stats.good stats.dig > /dev/null || ret=1
diff ixfr-stats-with-expire.good stats.dig > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
@@ -400,20 +400,20 @@ status=$((status+ret))
_wait_for_stats () {
get_named_xfer_stats ns4/named.run "$1" test "$2" > "$3"
diff ixfr-stats.good "$3" > /dev/null || return 1
diff "$4" "$3" > /dev/null || return 1
return 0
}
n=$((n+1))
echo_i "checking whether named calculates incoming IXFR statistics correctly ($n)"
ret=0
retry_quiet 10 _wait_for_stats 10.53.0.3 "Transfer completed" stats.incoming || ret=1
retry_quiet 10 _wait_for_stats 10.53.0.3 "Transfer completed" stats.incoming ixfr-stats-without-expire.good || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking whether named calculates outgoing IXFR statistics correctly ($n)"
retry_quiet 10 _wait_for_stats 10.53.0.4 "IXFR ended" stats.outgoing || ret=1
retry_quiet 10 _wait_for_stats 10.53.0.4 "IXFR ended" stats.outgoing ixfr-stats-with-expire.good || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))

View File

@@ -1,3 +1,3 @@
messages=16
records=10003
bytes=218227
bytes=218403

View File

@@ -541,7 +541,7 @@ tmp=0
# Use -b so that we can discern between incoming and outgoing transfers in ns3
# logs later on.
wait_for_xfer() (
$DIG $DIGOPTS +noedns +stat -b 10.53.0.2 @10.53.0.3 xfer-stats. AXFR > dig.out.ns3.test$n
$DIG $DIGOPTS +edns +nocookie +noexpire +stat -b 10.53.0.2 @10.53.0.3 xfer-stats. AXFR > dig.out.ns3.test$n
grep "; Transfer failed" dig.out.ns3.test$n > /dev/null || return 0
return 1
)

View File

@@ -30,6 +30,7 @@
#include <dns/journal.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/peer.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
@@ -1147,6 +1148,38 @@ request_type(dns_xfrin_t *xfr) {
}
}
static isc_result_t
add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
bool reqexpire) {
isc_result_t result;
dns_rdataset_t *rdataset = NULL;
dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
int count = 0;
/* Set EDNS options if applicable. */
if (reqnsid) {
INSIST(count < DNS_EDNSOPTIONS);
ednsopts[count].code = DNS_OPT_NSID;
ednsopts[count].length = 0;
ednsopts[count].value = NULL;
count++;
}
if (reqexpire) {
INSIST(count < DNS_EDNSOPTIONS);
ednsopts[count].code = DNS_OPT_EXPIRE;
ednsopts[count].length = 0;
ednsopts[count].value = NULL;
count++;
}
result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
ednsopts, count);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (dns_message_setopt(message, rdataset));
}
/*
* Build an *XFR request and send its length prefix.
*/
@@ -1160,6 +1193,10 @@ xfrin_send_request(dns_xfrin_t *xfr) {
dns_name_t *qname = NULL;
dns_dbversion_t *ver = NULL;
dns_name_t *msgsoaname = NULL;
bool edns = true;
bool reqnsid = xfr->view->requestnsid;
bool reqexpire = dns_zone_getrequestexpire(xfr->zone);
uint16_t udpsize = dns_view_getudpsize(xfr->view);
LIBDNS_XFRIN_RECV_SEND_REQUEST(xfr, xfr->info);
@@ -1198,6 +1235,24 @@ xfrin_send_request(dns_xfrin_t *xfr) {
&xfr->ixfr.request_serial));
}
if (xfr->view->peers != NULL) {
dns_peer_t *peer = NULL;
isc_netaddr_t primaryip;
isc_netaddr_fromsockaddr(&primaryip, &xfr->primaryaddr);
result = dns_peerlist_peerbyaddr(xfr->view->peers, &primaryip,
&peer);
if (result == ISC_R_SUCCESS) {
(void)dns_peer_getsupportedns(peer, &edns);
(void)dns_peer_getudpsize(peer, &udpsize);
(void)dns_peer_getrequestnsid(peer, &reqnsid);
(void)dns_peer_getrequestexpire(peer, &reqexpire);
}
}
if (edns) {
CHECK(add_opt(msg, udpsize, reqnsid, reqexpire));
}
xfr->nmsg = 0;
xfr->nrecs = 0;
xfr->nbytes = 0;