Browse Source

omit authority data which has already been provided in the answer section from the authority section.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac475@4164 e5f2f494-b856-4b98-b285-d166d9295462
Jerry 14 years ago
parent
commit
96e33bafc8
2 changed files with 42 additions and 5 deletions
  1. 14 3
      src/bin/auth/query.cc
  2. 28 2
      src/bin/auth/tests/query_unittest.cc

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

@@ -106,7 +106,8 @@ Query::getAuthAdditional(const Zone& zone) const {
                 zone.getOrigin().toText());
     } else {
         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);
     }
 }
@@ -139,13 +140,23 @@ Query::process() const {
                 response_.setRcode(Rcode::NOERROR());
                 response_.addRRset(Message::SECTION_ANSWER,
                     boost::const_pointer_cast<RRset>(db_result.rrset));
-                getAuthAdditional(*result.zone);
+                // Handle additional for answer section
+                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;
             case Zone::DELEGATION:
                 response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
                 response_.setRcode(Rcode::NOERROR());
                 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);
                 break;
             case Zone::NXDOMAIN:

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

@@ -228,6 +228,32 @@ TEST_F(QueryTest, exactAddrMatch) {
                                   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) {
     // find match rrset, omit additional data which has already been provided
     // in the answer section from the additional.
@@ -254,11 +280,11 @@ TEST_F(QueryTest, exactAnyMatch) {
                                   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
 // throw in that case.
 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)));
     const Name noglue_name(Name("noglue.example.com"));
     Query noglue_query(memory_datasrc, noglue_name, qtype, response);