srv_test.cc 8.6 KB

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