edns_unittest.cc 9.8 KB

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