Lines Matching refs:qctx
564 def match(self, qctx: QueryContext) -> bool:
575 self, qctx: QueryContext
581 qctx.response.
583 yield DnsResponseSend(qctx.response)
595 self, qctx: QueryContext
623 def match(self, qctx: QueryContext) -> bool:
628 return qctx.qname in self._qnames
654 def match(self, qctx: QueryContext) -> bool:
659 return qctx.qtype in self._qtypes and super().match(qctx)
717 self, qctx: QueryContext
719 qctx.prepare_new_response(with_zone_data=False)
720 qctx.response.answer.extend(self.answer)
721 qctx.response.authority.extend(self.authority)
722 qctx.response.additional.extend(self.additional)
724 qctx.response.set_rcode(self.rcode)
726 qctx.response, authoritative=self.authoritative, delay=self.delay
763 def match(self, qctx: QueryContext) -> bool:
770 if qctx.qname.is_subdomain(domain):
826 self, qctx: QueryContext
830 forwarding_target = f"{self.target}:{self.port or qctx.socket.port}"
836 qctx.protocol.name,
837 qctx.peer,
844 qctx.protocol.name,
845 qctx.peer,
850 lambda: self.ForwarderProtocol(qctx.query.to_wire(), response),
851 local_addr=(qctx.socket.host, 0),
852 remote_addr=(self.target, self.port or qctx.socket.port),
863 qctx.peer,
864 qctx.protocol.name,
1271 def _log_query(self, qctx: QueryContext) -> None:
1274 qctx.qname.to_text(omit_final_dot=True),
1275 dns.rdataclass.to_text(qctx.qclass),
1276 dns.rdatatype.to_text(qctx.qtype),
1277 qctx.query.id,
1278 qctx.peer,
1279 qctx.socket,
1280 qctx.protocol.name,
1283 "\n".join([f"[IN] {l}" for l in [""] + str(qctx.query).splitlines()])
1287 self, qctx: QueryContext, response: dns.message.Message | bytes | None
1292 qctx.query.id,
1293 qctx.peer,
1294 qctx.socket,
1295 qctx.protocol.name,
1319 qctx.query.id,
1320 qctx.peer,
1321 qctx.socket,
1322 qctx.protocol.name,
1332 qctx.query.id,
1333 qctx.peer,
1334 qctx.socket,
1335 qctx.protocol.name,
1351 qctx = QueryContext(query, response_stub, socket, peer, protocol)
1352 self._log_query(qctx)
1353 responses = self._prepare_responses(qctx)
1355 self._log_response(qctx, response)
1386 self, qctx: QueryContext
1391 qctx.response.set_rcode(self._default_rcode)
1393 qctx.response.flags |= dns.flags.AA
1394 qctx.save_initialized_response(with_zone_data=False)
1396 self._prepare_response_from_zone_data(qctx)
1397 qctx.save_initialized_response(with_zone_data=True)
1400 async for action in self._run_response_handlers(qctx):
1406 yield qctx.response
1408 def _prepare_response_from_zone_data(self, qctx: QueryContext) -> None:
1415 if self._refused_response(qctx):
1418 if self._delegation_response(qctx):
1421 qctx.response.flags |= dns.flags.AA
1423 if self._ent_response(qctx):
1426 if self._nxdomain_response(qctx):
1429 if self._cname_response(qctx):
1432 if self._nodata_response(qctx):
1435 self._noerror_response(qctx)
1437 def _refused_response(self, qctx: QueryContext) -> bool:
1438 zone = self._zone_tree.find_best_zone(qctx.current_qname)
1440 qctx.zone = zone
1447 def _delegation_response(self, qctx: QueryContext) -> bool:
1448 assert qctx.zone
1450 name = qctx.current_qname
1453 while name != qctx.zone.origin:
1454 node = qctx.zone.get_node(name)
1456 delegation = node.get_rdataset(qctx.qclass, dns.rdatatype.NS)
1464 delegation_rrset = dns.rrset.RRset(name, qctx.qclass, dns.rdatatype.NS)
1467 qctx.response.set_rcode(dns.rcode.NOERROR)
1468 qctx.response.authority.append(delegation_rrset)
1470 self._delegation_response_additional(qctx)
1474 def _delegation_response_additional(self, qctx: QueryContext) -> None:
1475 assert qctx.zone
1476 assert qctx.response.authority[0]
1478 for nameserver in qctx.response.authority[0]:
1479 if not nameserver.target.is_subdomain(qctx.response.authority[0].name):
1481 glue_a = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.A)
1483 qctx.response.additional.append(glue_a)
1484 glue_aaaa = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.AAAA)
1486 qctx.response.additional.append(glue_aaaa)
1488 def _ent_response(self, qctx: QueryContext) -> bool:
1489 assert qctx.zone
1490 assert qctx.zone.origin
1492 qctx.soa = qctx.zone.find_rrset(qctx.zone.origin, dns.rdatatype.SOA)
1493 assert qctx.soa
1495 qctx.node = qctx.zone.get_node(qctx.current_qname)
1496 if qctx.node or not any(
1497 n for n in qctx.zone.nodes if n.is_subdomain(qctx.current_qname)
1501 qctx.response.set_rcode(dns.rcode.NOERROR)
1502 qctx.response.authority.append(qctx.soa)
1505 def _nxdomain_response(self, qctx: QueryContext) -> bool:
1506 assert qctx.soa
1508 if qctx.node:
1511 qctx.response.set_rcode(dns.rcode.NXDOMAIN)
1512 qctx.response.authority.append(qctx.soa)
1515 def _cname_response(self, qctx: QueryContext) -> bool:
1516 assert qctx.node
1518 cname = qctx.node.get_rdataset(qctx.qclass, dns.rdatatype.CNAME)
1522 qctx.response.set_rcode(dns.rcode.NOERROR)
1523 cname_rrset = dns.rrset.RRset(qctx.current_qname, qctx.qclass, cname.rdtype)
1525 qctx.response.answer.append(cname_rrset)
1527 qctx.alias = cname[0].target
1528 self._prepare_response_from_zone_data(qctx)
1531 def _nodata_response(self, qctx: QueryContext) -> bool:
1532 assert qctx.node
1533 assert qctx.soa
1535 qctx.answer = qctx.node.get_rdataset(qctx.qclass, qctx.qtype)
1536 if qctx.answer:
1539 qctx.response.set_rcode(dns.rcode.NOERROR)
1540 if not qctx.response.answer:
1541 qctx.response.authority.append(qctx.soa)
1544 def _noerror_response(self, qctx: QueryContext) -> None:
1545 assert qctx.answer
1547 answer_rrset = dns.rrset.RRset(qctx.current_qname, qctx.qclass, qctx.qtype)
1548 answer_rrset.update(qctx.answer)
1550 qctx.response.set_rcode(dns.rcode.NOERROR)
1551 qctx.response.answer.append(answer_rrset)
1554 self, qctx: QueryContext
1560 if handler.match(qctx):
1562 async for response in handler.get_responses(qctx):
1600 self, qctx: QueryContext
1606 control_response = self._handle_control_command(qctx)
1611 async for response in super()._prepare_responses(qctx):
1614 def _handle_control_command(self, qctx: QueryContext) -> dns.message.Message | None:
1626 response via qctx.response and/or return a string that is converted to
1631 if not qctx.qname.is_subdomain(self._control_domain):
1634 if qctx.qtype != dns.rdatatype.TXT:
1635 logging.error("Non-TXT control query %s from %s", qctx.qname, qctx.peer)
1636 qctx.response.set_rcode(dns.rcode.FORMERR)
1637 return qctx.response
1639 control_subdomain = dns.name.Name(qctx.qname.labels[-3:])
1643 logging.error("Unhandled control query %s from %s", qctx.qname, qctx.peer)
1644 qctx.response.set_rcode(dns.rcode.NXDOMAIN)
1645 return qctx.response
1647 logging.info("Received control query %s from %s", qctx.qname, qctx.peer)
1648 logging.debug("Handling control query %s using %s", qctx.qname, command)
1649 qctx.response.set_rcode(dns.rcode.NOERROR)
1650 qctx.response.flags |= dns.flags.AA
1652 command_qname = qctx.qname.relativize(control_subdomain)
1656 logging.error("Non-ASCII control query %s from %s", qctx.qname, qctx.peer)
1657 qctx.response.set_rcode(dns.rcode.FORMERR)
1658 return qctx.response
1660 command_response = command.handle(command_args, self, qctx)
1663 qctx.qname, 0, qctx.qclass, dns.rdatatype.TXT, f'"{command_response}"'
1665 qctx.response.answer.append(command_response_rrset)
1667 return qctx.response
1689 self, args: list[str], server: ControllableAsyncDnsServer, qctx: QueryContext
1707 `qctx` is the query context for the control query. By operating on
1708 qctx.response, this method can prepare the DNS response sent to
1731 self, args: list[str], server: ControllableAsyncDnsServer, qctx: QueryContext
1734 logging.error("Invalid %s query %s", self, qctx.qname)
1735 qctx.response.set_rcode(dns.rcode.SERVFAIL)
1755 qctx.response.set_rcode(dns.rcode.SERVFAIL)
1775 self, args: list[str], server: ControllableAsyncDnsServer, qctx: QueryContext
1778 logging.error("Invalid %s query %s", self, qctx.qname)
1779 qctx.response.set_rcode(dns.rcode.SERVFAIL)