mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 16:59:59 -04:00
[9.20] chg: test: Use isctest.asyncserver in the "ixfr" test
Backport of MR !11403 Merge branch 'backport-stepan/ixfr-asyncserver-9.20' into 'bind-9.20' See merge request isc-projects/bind9!11453
This commit is contained in:
commit
d790527bd0
14 changed files with 349 additions and 137 deletions
|
|
@ -114,7 +114,7 @@ class Cve202125215(DomainHandler):
|
|||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(acknowledge_manual_dname_handling=True, default_aa=True)
|
||||
server.install_response_handlers([CnameThenDnameHandler(), Cve202125215()])
|
||||
server.install_response_handlers(CnameThenDnameHandler(), Cve202125215())
|
||||
server.run()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -194,13 +194,11 @@ def cookie_server(evil: bool) -> AsyncDnsServer:
|
|||
keyring=KEYRING, default_aa=True, default_rcode=dns.rcode.NOERROR
|
||||
)
|
||||
server.install_response_handlers(
|
||||
[
|
||||
NsHandler(evil),
|
||||
GlueHandler(evil),
|
||||
TcpAHandler(),
|
||||
WithtsigUdpAHandler(),
|
||||
UdpAHandler(),
|
||||
FallbackHandler(),
|
||||
]
|
||||
NsHandler(evil),
|
||||
GlueHandler(evil),
|
||||
TcpAHandler(),
|
||||
WithtsigUdpAHandler(),
|
||||
UdpAHandler(),
|
||||
)
|
||||
server.install_response_handler(FallbackHandler())
|
||||
return server
|
||||
|
|
|
|||
|
|
@ -63,11 +63,9 @@ class SilentThenServfailHandler(DomainHandler):
|
|||
def main() -> None:
|
||||
server = AsyncDnsServer()
|
||||
server.install_response_handlers(
|
||||
[
|
||||
CloseHandler(),
|
||||
SilentHandler(),
|
||||
SilentThenServfailHandler(),
|
||||
]
|
||||
CloseHandler(),
|
||||
SilentHandler(),
|
||||
SilentThenServfailHandler(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class AddNsecToTxtHandler(ResponseHandler):
|
|||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer()
|
||||
server.install_response_handlers([AddRrsigToAHandler(), AddNsecToTxtHandler()])
|
||||
server.install_response_handlers(AddNsecToTxtHandler(), AddRrsigToAHandler())
|
||||
server.run()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from typing import (
|
|||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Sequence,
|
||||
Tuple,
|
||||
Union,
|
||||
cast,
|
||||
|
|
@ -887,10 +888,18 @@ class AsyncDnsServer(AsyncServer):
|
|||
else:
|
||||
self._response_handlers.append(handler)
|
||||
|
||||
def install_response_handlers(self, handlers: List[ResponseHandler]) -> None:
|
||||
def install_response_handlers(self, *handlers: ResponseHandler) -> None:
|
||||
for handler in handlers:
|
||||
self.install_response_handler(handler)
|
||||
|
||||
def replace_response_handlers(self, *new_handlers: ResponseHandler) -> None:
|
||||
"""
|
||||
Uninstall all currently installed handlers and install the provided ones.
|
||||
"""
|
||||
logging.info("Uninstalling response handlers: %s", str(self._response_handlers))
|
||||
self._response_handlers.clear()
|
||||
self.install_response_handlers(*new_handlers)
|
||||
|
||||
def uninstall_response_handler(self, handler: ResponseHandler) -> None:
|
||||
"""
|
||||
Remove the specified handler from the list of response handlers.
|
||||
|
|
@ -1380,7 +1389,7 @@ class ControllableAsyncDnsServer(AsyncDnsServer):
|
|||
def _commands(self) -> Dict[dns.name.Name, "ControlCommand"]:
|
||||
return {}
|
||||
|
||||
def install_control_commands(self, commands: List["ControlCommand"]) -> None:
|
||||
def install_control_commands(self, *commands: "ControlCommand") -> None:
|
||||
for command in commands:
|
||||
self.install_control_command(command)
|
||||
|
||||
|
|
@ -1556,3 +1565,30 @@ class ToggleResponsesCommand(ControlCommand):
|
|||
logging.error("Unrecognized response sending mode '%s'", mode)
|
||||
qctx.response.set_rcode(dns.rcode.SERVFAIL)
|
||||
return f"unrecognized response sending mode '{mode}'"
|
||||
|
||||
|
||||
class SwitchControlCommand(ControlCommand):
|
||||
"""
|
||||
Switch the server's response handlers based on the control query.
|
||||
|
||||
A sequence of response handlers is associated with each key. When a
|
||||
control query is received, the server's response handlers are replaced
|
||||
with the sequence associated with the key extracted from the control
|
||||
query.
|
||||
"""
|
||||
|
||||
control_subdomain = "switch"
|
||||
|
||||
def __init__(self, handler_mapping: Dict[str, Sequence[ResponseHandler]]):
|
||||
self._handler_mapping = handler_mapping
|
||||
|
||||
def handle(
|
||||
self, args: List[str], server: ControllableAsyncDnsServer, qctx: QueryContext
|
||||
) -> Optional[str]:
|
||||
if len(args) != 1 or args[0] not in self._handler_mapping:
|
||||
logging.error("Invalid %s query %s", self, qctx.qname)
|
||||
qctx.response.set_rcode(dns.rcode.SERVFAIL)
|
||||
return f"invalid query; exactly one of {list(self._handler_mapping.keys())} is expected in QNAME"
|
||||
|
||||
server.replace_response_handlers(*self._handler_mapping[args[0]])
|
||||
return f"switched to handler set '{args[0]}'"
|
||||
|
|
|
|||
265
bin/tests/system/ixfr/ans2/ans.py
Normal file
265
bin/tests/system/ixfr/ans2/ans.py
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
"""
|
||||
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
See the COPYRIGHT file distributed with this work for additional
|
||||
information regarding copyright ownership.
|
||||
"""
|
||||
|
||||
import abc
|
||||
|
||||
import dns.rcode
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
import dns.rrset
|
||||
|
||||
from typing import AsyncGenerator, Collection, Iterable
|
||||
|
||||
from isctest.asyncserver import (
|
||||
ControllableAsyncDnsServer,
|
||||
DnsResponseSend,
|
||||
QueryContext,
|
||||
ResponseHandler,
|
||||
SwitchControlCommand,
|
||||
)
|
||||
|
||||
|
||||
def rrset(owner: str, rdtype: dns.rdatatype.RdataType, rdata: str) -> dns.rrset.RRset:
|
||||
return dns.rrset.from_text(
|
||||
owner,
|
||||
300,
|
||||
dns.rdataclass.IN,
|
||||
rdtype,
|
||||
rdata,
|
||||
)
|
||||
|
||||
|
||||
def soa(serial: int, *, owner: str = "nil.") -> dns.rrset.RRset:
|
||||
return rrset(
|
||||
owner,
|
||||
dns.rdatatype.SOA,
|
||||
f"ns.nil. root.nil. {serial} 300 300 604800 300",
|
||||
)
|
||||
|
||||
|
||||
def ns() -> dns.rrset.RRset:
|
||||
return rrset(
|
||||
"nil.",
|
||||
dns.rdatatype.NS,
|
||||
"ns.nil.",
|
||||
)
|
||||
|
||||
|
||||
def a(address: str, *, owner: str) -> dns.rrset.RRset:
|
||||
return rrset(
|
||||
owner,
|
||||
dns.rdatatype.A,
|
||||
address,
|
||||
)
|
||||
|
||||
|
||||
def txt(data: str, *, owner: str = "nil.") -> dns.rrset.RRset:
|
||||
return rrset(
|
||||
owner,
|
||||
dns.rdatatype.TXT,
|
||||
f'"{data}"',
|
||||
)
|
||||
|
||||
|
||||
class SoaHandler(ResponseHandler):
|
||||
def __init__(self, serial: int):
|
||||
self._serial = serial
|
||||
|
||||
def match(self, qctx: QueryContext) -> bool:
|
||||
return qctx.qtype == dns.rdatatype.SOA
|
||||
|
||||
async def get_responses(
|
||||
self, qctx: QueryContext
|
||||
) -> AsyncGenerator[DnsResponseSend, None]:
|
||||
qctx.response.answer.append(soa(self._serial))
|
||||
yield DnsResponseSend(qctx.response)
|
||||
|
||||
|
||||
class AxfrHandler(ResponseHandler):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def answers(self) -> Iterable[Collection[dns.rrset.RRset]]:
|
||||
"""
|
||||
Answer sections of response packets sent in response to
|
||||
AXFR queries.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def match(self, qctx: QueryContext) -> bool:
|
||||
return qctx.qtype == dns.rdatatype.AXFR
|
||||
|
||||
async def get_responses(
|
||||
self, qctx: QueryContext
|
||||
) -> AsyncGenerator[DnsResponseSend, None]:
|
||||
for answer in self.answers:
|
||||
response = qctx.prepare_new_response()
|
||||
for rrset_ in answer:
|
||||
response.answer.append(rrset_)
|
||||
yield DnsResponseSend(response)
|
||||
|
||||
|
||||
class IxfrHandler(ResponseHandler):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def answer(self) -> Collection[dns.rrset.RRset]:
|
||||
"""
|
||||
Answer section of a response packet sent in response to
|
||||
IXFR queries.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def match(self, qctx: QueryContext) -> bool:
|
||||
return qctx.qtype == dns.rdatatype.IXFR
|
||||
|
||||
async def get_responses(
|
||||
self, qctx: QueryContext
|
||||
) -> AsyncGenerator[DnsResponseSend, None]:
|
||||
for rrset_ in self.answer:
|
||||
qctx.response.answer.append(rrset_)
|
||||
yield DnsResponseSend(qctx.response)
|
||||
|
||||
|
||||
class InitialAfxrHandler(AxfrHandler):
|
||||
answers = (
|
||||
(soa(1),),
|
||||
(
|
||||
ns(),
|
||||
txt("initial AXFR"),
|
||||
a("10.0.0.61", owner="a.nil."),
|
||||
a("10.0.0.62", owner="b.nil."),
|
||||
),
|
||||
(soa(1),),
|
||||
)
|
||||
|
||||
|
||||
class SuccessfulIfxrHandler(IxfrHandler):
|
||||
answer = (
|
||||
soa(3),
|
||||
soa(1),
|
||||
a("10.0.0.61", owner="a.nil."),
|
||||
txt("initial AXFR"),
|
||||
soa(2),
|
||||
txt("successful IXFR"),
|
||||
a("10.0.1.61", owner="a.nil."),
|
||||
soa(2),
|
||||
soa(3),
|
||||
soa(3),
|
||||
)
|
||||
|
||||
|
||||
class NotExactIxfrHandler(IxfrHandler):
|
||||
answer = (
|
||||
soa(4),
|
||||
soa(3),
|
||||
txt("delete-nonexistent-txt-record"),
|
||||
soa(4),
|
||||
txt("this-txt-record-would-be-added"),
|
||||
soa(4),
|
||||
)
|
||||
|
||||
|
||||
class FallbackNotExactAxfrHandler(AxfrHandler):
|
||||
answers = (
|
||||
(soa(3),),
|
||||
(
|
||||
ns(),
|
||||
txt("fallback AXFR"),
|
||||
),
|
||||
(soa(3),),
|
||||
)
|
||||
|
||||
|
||||
class TooManyRecordsIxfrHandler(IxfrHandler):
|
||||
answer = (
|
||||
soa(4),
|
||||
soa(3),
|
||||
soa(4),
|
||||
txt("text 1"),
|
||||
txt("text 2"),
|
||||
txt("text 3"),
|
||||
txt("text 4"),
|
||||
txt("text 5"),
|
||||
txt("text 6: causing too many records"),
|
||||
soa(4),
|
||||
)
|
||||
|
||||
|
||||
class FallbackTooManyRecordsAxfrHandler(AxfrHandler):
|
||||
answers = (
|
||||
(
|
||||
soa(3),
|
||||
ns(),
|
||||
txt("fallback AXFR on too many records"),
|
||||
),
|
||||
(soa(3),),
|
||||
)
|
||||
|
||||
|
||||
class BadSoaOwnerIxfrHandler(IxfrHandler):
|
||||
answer = (
|
||||
soa(4),
|
||||
soa(3),
|
||||
soa(4, owner="bad-owner."),
|
||||
txt("serial 4, malformed IXFR", owner="test.nil."),
|
||||
soa(4),
|
||||
)
|
||||
|
||||
|
||||
class FallbackBadSoaOwnerAxfrHandler(AxfrHandler):
|
||||
answers = (
|
||||
(soa(4),),
|
||||
(
|
||||
ns(),
|
||||
txt("serial 4, fallback AXFR", owner="test.nil."),
|
||||
),
|
||||
(soa(4),),
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = ControllableAsyncDnsServer(
|
||||
default_aa=True, default_rcode=dns.rcode.NOERROR
|
||||
)
|
||||
switch_command = SwitchControlCommand(
|
||||
{
|
||||
"initial_axfr": (
|
||||
SoaHandler(1),
|
||||
InitialAfxrHandler(),
|
||||
),
|
||||
"successful_ixfr": (
|
||||
SoaHandler(3),
|
||||
SuccessfulIfxrHandler(),
|
||||
),
|
||||
"not_exact": (
|
||||
SoaHandler(4),
|
||||
NotExactIxfrHandler(),
|
||||
FallbackNotExactAxfrHandler(),
|
||||
),
|
||||
"too_many_records": (
|
||||
SoaHandler(4),
|
||||
TooManyRecordsIxfrHandler(),
|
||||
FallbackTooManyRecordsAxfrHandler(),
|
||||
),
|
||||
"bad_soa_owner": (
|
||||
SoaHandler(4),
|
||||
BadSoaOwnerIxfrHandler(),
|
||||
FallbackBadSoaOwnerAxfrHandler(),
|
||||
),
|
||||
}
|
||||
)
|
||||
server.install_control_command(switch_command)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -32,27 +32,16 @@ n=0
|
|||
DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd -p ${PORT}"
|
||||
RNDCCMD="$RNDC -p ${CONTROLPORT} -c ../_common/rndc.conf -s"
|
||||
|
||||
sendcmd() {
|
||||
send 10.53.0.2 "${EXTRAPORT1}"
|
||||
switch_responses() {
|
||||
RESPONSES_KEY="${1}"
|
||||
$DIG $DIGOPTS "@10.53.0.2" "${RESPONSES_KEY}.switch._control." TXT +time=5 +tries=1 +tcp >/dev/null 2>&1
|
||||
}
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "testing initial AXFR ($n)"
|
||||
ret=0
|
||||
|
||||
sendcmd <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 NS ns.nil.
|
||||
nil. 300 TXT "initial AXFR"
|
||||
a.nil. 60 A 10.0.0.61
|
||||
b.nil. 60 A 10.0.0.62
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
|
||||
EOF
|
||||
switch_responses "initial_axfr"
|
||||
|
||||
sleep 1
|
||||
|
||||
|
|
@ -84,21 +73,7 @@ ret=0
|
|||
# We change the IP address of a.nil., and the TXT record at the apex.
|
||||
# Then we do a SOA-only update.
|
||||
|
||||
sendcmd <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
/IXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
|
||||
a.nil. 60 A 10.0.0.61
|
||||
nil. 300 TXT "initial AXFR"
|
||||
nil. 300 SOA ns.nil. root.nil. 2 300 300 604800 300
|
||||
nil. 300 TXT "successful IXFR"
|
||||
a.nil. 60 A 10.0.1.61
|
||||
nil. 300 SOA ns.nil. root.nil. 2 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
EOF
|
||||
switch_responses "successful_ixfr"
|
||||
|
||||
sleep 1
|
||||
|
||||
|
|
@ -115,25 +90,7 @@ echo_i "testing AXFR fallback after IXFR failure (not exact error) ($n)"
|
|||
ret=0
|
||||
|
||||
# Provide a broken IXFR response and a working fallback AXFR response
|
||||
|
||||
sendcmd <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/IXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 TXT "delete-nonexistent-txt-record"
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 TXT "this-txt-record-would-be-added"
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 NS ns.nil.
|
||||
nil. 300 TXT "fallback AXFR"
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
EOF
|
||||
switch_responses "not_exact"
|
||||
|
||||
sleep 1
|
||||
|
||||
|
|
@ -150,28 +107,7 @@ echo_i "testing AXFR fallback after IXFR failure (too many records) ($n)"
|
|||
ret=0
|
||||
|
||||
# Provide an IXFR response that would cause a "too many records" condition
|
||||
|
||||
sendcmd <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/IXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 TXT "text 1"
|
||||
nil. 300 TXT "text 2"
|
||||
nil. 300 TXT "text 3"
|
||||
nil. 300 TXT "text 4"
|
||||
nil. 300 TXT "text 5"
|
||||
nil. 300 TXT "text 6: causing too many records"
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
nil. 300 NS ns.nil.
|
||||
nil. 300 TXT "fallback AXFR on too many records"
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
EOF
|
||||
switch_responses "too_many_records"
|
||||
|
||||
sleep 1
|
||||
|
||||
|
|
@ -196,23 +132,7 @@ ret=0
|
|||
nextpart ns1/named.run >/dev/null
|
||||
|
||||
# Provide a broken IXFR response and a working fallback AXFR response.
|
||||
sendcmd <<EOF
|
||||
/SOA/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/IXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
nil. 300 SOA ns.nil. root.nil. 3 300 300 604800 300
|
||||
bad-owner. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
test.nil. 300 TXT "serial 4, malformed IXFR"
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
/AXFR/
|
||||
nil. 300 NS ns.nil.
|
||||
test.nil. 300 TXT "serial 4, fallback AXFR"
|
||||
/AXFR/
|
||||
nil. 300 SOA ns.nil. root.nil. 4 300 300 604800 300
|
||||
EOF
|
||||
switch_responses "bad_soa_owner"
|
||||
$RNDCCMD 10.53.0.1 refresh nil | sed 's/^/ns1 /' | cat_i
|
||||
|
||||
# A broken server would accept the malformed IXFR and apply its contents to the
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
import pytest
|
||||
|
||||
# isctest.asyncserver requires dnspython >= 2.0.0
|
||||
pytest.importorskip("dns", minversion="2.0.0")
|
||||
|
||||
pytestmark = pytest.mark.extra_artifacts(
|
||||
[
|
||||
"dig.out*",
|
||||
|
|
|
|||
|
|
@ -100,13 +100,11 @@ class StaleHandler(DomainHandler):
|
|||
def main() -> None:
|
||||
server = AsyncDnsServer()
|
||||
server.install_response_handlers(
|
||||
[
|
||||
QueryLogger(),
|
||||
BadHandler(),
|
||||
UglyHandler(),
|
||||
SlowHandler(),
|
||||
StaleHandler(),
|
||||
]
|
||||
QueryLogger(),
|
||||
BadHandler(),
|
||||
UglyHandler(),
|
||||
SlowHandler(),
|
||||
StaleHandler(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,10 @@ class ZoopBoingSlowHandler(DelayedResponseHandler):
|
|||
def main() -> None:
|
||||
server = AsyncDnsServer()
|
||||
server.install_response_handlers(
|
||||
[
|
||||
QueryLogger(),
|
||||
ZoopBoingBadHandler(),
|
||||
ZoopBoingUglyHandler(),
|
||||
ZoopBoingSlowHandler(),
|
||||
]
|
||||
QueryLogger(),
|
||||
ZoopBoingBadHandler(),
|
||||
ZoopBoingUglyHandler(),
|
||||
ZoopBoingSlowHandler(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -87,13 +87,11 @@ class IckyPtangZoopBoingSlowHandler(DelayedResponseHandler):
|
|||
def main() -> None:
|
||||
server = AsyncDnsServer()
|
||||
server.install_response_handlers(
|
||||
[
|
||||
QueryLogger(),
|
||||
StaleHandler(),
|
||||
IckyPtangZoopBoingBadHandler(),
|
||||
IckyPtangZoopBoingUglyHandler(),
|
||||
IckyPtangZoopBoingSlowHandler(),
|
||||
]
|
||||
QueryLogger(),
|
||||
StaleHandler(),
|
||||
IckyPtangZoopBoingBadHandler(),
|
||||
IckyPtangZoopBoingUglyHandler(),
|
||||
IckyPtangZoopBoingSlowHandler(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class IgnoreNs(ResponseHandler):
|
|||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers([ReplyA(), IgnoreNs()])
|
||||
server.install_response_handlers(ReplyA(), IgnoreNs())
|
||||
server.run()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -162,18 +162,16 @@ class FallbackHandler(ResponseHandler):
|
|||
def main() -> None:
|
||||
server = AsyncDnsServer(default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers(
|
||||
[
|
||||
BadGoodCnameHandler(),
|
||||
Cname1Handler(),
|
||||
Cname2Handler(),
|
||||
ExampleHandler(),
|
||||
FooInfoHandler(),
|
||||
NoDataHandler(),
|
||||
NxdomainHandler(),
|
||||
SubHandler(),
|
||||
FallbackHandler(),
|
||||
]
|
||||
BadGoodCnameHandler(),
|
||||
Cname1Handler(),
|
||||
Cname2Handler(),
|
||||
ExampleHandler(),
|
||||
FooInfoHandler(),
|
||||
NoDataHandler(),
|
||||
NxdomainHandler(),
|
||||
SubHandler(),
|
||||
)
|
||||
server.install_response_handler(FallbackHandler())
|
||||
server.run()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue