edns_unittest.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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 <sstream>
  15. #include <exceptions/exceptions.h>
  16. #include <util/buffer.h>
  17. #include <dns/edns.h>
  18. #include <dns/exceptions.h>
  19. #include <dns/message.h>
  20. #include <dns/messagerenderer.h>
  21. #include <dns/name.h>
  22. #include <dns/rcode.h>
  23. #include <dns/rdataclass.h>
  24. #include <dns/rrclass.h>
  25. #include <dns/rrttl.h>
  26. #include <dns/rrtype.h>
  27. #include <gtest/gtest.h>
  28. #include <dns/tests/unittest_util.h>
  29. using isc::UnitTestUtil;
  30. using namespace std;
  31. using namespace isc::dns;
  32. using namespace isc::util;
  33. using namespace isc::dns::rdata;
  34. const uint8_t EDNS::SUPPORTED_VERSION;
  35. namespace {
  36. class EDNSTest : public ::testing::Test {
  37. protected:
  38. EDNSTest() : rrtype(RRType::OPT()), buffer(NULL, 0), obuffer(0), rcode(0) {
  39. opt_rdata = ConstRdataPtr(new generic::OPT());
  40. edns_base.setUDPSize(4096);
  41. }
  42. RRType rrtype;
  43. EDNS edns_base;
  44. ConstEDNSPtr edns;
  45. InputBuffer buffer;
  46. OutputBuffer obuffer;
  47. MessageRenderer renderer;
  48. ConstRdataPtr opt_rdata;
  49. Rcode rcode;
  50. vector<unsigned char> wiredata;
  51. };
  52. // RRClass of EDNS OPT means UDP buffer size
  53. const RRClass rrclass(4096);
  54. // RRTTL of EDNS OPT encodes extended-rcode, version, and DO bit
  55. const RRTTL rrttl_do_on(0x00008000); // DO=on
  56. const RRTTL rrttl_do_off(0); // DO=off
  57. const RRTTL rrttl_badver(0x00018000); // version=1, DO=on
  58. TEST_F(EDNSTest, badVerConstruct) {
  59. EXPECT_THROW(EDNS(1), isc::InvalidParameter);
  60. }
  61. TEST_F(EDNSTest, DNSSECDOBit) {
  62. // tests for EDNS from RR
  63. // DO bit is on, so DNSSEC should be considered to be supported.
  64. EXPECT_TRUE(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
  65. rrttl_do_on, *opt_rdata).getDNSSECAwareness());
  66. // DO bit is off. DNSSEC should be considered to be unsupported.
  67. EXPECT_FALSE(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
  68. rrttl_do_off, *opt_rdata).getDNSSECAwareness());
  69. // tests for EDNS constructed by hand
  70. EXPECT_FALSE(edns_base.getDNSSECAwareness()); // false by default
  71. edns_base.setDNSSECAwareness(true); // enable by hand
  72. EXPECT_TRUE(edns_base.getDNSSECAwareness());
  73. edns_base.setDNSSECAwareness(false); // disable by hand
  74. EXPECT_FALSE(edns_base.getDNSSECAwareness());
  75. }
  76. TEST_F(EDNSTest, UDPSize) {
  77. EXPECT_EQ(4096, EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
  78. *opt_rdata).getUDPSize());
  79. // EDNS UDP size smaller than the traditional max, 512. Unusual, but
  80. // not prohibited.
  81. edns_base.setUDPSize(511);
  82. EXPECT_EQ(511, edns_base.getUDPSize());
  83. // Even 0 is okay.
  84. edns_base.setUDPSize(0);
  85. EXPECT_EQ(0, edns_base.getUDPSize());
  86. // Possible max value is also okay, although the higher layer app may
  87. // adjust it to a reasonably lower value
  88. edns_base.setUDPSize(65535);
  89. EXPECT_EQ(65535, edns_base.getUDPSize());
  90. }
  91. TEST_F(EDNSTest, getVersion) {
  92. // Constructed by hand
  93. EXPECT_EQ(EDNS::SUPPORTED_VERSION, EDNS().getVersion());
  94. // From RR
  95. EXPECT_EQ(EDNS::SUPPORTED_VERSION,
  96. EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
  97. *opt_rdata).getVersion());
  98. }
  99. TEST_F(EDNSTest, BadWireData) {
  100. // Incompatible RR type
  101. EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, RRType::A(),
  102. rrttl_do_on, *opt_rdata), isc::InvalidParameter);
  103. // OPT RR of a non root name
  104. EXPECT_THROW(EDNS(Name("example.com"), rrclass, rrtype,
  105. rrttl_do_on, *opt_rdata), DNSMessageFORMERR);
  106. // Unsupported Version
  107. EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, rrtype,
  108. rrttl_badver, *opt_rdata), DNSMessageBADVERS);
  109. }
  110. TEST_F(EDNSTest, toText) {
  111. // Typical case, disabling DNSSEC
  112. EXPECT_EQ("; EDNS: version: 0, flags:; udp: 4096\n",
  113. EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_off,
  114. *opt_rdata).toText());
  115. // Typical case, enabling DNSSEC
  116. EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
  117. EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on,
  118. *opt_rdata).toText());
  119. // Non-0 extended Rcode: ignored in the toText() output.
  120. EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
  121. EDNS(Name::ROOT_NAME(), rrclass, rrtype,
  122. RRTTL(0x01008000), *opt_rdata).toText());
  123. // Unknown flag: ignored in the toText() output.
  124. EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n",
  125. EDNS(Name::ROOT_NAME(), rrclass, rrtype,
  126. RRTTL(0x00008001), *opt_rdata).toText());
  127. }
  128. TEST_F(EDNSTest, toWireRenderer) {
  129. // Typical case, (explicitly) disabling DNSSEC
  130. edns_base.setDNSSECAwareness(false);
  131. EXPECT_EQ(1, edns_base.toWire(renderer,
  132. Rcode::NOERROR().getExtendedCode()));
  133. UnitTestUtil::readWireData("edns_toWire1.wire", wiredata);
  134. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  135. renderer.getLength(), &wiredata[0], wiredata.size());
  136. // Typical case, enabling DNSSEC
  137. renderer.clear();
  138. wiredata.clear();
  139. edns_base.setDNSSECAwareness(true);
  140. EXPECT_EQ(1, edns_base.toWire(renderer,
  141. Rcode::NOERROR().getExtendedCode()));
  142. UnitTestUtil::readWireData("edns_toWire2.wire", wiredata);
  143. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  144. renderer.getLength(), &wiredata[0], wiredata.size());
  145. // Non-0 extended Rcode
  146. renderer.clear();
  147. wiredata.clear();
  148. edns_base.setDNSSECAwareness(true);
  149. EXPECT_EQ(1, edns_base.toWire(renderer,
  150. Rcode::BADVERS().getExtendedCode()));
  151. UnitTestUtil::readWireData("edns_toWire3.wire", wiredata);
  152. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  153. renderer.getLength(), &wiredata[0], wiredata.size());
  154. // Uncommon UDP buffer size
  155. renderer.clear();
  156. wiredata.clear();
  157. edns_base.setDNSSECAwareness(true);
  158. edns_base.setUDPSize(511);
  159. EXPECT_EQ(1, edns_base.toWire(renderer,
  160. Rcode::NOERROR().getExtendedCode()));
  161. UnitTestUtil::readWireData("edns_toWire4.wire", wiredata);
  162. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  163. renderer.getLength(), &wiredata[0], wiredata.size());
  164. // From RR with unknown flag. If used for toWire(), the unknown flag
  165. // should disappear.
  166. renderer.clear();
  167. wiredata.clear();
  168. EXPECT_EQ(1, EDNS(Name::ROOT_NAME(), rrclass, rrtype, RRTTL(0x00008001),
  169. *opt_rdata).toWire(renderer,
  170. Rcode::NOERROR().getExtendedCode()));
  171. UnitTestUtil::readWireData("edns_toWire2.wire", wiredata);
  172. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  173. renderer.getLength(), &wiredata[0], wiredata.size());
  174. // If the available length in the renderer is not sufficient for the OPT
  175. // RR, it shouldn't be inserted.
  176. renderer.clear();
  177. renderer.setLengthLimit(10); // 10 = minimum length of OPT RR - 1
  178. edns_base.setDNSSECAwareness(true);
  179. edns_base.setUDPSize(4096);
  180. EXPECT_EQ(0, edns_base.toWire(renderer,
  181. Rcode::NOERROR().getExtendedCode()));
  182. // renderer should be intact
  183. EXPECT_EQ(0, renderer.getLength());
  184. }
  185. TEST_F(EDNSTest, toWireBuffer) {
  186. // "to renderer" and "to buffer" should generally produce the same result.
  187. // for simplicity we only check one typical case to confirm that.
  188. EXPECT_EQ(1, edns_base.toWire(obuffer,
  189. Rcode::NOERROR().getExtendedCode()));
  190. UnitTestUtil::readWireData("edns_toWire1.wire", wiredata);
  191. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
  192. obuffer.getLength(), &wiredata[0], wiredata.size());
  193. }
  194. TEST_F(EDNSTest, createFromRR) {
  195. uint8_t extended_rcode;
  196. // normal case
  197. edns = ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
  198. rrttl_do_on, *opt_rdata,
  199. extended_rcode));
  200. EXPECT_EQ(EDNS::SUPPORTED_VERSION, edns->getVersion());
  201. EXPECT_TRUE(edns->getDNSSECAwareness());
  202. EXPECT_EQ(4096, edns->getUDPSize());
  203. EXPECT_EQ(0, static_cast<int>(extended_rcode));
  204. // non-0 extended rcode
  205. extended_rcode = 0;
  206. ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
  207. RRTTL(0x01008000), *opt_rdata,
  208. extended_rcode));
  209. EXPECT_EQ(1, static_cast<int>(extended_rcode));
  210. // creation triggers an exception. extended_rcode must be intact.
  211. extended_rcode = 0;
  212. EXPECT_THROW(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype,
  213. rrttl_badver, *opt_rdata, extended_rcode),
  214. DNSMessageBADVERS);
  215. EXPECT_EQ(0, static_cast<int>(extended_rcode));
  216. }
  217. // test operator<<. We simply confirm it appends the result of toText().
  218. TEST_F(EDNSTest, LeftShiftOperator) {
  219. ostringstream oss;
  220. oss << edns_base;
  221. EXPECT_EQ(edns_base.toText(), oss.str());
  222. }
  223. }