Follow the CNAME chain in the response to determine the answer RRset. Raises ``dns.message.NotQueryResponse`` if the message is not a response. Raises ``dns.message.ChainTooLong`` if the CNAME chain is too long. Raises ``dns.message.AnswerForNXDOMAIN`` if t
(self)
| 997 | |
| 998 | class QueryMessage(Message): |
| 999 | def resolve_chaining(self) -> ChainingResult: |
| 1000 | """Follow the CNAME chain in the response to determine the answer |
| 1001 | RRset. |
| 1002 | |
| 1003 | Raises ``dns.message.NotQueryResponse`` if the message is not |
| 1004 | a response. |
| 1005 | |
| 1006 | Raises ``dns.message.ChainTooLong`` if the CNAME chain is too long. |
| 1007 | |
| 1008 | Raises ``dns.message.AnswerForNXDOMAIN`` if the rcode is NXDOMAIN |
| 1009 | but an answer was found. |
| 1010 | |
| 1011 | Raises ``dns.exception.FormError`` if the question count is not 1. |
| 1012 | |
| 1013 | Returns a ChainingResult object. |
| 1014 | """ |
| 1015 | if self.flags & dns.flags.QR == 0: |
| 1016 | raise NotQueryResponse |
| 1017 | if len(self.question) != 1: |
| 1018 | raise dns.exception.FormError |
| 1019 | question = self.question[0] |
| 1020 | qname = question.name |
| 1021 | min_ttl = dns.ttl.MAX_TTL |
| 1022 | answer = None |
| 1023 | count = 0 |
| 1024 | cnames = [] |
| 1025 | while count < MAX_CHAIN: |
| 1026 | try: |
| 1027 | answer = self.find_rrset( |
| 1028 | self.answer, qname, question.rdclass, question.rdtype |
| 1029 | ) |
| 1030 | min_ttl = min(min_ttl, answer.ttl) |
| 1031 | break |
| 1032 | except KeyError: |
| 1033 | if question.rdtype != dns.rdatatype.CNAME: |
| 1034 | try: |
| 1035 | crrset = self.find_rrset( |
| 1036 | self.answer, qname, question.rdclass, dns.rdatatype.CNAME |
| 1037 | ) |
| 1038 | cnames.append(crrset) |
| 1039 | min_ttl = min(min_ttl, crrset.ttl) |
| 1040 | for rd in crrset: |
| 1041 | qname = rd.target |
| 1042 | break |
| 1043 | count += 1 |
| 1044 | continue |
| 1045 | except KeyError: |
| 1046 | # Exit the chaining loop |
| 1047 | break |
| 1048 | else: |
| 1049 | # Exit the chaining loop |
| 1050 | break |
| 1051 | if count >= MAX_CHAIN: |
| 1052 | raise ChainTooLong |
| 1053 | if self.rcode() == dns.rcode.NXDOMAIN and answer is not None: |
| 1054 | raise AnswerForNXDOMAIN |
| 1055 | if answer is None: |
| 1056 | # Further minimize the TTL with NCACHE. |