--- /dev/null
+; config options
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test trust in cname chain answer
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME xxx.example.com.
+xxx.example.com. IN CNAME yyy.example.com.
+yyy.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+qqq.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+yyy.example.com. IN A 10.20.30.42
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+
+; This stores it into cache.
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME xxx.example.com.
+xxx.example.com. IN CNAME yyy.example.com.
+yyy.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; This query creates and overwrites the cache
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+qqq.example.com. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+qqq.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+yyy.example.com. IN A 10.20.30.42
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; get it again from cache.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME xxx.example.com.
+xxx.example.com. IN CNAME yyy.example.com.
+yyy.example.com. IN A 10.20.30.42
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
{
uint16_t AA = msg->flags & BIT_AA;
if(rrset->section == LDNS_SECTION_ANSWER) {
- if(AA) return rrset_trust_ans_AA;
+ if(AA) {
+ /* RFC2181 says remainder of CNAME chain is nonauth*/
+ if(msg->rrset_first &&
+ msg->rrset_first->section==LDNS_SECTION_ANSWER
+ && msg->rrset_first->type==LDNS_RR_TYPE_CNAME){
+ if(rrset == msg->rrset_first)
+ return rrset_trust_ans_AA;
+ else return rrset_trust_ans_noAA;
+ }
+ if(msg->rrset_first &&
+ msg->rrset_first->section==LDNS_SECTION_ANSWER
+ && msg->rrset_first->type==LDNS_RR_TYPE_DNAME){
+ if(rrset == msg->rrset_first ||
+ rrset == msg->rrset_first->rrset_all_next)
+ return rrset_trust_ans_AA;
+ else return rrset_trust_ans_noAA;
+ }
+ return rrset_trust_ans_AA;
+ }
else return rrset_trust_ans_noAA;
} else if(rrset->section == LDNS_SECTION_AUTHORITY) {
if(AA) return rrset_trust_auth_AA;