srv_test.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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 <netinet/in.h>
  15. #include <dns/message.h>
  16. #include <dns/rcode.h>
  17. #include <asiolink/asiolink.h>
  18. #include <dns/tests/unittest_util.h>
  19. #include <testutils/dnsmessage_test.h>
  20. #include <testutils/srv_test.h>
  21. using namespace isc::dns;
  22. using namespace asiolink;
  23. namespace isc {
  24. namespace testutils {
  25. const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
  26. SrvTestBase::SrvTestBase() : request_message(Message::RENDER),
  27. parse_message(new Message(Message::PARSE)),
  28. response_message(new Message(Message::RENDER)),
  29. default_qid(0x1035),
  30. opcode(Opcode(Opcode::QUERY())),
  31. qname("www.example.com"),
  32. qclass(RRClass::IN()),
  33. qtype(RRType::A()), io_sock(NULL),
  34. io_message(NULL), endpoint(NULL),
  35. request_obuffer(0),
  36. request_renderer(request_obuffer),
  37. response_obuffer(new OutputBuffer(0))
  38. {}
  39. SrvTestBase::~SrvTestBase() {
  40. delete io_message;
  41. delete endpoint;
  42. }
  43. void
  44. SrvTestBase::createDataFromFile(const char* const datafile,
  45. const int protocol)
  46. {
  47. delete io_message;
  48. data.clear();
  49. delete endpoint;
  50. endpoint = IOEndpoint::create(protocol,
  51. IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
  52. UnitTestUtil::readWireData(datafile, data);
  53. io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
  54. &IOSocket::getDummyTCPSocket();
  55. io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
  56. }
  57. void
  58. SrvTestBase::createRequestPacket(Message& message,
  59. const int protocol)
  60. {
  61. message.toWire(request_renderer);
  62. delete io_message;
  63. endpoint = IOEndpoint::create(protocol,
  64. IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
  65. io_sock = (protocol == IPPROTO_UDP) ? &IOSocket::getDummyUDPSocket() :
  66. &IOSocket::getDummyTCPSocket();
  67. io_message = new IOMessage(request_renderer.getData(),
  68. request_renderer.getLength(),
  69. *io_sock, *endpoint);
  70. }
  71. // Unsupported requests. Should result in NOTIMP.
  72. void
  73. SrvTestBase::unsupportedRequest() {
  74. for (unsigned int i = 0; i < 16; ++i) {
  75. // set Opcode to 'i', which iterators over all possible codes except
  76. // the standard query and notify
  77. if (i == isc::dns::Opcode::QUERY().getCode() ||
  78. i == isc::dns::Opcode::NOTIFY().getCode()) {
  79. continue;
  80. }
  81. createDataFromFile("simplequery_fromWire.wire");
  82. data[2] = ((i << 3) & 0xff);
  83. parse_message->clear(isc::dns::Message::PARSE);
  84. processMessage();
  85. EXPECT_TRUE(dnsserv.hasAnswer());
  86. headerCheck(*parse_message, default_qid, isc::dns::Rcode::NOTIMP(), i,
  87. QR_FLAG, 0, 0, 0, 0);
  88. }
  89. }
  90. // Multiple questions. Should result in FORMERR.
  91. void
  92. SrvTestBase::multiQuestion() {
  93. createDataFromFile("multiquestion_fromWire.wire");
  94. processMessage();
  95. EXPECT_TRUE(dnsserv.hasAnswer());
  96. headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
  97. opcode.getCode(), QR_FLAG, 2, 0, 0, 0);
  98. isc::dns::QuestionIterator qit = parse_message->beginQuestion();
  99. EXPECT_EQ(isc::dns::Name("example.com"), (*qit)->getName());
  100. EXPECT_EQ(isc::dns::RRClass::IN(), (*qit)->getClass());
  101. EXPECT_EQ(isc::dns::RRType::A(), (*qit)->getType());
  102. ++qit;
  103. EXPECT_EQ(isc::dns::Name("example.com"), (*qit)->getName());
  104. EXPECT_EQ(isc::dns::RRClass::IN(), (*qit)->getClass());
  105. EXPECT_EQ(isc::dns::RRType::AAAA(), (*qit)->getType());
  106. ++qit;
  107. EXPECT_TRUE(qit == parse_message->endQuestion());
  108. }
  109. // Incoming data doesn't even contain the complete header. Must be silently
  110. // dropped.
  111. void
  112. SrvTestBase::shortMessage() {
  113. createDataFromFile("shortmessage_fromWire");
  114. processMessage();
  115. EXPECT_FALSE(dnsserv.hasAnswer());
  116. }
  117. // Response messages. Must be silently dropped, whether it's a valid response
  118. // or malformed or could otherwise cause a protocol error.
  119. void
  120. SrvTestBase::response() {
  121. // A valid (although unusual) response
  122. createDataFromFile("simpleresponse_fromWire.wire");
  123. processMessage();
  124. EXPECT_FALSE(dnsserv.hasAnswer());
  125. // A response with a broken question section. must be dropped rather than
  126. //returning FORMERR.
  127. createDataFromFile("shortresponse_fromWire");
  128. processMessage();
  129. EXPECT_FALSE(dnsserv.hasAnswer());
  130. // A response to iquery. must be dropped rather than returning NOTIMP.
  131. createDataFromFile("iqueryresponse_fromWire.wire");
  132. processMessage();
  133. EXPECT_FALSE(dnsserv.hasAnswer());
  134. }
  135. // Query with a broken question
  136. void
  137. SrvTestBase::shortQuestion() {
  138. createDataFromFile("shortquestion_fromWire");
  139. processMessage();
  140. EXPECT_TRUE(dnsserv.hasAnswer());
  141. // Since the query's question is broken, the question section of the
  142. // response should be empty.
  143. headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
  144. opcode.getCode(), QR_FLAG, 0, 0, 0, 0);
  145. }
  146. // Query with a broken answer section
  147. void
  148. SrvTestBase::shortAnswer() {
  149. createDataFromFile("shortanswer_fromWire.wire");
  150. processMessage();
  151. EXPECT_TRUE(dnsserv.hasAnswer());
  152. // This is a bogus query, but question section is valid. So the response
  153. // should copy the question section.
  154. headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
  155. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  156. isc::dns::QuestionIterator qit = parse_message->beginQuestion();
  157. EXPECT_EQ(isc::dns::Name("example.com"), (*qit)->getName());
  158. EXPECT_EQ(isc::dns::RRClass::IN(), (*qit)->getClass());
  159. EXPECT_EQ(isc::dns::RRType::A(), (*qit)->getType());
  160. ++qit;
  161. EXPECT_TRUE(qit == parse_message->endQuestion());
  162. }
  163. // Query with unsupported version of EDNS.
  164. void
  165. SrvTestBase::ednsBadVers() {
  166. createDataFromFile("queryBadEDNS_fromWire.wire");
  167. processMessage();
  168. EXPECT_TRUE(dnsserv.hasAnswer());
  169. // The response must have an EDNS OPT RR in the additional section,
  170. // it will be added automatically at the render time.
  171. // Note that the DNSSEC DO bit is cleared even if this bit in the query
  172. // is set. This is a limitation of the current implementation.
  173. headerCheck(*parse_message, default_qid, isc::dns::Rcode::BADVERS(),
  174. opcode.getCode(), QR_FLAG, 1, 0, 0, 1);
  175. EXPECT_FALSE(parse_message->getEDNS()); // EDNS isn't added at this point
  176. isc::dns::InputBuffer ib(response_obuffer->getData(),
  177. response_obuffer->getLength());
  178. isc::dns::Message parsed(isc::dns::Message::PARSE);
  179. parsed.fromWire(ib);
  180. EXPECT_EQ(isc::dns::Rcode::BADVERS(), parsed.getRcode());
  181. isc::dns::ConstEDNSPtr edns(parsed.getEDNS());
  182. ASSERT_TRUE(edns);
  183. EXPECT_FALSE(edns->getDNSSECAwareness());
  184. }
  185. void
  186. SrvTestBase::axfrOverUDP() {
  187. // AXFR over UDP is invalid and should result in FORMERR.
  188. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  189. isc::dns::Name("example.com"),
  190. isc::dns::RRClass::IN(),
  191. isc::dns::RRType::AXFR());
  192. createRequestPacket(request_message, IPPROTO_UDP);
  193. processMessage();
  194. EXPECT_TRUE(dnsserv.hasAnswer());
  195. headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
  196. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  197. }
  198. } // end of namespace testutils
  199. } // end of namespace isc
  200. // Local Variables:
  201. // mode: c++
  202. // End: