mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Force manual DNAME handling to be acknowledged
Adding proper DNAME support to AsyncDnsServer would add complexity to its code for little gain: DNAME use in custom system test servers is limited to crafting responses that attempt to trigger bugs in named. This fact will not be obvious to AsyncDnsServer users as it automatically loads all zone files it finds and handles CNAME records like a normal authoritative DNS server would. Therefore, to prevent surprises: - raise an exception whenever DNAME records are found in any of the zone files loaded by AsyncDnsServer, - add a new optional argument to the AsyncDnsServer constructor that enables suppressing this new behavior, enabling zones with DNAME records to be loaded anyway. This enables response handlers to use the DNAME records present in zone files in arbitrary ways without complicating the "base" code. (cherry picked from commit 8a562526f6cdaaab37ce31b20e223537281a3d43)
This commit is contained in:
parent
8acd4c685c
commit
f39864d3ec
@ -533,11 +533,12 @@ class AsyncDnsServer(AsyncServer):
|
||||
response from scratch, without using zone data at all.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, acknowledge_manual_dname_handling: bool = False) -> None:
|
||||
super().__init__(self._handle_udp, self._handle_tcp, "ans.pid")
|
||||
|
||||
self._zone_tree: _ZoneTree = _ZoneTree()
|
||||
self._response_handlers: List[ResponseHandler] = []
|
||||
self._acknowledge_manual_dname_handling = acknowledge_manual_dname_handling
|
||||
|
||||
self._load_zones()
|
||||
|
||||
@ -572,11 +573,31 @@ class AsyncDnsServer(AsyncServer):
|
||||
entry_path = pathlib.Path(entry.path)
|
||||
if entry_path.suffix != ".db":
|
||||
continue
|
||||
origin = dns.name.from_text(entry_path.stem)
|
||||
logging.info("Loading zone file %s", entry_path)
|
||||
zone = dns.zone.from_file(entry.path, origin, relativize=False)
|
||||
zone = self._load_zone(entry_path)
|
||||
self._zone_tree.add(zone)
|
||||
|
||||
def _load_zone(self, zone_file_path: pathlib.Path) -> dns.zone.Zone:
|
||||
origin = dns.name.from_text(zone_file_path.stem)
|
||||
logging.info("Loading zone file %s", zone_file_path)
|
||||
with open(zone_file_path, encoding="utf-8") as zone_file:
|
||||
zone = dns.zone.from_file(zone_file, origin, relativize=False)
|
||||
self._abort_if_dname_found_unless_acknowledged(zone)
|
||||
return zone
|
||||
|
||||
def _abort_if_dname_found_unless_acknowledged(self, zone: dns.zone.Zone) -> None:
|
||||
if self._acknowledge_manual_dname_handling:
|
||||
return
|
||||
|
||||
error = f'DNAME records found in zone "{zone.origin}"; '
|
||||
error += "this server does not handle DNAME in a standards-compliant way; "
|
||||
error += "pass `acknowledge_manual_dname_handling=True` to the "
|
||||
error += "AsyncDnsServer constructor to acknowledge this and load zone anyway"
|
||||
|
||||
for node in zone.nodes.values():
|
||||
for rdataset in node:
|
||||
if rdataset.rdtype == dns.rdatatype.DNAME:
|
||||
raise ValueError(error)
|
||||
|
||||
async def _handle_udp(
|
||||
self, wire: bytes, addr: Tuple[str, int], transport: asyncio.DatagramTransport
|
||||
) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user