Browse Source

[trac910] supported TSIG+TC case, first step: if TC is set even before
adding the TSIG, clear everything.

JINMEI Tatuya 14 years ago
parent
commit
d7d6079727

+ 15 - 0
src/lib/dns/message.cc

@@ -284,6 +284,21 @@ MessageImpl::toWire(AbstractMessageRenderer& renderer, TSIGContext* tsig_ctx) {
         }
         }
     }
     }
 
 
+    // If we're adding a TSIG to a truncated message, clear all RRsets
+    // from the message except for the question before adding the TSIG.
+    // If even the question doesn't fit, don't include any question (TBD).
+    if (tsig_ctx != NULL && renderer.isTruncated()) {
+        renderer.clear();
+        renderer.skip(HEADERLEN);
+        qdcount =
+            for_each(questions_.begin(), questions_.end(),
+                     RenderSection<QuestionPtr>(renderer,
+                                                false)).getTotalCount();
+        ancount = 0;
+        nscount = 0;
+        arcount = 0;
+    }
+
     // Adjust the counter buffer.
     // Adjust the counter buffer.
     // XXX: these may not be equal to the number of corresponding entries
     // XXX: these may not be equal to the number of corresponding entries
     // in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
     // in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR

+ 50 - 8
src/lib/dns/tests/message_unittest.cc

@@ -62,7 +62,6 @@ using namespace isc::dns::rdata;
 //
 //
 
 
 const uint16_t Message::DEFAULT_MAX_UDPSIZE;
 const uint16_t Message::DEFAULT_MAX_UDPSIZE;
