]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't ignore the local port number in dns_dispatch_add() for TCP
authorAram Sargsyan <aram@isc.org>
Tue, 1 Oct 2024 14:16:47 +0000 (14:16 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Wed, 2 Oct 2024 09:53:45 +0000 (09:53 +0000)
The dns_dispatch_add() function registers the 'resp' entry in
'disp->mgr->qids' hash table with 'resp->port' being 0, but in
tcp_recv_success(), when looking up an entry in the hash table
after a successfully received data the port is used, so if the
local port was set (i.e. it was not 0) it fails to find the
entry and results in an unexpected error.

Set the 'resp->port' to the given local port value extracted from
'disp->local'.

(cherry picked from commit d49a8f518a8ffe4b2db2ea20ed3171723ff0404b)

bin/tests/system/digdelv/tests.sh
lib/dns/dispatch.c

index 284646b60f3fe146f453b5b0c2c2dc066a8f2698..e147912a1bec08e569bae077dd1771ac10dc2680 100644 (file)
@@ -1140,6 +1140,20 @@ else
 fi
 
 if [ -x "$MDIG" ]; then
+  n=$((n + 1))
+  echo_i "checking mdig +tcp works with a source address and port ($n)"
+  ret=0
+  # When running more than once in quick succession with a source address#port,
+  # we can get a "response failed with address not available" error because
+  # the address#port is still busy, but we are not interested in that error,
+  # as we are only looking for the unexpected error case, that's why we ignore
+  # the return code from mdig, but we check for the unexpected error message
+  # using grep. See GitLab #4969.
+  mdig_with_opts -b "10.53.0.3#${EXTRAPORT8}" +tcp @10.53.0.3 example >dig.out.test$n 2>&1 || true
+  grep -F "unexpected error" 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 "check that mdig handles malformed option '+ednsopt=:' gracefully ($n)"
   ret=0
index 01224322169a100b6c41195a269dc70d654dc0c5..9a9d5d72dfae69ee6e63e6f4640f0c022e6eb7aa 100644 (file)
@@ -1435,6 +1435,7 @@ dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop,
        dns_dispentry_t *resp = isc_mem_get(disp->mctx, sizeof(*resp));
        *resp = (dns_dispentry_t){
                .timeout = timeout,
+               .port = localport,
                .peer = *dest,
                .loop = loop,
                .connected = connected,