+6 August 2008: Wouter
+ - patch for scrubber that removes ends of CNAMEs, no more DNAMEs
+ from cache. Remove more irrelevant rrsets from the message.
+
5 August 2008: Wouter
- fixup DS test so apex nodata works again (from trunk).
{
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
- struct rrset_parse* rrset, *prev;
+ struct rrset_parse* rrset, *prev, *nsset=NULL;
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
}
/* Mark the additional names from relevant rrset as OK. */
- mark_additional_rrset(pkt, msg, rrset);
+ /* only for RRsets that match the query name, other ones
+ * will be removed by sanitize, so no additional for them */
+ if(dname_pkt_compare(pkt, qinfo->qname, rrset->dname) == 0)
+ mark_additional_rrset(pkt, msg, rrset);
prev = rrset;
rrset = rrset->rrset_all_next;
/* Mark additional names from AUTHORITY */
while(rrset && rrset->section == LDNS_SECTION_AUTHORITY) {
+ if(rrset->type==LDNS_RR_TYPE_DNAME ||
+ rrset->type==LDNS_RR_TYPE_CNAME ||
+ rrset->type==LDNS_RR_TYPE_A ||
+ rrset->type==LDNS_RR_TYPE_AAAA) {
+ remove_rrset("normalize: removing irrelevant "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
+ /* only one NS set allowed in authority section */
+ if(rrset->type==LDNS_RR_TYPE_NS) {
+ if(nsset == NULL) {
+ nsset = rrset;
+ } else {
+ remove_rrset("normalize: removing irrelevant "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
+ }
mark_additional_rrset(pkt, msg, rrset);
prev = rrset;
rrset = rrset->rrset_all_next;
continue;
}
}
+ if(rrset->type==LDNS_RR_TYPE_DNAME ||
+ rrset->type==LDNS_RR_TYPE_CNAME ||
+ rrset->type==LDNS_RR_TYPE_NS) {
+ remove_rrset("normalize: removing irrelevant "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
prev = rrset;
rrset = rrset->rrset_all_next;
}
*
* @param pkt: packet.
* @param msg: msg to normalize.
+ * @param qinfo: the question originally asked.
* @param zonename: name of server zone.
* @param env: module environment with config and cache.
* @return 0 on error.
*/
static int
-scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg, uint8_t* zonename,
- struct module_env* env)
+scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg,
+ struct query_info* qinfo, uint8_t* zonename, struct module_env* env)
{
struct rrset_parse* rrset, *prev;
prev = NULL;
rrset = msg->rrset_first;
+ /* the first DNAME is allowed to stay. It needs checking before
+ * it can be used from the cache. After normalization, an initial
+ * DNAME will have a correctly synthesized CNAME after it. */
+ if(rrset && rrset->type == LDNS_RR_TYPE_DNAME &&
+ rrset->section == LDNS_SECTION_ANSWER &&
+ pkt_strict_sub(pkt, qinfo->qname, rrset->dname) &&
+ pkt_sub(pkt, rrset->dname, zonename)) {
+ prev = rrset; /* DNAME allowed to stay in answer section */
+ rrset = rrset->rrset_all_next;
+ }
+
+ /* remove all records from the answer section that are
+ * not the same domain name as the query domain name.
+ * The answer section should contain rrsets with the same name
+ * as the question. For DNAMEs a CNAME has been synthesized.
+ * Wildcards have the query name in answer section.
+ * ANY queries get query name in answer section.
+ * Remainders of CNAME chains are cut off and resolved by iterator. */
+ while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
+ if(dname_pkt_compare(pkt, qinfo->qname, rrset->dname) != 0) {
+ remove_rrset("sanitize: removing extraneous answer "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
+ prev = rrset;
+ rrset = rrset->rrset_all_next;
+ }
+
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
* be authoriative for any other zones, and of course, MAY
* NOT be authoritative for some subdomains of the originating
* zone. */
+ prev = NULL;
+ rrset = msg->rrset_first;
while(rrset) {
/* skip DNAME records -- they will always be followed by a
if(!scrub_normalize(pkt, msg, qinfo, region))
return 0;
/* delete all out-of-zone information */
- if(!scrub_sanitize(pkt, msg, zonename, env))
+ if(!scrub_sanitize(pkt, msg, qinfo, zonename, env))
return 0;
return 1;
}
size_t newlen, dtarglen;
if(now > d->ttl)
return NULL;
+ /* only allow validated (with DNSSEC) DNAMEs used from cache
+ * for insecure DNAMEs, query again. */
+ if(d->security != sec_status_secure)
+ return NULL;
msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */
if(!msg)
return NULL;
--- /dev/null
+; config options
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of CNAME in answer section
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 20 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+. IN NS
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA 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
+
+; query sent to root server
+STEP 40 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+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
+
+; query sent to .com server
+STEP 60 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; this query reply has to be scrubbed
+STEP 80 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+STEP 90 REPLY
+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 next.example.com.
+next.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; iterator should try again and ask the other nameserver.
+STEP 100 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+next.example.com. IN A
+ENTRY_END
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+next.example.com. IN A
+SECTION ANSWER
+next.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; is the final answer correct?
+STEP 200 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME next.example.com.
+next.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+SCENARIO_END
--- /dev/null
+; config options
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of insecure DNAME in answer section
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 20 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+. IN NS
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA 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
+
+; query sent to root server
+STEP 40 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.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
+
+; query sent to .com server
+STEP 60 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 80 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 90 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 100 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.z.example.com. IN A
+ENTRY_END
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.z.example.com. IN A
+SECTION ANSWER
+x.z.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; answer to first query (simply puts DNAME in cache)
+STEP 120 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; now, DNAME insecure from cache should not be used.
+; new query
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+
+STEP 210 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+STEP 220 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 230 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.z.example.com. IN A
+ENTRY_END
+STEP 240 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.z.example.com. IN A
+SECTION ANSWER
+other.z.example.com. IN A 50.60.70.80
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 250 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.80
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+SCENARIO_END
--- /dev/null
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ trust-anchor: "example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}"
+ val-override-date: "20070916134226"
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of secure DNAME in answer section
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 20 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+. IN NS
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA 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
+
+; query sent to root server
+STEP 40 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.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
+
+; query sent to .com server
+STEP 60 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; query sent to example.com. server
+STEP 80 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 90 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. AA3IkI13XbKFU5NSqBVA9oM1WiyEKCy4DYFOAdihDf6uHps9lce3kEc= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. AKcUlwrSz2xYKnQ7b7oMblRa0rKjfUNT900bIkGjLKLWDUGc8mKZE2M= ;{id = 2854}
+ENTRY_END
+
+STEP 100 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.z.example.com. IN A
+ENTRY_END
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.z.example.com. IN A
+SECTION ANSWER
+x.z.example.com. IN A 10.20.30.40
+x.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. ADZ12PiZGEjVUyLLYkct/SBE2WT4D5IkMOKdcl0dzQ0XRAC5y/0bS7A= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+; DNSKEY prime
+STEP 115 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+example.com. IN DNSKEY
+ENTRY_END
+STEP 116 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; answer to first query (simply puts DNAME in cache)
+STEP 120 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.40
+x.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. ADZ12PiZGEjVUyLLYkct/SBE2WT4D5IkMOKdcl0dzQ0XRAC5y/0bS7A= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+; now, DNAME is secure and can be used from cache.
+; new query
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+
+STEP 230 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.z.example.com. IN A
+ENTRY_END
+STEP 240 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.z.example.com. IN A
+SECTION ANSWER
+other.z.example.com. IN A 50.60.70.80
+other.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. AAp6G89oAvkyAaeF2d35AJNlzMhedGo0Bcppl0IOyF3HRzoc51vjJoU= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+STEP 250 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.80
+other.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. AAp6G89oAvkyAaeF2d35AJNlzMhedGo0Bcppl0IOyF3HRzoc51vjJoU= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
bla.example.com. IN A 10.20.30.140
SECTION AUTHORITY
SECTION ADDITIONAL
- example.com. IN NS ns.eeeek.com.
- example.com. IN NS ns2.eeeek.com.
ENTRY_END
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
-qqq.example.com. IN A
+xxx.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
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
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
SECTION QUESTION
-qqq.example.com. IN A
+yyy.example.com. IN A
SECTION ANSWER
+yyy.example.com. IN A 10.20.30.42
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
-; get it again from cache.
-STEP 30 QUERY
+
+; This stores it into cache.
+STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
-STEP 31 CHECK_ANSWER
+; recursion happens here.
+STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION ANSWER
www.example.com. IN CNAME xxx.example.com.
xxx.example.com. IN CNAME yyy.example.com.
+;;; did not trust the remainder of the CNAME chain!
yyy.example.com. IN A 10.20.30.42
SECTION AUTHORITY
example.com. IN NS ns.example.com.