message_unittest.cc 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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. // $Id$
  15. #include <exceptions/exceptions.h>
  16. #include <dns/buffer.h>
  17. #include <dns/message.h>
  18. #include <dns/messagerenderer.h>
  19. #include <dns/question.h>
  20. #include <dns/rdataclass.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrttl.h>
  23. #include <dns/rrtype.h>
  24. #include <gtest/gtest.h>
  25. #include "unittest_util.h"
  26. using isc::UnitTestUtil;
  27. using namespace std;
  28. using namespace isc::dns;
  29. using namespace isc::dns::rdata;
  30. const uint16_t Message::DEFAULT_MAX_UDPSIZE;
  31. namespace {
  32. class MessageTest : public ::testing::Test {
  33. protected:
  34. MessageTest() : obuffer(0), renderer(obuffer),
  35. message_parse(Message::PARSE),
  36. message_render(Message::RENDER)
  37. {}
  38. static Question factoryFromFile(const char* datafile);
  39. OutputBuffer obuffer;
  40. MessageRenderer renderer;
  41. Message message_parse;
  42. Message message_render;
  43. static void factoryFromFile(Message& message, const char* datafile);
  44. };
  45. const Name test_name("test.example.com");
  46. void
  47. MessageTest::factoryFromFile(Message& message, const char* datafile)
  48. {
  49. std::vector<unsigned char> data;
  50. UnitTestUtil::readWireData(datafile, data);
  51. InputBuffer buffer(&data[0], data.size());
  52. message.fromWire(buffer);
  53. }
  54. TEST_F(MessageTest, RcodeConstruct)
  55. {
  56. // normal cases
  57. EXPECT_EQ(0, Rcode(0).getCode());
  58. EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code
  59. // should fail on attempt of construction with an out of range code
  60. EXPECT_THROW(Rcode(0x1000), isc::OutOfRange);
  61. EXPECT_THROW(Rcode(0xffff), isc::OutOfRange);
  62. }
  63. TEST_F(MessageTest, RcodeToText)
  64. {
  65. EXPECT_EQ("NOERROR", Rcode::NOERROR().toText());
  66. EXPECT_EQ("BADVERS", Rcode::BADVERS().toText());
  67. EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText());
  68. EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText());
  69. }
  70. TEST_F(MessageTest, fromWire)
  71. {
  72. factoryFromFile(message_parse, "testdata/message_fromWire1");
  73. EXPECT_EQ(0x1035, message_parse.getQid());
  74. EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
  75. EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
  76. EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::QR()));
  77. EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::RD()));
  78. EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::AA()));
  79. QuestionPtr q = *message_parse.beginQuestion();
  80. EXPECT_EQ(test_name, q->getName());
  81. EXPECT_EQ(RRType::A(), q->getType());
  82. EXPECT_EQ(RRClass::IN(), q->getClass());
  83. EXPECT_EQ(1, message_parse.getRRCount(Section::QUESTION()));
  84. EXPECT_EQ(2, message_parse.getRRCount(Section::ANSWER()));
  85. EXPECT_EQ(0, message_parse.getRRCount(Section::AUTHORITY()));
  86. EXPECT_EQ(0, message_parse.getRRCount(Section::ADDITIONAL()));
  87. RRsetPtr rrset = *message_parse.beginSection(Section::ANSWER());
  88. EXPECT_EQ(test_name, rrset->getName());
  89. EXPECT_EQ(RRType::A(), rrset->getType());
  90. EXPECT_EQ(RRClass::IN(), rrset->getClass());
  91. // TTL should be 3600, even though that of the 2nd RR is 7200
  92. EXPECT_EQ(RRTTL(3600), rrset->getTTL());
  93. RdataIteratorPtr it = rrset->getRdataIterator();
  94. it->first();
  95. EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
  96. it->next();
  97. EXPECT_EQ("192.0.2.2", it->getCurrent().toText());
  98. it->next();
  99. EXPECT_TRUE(it->isLast());
  100. }
  101. TEST_F(MessageTest, GetEDNS0DOBit)
  102. {
  103. // Without EDNS0, DNSSEC is considered to be unsupported.
  104. factoryFromFile(message_parse, "testdata/message_fromWire1");
  105. EXPECT_FALSE(message_parse.isDNSSECSupported());
  106. // If DO bit is on, DNSSEC is considered to be supported.
  107. message_parse.clear(Message::PARSE);
  108. factoryFromFile(message_parse, "testdata/message_fromWire2");
  109. EXPECT_TRUE(message_parse.isDNSSECSupported());
  110. // If DO bit is off, DNSSEC is considered to be unsupported.
  111. message_parse.clear(Message::PARSE);
  112. factoryFromFile(message_parse, "testdata/message_fromWire3");
  113. EXPECT_FALSE(message_parse.isDNSSECSupported());
  114. }
  115. TEST_F(MessageTest, SetEDNS0DOBit)
  116. {
  117. // By default, it's false, and we can enable/disable it.
  118. EXPECT_FALSE(message_render.isDNSSECSupported());
  119. message_render.setDNSSECSupported(true);
  120. EXPECT_TRUE(message_render.isDNSSECSupported());
  121. message_render.setDNSSECSupported(false);
  122. EXPECT_FALSE(message_render.isDNSSECSupported());
  123. // A message in the parse mode doesn't allow this flag to be set.
  124. EXPECT_THROW(message_parse.setDNSSECSupported(true),
  125. InvalidMessageOperation);
  126. // Once converted to the render mode, it works as above
  127. message_parse.makeResponse();
  128. EXPECT_FALSE(message_parse.isDNSSECSupported());
  129. message_parse.setDNSSECSupported(true);
  130. EXPECT_TRUE(message_parse.isDNSSECSupported());
  131. message_parse.setDNSSECSupported(false);
  132. EXPECT_FALSE(message_parse.isDNSSECSupported());
  133. }
  134. TEST_F(MessageTest, GetEDNS0UDPSize)
  135. {
  136. // Without EDNS0, the default max UDP size is used.
  137. factoryFromFile(message_parse, "testdata/message_fromWire1");
  138. EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
  139. // If the size specified in EDNS0 > default max, use it.
  140. message_parse.clear(Message::PARSE);
  141. factoryFromFile(message_parse, "testdata/message_fromWire2");
  142. EXPECT_EQ(4096, message_parse.getUDPSize());
  143. // If the size specified in EDNS0 < default max, keep using the default.
  144. message_parse.clear(Message::PARSE);
  145. factoryFromFile(message_parse, "testdata/message_fromWire8");
  146. EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
  147. }
  148. TEST_F(MessageTest, SetEDNS0UDPSize)
  149. {
  150. // The default size if unspecified
  151. EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
  152. // A common buffer size with EDNS, should succeed
  153. message_render.setUDPSize(4096);
  154. EXPECT_EQ(4096, message_render.getUDPSize());
  155. // Unusual large value, but accepted
  156. message_render.setUDPSize(0xffff);
  157. EXPECT_EQ(0xffff, message_render.getUDPSize());
  158. // Too small is value is rejected
  159. EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
  160. // A message in the parse mode doesn't allow the set operation.
  161. EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
  162. // Once converted to the render mode, it works as above.
  163. message_parse.makeResponse();
  164. message_parse.setUDPSize(4096);
  165. EXPECT_EQ(4096, message_parse.getUDPSize());
  166. message_parse.setUDPSize(0xffff);
  167. EXPECT_EQ(0xffff, message_parse.getUDPSize());
  168. EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
  169. }
  170. TEST_F(MessageTest, EDNS0ExtCode)
  171. {
  172. // Extended Rcode = BADVERS
  173. factoryFromFile(message_parse, "testdata/message_fromWire10");
  174. EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
  175. // Maximum extended Rcode
  176. message_parse.clear(Message::PARSE);
  177. factoryFromFile(message_parse, "testdata/message_fromWire11");
  178. EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
  179. }
  180. TEST_F(MessageTest, BadEDNS0)
  181. {
  182. // OPT RR in the answer section
  183. EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire4"),
  184. DNSMessageFORMERR);
  185. // multiple OPT RRs (in the additional section)
  186. message_parse.clear(Message::PARSE);
  187. EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire5"),
  188. DNSMessageFORMERR);
  189. // OPT RR of a non root name
  190. message_parse.clear(Message::PARSE);
  191. EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire6"),
  192. DNSMessageFORMERR);
  193. // Compressed owner name of OPT RR points to a root name.
  194. // Not necessarily bogus, but very unusual and mostly pathological.
  195. // We accept it, but is it okay?
  196. message_parse.clear(Message::PARSE);
  197. EXPECT_NO_THROW(factoryFromFile(message_parse,
  198. "testdata/message_fromWire7"));
  199. // Unsupported Version
  200. message_parse.clear(Message::PARSE);
  201. EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire9"),
  202. DNSMessageBADVERS);
  203. }
  204. TEST_F(MessageTest, toWire)
  205. {
  206. message_render.setQid(0x1035);
  207. message_render.setOpcode(Opcode::QUERY());
  208. message_render.setRcode(Rcode::NOERROR());
  209. message_render.setHeaderFlag(MessageFlag::QR());
  210. message_render.setHeaderFlag(MessageFlag::RD());
  211. message_render.setHeaderFlag(MessageFlag::AA());
  212. message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
  213. RRType::A()));
  214. RRsetPtr rrset = RRsetPtr(new RRset(Name("test.example.com"), RRClass::IN(),
  215. RRType::A(), RRTTL(3600)));
  216. rrset->addRdata(in::A("192.0.2.1"));
  217. rrset->addRdata(in::A("192.0.2.2"));
  218. message_render.addRRset(Section::ANSWER(), rrset);
  219. EXPECT_EQ(1, message_render.getRRCount(Section::QUESTION()));
  220. EXPECT_EQ(2, message_render.getRRCount(Section::ANSWER()));
  221. EXPECT_EQ(0, message_render.getRRCount(Section::AUTHORITY()));
  222. EXPECT_EQ(0, message_render.getRRCount(Section::ADDITIONAL()));
  223. message_render.toWire(renderer);
  224. vector<unsigned char> data;
  225. UnitTestUtil::readWireData("testdata/message_toWire1", data);
  226. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
  227. obuffer.getLength(), &data[0], data.size());
  228. }
  229. }