diff --git a/iterator/iterator.c b/iterator/iterator.c
-index 7f3c6573..26660059 100644
+index 7f3c6573..33fb02dd 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -1157,6 +1157,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
-@@ -1246,6 +1253,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
+@@ -1246,6 +1253,11 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qchase.qname_len = slen;
/* This *is* a query restart, even if it is a cheap
* one. */
+ msg->rep->ns_numrrsets = 0;
+ msg->rep->ar_numrrsets = 0;
+ msg->rep->rrset_count = 0;
++ iq->response = msg;
iq->dp = NULL;
iq->refetch_glue = 0;
iq->query_restart_count++;
-@@ -2739,6 +2750,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
+@@ -2739,6 +2751,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
/* Clear the query state, since this is a query restart. */
iq->deleg_msg = NULL;
iq->dp = NULL;
iq->dsns_point = NULL;
+diff --git a/testdata/iter_dname_insec.rpl b/testdata/iter_dname_insec.rpl
+index 8f4a29c7..1ce8c2cb 100644
+--- a/testdata/iter_dname_insec.rpl
++++ b/testdata/iter_dname_insec.rpl
+@@ -776,12 +776,18 @@ ENTRY_END
+
+ ; Expected result is defined by RFC 1034 section 3.6.2:
+ ; CNAME chains should be followed and CNAME loops signalled as an error
++; but bug#3512: return partial contents with NOERROR.
+ STEP 221002 CHECK_ANSWER
+ ENTRY_BEGIN
+ MATCH all
+-REPLY QR RD RA DO SERVFAIL
++REPLY QR RD RA DO NOERROR
+ SECTION QUESTION
+ cyc2.example.com. IN A
++SECTION ANSWER
++example.com. 0 IN DNAME cyc2.example.net.
++cyc2.example.com. 0 IN CNAME cyc2.cyc2.example.net.
++cyc2.example.net. 0 IN DNAME example.com.
++cyc2.cyc2.example.net. 0 IN CNAME cyc2.example.com.
+ ENTRY_END
+
+ ; ns1.example.com.
+diff --git a/testdata/val_cname_loop1.rpl b/testdata/val_cname_loop1.rpl
+index 61fcdb70..b942cb26 100644
+--- a/testdata/val_cname_loop1.rpl
++++ b/testdata/val_cname_loop1.rpl
+@@ -5,6 +5,7 @@ server:
+ val-override-date: "20070916134226"
+ target-fetch-policy: "0 0 0 0 0"
+ fake-sha1: yes
++ trust-anchor-signaling: no
+
+ stub-zone:
+ name: "."
+@@ -86,6 +87,17 @@ ns.example.com. IN A 1.2.3.4
+ ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ ENTRY_END
+
++ENTRY_BEGIN
++MATCH opcode qtype qname
++ADJUST copy_id
++REPLY QR NOERROR
++SECTION QUESTION
++ns.example.com. IN AAAA
++SECTION AUTHORITY
++ns.example.com. IN NSEC www.example.com. A RRSIG NSEC
++ns.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AE+zfHodyVCTnni/bur8IiUhTUtdac6ip/znrYYN0l1nqll1fon2+kQ=
++ENTRY_END
++
+ ; response to DNSKEY priming query
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+@@ -104,6 +116,18 @@ ns.example.com. IN A 1.2.3.4
+ ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ ENTRY_END
+
++; response to DNSKEY priming query
++ENTRY_BEGIN
++MATCH opcode qtype qname
++ADJUST copy_id
++REPLY QR NOERROR
++SECTION QUESTION
++www.example.com. IN DS
++SECTION AUTHORITY
++www.example.com. IN NSEC z.example.com. CNAME RRSIG NSEC
++www.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AJ8hqdeoKtvR094y+0KjO6LkCe1SCs6z5YhuY2YZCmzvUiYHP9wiMTw=
++ENTRY_END
++
+ ; response to query of interest
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+@@ -134,10 +158,12 @@ ENTRY_END
+ STEP 10 CHECK_ANSWER
+ ENTRY_BEGIN
+ MATCH all
+-REPLY QR RD RA DO SERVFAIL
++REPLY QR RD RA DO AD NOERROR
+ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
++www.example.com. 3600 IN CNAME www.example.com.
++www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFH0SwLHe7u56TshoVciFRHEl1KqbAhQ3zBOZMlL8bt1DqoDoM5ni8U/1UA== ;{id = 2854}
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+diff --git a/testdata/val_cname_loop2.rpl b/testdata/val_cname_loop2.rpl
+index 26644bc1..d42bbd2c 100644
+--- a/testdata/val_cname_loop2.rpl
++++ b/testdata/val_cname_loop2.rpl
+@@ -5,6 +5,7 @@ server:
+ val-override-date: "20070916134226"
+ target-fetch-policy: "0 0 0 0 0"
+ fake-sha1: yes
++ trust-anchor-signaling: no
+
+ stub-zone:
+ name: "."
+@@ -113,7 +114,7 @@ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
+ www.example.com. IN CNAME foo.example.com.
+-www.example.com. 3600 IN RRSIG CNAME DSA 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFH0SwLHe7u56TshoVciFRHEl1KqbAhQ3zBOZMlL8bt1DqoDoM5ni8U/1UA== ;{id = 2854}
++www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AD50yy1elnzRmjGCd7FBiWEkYlhQYXaZu0g1JoJMr/ONiXVnV2yiONg=
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+@@ -126,7 +127,7 @@ SECTION QUESTION
+ foo.example.com. IN A
+ SECTION ANSWER
+ foo.example.com. IN CNAME www.example.com.
+-foo.example.com. 3600 IN RRSIG CNAME DSA 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC7kcWPsMnGbjvzj5UNnxQzM0YvnAhUAgxIKgs1huJHvcAP2Xt3p8Adpy/c= ;{id = 2854}
++foo.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AEEIVUwbtfcn2RP41l0PDO+Sk4YdJ0HyRVsgq20fJnrDDC6eFXFGqUg=
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+@@ -143,10 +144,14 @@ ENTRY_END
+ STEP 10 CHECK_ANSWER
+ ENTRY_BEGIN
+ MATCH all
+-REPLY QR RD RA DO SERVFAIL
++REPLY QR RD RA DO AD NOERROR
+ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
++www.example.com. 3600 IN CNAME foo.example.com.
++www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AD50yy1elnzRmjGCd7FBiWEkYlhQYXaZu0g1JoJMr/ONiXVnV2yiONg= ;{id = 2854}
++foo.example.com. 3600 IN CNAME www.example.com.
++foo.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AEEIVUwbtfcn2RP41l0PDO+Sk4YdJ0HyRVsgq20fJnrDDC6eFXFGqUg= ;{id = 2854}
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+diff --git a/testdata/val_cname_loop3.rpl b/testdata/val_cname_loop3.rpl
+index fbd0d8ab..30e6abfb 100644
+--- a/testdata/val_cname_loop3.rpl
++++ b/testdata/val_cname_loop3.rpl
+@@ -5,6 +5,7 @@ server:
+ val-override-date: "20070916134226"
+ target-fetch-policy: "0 0 0 0 0"
+ fake-sha1: yes
++ trust-anchor-signaling: no
+
+ stub-zone:
+ name: "."
+@@ -113,7 +114,7 @@ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
+ www.example.com. IN CNAME foo.example.com.
+-www.example.com. 3600 IN RRSIG CNAME DSA 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFH0SwLHe7u56TshoVciFRHEl1KqbAhQ3zBOZMlL8bt1DqoDoM5ni8U/1UA== ;{id = 2854}
++www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AD50yy1elnzRmjGCd7FBiWEkYlhQYXaZu0g1JoJMr/ONiXVnV2yiONg=
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+@@ -126,7 +127,7 @@ SECTION QUESTION
+ foo.example.com. IN A
+ SECTION ANSWER
+ foo.example.com. IN CNAME bar.example.com.
+-foo.example.com. 3600 IN RRSIG CNAME DSA 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFFMlXuWrNL/8aYOl9U9WYjgif8gAAhUAqsC/xOXakHP1SYxMSLANziOik94= ;{id = 2854}
++foo.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AILRq+NAK+k+qCNJAmByoTAkGNveSHT+au0u360OeUa56b8zU7gi6+I=
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+@@ -139,7 +140,7 @@ SECTION QUESTION
+ bar.example.com. IN A
+ SECTION ANSWER
+ bar.example.com. IN CNAME www.example.com.
+-bar.example.com. 3600 IN RRSIG CNAME DSA 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFAsalUJJSV86uPlfiGS3kKDc0JB7AhQ+qmHqagY/r36Re/J3Q1OfvcA1dA== ;{id = 2854}
++bar.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AKA7eO4DAGPB8vg/OdBLk41/2txpklOJrszT8Gvp+UOVSLYtddNGz+k=
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+@@ -156,10 +157,13 @@ ENTRY_END
+ STEP 10 CHECK_ANSWER
+ ENTRY_BEGIN
+ MATCH all
+-REPLY QR RD RA SERVFAIL
++REPLY QR RD RA NOERROR
+ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
++www.example.com. 3600 IN CNAME foo.example.com.
++foo.example.com. 3600 IN CNAME bar.example.com.
++bar.example.com. 3600 IN CNAME www.example.com.
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+diff --git a/validator/validator.c b/validator/validator.c
+index a924a3f8..81d67cd3 100644
+--- a/validator/validator.c
++++ b/validator/validator.c
+@@ -1529,6 +1529,22 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
+ if(verbosity >= VERB_ALGO)
+ log_dns_msg("chased extract", &vq->qchase,
+ vq->chase_reply);
++ /* we skipped cnames, and now the reply is empty, is this
++ * a CNAME loop? */
++ if(vq->rrset_skip > 0 && vq->chase_reply->rrset_count == 0) {
++ if(reply_find_rrset_section_an(vq->orig_msg->rep,
++ lookup_name, lookup_len, LDNS_RR_TYPE_CNAME,
++ vq->qchase.qclass)) {
++ if(anchor) {
++ lock_basic_unlock(&anchor->lock);
++ }
++ verbose(VERB_ALGO, "validator: encountered "
++ "CNAME loop - terminating");
++ vq->chase_reply->security = vq->orig_msg->rep->security;
++ vq->state = VAL_FINISHED_STATE;
++ return 1;
++ }
++ }
+ }
+
+ vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,