Browse Source

merge #475 : Remove duplicate records from authority section

chenzhengzhang 14 years ago
parent
commit
eef82e02f9
2 changed files with 41 additions and 5 deletions
  1. 13 3
      src/bin/auth/query.cc
  2. 28 2
      src/bin/auth/tests/query_unittest.cc

+ 13 - 3
src/bin/auth/query.cc

@@ -118,7 +118,8 @@ Query::getAuthAdditional(const Zone& zone) const {
                 zone.getOrigin().toText());
                 zone.getOrigin().toText());
     } else {
     } else {
         response_.addRRset(Message::SECTION_AUTHORITY,
         response_.addRRset(Message::SECTION_AUTHORITY,
-                boost::const_pointer_cast<RRset>(ns_result.rrset));
+            boost::const_pointer_cast<RRset>(ns_result.rrset));
+        // Handle additional for authority section
         getAdditional(zone, *ns_result.rrset);
         getAdditional(zone, *ns_result.rrset);
     }
     }
 }
 }
@@ -151,14 +152,23 @@ Query::process() const {
                 response_.setRcode(Rcode::NOERROR());
                 response_.setRcode(Rcode::NOERROR());
                 response_.addRRset(Message::SECTION_ANSWER,
                 response_.addRRset(Message::SECTION_ANSWER,
                     boost::const_pointer_cast<RRset>(db_result.rrset));
                     boost::const_pointer_cast<RRset>(db_result.rrset));
-                getAuthAdditional(*result.zone);
+                // Handle additional for answer section
                 getAdditional(*result.zone, *db_result.rrset);
                 getAdditional(*result.zone, *db_result.rrset);
+                // If apex NS records haven't been provided in the answer
+                // section, insert apex NS records into the authority section
+                // and AAAA/A RRS of each of the NS RDATA into the additional
+                // section.
+                if (qname_ != result.zone->getOrigin() ||
+                    (qtype_ != RRType::NS() && qtype_ != RRType::ANY()))
+                {
+                    getAuthAdditional(*result.zone);
+                }
                 break;
                 break;
             case Zone::DELEGATION:
             case Zone::DELEGATION:
                 response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
                 response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
                 response_.setRcode(Rcode::NOERROR());
                 response_.setRcode(Rcode::NOERROR());
                 response_.addRRset(Message::SECTION_AUTHORITY,
                 response_.addRRset(Message::SECTION_AUTHORITY,
-                            boost::const_pointer_cast<RRset>(db_result.rrset));
+                    boost::const_pointer_cast<RRset>(db_result.rrset));
                 getAdditional(*result.zone, *db_result.rrset);
                 getAdditional(*result.zone, *db_result.rrset);
                 break;
                 break;
             case Zone::NXDOMAIN:
             case Zone::NXDOMAIN:

+ 28 - 2
src/bin/auth/tests/query_unittest.cc

@@ -255,6 +255,32 @@ TEST_F(QueryTest, exactAddrMatch) {
                                   RRClass::IN(), RRType::A()));
                                   RRClass::IN(), RRType::A()));
 }
 }
 
 
+TEST_F(QueryTest, apexNSMatch) {
+    // find match rrset, omit authority data which has already been provided
+    // in the answer section from the authority section.
+    memory_datasrc.addZone(ZonePtr(new MockZone()));
+    const Name apex_name(Name("example.com"));
+    Query apex_ns_query(memory_datasrc, apex_name, RRType::NS(), response);
+    EXPECT_NO_THROW(apex_ns_query.process());
+    EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
+    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
+                                  Name("example.com"), RRClass::IN(),
+                                  RRType::NS()));
+    EXPECT_FALSE(response.hasRRset(Message::SECTION_AUTHORITY,
+                                  Name("example.com"), RRClass::IN(),
+                                  RRType::NS()));
+    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
+                                  Name("glue.ns.example.com"),
+                                  RRClass::IN(), RRType::A()));
+    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
+                                  Name("glue.ns.example.com"),
+                                  RRClass::IN(), RRType::AAAA()));
+    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
+                                  Name("noglue.example.com"),
+                                  RRClass::IN(), RRType::A()));
+}
+
 TEST_F(QueryTest, exactAnyMatch) {
 TEST_F(QueryTest, exactAnyMatch) {
     // find match rrset, omit additional data which has already been provided
     // find match rrset, omit additional data which has already been provided
     // in the answer section from the additional.
     // in the answer section from the additional.
@@ -281,11 +307,11 @@ TEST_F(QueryTest, exactAnyMatch) {
                                   RRClass::IN(), RRType::A()));
                                   RRClass::IN(), RRType::A()));
 }
 }
 
 
-// This tests that when we need to look up Zone's apex NS records for 
+// This tests that when we need to look up Zone's apex NS records for
 // authoritative answer, and there is no apex NS records. It should
 // authoritative answer, and there is no apex NS records. It should
 // throw in that case.
 // throw in that case.
 TEST_F(QueryTest, noApexNS) {
 TEST_F(QueryTest, noApexNS) {
-    // Add a zone without apex NS records 
+    // Add a zone without apex NS records
     memory_datasrc.addZone(ZonePtr(new MockZone(true, false)));
     memory_datasrc.addZone(ZonePtr(new MockZone(true, false)));
     const Name noglue_name(Name("noglue.example.com"));
     const Name noglue_name(Name("noglue.example.com"));
     Query noglue_query(memory_datasrc, noglue_name, qtype, response);
     Query noglue_query(memory_datasrc, noglue_name, qtype, response);