aboutsummaryrefslogtreecommitdiffstats
path: root/main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch')
-rw-r--r--main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch265
1 files changed, 265 insertions, 0 deletions
diff --git a/main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch b/main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch
new file mode 100644
index 0000000000..fb703b352d
--- /dev/null
+++ b/main/gdnsd/0001-Fix-auth-section-of-ANY-query-on-CNAME.patch
@@ -0,0 +1,265 @@
+From 22b0dcf8a19aaeb1e6f32ad9f0aad95ab26b8a61 Mon Sep 17 00:00:00 2001
+From: Brandon Black <blblack@gmail.com>
+Date: Thu, 11 Jul 2013 14:37:57 -0500
+Subject: [PATCH] Fix auth section of ANY-query on CNAME
+
+Queries with QTYPE=ANY for a name which has a CNAME RR
+ should be treated as if QTYPE=CNAME. Prior to this
+ fix, they were being treated more like QTYPE=A. Given
+ it's QTYPE=ANY and the effects seem to be limited to
+ the auth section, I doubt this is a production concern
+ for anyone, but it's good to be correct.
+
+Fixes Issue #51 (thanks Timo!)
+---
+ gdnsd/dnspacket.c | 11 ++-
+ t/012cname/001cname.t | 157 +++++++++++++++++++++++++++++++++++++++++++
+ t/012cname/gdnsd.conf | 11 +++
+ t/012cname/zones/example.com | 24 +++++++
+ 4 files changed, 201 insertions(+), 2 deletions(-)
+ create mode 100644 t/012cname/001cname.t
+ create mode 100644 t/012cname/gdnsd.conf
+ create mode 100644 t/012cname/zones/example.com
+
+diff --git a/gdnsd/dnspacket.c b/gdnsd/dnspacket.c
+index 3c26d83..db7e26a 100644
+--- a/gdnsd/dnspacket.c
++++ b/gdnsd/dnspacket.c
+@@ -1190,6 +1190,9 @@ static unsigned int encode_rrs_any(dnspacket_context_t* c, unsigned int offset,
+ case DNS_TYPE_SOA:
+ offset = encode_rr_soa(c, offset, (const void*)rrset, true);
+ break;
++ case DNS_TYPE_CNAME:
++ offset = encode_rr_cname(c, offset, (const void*)rrset, true);
++ break;
+ case DNS_TYPE_NS:
+ offset = encode_rrs_ns(c, offset, (const void*)rrset, true);
+ break;
+@@ -1659,8 +1662,12 @@ static unsigned int answer_from_db(dnspacket_context_t* c, const uint8_t* qname,
+ // for the normal response handling code below. The explicit check of the first
+ // rrsets entry works because if CNAME exists at all, by definition it is the only
+ // type of rrset at this node.
+- while(resdom && resdom->rrsets
+- && resdom->rrsets->gen.type == DNS_TYPE_CNAME && c->qtype != DNS_TYPE_CNAME) {
++ while(resdom
++ && resdom->rrsets
++ && resdom->rrsets->gen.type == DNS_TYPE_CNAME
++ && c->qtype != DNS_TYPE_CNAME
++ && c->qtype != DNS_TYPE_ANY) {
++
+ dmn_assert(status == DNAME_AUTH);
+
+ res_hdr->flags1 |= 4; // AA bit
+diff --git a/t/012cname/001cname.t b/t/012cname/001cname.t
+new file mode 100644
+index 0000000..6e96335
+--- /dev/null
++++ b/t/012cname/001cname.t
+@@ -0,0 +1,157 @@
++
++# CNAME test, with include_optional_ns to get the auth section right...
++# this is basically going through A, CNAME, and ANY queries against
++# five different classes of CNAME targets (local nonexistent,
++# local existent, delegation, delegation glue record, and external).
++# CNAME and ANY responses should be identical (this was the bug that
++# triggered writing these testcases - ANY was being treated more like A).
++
++use _GDT ();
++use FindBin ();
++use File::Spec ();
++use Test::More tests => 17;
++
++my $standard_soa = 'example.com 21600 SOA ns1.example.com hmaster.example.net 1 7200 1800 259200 900';
++
++my $pid = _GDT->test_spawn_daemon(File::Spec->catfile($FindBin::Bin, 'gdnsd.conf'));
++
++_GDT->test_dns(
++ qname => 'cn-nx.example.com', qtype => 'A',
++ header => { rcode => 'NXDOMAIN' },
++ answer => 'cn-nx.example.com 21600 CNAME nx.example.com',
++ auth => $standard_soa,
++ stats => [qw/udp_reqs nxdomain/],
++);
++
++foreach my $qt (qw/CNAME ANY/) {
++ _GDT->test_dns(
++ qname => 'cn-nx.example.com', qtype => $qt,
++ answer => 'cn-nx.example.com 21600 CNAME nx.example.com',
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns1.example.com 21600 A 192.0.2.1',
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++ );
++}
++
++_GDT->test_dns(
++ qname => 'cn-local.example.com', qtype => 'A',
++ answer => [
++ 'cn-local.example.com 21600 CNAME ns1.example.com',
++ 'ns1.example.com 21600 A 192.0.2.1',
++ ],
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++);
++
++foreach my $qt (qw/CNAME ANY/) {
++ _GDT->test_dns(
++ qname => 'cn-local.example.com', qtype => $qt,
++ answer => [
++ 'cn-local.example.com 21600 CNAME ns1.example.com'
++ ],
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns1.example.com 21600 A 192.0.2.1',
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++ );
++}
++
++_GDT->test_dns(
++ qname => 'cn-deleg.example.com', qtype => 'A',
++ answer => [
++ 'cn-deleg.example.com 21600 CNAME foo.subz.example.com',
++ ],
++ auth => [
++ 'subz.example.com 21600 NS ns1.subz.example.com',
++ 'subz.example.com 21600 NS ns2.subz.example.com',
++ ],
++ addtl => [
++ 'ns1.subz.example.com 21600 A 192.0.2.10',
++ 'ns2.subz.example.com 21600 A 192.0.2.20',
++ ],
++);
++
++foreach my $qt (qw/CNAME ANY/) {
++ _GDT->test_dns(
++ qname => 'cn-deleg.example.com', qtype => $qt,
++ answer => [
++ 'cn-deleg.example.com 21600 CNAME foo.subz.example.com',
++ ],
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns1.example.com 21600 A 192.0.2.1',
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++ );
++}
++
++_GDT->test_dns(
++ qname => 'cn-deleg-glue.example.com', qtype => 'A',
++ answer => [
++ 'cn-deleg-glue.example.com 21600 CNAME ns1.subz.example.com',
++ ],
++ auth => [
++ 'subz.example.com 21600 NS ns1.subz.example.com',
++ 'subz.example.com 21600 NS ns2.subz.example.com',
++ ],
++ addtl => [
++ 'ns1.subz.example.com 21600 A 192.0.2.10',
++ 'ns2.subz.example.com 21600 A 192.0.2.20',
++ ],
++);
++
++foreach my $qt (qw/CNAME ANY/) {
++ _GDT->test_dns(
++ qname => 'cn-deleg-glue.example.com', qtype => $qt,
++ answer => [
++ 'cn-deleg-glue.example.com 21600 CNAME ns1.subz.example.com',
++ ],
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns1.example.com 21600 A 192.0.2.1',
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++ );
++}
++
++_GDT->test_dns(
++ qname => 'cn-ext.example.com', qtype => 'A',
++ answer => 'cn-ext.example.com 21600 CNAME www.example.net',
++);
++
++foreach my $qt (qw/CNAME ANY/) {
++ _GDT->test_dns(
++ qname => 'cn-ext.example.com', qtype => $qt,
++ answer => 'cn-ext.example.com 21600 CNAME www.example.net',
++ auth => [
++ 'example.com 21600 NS ns1.example.com',
++ 'example.com 21600 NS ns2.example.com',
++ ],
++ addtl => [
++ 'ns1.example.com 21600 A 192.0.2.1',
++ 'ns2.example.com 21600 A 192.0.2.2',
++ ],
++ );
++}
++
++_GDT->test_kill_daemon($pid);
+diff --git a/t/012cname/gdnsd.conf b/t/012cname/gdnsd.conf
+new file mode 100644
+index 0000000..2bc6c92
+--- /dev/null
++++ b/t/012cname/gdnsd.conf
+@@ -0,0 +1,11 @@
++options => {
++ listen => @dns_lspec@
++ http_listen => @http_lspec@
++ dns_port => @dns_port@
++ http_port => @http_port@
++ zones_default_ttl = 21600
++ realtime_stats = true
++ max_response = 62464
++ chaos_response = "some random string"
++ include_optional_ns = true
++}
+diff --git a/t/012cname/zones/example.com b/t/012cname/zones/example.com
+new file mode 100644
+index 0000000..94a452f
+--- /dev/null
++++ b/t/012cname/zones/example.com
+@@ -0,0 +1,24 @@
++
++@ SOA ns1 hmaster.example.net. (
++ 1 ; serial
++ 7200 ; refresh
++ 1800 ; retry
++ 259200 ; expire
++ 900 ; ncache
++)
++
++@ NS ns1
++@ NS ns2
++ns1 A 192.0.2.1
++ns2 A 192.0.2.2
++
++subz NS ns1.subz
++subz NS ns2.subz
++ns1.subz A 192.0.2.10
++ns2.subz A 192.0.2.20
++
++cn-nx CNAME nx
++cn-local CNAME ns1
++cn-deleg CNAME foo.subz
++cn-deleg-glue CNAME ns1.subz
++cn-ext CNAME www.example.net.
+--
+1.8.3.2
+