Commit 18ca7a16d2 for bind

commit 18ca7a16d225aae488af282058bdd068807344eb
Author: Nicki Křížek <nicki@isc.org>
Date:   Thu Sep 24 09:12:20 2026 +0000

    Send unique query IDs from the ditch tool

    isctest.tools.ditch leaves the message ID to dnspython, which draws a
    random ID for every query, so IDs can repeat within a single run.
    ditch.pl avoided that, because Net::DNS does not reuse recently sent
    IDs.  Number the queries sequentially from a random start instead,
    which keeps the IDs unique within a run.

    This intermittently broke the fetchlimit clients-per-query checks,
    where named rejected such a query as a duplicate instead of counting
    it against the quota.

    Assisted-by: Claude:claude-opus-5-5

diff --git a/bin/tests/system/isctest/tools/ditch.py b/bin/tests/system/isctest/tools/ditch.py
index cec223121a..33944f3c5a 100644
--- a/bin/tests/system/isctest/tools/ditch.py
+++ b/bin/tests/system/isctest/tools/ditch.py
@@ -22,6 +22,7 @@ from collections.abc import Iterable

 import argparse
 import fileinput
+import random
 import socket

 import dns.inet
@@ -37,6 +38,10 @@ def send_queries(
     with "#" are skipped.  Return the number of queries sent.
     """
     family = dns.inet.af_for_address(address)
+    # All queries share a source port, so named would drop a repeated
+    # message ID for the same name as a duplicate query; use sequential
+    # IDs from a random start.
+    first_id = random.getrandbits(16)
     sent = 0
     with socket.socket(family, socket.SOCK_DGRAM) as sock:
         sock.bind(("", source_port))
@@ -45,7 +50,7 @@ def send_queries(
             if not fields or fields[0].startswith("#"):
                 continue
             name, rdtype = fields[:2]
-            query = dns.message.make_query(name, rdtype)
+            query = dns.message.make_query(name, rdtype, id=(first_id + sent) & 0xFFFF)
             sock.sendto(query.to_wire(), (address, port))
             sent += 1
     return sent