-const Name test_name("test.example.com");
 
 
 namespace isc {
 namespace isc {
 namespace util {
 namespace util {
@@ -79,7 +78,8 @@ const uint16_t TSIGContext::DEFAULT_FUDGE;
 namespace {
 namespace {
 class MessageTest : public ::testing::Test {
 class MessageTest : public ::testing::Test {
 protected:
 protected:
-    MessageTest() : obuffer(0), renderer(obuffer),
+    MessageTest() : test_name("test.example.com"), obuffer(0),
+                    renderer(obuffer),
                     message_parse(Message::PARSE),
                     message_parse(Message::PARSE),
                     message_render(Message::RENDER),
                     message_render(Message::RENDER),
                     bogus_section(static_cast<Message::Section>(
                     bogus_section(static_cast<Message::Section>(
@@ -103,8 +103,9 @@ protected:
                                              "FAKEFAKEFAKEFAKE"));
                                              "FAKEFAKEFAKEFAKE"));
         rrset_aaaa->addRRsig(rrset_rrsig);
         rrset_aaaa->addRRsig(rrset_rrsig);
     }
     }
-    
+
     static Question factoryFromFile(const char* datafile);
     static Question factoryFromFile(const char* datafile);
+    const Name test_name;
     OutputBuffer obuffer;
     OutputBuffer obuffer;
     MessageRenderer renderer;
     MessageRenderer renderer;
     Message message_parse;
     Message message_parse;
@@ -114,17 +115,18 @@ protected:
     RRsetPtr rrset_aaaa;        // AAAA RRset with one RDATA with RRSIG
     RRsetPtr rrset_aaaa;        // AAAA RRset with one RDATA with RRSIG
     RRsetPtr rrset_rrsig;       // RRSIG for the AAAA RRset
     RRsetPtr rrset_rrsig;       // RRSIG for the AAAA RRset
     TSIGContext tsig_ctx;
     TSIGContext tsig_ctx;
+    vector<unsigned char> received_data;
     vector<unsigned char> expected_data;
     vector<unsigned char> expected_data;
 
 
-    static void factoryFromFile(Message& message, const char* datafile);
+    void factoryFromFile(Message& message, const char* datafile);
 };
 };
 
 
 void
 void
 MessageTest::factoryFromFile(Message& message, const char* datafile) {
 MessageTest::factoryFromFile(Message& message, const char* datafile) {
-    std::vector<unsigned char> data;
-    UnitTestUtil::readWireData(datafile, data);
+    received_data.clear();
+    UnitTestUtil::readWireData(datafile, received_data);
 
 
-    InputBuffer buffer(&data[0], data.size());
+    InputBuffer buffer(&received_data[0], received_data.size());
     message.fromWire(buffer);
     message.fromWire(buffer);
 }
 }
 
 
@@ -624,7 +626,7 @@ commonTSIGToWireCheck(Message& message, MessageRenderer& renderer,
 {
 {
     message.setOpcode(Opcode::QUERY());
     message.setOpcode(Opcode::QUERY());
     message.setRcode(Rcode::NOERROR());
     message.setRcode(Rcode::NOERROR());
-    message.setHeaderFlag(Message::HEADERFLAG_RD, true);
+    message.setHeaderFlag(Message::HEADERFLAG_RD);
     message.addQuestion(Question(Name("www.example.com"), RRClass::IN(),
     message.addQuestion(Question(Name("www.example.com"), RRClass::IN(),
                                  RRType::A()));
                                  RRType::A()));
 
 
@@ -670,6 +672,46 @@ TEST_F(MessageTest, toWireWithEDNSAndTSIG) {
     }
     }
 }
 }
 
 
+const char* const long_txt1 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde";
+const char* const long_txt2 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456";
+
+// Example output generated by
+// "dig -y www.example.com:SFuWd/q99SzF8Yzd1QbB9g== www.example.com txt
+// QID: 0x22c2
+// Time Signed: 0x00004e179212
+// Query MAC:    8214b04634e32323d651ac60b08e6388
+// Response MAC: 88adc3811d1d6bec7c684438906fc694
+TEST_F(MessageTest, toWireTSIGTruncation) {
+    isc::util::detail::gettimeFunction = testGetTime<0x4e179212>;
+
+    factoryFromFile(message_parse, "message_fromWire17.wire");
+    EXPECT_EQ(TSIGError::NOERROR(),
+              tsig_ctx.verify(message_parse.getTSIGRecord(),
+                              &received_data[0], received_data.size()));
+
+    // Note: the following should be merged to commonTSIGToWireCheck:
+    message_render.setQid(0x22c2);
+    message_render.setOpcode(Opcode::QUERY());
+    message_render.setRcode(Rcode::NOERROR());
+    message_render.setHeaderFlag(Message::HEADERFLAG_QR);
+    message_render.setHeaderFlag(Message::HEADERFLAG_RD);
+    message_render.setHeaderFlag(Message::HEADERFLAG_AA);
+    message_render.addQuestion(Question(Name("www.example.com"),
+                                        RRClass::IN(), RRType::TXT()));
+    RRsetPtr rrset(new RRset(Name("www.example.com"), RRClass::IN(),
+                             RRType::TXT(), RRTTL(86400)));
+    rrset->addRdata(generic::TXT(long_txt1));
+    rrset->addRdata(generic::TXT(long_txt2));
+    message_render.addRRset(Message::SECTION_ANSWER, rrset);
+    message_render.toWire(renderer, tsig_ctx);
+
+    vector<unsigned char> expected_data;
+    UnitTestUtil::readWireData("message_toWire4.wire", expected_data);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+                        renderer.getLength(),
+                        &expected_data[0], expected_data.size());
+}
+
 TEST_F(MessageTest, toWireWithoutOpcode) {
 TEST_F(MessageTest, toWireWithoutOpcode) {
     message_render.setRcode(Rcode::NOERROR());
     message_render.setRcode(Rcode::NOERROR());
     EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
     EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);

+ 4 - 1
src/lib/dns/tests/testdata/Makefile.am

@@ -5,8 +5,9 @@ BUILT_SOURCES += edns_toWire4.wire
 BUILT_SOURCES += message_fromWire10.wire message_fromWire11.wire
 BUILT_SOURCES += message_fromWire10.wire message_fromWire11.wire
 BUILT_SOURCES += message_fromWire12.wire message_fromWire13.wire
 BUILT_SOURCES += message_fromWire12.wire message_fromWire13.wire
 BUILT_SOURCES += message_fromWire14.wire message_fromWire15.wire
 BUILT_SOURCES += message_fromWire14.wire message_fromWire15.wire
-BUILT_SOURCES += message_fromWire16.wire
+BUILT_SOURCES += message_fromWire16.wire message_fromWire17.wire
 BUILT_SOURCES += message_toWire2.wire message_toWire3.wire
 BUILT_SOURCES += message_toWire2.wire message_toWire3.wire
+BUILT_SOURCES += message_toWire4.wire
 BUILT_SOURCES += message_toText1.wire message_toText2.wire
 BUILT_SOURCES += message_toText1.wire message_toText2.wire
 BUILT_SOURCES += message_toText3.wire
 BUILT_SOURCES += message_toText3.wire
 BUILT_SOURCES += name_toWire5.wire name_toWire6.wire
 BUILT_SOURCES += name_toWire5.wire name_toWire6.wire
@@ -59,7 +60,9 @@ EXTRA_DIST += message_fromWire9 message_fromWire10.spec
 EXTRA_DIST += message_fromWire11.spec message_fromWire12.spec
 EXTRA_DIST += message_fromWire11.spec message_fromWire12.spec
 EXTRA_DIST += message_fromWire13.spec message_fromWire14.spec
 EXTRA_DIST += message_fromWire13.spec message_fromWire14.spec
 EXTRA_DIST += message_fromWire15.spec message_fromWire16.spec
 EXTRA_DIST += message_fromWire15.spec message_fromWire16.spec
+EXTRA_DIST += message_fromWire17.spec
 EXTRA_DIST += message_toWire1 message_toWire2.spec message_toWire3.spec
 EXTRA_DIST += message_toWire1 message_toWire2.spec message_toWire3.spec
+EXTRA_DIST += message_toWire4.wire
 EXTRA_DIST += message_toText1.txt message_toText1.spec
 EXTRA_DIST += message_toText1.txt message_toText1.spec
 EXTRA_DIST += message_toText2.txt message_toText2.spec
 EXTRA_DIST += message_toText2.txt message_toText2.spec
 EXTRA_DIST += message_toText3.txt message_toText3.spec
 EXTRA_DIST += message_toText3.txt message_toText3.spec