]> granicus.if.org Git - pdns/commitdiff
Add more tests for dnsdist ECS support.
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 4 Dec 2015 14:09:08 +0000 (15:09 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 7 Dec 2015 08:24:01 +0000 (09:24 +0100)
Add regression tests for rewriting the ECS value with
larger / smaller values.
Add one unit test for rewriting response.

pdns/test-dnsdist_cc.cc
regression-tests.dnsdist/test_EdnsClientSubnet.py

index fd2eddf00672eef86ba0daaa6b8c2cac1219b7e6..4a1491679aa3f63a4fc0514cae8b1e3cf996c707 100644 (file)
@@ -43,7 +43,7 @@ bool g_verbose{true};
 static void validateQuery(const char * packet, size_t packetSize)
 {
   MOADNSParser mdp(packet, packetSize);
-  
+
   BOOST_CHECK_EQUAL(mdp.d_qname.toString(), "www.powerdns.com.");
 
   BOOST_CHECK_EQUAL(mdp.d_header.qdcount, 1);
@@ -52,6 +52,19 @@ static void validateQuery(const char * packet, size_t packetSize)
   BOOST_CHECK_EQUAL(mdp.d_header.arcount, 1);
 }
 
+static void validateResponse(const char * packet, size_t packetSize, bool hasEdns)
+{
+  MOADNSParser mdp(packet, packetSize);
+
+  BOOST_CHECK_EQUAL(mdp.d_qname.toString(), "www.powerdns.com.");
+
+  BOOST_CHECK_EQUAL(mdp.d_header.qr, 1);
+  BOOST_CHECK_EQUAL(mdp.d_header.qdcount, 1);
+  BOOST_CHECK_EQUAL(mdp.d_header.ancount, 1);
+  BOOST_CHECK_EQUAL(mdp.d_header.nscount, 0);
+  BOOST_CHECK_EQUAL(mdp.d_header.arcount, hasEdns ? 1 : 0);
+}
+
 BOOST_AUTO_TEST_CASE(addECSWithoutEDNS)
 {
   string largerPacket;
@@ -60,10 +73,10 @@ BOOST_AUTO_TEST_CASE(addECSWithoutEDNS)
   DNSName name("www.powerdns.com.");
 
   vector<uint8_t> query;
-  DNSPacketWriter pw(query, name, QType::OPT, QClass::IN, 0);
+  DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0);
   pw.getHeader()->rd = 1;
   int len = query.size();
-    
+
   /* large enough packet */
   char packet[1500];
   memcpy(packet, query.data(), query.size());
@@ -72,21 +85,21 @@ BOOST_AUTO_TEST_CASE(addECSWithoutEDNS)
   uint16_t qtype;
   DNSName qname(packet, len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
-  
+  BOOST_CHECK(qtype == QType::A);
+
   handleEDNSClientSubnet(packet, sizeof packet, consumed, &len, largerPacket, &ednsAdded, remote);
   BOOST_CHECK((size_t) len > query.size());
   BOOST_CHECK_EQUAL(largerPacket.size(), 0);
   BOOST_CHECK_EQUAL(ednsAdded, true);
   validateQuery(packet, len);
-  
+
   /* not large enought packet */
   consumed = 0;
   len = query.size();
   qname = DNSName((char*) query.data(), len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
-  
+  BOOST_CHECK(qtype == QType::A);
+
   handleEDNSClientSubnet((char*) query.data(), query.size(), consumed, &len, largerPacket, &ednsAdded, remote);
   BOOST_CHECK_EQUAL((size_t) len, query.size());
   BOOST_CHECK(largerPacket.size() > query.size());
@@ -98,15 +111,15 @@ BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECS) {
   string largerPacket;
   bool ednsAdded = false;
   ComboAddress remote;
-  DNSName name("www.powerdns.com");
+  DNSName name("www.powerdns.com.");
 
   vector<uint8_t> query;
-  DNSPacketWriter pw(query, name, QType::OPT, QClass::IN, 0);
+  DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0);
   pw.getHeader()->rd = 1;
   pw.addOpt(512, 0, 0);
   pw.commit();
   int len = query.size();
-    
+
   /* large enough packet */
   char packet[1500];
   memcpy(packet, query.data(), query.size());
@@ -115,21 +128,21 @@ BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECS) {
   uint16_t qtype;
   DNSName qname(packet, len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
-  
+  BOOST_CHECK(qtype == QType::A);
+
   handleEDNSClientSubnet(packet, sizeof packet, consumed, &len, largerPacket, &ednsAdded, remote);
   BOOST_CHECK((size_t) len > query.size());
   BOOST_CHECK_EQUAL(largerPacket.size(), 0);
   BOOST_CHECK_EQUAL(ednsAdded, false);
   validateQuery(packet, len);
-  
+
   /* not large enought packet */
   consumed = 0;
   len = query.size();
   qname = DNSName((char*) query.data(), len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
-  
+  BOOST_CHECK(qtype == QType::A);
+
   handleEDNSClientSubnet((char*) query.data(), query.size(), consumed, &len, largerPacket, &ednsAdded, remote);
   BOOST_CHECK_EQUAL((size_t) len, query.size());
   BOOST_CHECK(largerPacket.size() > query.size());
@@ -141,11 +154,11 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSameSize) {
   string largerPacket;
   bool ednsAdded = false;
   ComboAddress remote("192.168.1.25");
-  DNSName name("www.powerdns.com");
+  DNSName name("www.powerdns.com.");
   ComboAddress origRemote("127.0.0.1");
 
   vector<uint8_t> query;
-  DNSPacketWriter pw(query, name, QType::OPT, QClass::IN, 0);
+  DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0);
   pw.getHeader()->rd = 1;
   EDNSSubnetOpts ecsOpts;
   ecsOpts.source = Netmask(origRemote, g_ECSSourcePrefixV4);
@@ -155,7 +168,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSameSize) {
   pw.addOpt(512, 0, 0, opts);
   pw.commit();
   int len = query.size();
-    
+
   /* large enough packet */
   char packet[1500];
   memcpy(packet, query.data(), query.size());
@@ -164,7 +177,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSameSize) {
   uint16_t qtype;
   DNSName qname(packet, len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
+  BOOST_CHECK(qtype == QType::A);
 
   g_ECSOverride = true;
   handleEDNSClientSubnet(packet, sizeof packet, consumed, &len, largerPacket, &ednsAdded, remote);
@@ -178,11 +191,11 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSmaller) {
   string largerPacket;
   bool ednsAdded = false;
   ComboAddress remote("192.168.1.25");
-  DNSName name("www.powerdns.com");
+  DNSName name("www.powerdns.com.");
   ComboAddress origRemote("127.0.0.1");
 
   vector<uint8_t> query;
-  DNSPacketWriter pw(query, name, QType::OPT, QClass::IN, 0);
+  DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0);
   pw.getHeader()->rd = 1;
   EDNSSubnetOpts ecsOpts;
   ecsOpts.source = Netmask(origRemote, 32);
@@ -192,7 +205,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSmaller) {
   pw.addOpt(512, 0, 0, opts);
   pw.commit();
   int len = query.size();
-    
+
   /* large enough packet */
   char packet[1500];
   memcpy(packet, query.data(), query.size());
@@ -201,7 +214,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSmaller) {
   uint16_t qtype;
   DNSName qname(packet, len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
+  BOOST_CHECK(qtype == QType::A);
 
   g_ECSOverride = true;
   handleEDNSClientSubnet(packet, sizeof packet, consumed, &len, largerPacket, &ednsAdded, remote);
@@ -215,11 +228,11 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
   string largerPacket;
   bool ednsAdded = false;
   ComboAddress remote("192.168.1.25");
-  DNSName name("www.powerdns.com");
+  DNSName name("www.powerdns.com.");
   ComboAddress origRemote("127.0.0.1");
 
   vector<uint8_t> query;
-  DNSPacketWriter pw(query, name, QType::OPT, QClass::IN, 0);
+  DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0);
   pw.getHeader()->rd = 1;
   EDNSSubnetOpts ecsOpts;
   ecsOpts.source = Netmask(origRemote, 8);
@@ -229,7 +242,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
   pw.addOpt(512, 0, 0, opts);
   pw.commit();
   int len = query.size();
-    
+
   /* large enough packet */
   char packet[1500];
   memcpy(packet, query.data(), query.size());
@@ -238,7 +251,7 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
   uint16_t qtype;
   DNSName qname(packet, len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
+  BOOST_CHECK(qtype == QType::A);
 
   g_ECSOverride = true;
   handleEDNSClientSubnet(packet, sizeof packet, consumed, &len, largerPacket, &ednsAdded, remote);
@@ -252,8 +265,8 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
   len = query.size();
   qname = DNSName((char*) query.data(), len, sizeof(dnsheader), false, &qtype, NULL, &consumed);
   BOOST_CHECK_EQUAL(qname, name);
-  BOOST_CHECK(qtype == QType::OPT);
-  
+  BOOST_CHECK(qtype == QType::A);
+
   g_ECSOverride = true;
   handleEDNSClientSubnet((char*) query.data(), query.size(), consumed, &len, largerPacket, &ednsAdded, remote);
   BOOST_CHECK_EQUAL((size_t) len, query.size());
@@ -262,4 +275,31 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
   validateQuery(largerPacket.c_str(), largerPacket.size());
 }
 
+BOOST_AUTO_TEST_CASE(removeEDNS) {
+  DNSName name("www.powerdns.com.");
+
+  vector<uint8_t> response;
+  DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0);
+  pw.getHeader()->qr = 1;
+  pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true);
+  pw.xfr32BitInt(0x01020304);
+  pw.addOpt(512, 0, 0);
+  pw.commit();
+
+  vector<uint8_t> newResponse;
+  int res = rewriteResponseWithoutEDNS((const char *) response.data(), response.size(), newResponse);
+
+  BOOST_CHECK_EQUAL(res, 0);
+
+  unsigned int consumed = 0;
+  uint16_t qtype;
+  DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, NULL, &consumed);
+  BOOST_CHECK_EQUAL(qname, name);
+  BOOST_CHECK(qtype == QType::A);
+  size_t const ednsOptRRSize = sizeof(struct dnsrecordheader) + 1 /* root in OPT RR */;
+  BOOST_CHECK_EQUAL(newResponse.size(), response.size() - ednsOptRRSize);
+
+  validateResponse((const char *) newResponse.data(), newResponse.size(), false);
+}
+
 BOOST_AUTO_TEST_SUITE_END();
