From: Mark Andrews Date: Thu, 29 Jun 2023 07:25:15 +0000 (+1000) Subject: Allow EDNS to be used when making requests in xfrin X-Git-Tag: v9.19.17~25^2~7 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=690fd050a0b8720a4094f315e3c313a1a1fceea0;p=thirdparty%2Fbind9.git 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). --- diff --git a/bin/tests/system/ixfr/ixfr-stats.good b/bin/tests/system/ixfr/ixfr-stats-with-expire.good similarity index 67% rename from bin/tests/system/ixfr/ixfr-stats.good rename to bin/tests/system/ixfr/ixfr-stats-with-expire.good index 3d0d2dde32e..c02992b14fc 100644 --- a/bin/tests/system/ixfr/ixfr-stats.good +++ b/bin/tests/system/ixfr/ixfr-stats-with-expire.good @@ -1,3 +1,3 @@ messages=1 records=5 -bytes=204 +bytes=223 diff --git a/bin/tests/system/ixfr/ixfr-stats-without-expire.good b/bin/tests/system/ixfr/ixfr-stats-without-expire.good new file mode 100644 index 00000000000..0713c0b8ee0 --- /dev/null +++ b/bin/tests/system/ixfr/ixfr-stats-without-expire.good @@ -0,0 +1,3 @@ +messages=1 +records=5 +bytes=215 diff --git a/bin/tests/system/ixfr/tests.sh b/bin/tests/system/ixfr/tests.sh index f1e3b622411..4b61a2c9e11 100644 --- a/bin/tests/system/ixfr/tests.sh +++ b/bin/tests/system/ixfr/tests.sh @@ -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)) diff --git a/bin/tests/system/xfer/axfr-stats.good b/bin/tests/system/xfer/axfr-stats.good index 264af09705b..616854e6466 100644 --- a/bin/tests/system/xfer/axfr-stats.good +++ b/bin/tests/system/xfer/axfr-stats.good @@ -1,3 +1,3 @@ messages=16 records=10003 -bytes=218227 +bytes=218403 diff --git a/bin/tests/system/xfer/tests.sh b/bin/tests/system/xfer/tests.sh index 33eee6ae47f..6595927e7ee 100755 --- a/bin/tests/system/xfer/tests.sh +++ b/bin/tests/system/xfer/tests.sh @@ -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 ) diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index be7a427226a..3961f8eb84e 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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;