message_unittest.cc 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <fstream>
  15. #include <boost/scoped_ptr.hpp>
  16. #include <exceptions/exceptions.h>
  17. #include <util/buffer.h>
  18. #include <util/time_utilities.h>
  19. #include <util/unittests/testdata.h>
  20. #include <util/unittests/textdata.h>
  21. #include <dns/edns.h>
  22. #include <dns/exceptions.h>
  23. #include <dns/message.h>
  24. #include <dns/messagerenderer.h>
  25. #include <dns/question.h>
  26. #include <dns/opcode.h>
  27. #include <dns/rcode.h>
  28. #include <dns/rdataclass.h>
  29. #include <dns/rrclass.h>
  30. #include <dns/rrttl.h>
  31. #include <dns/rrtype.h>
  32. #include <dns/tsig.h>
  33. #include <dns/tsigkey.h>
  34. #include <gtest/gtest.h>
  35. #include <dns/tests/unittest_util.h>
  36. using isc::UnitTestUtil;
  37. using namespace std;
  38. using namespace isc;
  39. using namespace isc::dns;
  40. using namespace isc::util;
  41. using namespace isc::dns::rdata;
  42. //
  43. // Note: we need more tests, including:
  44. // parsing malformed headers
  45. // more complete tests about parsing/rendering header flags, opcode, rcode, etc.
  46. // tests for adding RRsets
  47. // tests for RRset/Question iterators
  48. // But, we'll ship with the current set of tests for now, partly because many
  49. // of the above are covered as part of other tests, and partly due to time
  50. // limitation. We also expect to revisit the fundamental design of the Message
  51. // class, at which point we'll also revise the tests including more cases.
  52. //
  53. const uint16_t Message::DEFAULT_MAX_UDPSIZE;
  54. namespace isc {
  55. namespace util {
  56. namespace detail {
  57. extern int64_t (*gettimeFunction)();
  58. }
  59. }
  60. }
  61. // XXX: this is defined as class static constants, but some compilers
  62. // seemingly cannot find the symbol when used in the EXPECT_xxx macros.
  63. const uint16_t TSIGContext::DEFAULT_FUDGE;
  64. namespace {
  65. class MessageTest : public ::testing::Test {
  66. protected:
  67. MessageTest() : test_name("test.example.com"), obuffer(0),
  68. renderer(obuffer),
  69. message_parse(Message::PARSE),
  70. message_render(Message::RENDER),
  71. bogus_section(static_cast<Message::Section>(
  72. Message::SECTION_ADDITIONAL + 1)),
  73. tsig_ctx(TSIGKey("www.example.com:"
  74. "SFuWd/q99SzF8Yzd1QbB9g=="))
  75. {
  76. rrset_a = RRsetPtr(new RRset(test_name, RRClass::IN(),
  77. RRType::A(), RRTTL(3600)));
  78. rrset_a->addRdata(in::A("192.0.2.1"));
  79. rrset_a->addRdata(in::A("192.0.2.2"));
  80. rrset_aaaa = RRsetPtr(new RRset(test_name, RRClass::IN(),
  81. RRType::AAAA(), RRTTL(3600)));
  82. rrset_aaaa->addRdata(in::AAAA("2001:db8::1234"));
  83. rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
  84. RRType::RRSIG(), RRTTL(3600)));
  85. rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
  86. "20100220084538 1 example.com "
  87. "FAKEFAKEFAKEFAKE"));
  88. rrset_aaaa->addRRsig(rrset_rrsig);
  89. }
  90. static Question factoryFromFile(const char* datafile);
  91. const Name test_name;
  92. OutputBuffer obuffer;
  93. MessageRenderer renderer;
  94. Message message_parse;
  95. Message message_render;
  96. const Message::Section bogus_section;
  97. RRsetPtr rrset_a; // A RRset with two RDATAs
  98. RRsetPtr rrset_aaaa; // AAAA RRset with one RDATA with RRSIG
  99. RRsetPtr rrset_rrsig; // RRSIG for the AAAA RRset
  100. TSIGContext tsig_ctx;
  101. vector<unsigned char> received_data;
  102. vector<unsigned char> expected_data;
  103. void factoryFromFile(Message& message, const char* datafile);
  104. };
  105. void
  106. MessageTest::factoryFromFile(Message& message, const char* datafile) {
  107. received_data.clear();
  108. UnitTestUtil::readWireData(datafile, received_data);
  109. InputBuffer buffer(&received_data[0], received_data.size());
  110. message.fromWire(buffer);
  111. }
  112. TEST_F(MessageTest, headerFlag) {
  113. // by default no flag is set
  114. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_QR));
  115. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
  116. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_TC));
  117. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RD));
  118. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RA));
  119. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AD));
  120. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_CD));
  121. // set operation: by default it will be on
  122. message_render.setHeaderFlag(Message::HEADERFLAG_QR);
  123. EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_QR));
  124. // it can be set to on explicitly, too
  125. message_render.setHeaderFlag(Message::HEADERFLAG_AA, true);
  126. EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
  127. // the bit can also be cleared
  128. message_render.setHeaderFlag(Message::HEADERFLAG_AA, false);
  129. EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA));
  130. // Invalid flag values
  131. EXPECT_THROW(message_render.setHeaderFlag(
  132. static_cast<Message::HeaderFlag>(0)), InvalidParameter);
  133. EXPECT_THROW(message_render.setHeaderFlag(
  134. static_cast<Message::HeaderFlag>(0x7000)),
  135. InvalidParameter);
  136. EXPECT_THROW(message_render.setHeaderFlag(
  137. static_cast<Message::HeaderFlag>(0x0800)),
  138. InvalidParameter);
  139. EXPECT_THROW(message_render.setHeaderFlag(
  140. static_cast<Message::HeaderFlag>(0x0040)),
  141. InvalidParameter);
  142. EXPECT_THROW(message_render.setHeaderFlag(
  143. static_cast<Message::HeaderFlag>(0x10000)),
  144. InvalidParameter);
  145. EXPECT_THROW(message_render.setHeaderFlag(
  146. static_cast<Message::HeaderFlag>(0x80000000)),
  147. InvalidParameter);
  148. // set operation isn't allowed in the parse mode.
  149. EXPECT_THROW(message_parse.setHeaderFlag(Message::HEADERFLAG_QR),
  150. InvalidMessageOperation);
  151. }
  152. TEST_F(MessageTest, getEDNS) {
  153. EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set
  154. factoryFromFile(message_parse, "message_fromWire10.wire");
  155. EXPECT_TRUE(message_parse.getEDNS());
  156. EXPECT_EQ(0, message_parse.getEDNS()->getVersion());
  157. EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize());
  158. EXPECT_TRUE(message_parse.getEDNS()->getDNSSECAwareness());
  159. }
  160. TEST_F(MessageTest, setEDNS) {
  161. // setEDNS() isn't allowed in the parse mode
  162. EXPECT_THROW(message_parse.setEDNS(EDNSPtr(new EDNS())),
  163. InvalidMessageOperation);
  164. EDNSPtr edns = EDNSPtr(new EDNS());
  165. message_render.setEDNS(edns);
  166. EXPECT_EQ(edns, message_render.getEDNS());
  167. }
  168. TEST_F(MessageTest, fromWireWithTSIG) {
  169. // Initially there should be no TSIG
  170. EXPECT_EQ(static_cast<void*>(NULL), message_parse.getTSIGRecord());
  171. // getTSIGRecord() is only valid in the parse mode.
  172. EXPECT_THROW(message_render.getTSIGRecord(), InvalidMessageOperation);
  173. factoryFromFile(message_parse, "message_toWire2.wire");
  174. const char expected_mac[] = {
  175. 0x22, 0x70, 0x26, 0xad, 0x29, 0x7b, 0xee, 0xe7,
  176. 0x21, 0xce, 0x6c, 0x6f, 0xff, 0x1e, 0x9e, 0xf3
  177. };
  178. const TSIGRecord* tsig_rr = message_parse.getTSIGRecord();
  179. ASSERT_NE(static_cast<void*>(NULL), tsig_rr);
  180. EXPECT_EQ(Name("www.example.com"), tsig_rr->getName());
  181. EXPECT_EQ(85, tsig_rr->getLength()); // see TSIGRecordTest.getLength
  182. EXPECT_EQ(TSIGKey::HMACMD5_NAME(), tsig_rr->getRdata().getAlgorithm());
  183. EXPECT_EQ(0x4da8877a, tsig_rr->getRdata().getTimeSigned());
  184. EXPECT_EQ(TSIGContext::DEFAULT_FUDGE, tsig_rr->getRdata().getFudge());
  185. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  186. tsig_rr->getRdata().getMAC(),
  187. tsig_rr->getRdata().getMACSize(),
  188. expected_mac, sizeof(expected_mac));
  189. EXPECT_EQ(0, tsig_rr->getRdata().getError());
  190. EXPECT_EQ(0, tsig_rr->getRdata().getOtherLen());
  191. EXPECT_EQ(static_cast<void*>(NULL), tsig_rr->getRdata().getOtherData());
  192. // If we clear the message for reuse, the recorded TSIG will be cleared.
  193. message_parse.clear(Message::PARSE);
  194. EXPECT_EQ(static_cast<void*>(NULL), message_parse.getTSIGRecord());
  195. }
  196. TEST_F(MessageTest, fromWireWithTSIGCompressed) {
  197. // Mostly same as fromWireWithTSIG, but the TSIG owner name is compressed.
  198. factoryFromFile(message_parse, "message_fromWire12.wire");
  199. const TSIGRecord* tsig_rr = message_parse.getTSIGRecord();
  200. ASSERT_NE(static_cast<void*>(NULL), tsig_rr);
  201. EXPECT_EQ(Name("www.example.com"), tsig_rr->getName());
  202. // len(www.example.com) = 17, but when fully compressed, the length is
  203. // 2 bytes. So the length of the record should be 15 bytes shorter.
  204. EXPECT_EQ(70, tsig_rr->getLength());
  205. }
  206. TEST_F(MessageTest, fromWireWithBadTSIG) {
  207. // Multiple TSIG RRs
  208. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire13.wire"),
  209. DNSMessageFORMERR);
  210. message_parse.clear(Message::PARSE);
  211. // TSIG in the answer section (must be in additional)
  212. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire14.wire"),
  213. DNSMessageFORMERR);
  214. message_parse.clear(Message::PARSE);
  215. // TSIG is not the last record.
  216. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire15.wire"),
  217. DNSMessageFORMERR);
  218. message_parse.clear(Message::PARSE);
  219. // Unexpected RR Class (this will fail in constructing TSIGRecord)
  220. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire16.wire"),
  221. DNSMessageFORMERR);
  222. }
  223. TEST_F(MessageTest, getRRCount) {
  224. // by default all counters should be 0
  225. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_QUESTION));
  226. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER));
  227. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
  228. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
  229. message_render.addQuestion(Question(Name("test.example.com"),
  230. RRClass::IN(), RRType::A()));
  231. EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
  232. // rrset_a contains two RRs
  233. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  234. EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
  235. // parse a message containing a Question and EDNS OPT RR.
  236. // OPT shouldn't be counted as normal RR, so result of getRRCount
  237. // shouldn't change.
  238. factoryFromFile(message_parse, "message_fromWire11.wire");
  239. EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
  240. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
  241. // out-of-band section ID
  242. EXPECT_THROW(message_parse.getRRCount(bogus_section), OutOfRange);
  243. }
  244. TEST_F(MessageTest, addRRset) {
  245. // default case
  246. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  247. EXPECT_EQ(rrset_a,
  248. *message_render.beginSection(Message::SECTION_ANSWER));
  249. EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
  250. // signed RRset, default case
  251. message_render.clear(Message::RENDER);
  252. message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa);
  253. EXPECT_EQ(rrset_aaaa,
  254. *message_render.beginSection(Message::SECTION_ANSWER));
  255. EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_ANSWER));
  256. // signed RRset, add with the RRSIG. getRRCount() should return 2
  257. message_render.clear(Message::RENDER);
  258. message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa, true);
  259. EXPECT_EQ(rrset_aaaa,
  260. *message_render.beginSection(Message::SECTION_ANSWER));
  261. EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
  262. // signed RRset, add explicitly without RRSIG.
  263. message_render.clear(Message::RENDER);
  264. message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa, false);
  265. EXPECT_EQ(rrset_aaaa,
  266. *message_render.beginSection(Message::SECTION_ANSWER));
  267. EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_ANSWER));
  268. }
  269. TEST_F(MessageTest, badAddRRset) {
  270. // addRRset() isn't allowed in the parse mode.
  271. EXPECT_THROW(message_parse.addRRset(Message::SECTION_ANSWER,
  272. rrset_a), InvalidMessageOperation);
  273. // out-of-band section ID
  274. EXPECT_THROW(message_render.addRRset(bogus_section, rrset_a), OutOfRange);
  275. }
  276. TEST_F(MessageTest, hasRRset) {
  277. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  278. EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  279. RRClass::IN(), RRType::A()));
  280. // section doesn't match
  281. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  282. RRClass::IN(), RRType::A()));
  283. // name doesn't match
  284. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER,
  285. Name("nomatch.example"),
  286. RRClass::IN(), RRType::A()));
  287. // RR class doesn't match
  288. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  289. RRClass::CH(), RRType::A()));
  290. // RR type doesn't match
  291. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  292. RRClass::IN(), RRType::AAAA()));
  293. // out-of-band section ID
  294. EXPECT_THROW(message_render.hasRRset(bogus_section, test_name,
  295. RRClass::IN(), RRType::A()),
  296. OutOfRange);
  297. // Repeat the checks having created an RRset of the appropriate type.
  298. RRsetPtr rrs1(new RRset(test_name, RRClass::IN(), RRType::A(), RRTTL(60)));
  299. EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, rrs1));
  300. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, rrs1));
  301. RRsetPtr rrs2(new RRset(Name("nomatch.example"), RRClass::IN(), RRType::A(),
  302. RRTTL(5)));
  303. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs2));
  304. RRsetPtr rrs3(new RRset(test_name, RRClass::CH(), RRType::A(), RRTTL(60)));
  305. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs3));
  306. RRsetPtr rrs4(new RRset(test_name, RRClass::IN(), RRType::AAAA(), RRTTL(5)));
  307. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs4));
  308. RRsetPtr rrs5(new RRset(test_name, RRClass::IN(), RRType::AAAA(), RRTTL(5)));
  309. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs4));
  310. EXPECT_THROW(message_render.hasRRset(bogus_section, rrs1), OutOfRange);
  311. }
  312. TEST_F(MessageTest, removeRRset) {
  313. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  314. message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa);
  315. EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  316. RRClass::IN(), RRType::A()));
  317. EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  318. RRClass::IN(), RRType::AAAA()));
  319. EXPECT_EQ(3, message_render.getRRCount(Message::SECTION_ANSWER));
  320. // Locate the AAAA RRset and remove it; this has one RR in it.
  321. RRsetIterator i = message_render.beginSection(Message::SECTION_ANSWER);
  322. if ((*i)->getType() == RRType::A()) {
  323. ++i;
  324. }
  325. EXPECT_EQ(RRType::AAAA(), (*i)->getType());
  326. message_render.removeRRset(Message::SECTION_ANSWER, i);
  327. EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  328. RRClass::IN(), RRType::A()));
  329. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  330. RRClass::IN(), RRType::AAAA()));
  331. EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
  332. }
  333. TEST_F(MessageTest, clearQuestionSection) {
  334. QuestionPtr q(new Question(Name("www.example.com"), RRClass::IN(),
  335. RRType::A()));
  336. message_render.addQuestion(q);
  337. ASSERT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
  338. message_render.clearSection(Message::SECTION_QUESTION);
  339. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_QUESTION));
  340. }
  341. TEST_F(MessageTest, clearAnswerSection) {
  342. // Add two RRsets, check they are present, clear the section,
  343. // check if they are gone.
  344. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  345. message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa);
  346. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  347. RRClass::IN(), RRType::A()));
  348. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  349. RRClass::IN(), RRType::AAAA()));
  350. ASSERT_EQ(3, message_render.getRRCount(Message::SECTION_ANSWER));
  351. message_render.clearSection(Message::SECTION_ANSWER);
  352. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  353. RRClass::IN(), RRType::A()));
  354. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name,
  355. RRClass::IN(), RRType::AAAA()));
  356. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER));
  357. }
  358. TEST_F(MessageTest, clearAuthoritySection) {
  359. // Add two RRsets, check they are present, clear the section,
  360. // check if they are gone.
  361. message_render.addRRset(Message::SECTION_AUTHORITY, rrset_a);
  362. message_render.addRRset(Message::SECTION_AUTHORITY, rrset_aaaa);
  363. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name,
  364. RRClass::IN(), RRType::A()));
  365. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name,
  366. RRClass::IN(), RRType::AAAA()));
  367. ASSERT_EQ(3, message_render.getRRCount(Message::SECTION_AUTHORITY));
  368. message_render.clearSection(Message::SECTION_AUTHORITY);
  369. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name,
  370. RRClass::IN(), RRType::A()));
  371. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name,
  372. RRClass::IN(), RRType::AAAA()));
  373. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
  374. }
  375. TEST_F(MessageTest, clearAdditionalSection) {
  376. // Add two RRsets, check they are present, clear the section,
  377. // check if they are gone.
  378. message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_a);
  379. message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_aaaa);
  380. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  381. RRClass::IN(), RRType::A()));
  382. ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  383. RRClass::IN(), RRType::AAAA()));
  384. ASSERT_EQ(3, message_render.getRRCount(Message::SECTION_ADDITIONAL));
  385. message_render.clearSection(Message::SECTION_ADDITIONAL);
  386. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  387. RRClass::IN(), RRType::A()));
  388. EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  389. RRClass::IN(), RRType::AAAA()));
  390. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
  391. }
  392. TEST_F(MessageTest, badBeginSection) {
  393. // valid cases are tested via other tests
  394. EXPECT_THROW(message_render.beginSection(Message::SECTION_QUESTION),
  395. InvalidMessageSection);
  396. EXPECT_THROW(message_render.beginSection(bogus_section), OutOfRange);
  397. }
  398. TEST_F(MessageTest, badEndSection) {
  399. // valid cases are tested via other tests
  400. EXPECT_THROW(message_render.endSection(Message::SECTION_QUESTION),
  401. InvalidMessageSection);
  402. EXPECT_THROW(message_render.endSection(bogus_section), OutOfRange);
  403. }
  404. TEST_F(MessageTest, appendSection) {
  405. Message target(Message::RENDER);
  406. // Section check
  407. EXPECT_THROW(target.appendSection(bogus_section, message_render),
  408. OutOfRange);
  409. // Make sure nothing is copied if there is nothing to copy
  410. target.appendSection(Message::SECTION_QUESTION, message_render);
  411. EXPECT_EQ(0, target.getRRCount(Message::SECTION_QUESTION));
  412. target.appendSection(Message::SECTION_ANSWER, message_render);
  413. EXPECT_EQ(0, target.getRRCount(Message::SECTION_ANSWER));
  414. target.appendSection(Message::SECTION_AUTHORITY, message_render);
  415. EXPECT_EQ(0, target.getRRCount(Message::SECTION_AUTHORITY));
  416. target.appendSection(Message::SECTION_ADDITIONAL, message_render);
  417. EXPECT_EQ(0, target.getRRCount(Message::SECTION_ADDITIONAL));
  418. // Now add some data, copy again, and see if it got added
  419. message_render.addQuestion(Question(Name("test.example.com"),
  420. RRClass::IN(), RRType::A()));
  421. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  422. message_render.addRRset(Message::SECTION_AUTHORITY, rrset_a);
  423. message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_a);
  424. message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_aaaa);
  425. target.appendSection(Message::SECTION_QUESTION, message_render);
  426. EXPECT_EQ(1, target.getRRCount(Message::SECTION_QUESTION));
  427. target.appendSection(Message::SECTION_ANSWER, message_render);
  428. EXPECT_EQ(2, target.getRRCount(Message::SECTION_ANSWER));
  429. EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name,
  430. RRClass::IN(), RRType::A()));
  431. target.appendSection(Message::SECTION_AUTHORITY, message_render);
  432. EXPECT_EQ(2, target.getRRCount(Message::SECTION_AUTHORITY));
  433. EXPECT_TRUE(target.hasRRset(Message::SECTION_AUTHORITY, test_name,
  434. RRClass::IN(), RRType::A()));
  435. target.appendSection(Message::SECTION_ADDITIONAL, message_render);
  436. EXPECT_EQ(3, target.getRRCount(Message::SECTION_ADDITIONAL));
  437. EXPECT_TRUE(target.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  438. RRClass::IN(), RRType::A()));
  439. EXPECT_TRUE(target.hasRRset(Message::SECTION_ADDITIONAL, test_name,
  440. RRClass::IN(), RRType::AAAA()));
  441. // One more test, test to see if the section gets added, not replaced
  442. Message source2(Message::RENDER);
  443. source2.addRRset(Message::SECTION_ANSWER, rrset_aaaa);
  444. target.appendSection(Message::SECTION_ANSWER, source2);
  445. EXPECT_EQ(3, target.getRRCount(Message::SECTION_ANSWER));
  446. EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name,
  447. RRClass::IN(), RRType::A()));
  448. EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name,
  449. RRClass::IN(), RRType::AAAA()));
  450. }
  451. TEST_F(MessageTest, parseHeader) {
  452. received_data.clear();
  453. UnitTestUtil::readWireData("message_fromWire1", received_data);
  454. // parseHeader() isn't allowed in the render mode.
  455. InputBuffer buffer(&received_data[0], received_data.size());
  456. EXPECT_THROW(message_render.parseHeader(buffer), InvalidMessageOperation);
  457. message_parse.parseHeader(buffer);
  458. EXPECT_EQ(0x1035, message_parse.getQid());
  459. EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
  460. EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
  461. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_QR));
  462. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_AA));
  463. EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_TC));
  464. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_RD));
  465. EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_RA));
  466. EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_AD));
  467. EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_CD));
  468. EXPECT_EQ(1, message_parse.getRRCount(Message::SECTION_QUESTION));
  469. EXPECT_EQ(2, message_parse.getRRCount(Message::SECTION_ANSWER));
  470. EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_AUTHORITY));
  471. EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_ADDITIONAL));
  472. // Only the header part should have been examined.
  473. EXPECT_EQ(12, buffer.getPosition()); // 12 = size of the header section
  474. EXPECT_TRUE(message_parse.beginQuestion() == message_parse.endQuestion());
  475. EXPECT_TRUE(message_parse.beginSection(Message::SECTION_ANSWER) ==
  476. message_parse.endSection(Message::SECTION_ANSWER));
  477. EXPECT_TRUE(message_parse.beginSection(Message::SECTION_AUTHORITY) ==
  478. message_parse.endSection(Message::SECTION_AUTHORITY));
  479. EXPECT_TRUE(message_parse.beginSection(Message::SECTION_ADDITIONAL) ==
  480. message_parse.endSection(Message::SECTION_ADDITIONAL));
  481. }
  482. TEST_F(MessageTest, fromWire) {
  483. // fromWire() isn't allowed in the render mode.
  484. EXPECT_THROW(factoryFromFile(message_render, "message_fromWire1"),
  485. InvalidMessageOperation);
  486. factoryFromFile(message_parse, "message_fromWire1");
  487. EXPECT_EQ(0x1035, message_parse.getQid());
  488. EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
  489. EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
  490. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_QR));
  491. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_RD));
  492. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_AA));
  493. QuestionPtr q = *message_parse.beginQuestion();
  494. EXPECT_EQ(test_name, q->getName());
  495. EXPECT_EQ(RRType::A(), q->getType());
  496. EXPECT_EQ(RRClass::IN(), q->getClass());
  497. EXPECT_EQ(1, message_parse.getRRCount(Message::SECTION_QUESTION));
  498. EXPECT_EQ(2, message_parse.getRRCount(Message::SECTION_ANSWER));
  499. EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_AUTHORITY));
  500. EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_ADDITIONAL));
  501. RRsetPtr rrset = *message_parse.beginSection(Message::SECTION_ANSWER);
  502. EXPECT_EQ(test_name, rrset->getName());
  503. EXPECT_EQ(RRType::A(), rrset->getType());
  504. EXPECT_EQ(RRClass::IN(), rrset->getClass());
  505. // TTL should be 3600, even though that of the 2nd RR is 7200
  506. EXPECT_EQ(RRTTL(3600), rrset->getTTL());
  507. RdataIteratorPtr it = rrset->getRdataIterator();
  508. EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
  509. it->next();
  510. EXPECT_EQ("192.0.2.2", it->getCurrent().toText());
  511. it->next();
  512. EXPECT_TRUE(it->isLast());
  513. }
  514. TEST_F(MessageTest, EDNS0ExtRcode) {
  515. // Extended Rcode = BADVERS
  516. factoryFromFile(message_parse, "message_fromWire10.wire");
  517. EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
  518. // Maximum extended Rcode
  519. message_parse.clear(Message::PARSE);
  520. factoryFromFile(message_parse, "message_fromWire11.wire");
  521. EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
  522. }
  523. TEST_F(MessageTest, BadEDNS0) {
  524. // OPT RR in the answer section
  525. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire4"),
  526. DNSMessageFORMERR);
  527. // multiple OPT RRs (in the additional section)
  528. message_parse.clear(Message::PARSE);
  529. EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"),
  530. DNSMessageFORMERR);
  531. }
  532. TEST_F(MessageTest, toWire) {
  533. message_render.setQid(0x1035);
  534. message_render.setOpcode(Opcode::QUERY());
  535. message_render.setRcode(Rcode::NOERROR());
  536. message_render.setHeaderFlag(Message::HEADERFLAG_QR, true);
  537. message_render.setHeaderFlag(Message::HEADERFLAG_RD, true);
  538. message_render.setHeaderFlag(Message::HEADERFLAG_AA, true);
  539. message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
  540. RRType::A()));
  541. message_render.addRRset(Message::SECTION_ANSWER, rrset_a);
  542. EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
  543. EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER));
  544. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
  545. EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
  546. message_render.toWire(renderer);
  547. vector<unsigned char> data;
  548. UnitTestUtil::readWireData("message_toWire1", data);
  549. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
  550. obuffer.getLength(), &data[0], data.size());
  551. }
  552. TEST_F(MessageTest, toWireInParseMode) {
  553. // toWire() isn't allowed in the parse mode.
  554. EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);
  555. }
  556. // See dnssectime_unittest.cc
  557. template <int64_t NOW>
  558. int64_t
  559. testGetTime() {
  560. return (NOW);
  561. }
  562. // bit-wise constant flags to configure DNS header flags for test
  563. // messages.
  564. const unsigned int QR_FLAG = 0x1;
  565. const unsigned int AA_FLAG = 0x2;
  566. const unsigned int RD_FLAG = 0x4;
  567. void
  568. commonTSIGToWireCheck(Message& message, MessageRenderer& renderer,
  569. TSIGContext& tsig_ctx, const char* const expected_file,
  570. unsigned int message_flags = RD_FLAG,
  571. RRType qtype = RRType::A(),
  572. const vector<const char*>* answer_data = NULL)
  573. {
  574. message.setOpcode(Opcode::QUERY());
  575. message.setRcode(Rcode::NOERROR());
  576. if ((message_flags & QR_FLAG) != 0) {
  577. message.setHeaderFlag(Message::HEADERFLAG_QR);
  578. }
  579. if ((message_flags & AA_FLAG) != 0) {
  580. message.setHeaderFlag(Message::HEADERFLAG_AA);
  581. }
  582. if ((message_flags & RD_FLAG) != 0) {
  583. message.setHeaderFlag(Message::HEADERFLAG_RD);
  584. }
  585. message.addQuestion(Question(Name("www.example.com"), RRClass::IN(),
  586. qtype));
  587. if (answer_data != NULL) {
  588. RRsetPtr ans_rrset(new RRset(Name("www.example.com"), RRClass::IN(),
  589. qtype, RRTTL(86400)));
  590. for (vector<const char*>::const_iterator it = answer_data->begin();
  591. it != answer_data->end();
  592. ++it) {
  593. ans_rrset->addRdata(createRdata(qtype, RRClass::IN(), *it));
  594. }
  595. message.addRRset(Message::SECTION_ANSWER, ans_rrset);
  596. }
  597. message.toWire(renderer, tsig_ctx);
  598. vector<unsigned char> expected_data;
  599. UnitTestUtil::readWireData(expected_file, expected_data);
  600. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  601. renderer.getLength(),
  602. &expected_data[0], expected_data.size());
  603. }
  604. TEST_F(MessageTest, toWireWithTSIG) {
  605. // Rendering a message with TSIG. Various special cases specific to
  606. // TSIG are tested in the tsig tests. We only check the message contains
  607. // a TSIG at the end and the ARCOUNT of the header is updated.
  608. isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>;
  609. message_render.setQid(0x2d65);
  610. {
  611. SCOPED_TRACE("Message sign with TSIG");
  612. commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  613. "message_toWire2.wire");
  614. }
  615. }
  616. TEST_F(MessageTest, toWireWithEDNSAndTSIG) {
  617. // Similar to the previous test, but with an EDNS before TSIG.
  618. // The wire data check will confirm the ordering.
  619. isc::util::detail::gettimeFunction = testGetTime<0x4db60d1f>;
  620. message_render.setQid(0x6cd);
  621. EDNSPtr edns(new EDNS());
  622. edns->setUDPSize(4096);
  623. message_render.setEDNS(edns);
  624. {
  625. SCOPED_TRACE("Message sign with TSIG and EDNS");
  626. commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  627. "message_toWire3.wire");
  628. }
  629. }
  630. // Some of the following tests involve truncation. We use the query name
  631. // "www.example.com" and some TXT question/answers. The length of the
  632. // header and question will be 33 bytes. If we also try to include a
  633. // TSIG of the same key name (not compressed) with HMAC-MD5, the TSIG RR
  634. // will be 85 bytes.
  635. // A long TXT RDATA. With a fully compressed owner name, the corresponding
  636. // RR will be 268 bytes.
  637. const char* const long_txt1 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde";
  638. // With a fully compressed owner name, the corresponding RR will be 212 bytes.
  639. // It should result in truncation even without TSIG (33 + 268 + 212 = 513)
  640. const char* const long_txt2 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456";
  641. // With a fully compressed owner name, the corresponding RR will be 127 bytes.
  642. // So, it can fit in the standard 512 bytes with txt1 and without TSIG, but
  643. // adding a TSIG would result in truncation (33 + 268 + 127 + 85 = 513)
  644. const char* const long_txt3 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01";
  645. // This is 1 byte shorter than txt3, which will result in a possible longest
  646. // message containing answer RRs and TSIG.
  647. const char* const long_txt4 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0";
  648. // Example output generated by
  649. // "dig -y www.example.com:SFuWd/q99SzF8Yzd1QbB9g== www.example.com txt
  650. // QID: 0x22c2
  651. // Time Signed: 0x00004e179212
  652. TEST_F(MessageTest, toWireTSIGTruncation) {
  653. isc::util::detail::gettimeFunction = testGetTime<0x4e179212>;
  654. // Verify a validly signed query so that we can use the TSIG context
  655. factoryFromFile(message_parse, "message_fromWire17.wire");
  656. EXPECT_EQ(TSIGError::NOERROR(),
  657. tsig_ctx.verify(message_parse.getTSIGRecord(),
  658. &received_data[0], received_data.size()));
  659. message_render.setQid(0x22c2);
  660. vector<const char*> answer_data;
  661. answer_data.push_back(long_txt1);
  662. answer_data.push_back(long_txt2);
  663. {
  664. SCOPED_TRACE("Message sign with TSIG and TC bit on");
  665. commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  666. "message_toWire4.wire",
  667. QR_FLAG|AA_FLAG|RD_FLAG,
  668. RRType::TXT(), &answer_data);
  669. }
  670. }
  671. TEST_F(MessageTest, toWireTSIGTruncation2) {
  672. // Similar to the previous test, but without TSIG it wouldn't cause
  673. // truncation.
  674. isc::util::detail::gettimeFunction = testGetTime<0x4e179212>;
  675. factoryFromFile(message_parse, "message_fromWire17.wire");
  676. EXPECT_EQ(TSIGError::NOERROR(),
  677. tsig_ctx.verify(message_parse.getTSIGRecord(),
  678. &received_data[0], received_data.size()));
  679. message_render.setQid(0x22c2);
  680. vector<const char*> answer_data;
  681. answer_data.push_back(long_txt1);
  682. answer_data.push_back(long_txt3);
  683. {
  684. SCOPED_TRACE("Message sign with TSIG and TC bit on (2)");
  685. commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  686. "message_toWire4.wire",
  687. QR_FLAG|AA_FLAG|RD_FLAG,
  688. RRType::TXT(), &answer_data);
  689. }
  690. }
  691. TEST_F(MessageTest, toWireTSIGTruncation3) {
  692. // Similar to previous ones, but truncation occurs due to too many
  693. // Questions (very unusual, but not necessarily illegal).
  694. // We are going to create a message starting with a standard
  695. // header (12 bytes) and multiple questions in the Question
  696. // section of the same owner name (changing the RRType, just so
  697. // that it would be the form that would be accepted by the BIND 9
  698. // parser). The first Question is 21 bytes in length, and the subsequent
  699. // ones are 6 bytes. We'll also use a TSIG whose size is 85 bytes.
  700. // Up to 66 questions can fit in the standard 512-byte buffer
  701. // (12 + 21 + 6 * 65 + 85 = 508). If we try to add one more it would
  702. // result in truncation.
  703. message_render.setOpcode(Opcode::QUERY());
  704. message_render.setRcode(Rcode::NOERROR());
  705. for (int i = 1; i <= 67; ++i) {
  706. message_render.addQuestion(Question(Name("www.example.com"),
  707. RRClass::IN(), RRType(i)));
  708. }
  709. message_render.toWire(renderer, tsig_ctx);
  710. // Check the rendered data by parsing it. We only check it has the
  711. // TC bit on, has the correct number of questions, and has a TSIG RR.
  712. // Checking the signature wouldn't be necessary for this rare case
  713. // scenario.
  714. InputBuffer buffer(renderer.getData(), renderer.getLength());
  715. message_parse.fromWire(buffer);
  716. EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_TC));
  717. // Note that the number of questions are 66, not 67 as we tried to add.
  718. EXPECT_EQ(66, message_parse.getRRCount(Message::SECTION_QUESTION));
  719. EXPECT_TRUE(message_parse.getTSIGRecord() != NULL);
  720. }
  721. TEST_F(MessageTest, toWireTSIGNoTruncation) {
  722. // A boundary case that shouldn't cause truncation: the resulting
  723. // response message with a TSIG will be 512 bytes long.
  724. isc::util::detail::gettimeFunction = testGetTime<0x4e17b38d>;
  725. factoryFromFile(message_parse, "message_fromWire18.wire");
  726. EXPECT_EQ(TSIGError::NOERROR(),
  727. tsig_ctx.verify(message_parse.getTSIGRecord(),
  728. &received_data[0], received_data.size()));
  729. message_render.setQid(0xd6e2);
  730. vector<const char*> answer_data;
  731. answer_data.push_back(long_txt1);
  732. answer_data.push_back(long_txt4);
  733. {
  734. SCOPED_TRACE("Message sign with TSIG, no truncation");
  735. commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  736. "message_toWire5.wire",
  737. QR_FLAG|AA_FLAG|RD_FLAG,
  738. RRType::TXT(), &answer_data);
  739. }
  740. }
  741. // This is a buggy renderer for testing. It behaves like the straightforward
  742. // MessageRenderer, but once it has some data, its setLengthLimit() ignores
  743. // the given parameter and resets the limit to the current length, making
  744. // subsequent insertion result in truncation, which would make TSIG RR
  745. // rendering fail unexpectedly in the test that follows.
  746. class BadRenderer : public MessageRenderer {
  747. public:
  748. BadRenderer(isc::util::OutputBuffer& buffer) :
  749. MessageRenderer(buffer)
  750. {}
  751. virtual void setLengthLimit(size_t len) {
  752. if (getLength() > 0) {
  753. MessageRenderer::setLengthLimit(getLength());
  754. } else {
  755. MessageRenderer::setLengthLimit(len);
  756. }
  757. }
  758. };
  759. TEST_F(MessageTest, toWireTSIGLengthErrors) {
  760. // specify an unusual short limit that wouldn't be able to hold
  761. // the TSIG.
  762. renderer.setLengthLimit(tsig_ctx.getTSIGLength() - 1);
  763. // Use commonTSIGToWireCheck() only to call toWire() with otherwise valid
  764. // conditions. The checks inside it don't matter because we expect an
  765. // exception before any of the checks.
  766. EXPECT_THROW(commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  767. "message_toWire2.wire"),
  768. InvalidParameter);
  769. // This one is large enough for TSIG, but the remaining limit isn't
  770. // even enough for the Header section.
  771. renderer.clear();
  772. message_render.clear(Message::RENDER);
  773. renderer.setLengthLimit(tsig_ctx.getTSIGLength() + 1);
  774. EXPECT_THROW(commonTSIGToWireCheck(message_render, renderer, tsig_ctx,
  775. "message_toWire2.wire"),
  776. InvalidParameter);
  777. // Trying to render a message with TSIG using a buggy renderer.
  778. obuffer.clear();
  779. BadRenderer bad_renderer(obuffer);
  780. bad_renderer.setLengthLimit(512);
  781. message_render.clear(Message::RENDER);
  782. EXPECT_THROW(commonTSIGToWireCheck(message_render, bad_renderer, tsig_ctx,
  783. "message_toWire2.wire"),
  784. Unexpected);
  785. }
  786. TEST_F(MessageTest, toWireWithoutOpcode) {
  787. message_render.setRcode(Rcode::NOERROR());
  788. EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
  789. }
  790. TEST_F(MessageTest, toWireWithoutRcode) {
  791. message_render.setOpcode(Opcode::QUERY());
  792. EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
  793. }
  794. TEST_F(MessageTest, toText) {
  795. // Check toText() output for a typical DNS response with records in
  796. // all sections
  797. factoryFromFile(message_parse, "message_toText1.wire");
  798. {
  799. SCOPED_TRACE("Message toText test (basic case)");
  800. ifstream ifs;
  801. unittests::openTestData("message_toText1.txt", ifs);
  802. unittests::matchTextData(ifs, message_parse.toText());
  803. }
  804. // Another example with EDNS. The expected data was slightly modified
  805. // from the dig output (other than replacing tabs with a space): adding
  806. // a newline after the "OPT PSEUDOSECTION". This is an intentional change
  807. // in our version for better readability.
  808. message_parse.clear(Message::PARSE);
  809. factoryFromFile(message_parse, "message_toText2.wire");
  810. {
  811. SCOPED_TRACE("Message toText test with EDNS");
  812. ifstream ifs;
  813. unittests::openTestData("message_toText2.txt", ifs);
  814. unittests::matchTextData(ifs, message_parse.toText());
  815. }
  816. // Another example with TSIG. The expected data was slightly modified
  817. // from the dig output (other than replacing tabs with a space): removing
  818. // a redundant white space at the end of TSIG RDATA. We'd rather consider
  819. // it a dig's defect than a feature.
  820. message_parse.clear(Message::PARSE);
  821. factoryFromFile(message_parse, "message_toText3.wire");
  822. {
  823. SCOPED_TRACE("Message toText test with TSIG");
  824. ifstream ifs;
  825. unittests::openTestData("message_toText3.txt", ifs);
  826. unittests::matchTextData(ifs, message_parse.toText());
  827. }
  828. }
  829. TEST_F(MessageTest, toTextWithoutOpcode) {
  830. message_render.setRcode(Rcode::NOERROR());
  831. EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
  832. }
  833. TEST_F(MessageTest, toTextWithoutRcode) {
  834. message_render.setOpcode(Opcode::QUERY());
  835. EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
  836. }
  837. }