index c0412526fcf88a5fbfbafd9e0fd129428abee000..aa4d87389421cc15cc405f96563b01d9d2cb9329 100644 (file)
@@ -280,16 +280,96 @@ class TestEdnsClientSubnetOverride(DNSDistTest):
         self.assertEquals(expectedQuery, receivedQuery)
         self.assertEquals(expectedResponse, receivedResponse)
 
-    def testWithEDNSECS(self):
+    def testWithEDNSShorterInitialECS(self):
         """
         Send a query with EDNS and a crafted ECS value.
         Check that the query received by the responder
         has an overwritten ECS value (not the initial one)
         and that the response received from dnsdist contains
         an EDNS pseudo-RR.
+        The initial ECS value is shorter than the one it will
+        replaced with.
         """
         name = 'withednsecs.overriden.ecs.tests.powerdns.com.'
-        ecso = clientsubnetoption.ClientSubnetOption('1.2.3.4', 24)
+        ecso = clientsubnetoption.ClientSubnetOption('192.0.2.1', 8)
+        rewrittenEcso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
+        query = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[ecso])
+        expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[rewrittenEcso])
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '127.0.0.1')
+        response.answer.append(rrset)
+
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = expectedQuery.id
+        receivedResponse.id = response.id
+        self.assertEquals(expectedQuery, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = expectedQuery.id
+        receivedResponse.id = response.id
+        self.assertEquals(expectedQuery, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+    def testWithEDNSLongerInitialECS(self):
+        """
+        Send a query with EDNS and a crafted ECS value.
+        Check that the query received by the responder
+        has an overwritten ECS value (not the initial one)
+        and that the response received from dnsdist contains
+        an EDNS pseudo-RR.
+        The initial ECS value is longer than the one it will
+        replaced with.
+        """
+        name = 'withednsecs.overriden.ecs.tests.powerdns.com.'
+        ecso = clientsubnetoption.ClientSubnetOption('192.0.2.1', 32)
+        rewrittenEcso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
+        query = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[ecso])
+        expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[rewrittenEcso])
+        response = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    3600,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '127.0.0.1')
+        response.answer.append(rrset)
+
+        (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = expectedQuery.id
+        receivedResponse.id = response.id
+        self.assertEquals(expectedQuery, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+        (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+        self.assertTrue(receivedQuery)
+        self.assertTrue(receivedResponse)
+        receivedQuery.id = expectedQuery.id
+        receivedResponse.id = response.id
+        self.assertEquals(expectedQuery, receivedQuery)
+        self.assertEquals(response, receivedResponse)
+
+    def testWithEDNSSameSizeInitialECS(self):
+        """
+        Send a query with EDNS and a crafted ECS value.
+        Check that the query received by the responder
+        has an overwritten ECS value (not the initial one)
+        and that the response received from dnsdist contains
+        an EDNS pseudo-RR.
+        The initial ECS value is exactly the same size as
+        the one it will replaced with.
+        """
+        name = 'withednsecs.overriden.ecs.tests.powerdns.com.'
+        ecso = clientsubnetoption.ClientSubnetOption('192.0.2.1', 24)
         rewrittenEcso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
         query = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[ecso])
         expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096, options=[rewrittenEcso])