1 1.1 christos """ 2 1.1 christos Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 1.1 christos 4 1.1 christos SPDX-License-Identifier: MPL-2.0 5 1.1 christos 6 1.1 christos This Source Code Form is subject to the terms of the Mozilla Public 7 1.1 christos License, v. 2.0. If a copy of the MPL was not distributed with this 8 1.1 christos file, you can obtain one at https://mozilla.org/MPL/2.0/. 9 1.1 christos 10 1.1 christos See the COPYRIGHT file distributed with this work for additional 11 1.1 christos information regarding copyright ownership. 12 1.1 christos """ 13 1.1 christos 14 1.1 christos from collections.abc import AsyncGenerator 15 1.1 christos 16 1.1 christos import dns.rcode 17 1.1 christos 18 1.1 christos from isctest.asyncserver import ( 19 1.1 christos ControllableAsyncDnsServer, 20 1.1 christos DnsResponseSend, 21 1.1 christos QueryContext, 22 1.1 christos ) 23 1.1 christos 24 1.1 christos from ..reclimit_ans import ( 25 1.1 christos DirectExampleHandler, 26 1.1 christos FallbackNxdomainHandler, 27 1.1 christos IndirectExampleOrgHandler, 28 1.1 christos LimitControlCommand, 29 1.1 christos Ns1ExampleOrgHandler, 30 1.1 christos ReclimitHandler, 31 1.1 christos ReclimitStateHandler, 32 1.1 christos a, 33 1.1 christos is_ns1_example, 34 1.1 christos ns, 35 1.1 christos ) 36 1.1 christos 37 1.1 christos 38 1.1 christos class Ns1ExampleNetHandler(ReclimitHandler): 39 1.1 christos def match(self, qctx: QueryContext) -> bool: 40 1.1 christos return is_ns1_example(qctx.qname, "net") 41 1.1 christos 42 1.1 christos async def _get_counted_responses( 43 1.1 christos self, qctx: QueryContext 44 1.1 christos ) -> AsyncGenerator[DnsResponseSend, None]: 45 1.1 christos current_ns_number = int(qctx.qname.labels[1]) 46 1.1 christos next_ns_block_start = (current_ns_number + 1) * 16 47 1.1 christos for offset in range(1, 16): 48 1.1 christos target_ns_number = next_ns_block_start + offset 49 1.1 christos qctx.response.authority.append( 50 1.1 christos ns( 51 1.1 christos f"{current_ns_number}.example.net.", 52 1.1 christos f"ns1.{target_ns_number}.example.net.", 53 1.1 christos ) 54 1.1 christos ) 55 1.1 christos qctx.response.additional.append( 56 1.1 christos a(f"ns1.{target_ns_number}.example.net.", 7) 57 1.1 christos ) 58 1.1 christos 59 1.1 christos yield DnsResponseSend(qctx.response, authoritative=False) 60 1.1 christos 61 1.1 christos 62 1.1 christos def main() -> None: 63 1.1 christos server = ControllableAsyncDnsServer( 64 1.1 christos default_aa=True, default_rcode=dns.rcode.NOERROR 65 1.1 christos ) 66 1.1 christos server.install_response_handlers( 67 1.1 christos state_handler := ReclimitStateHandler(indirect_send_response_default=False), 68 1.1 christos DirectExampleHandler(state_handler, 2), 69 1.1 christos IndirectExampleOrgHandler(state_handler, 2), 70 1.1 christos Ns1ExampleOrgHandler(state_handler), 71 1.1 christos Ns1ExampleNetHandler(state_handler), 72 1.1 christos FallbackNxdomainHandler(state_handler), 73 1.1 christos ) 74 1.1 christos server.install_control_command(LimitControlCommand(state_handler)) 75 1.1 christos server.run() 76 1.1 christos 77 1.1 christos 78 1.1 christos if __name__ == "__main__": 79 1.1 christos main() 80