auth_srv_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  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 <config.h>
  16. #include <gtest/gtest.h>
  17. #include <dns/buffer.h>
  18. #include <dns/name.h>
  19. #include <dns/message.h>
  20. #include <dns/messagerenderer.h>
  21. #include <dns/opcode.h>
  22. #include <dns/rcode.h>
  23. #include <dns/rrclass.h>
  24. #include <dns/rrtype.h>
  25. #include <cc/data.h>
  26. #include <cc/session.h>
  27. #include <xfr/xfrout_client.h>
  28. #include <auth/auth_srv.h>
  29. #include <auth/asio_link.h>
  30. #include <dns/tests/unittest_util.h>
  31. using isc::UnitTestUtil;
  32. using namespace std;
  33. using namespace isc::cc;
  34. using namespace isc::dns;
  35. using namespace isc::data;
  36. using namespace isc::xfr;
  37. using namespace asio_link;
  38. namespace {
  39. const char* const CONFIG_TESTDB =
  40. "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\", \"use_memory_datasrc\": false}";
  41. const char* const MEMORY_CONFIG_TESTDB =
  42. "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\", \"use_memory_datasrc\": true}";
  43. // The following file must be non existent and must be non"creatable" (see
  44. // the sqlite3 test).
  45. const char* const BADCONFIG_TESTDB =
  46. "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\", \"use_memory_datasrc\": false}";
  47. const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
  48. class AuthSrvTest : public ::testing::Test {
  49. private:
  50. class MockXfroutClient : public AbstractXfroutClient {
  51. public:
  52. MockXfroutClient() :
  53. is_connected_(false), connect_ok_(true), send_ok_(true),
  54. disconnect_ok_(true)
  55. {}
  56. virtual void connect();
  57. virtual void disconnect();
  58. virtual int sendXfroutRequestInfo(int tcp_sock, const void* msg_data,
  59. uint16_t msg_len);
  60. bool isConnected() const { return (is_connected_); }
  61. void disableConnect() { connect_ok_ = false; }
  62. void disableDisconnect() { disconnect_ok_ = false; }
  63. void enableDisconnect() { disconnect_ok_ = true; }
  64. void disableSend() { send_ok_ = false; }
  65. private:
  66. bool is_connected_;
  67. bool connect_ok_;
  68. bool send_ok_;
  69. bool disconnect_ok_;
  70. };
  71. class MockSession : public AbstractSession {
  72. public:
  73. MockSession() :
  74. // by default we return a simple "success" message.
  75. msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
  76. send_ok_(true), receive_ok_(true)
  77. {}
  78. virtual void establish(const char* socket_file);
  79. virtual void disconnect();
  80. virtual int group_sendmsg(ConstElementPtr msg, string group,
  81. string instance, string to);
  82. virtual bool group_recvmsg(ConstElementPtr& envelope,
  83. ConstElementPtr& msg,
  84. bool nonblock, int seq);
  85. virtual void subscribe(string group, string instance);
  86. virtual void unsubscribe(string group, string instance);
  87. virtual void startRead(boost::function<void()> read_callback);
  88. virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
  89. virtual bool hasQueuedMsgs() const;
  90. virtual void setTimeout(size_t) {}
  91. virtual size_t getTimeout() const { return 0; };
  92. void setMessage(ConstElementPtr msg) { msg_ = msg; }
  93. void disableSend() { send_ok_ = false; }
  94. void disableReceive() { receive_ok_ = false; }
  95. ConstElementPtr sent_msg;
  96. string msg_destination;
  97. private:
  98. ConstElementPtr msg_;
  99. bool send_ok_;
  100. bool receive_ok_;
  101. };
  102. protected:
  103. AuthSrvTest() : server(true, xfrout),
  104. request_message(Message::RENDER),
  105. parse_message(Message::PARSE), default_qid(0x1035),
  106. opcode(Opcode::QUERY()), qname("www.example.com"),
  107. qclass(RRClass::IN()), qtype(RRType::A()),
  108. io_message(NULL), endpoint(NULL), request_obuffer(0),
  109. request_renderer(request_obuffer),
  110. response_obuffer(0), response_renderer(response_obuffer)
  111. {
  112. server.setXfrinSession(&notify_session);
  113. }
  114. ~AuthSrvTest() {
  115. delete io_message;
  116. delete endpoint;
  117. }
  118. MockSession notify_session;
  119. MockXfroutClient xfrout;
  120. AuthSrv server;
  121. Message request_message;
  122. Message parse_message;
  123. const qid_t default_qid;
  124. const Opcode opcode;
  125. const Name qname;
  126. const RRClass qclass;
  127. const RRType qtype;
  128. IOMessage* io_message;
  129. const IOEndpoint* endpoint;
  130. OutputBuffer request_obuffer;
  131. MessageRenderer request_renderer;
  132. OutputBuffer response_obuffer;
  133. MessageRenderer response_renderer;
  134. vector<uint8_t> data;
  135. void createDataFromFile(const char* const datafile, int protocol);
  136. void createRequestMessage(const Opcode& opcode, const Name& request_name,
  137. const RRClass& rrclass, const RRType& rrtype);
  138. void createRequestPacket(const Opcode& opcode, const Name& request_name,
  139. const RRClass& rrclass, const RRType& rrtype,
  140. int protocol);
  141. void createRequestPacket(int protocol);
  142. };
  143. void
  144. AuthSrvTest::MockSession::establish(const char*) {}
  145. void
  146. AuthSrvTest::MockSession::disconnect() {}
  147. void
  148. AuthSrvTest::MockSession::subscribe(string, string)
  149. {}
  150. void
  151. AuthSrvTest::MockSession::unsubscribe(string, string)
  152. {}
  153. void
  154. AuthSrvTest::MockSession::startRead(boost::function<void()>)
  155. {}
  156. int
  157. AuthSrvTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
  158. return (-1);
  159. }
  160. bool
  161. AuthSrvTest::MockSession::hasQueuedMsgs() const {
  162. return (false);
  163. }
  164. int
  165. AuthSrvTest::MockSession::group_sendmsg(ConstElementPtr msg, string group,
  166. string, string)
  167. {
  168. if (!send_ok_) {
  169. isc_throw(XfroutError, "mock session send is disabled for test");
  170. }
  171. sent_msg = msg;
  172. msg_destination = group;
  173. return (0);
  174. }
  175. bool
  176. AuthSrvTest::MockSession::group_recvmsg(ConstElementPtr&,
  177. ConstElementPtr& msg, bool, int)
  178. {
  179. if (!receive_ok_) {
  180. isc_throw(XfroutError, "mock session receive is disabled for test");
  181. }
  182. msg = msg_;
  183. return (true);
  184. }
  185. void
  186. AuthSrvTest::MockXfroutClient::connect() {
  187. if (!connect_ok_) {
  188. isc_throw(XfroutError, "xfrout connection disabled for test");
  189. }
  190. is_connected_ = true;
  191. }
  192. void
  193. AuthSrvTest::MockXfroutClient::disconnect() {
  194. if (!disconnect_ok_) {
  195. isc_throw(XfroutError,
  196. "closing xfrout connection is disabled for test");
  197. }
  198. is_connected_ = false;
  199. }
  200. int
  201. AuthSrvTest::MockXfroutClient::sendXfroutRequestInfo(const int,
  202. const void*,
  203. const uint16_t)
  204. {
  205. if (!send_ok_) {
  206. isc_throw(XfroutError, "xfrout connection send is disabled for test");
  207. }
  208. return (0);
  209. }
  210. // These are flags to indicate whether the corresponding flag bit of the
  211. // DNS header is to be set in the test cases. (Note that the flag values
  212. // is irrelevant to their wire-format values)
  213. const unsigned int QR_FLAG = 0x1;
  214. const unsigned int AA_FLAG = 0x2;
  215. const unsigned int TC_FLAG = 0x4;
  216. const unsigned int RD_FLAG = 0x8;
  217. const unsigned int RA_FLAG = 0x10;
  218. const unsigned int AD_FLAG = 0x20;
  219. const unsigned int CD_FLAG = 0x40;
  220. void
  221. AuthSrvTest::createDataFromFile(const char* const datafile,
  222. const int protocol = IPPROTO_UDP)
  223. {
  224. delete io_message;
  225. data.clear();
  226. delete endpoint;
  227. endpoint = IOEndpoint::create(protocol,
  228. IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
  229. UnitTestUtil::readWireData(datafile, data);
  230. io_message = new IOMessage(&data[0], data.size(),
  231. protocol == IPPROTO_UDP ?
  232. IOSocket::getDummyUDPSocket() :
  233. IOSocket::getDummyTCPSocket(), *endpoint);
  234. }
  235. void
  236. AuthSrvTest::createRequestMessage(const Opcode& opcode,
  237. const Name& request_name,
  238. const RRClass& rrclass,
  239. const RRType& rrtype)
  240. {
  241. request_message.clear(Message::RENDER);
  242. request_message.setOpcode(opcode);
  243. request_message.setRcode(Rcode::NOERROR());
  244. request_message.setQid(default_qid);
  245. request_message.addQuestion(Question(request_name, rrclass, rrtype));
  246. }
  247. void
  248. AuthSrvTest::createRequestPacket(const Opcode& opcode,
  249. const Name& request_name,
  250. const RRClass& rrclass, const RRType& rrtype,
  251. const int protocol = IPPROTO_UDP)
  252. {
  253. createRequestMessage(opcode, request_name, rrclass, rrtype);
  254. createRequestPacket(protocol);
  255. }
  256. void
  257. AuthSrvTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
  258. request_message.toWire(request_renderer);
  259. delete io_message;
  260. endpoint = IOEndpoint::create(protocol,
  261. IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
  262. io_message = new IOMessage(request_renderer.getData(),
  263. request_renderer.getLength(),
  264. protocol == IPPROTO_UDP ?
  265. IOSocket::getDummyUDPSocket() :
  266. IOSocket::getDummyTCPSocket(), *endpoint);
  267. }
  268. void
  269. headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
  270. const uint16_t opcodeval, const unsigned int flags,
  271. const unsigned int qdcount,
  272. const unsigned int ancount, const unsigned int nscount,
  273. const unsigned int arcount)
  274. {
  275. EXPECT_EQ(qid, message.getQid());
  276. EXPECT_EQ(rcode, message.getRcode());
  277. EXPECT_EQ(opcodeval, message.getOpcode().getCode());
  278. EXPECT_EQ((flags & QR_FLAG) != 0,
  279. message.getHeaderFlag(Message::HEADERFLAG_QR));
  280. EXPECT_EQ((flags & AA_FLAG) != 0,
  281. message.getHeaderFlag(Message::HEADERFLAG_AA));
  282. EXPECT_EQ((flags & TC_FLAG) != 0,
  283. message.getHeaderFlag(Message::HEADERFLAG_TC));
  284. EXPECT_EQ((flags & RA_FLAG) != 0,
  285. message.getHeaderFlag(Message::HEADERFLAG_RA));
  286. EXPECT_EQ((flags & RD_FLAG) != 0,
  287. message.getHeaderFlag(Message::HEADERFLAG_RD));
  288. EXPECT_EQ((flags & AD_FLAG) != 0,
  289. message.getHeaderFlag(Message::HEADERFLAG_AD));
  290. EXPECT_EQ((flags & CD_FLAG) != 0,
  291. message.getHeaderFlag(Message::HEADERFLAG_CD));
  292. EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
  293. EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
  294. EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
  295. EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
  296. }
  297. // Unsupported requests. Should result in NOTIMP.
  298. TEST_F(AuthSrvTest, unsupportedRequest) {
  299. for (unsigned int i = 0; i < 16; ++i) {
  300. // set Opcode to 'i', which iterators over all possible codes except
  301. // the standard query and notify
  302. if (i == Opcode::QUERY().getCode() ||
  303. i == Opcode::NOTIFY().getCode()) {
  304. continue;
  305. }
  306. createDataFromFile("simplequery_fromWire.wire");
  307. data[2] = ((i << 3) & 0xff);
  308. parse_message.clear(Message::PARSE);
  309. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  310. response_renderer));
  311. headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
  312. 0, 0, 0, 0);
  313. }
  314. }
  315. // Simple API check
  316. TEST_F(AuthSrvTest, verbose) {
  317. EXPECT_FALSE(server.getVerbose());
  318. server.setVerbose(true);
  319. EXPECT_TRUE(server.getVerbose());
  320. server.setVerbose(false);
  321. EXPECT_FALSE(server.getVerbose());
  322. }
  323. // Multiple questions. Should result in FORMERR.
  324. TEST_F(AuthSrvTest, multiQuestion) {
  325. createDataFromFile("multiquestion_fromWire.wire");
  326. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  327. response_renderer));
  328. headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
  329. QR_FLAG, 2, 0, 0, 0);
  330. QuestionIterator qit = parse_message.beginQuestion();
  331. EXPECT_EQ(Name("example.com"), (*qit)->getName());
  332. EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
  333. EXPECT_EQ(RRType::A(), (*qit)->getType());
  334. ++qit;
  335. EXPECT_EQ(Name("example.com"), (*qit)->getName());
  336. EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
  337. EXPECT_EQ(RRType::AAAA(), (*qit)->getType());
  338. ++qit;
  339. EXPECT_TRUE(qit == parse_message.endQuestion());
  340. }
  341. // Incoming data doesn't even contain the complete header. Must be silently
  342. // dropped.
  343. TEST_F(AuthSrvTest, shortMessage) {
  344. createDataFromFile("shortmessage_fromWire");
  345. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  346. response_renderer));
  347. }
  348. // Response messages. Must be silently dropped, whether it's a valid response
  349. // or malformed or could otherwise cause a protocol error.
  350. TEST_F(AuthSrvTest, response) {
  351. // A valid (although unusual) response
  352. createDataFromFile("simpleresponse_fromWire.wire");
  353. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  354. response_renderer));
  355. // A response with a broken question section. must be dropped rather than
  356. // returning FORMERR.
  357. createDataFromFile("shortresponse_fromWire");
  358. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  359. response_renderer));
  360. // A response to iquery. must be dropped rather than returning NOTIMP.
  361. createDataFromFile("iqueryresponse_fromWire.wire");
  362. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  363. response_renderer));
  364. }
  365. // Query with a broken question
  366. TEST_F(AuthSrvTest, shortQuestion) {
  367. createDataFromFile("shortquestion_fromWire");
  368. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  369. response_renderer));
  370. // Since the query's question is broken, the question section of the
  371. // response should be empty.
  372. headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
  373. QR_FLAG, 0, 0, 0, 0);
  374. }
  375. // Query with a broken answer section
  376. TEST_F(AuthSrvTest, shortAnswer) {
  377. createDataFromFile("shortanswer_fromWire.wire");
  378. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  379. response_renderer));
  380. // This is a bogus query, but question section is valid. So the response
  381. // should copy the question section.
  382. headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
  383. QR_FLAG, 1, 0, 0, 0);
  384. QuestionIterator qit = parse_message.beginQuestion();
  385. EXPECT_EQ(Name("example.com"), (*qit)->getName());
  386. EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
  387. EXPECT_EQ(RRType::A(), (*qit)->getType());
  388. ++qit;
  389. EXPECT_TRUE(qit == parse_message.endQuestion());
  390. }
  391. // Query with unsupported version of EDNS.
  392. TEST_F(AuthSrvTest, ednsBadVers) {
  393. createDataFromFile("queryBadEDNS_fromWire.wire");
  394. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  395. response_renderer));
  396. // The response must have an EDNS OPT RR in the additional section, but
  397. // it will be added automatically at the render time.
  398. // Note that the DNSSEC DO bit is cleared even if this bit in the query
  399. // is set. This is a limitation of the current implementation.
  400. headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
  401. QR_FLAG, 1, 0, 0, 1);
  402. EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
  403. parse_message.clear(Message::PARSE);
  404. InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
  405. parse_message.fromWire(ib);
  406. EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
  407. EXPECT_TRUE(parse_message.getEDNS());
  408. EXPECT_FALSE(parse_message.getEDNS()->getDNSSECAwareness());
  409. }
  410. TEST_F(AuthSrvTest, AXFROverUDP) {
  411. // AXFR over UDP is invalid and should result in FORMERR.
  412. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  413. RRType::AXFR(), IPPROTO_UDP);
  414. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  415. response_renderer));
  416. headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
  417. QR_FLAG, 1, 0, 0, 0);
  418. }
  419. TEST_F(AuthSrvTest, AXFRSuccess) {
  420. EXPECT_FALSE(xfrout.isConnected());
  421. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  422. RRType::AXFR(), IPPROTO_TCP);
  423. // On success, the AXFR query has been passed to a separate process,
  424. // so we shouldn't have to respond.
  425. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  426. response_renderer));
  427. EXPECT_TRUE(xfrout.isConnected());
  428. }
  429. TEST_F(AuthSrvTest, AXFRConnectFail) {
  430. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  431. xfrout.disableConnect();
  432. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  433. RRType::AXFR(), IPPROTO_TCP);
  434. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  435. response_renderer));
  436. headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
  437. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  438. EXPECT_FALSE(xfrout.isConnected());
  439. }
  440. TEST_F(AuthSrvTest, AXFRSendFail) {
  441. // first send a valid query, making the connection with the xfr process
  442. // open.
  443. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  444. RRType::AXFR(), IPPROTO_TCP);
  445. server.processMessage(*io_message, parse_message, response_renderer);
  446. EXPECT_TRUE(xfrout.isConnected());
  447. xfrout.disableSend();
  448. parse_message.clear(Message::PARSE);
  449. response_renderer.clear();
  450. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  451. RRType::AXFR(), IPPROTO_TCP);
  452. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  453. response_renderer));
  454. headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
  455. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  456. // The connection should have been closed due to the send failure.
  457. EXPECT_FALSE(xfrout.isConnected());
  458. }
  459. TEST_F(AuthSrvTest, AXFRDisconnectFail) {
  460. // In our usage disconnect() shouldn't fail. So we'll see the exception
  461. // should it be thrown.
  462. xfrout.disableSend();
  463. xfrout.disableDisconnect();
  464. createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
  465. RRType::AXFR(), IPPROTO_TCP);
  466. EXPECT_THROW(server.processMessage(*io_message, parse_message,
  467. response_renderer),
  468. XfroutError);
  469. EXPECT_TRUE(xfrout.isConnected());
  470. // XXX: we need to re-enable disconnect. otherwise an exception would be
  471. // thrown via the destructor of the server.
  472. xfrout.enableDisconnect();
  473. }
  474. TEST_F(AuthSrvTest, notify) {
  475. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  476. RRType::SOA());
  477. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  478. createRequestPacket(IPPROTO_UDP);
  479. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  480. response_renderer));
  481. // An internal command message should have been created and sent to an
  482. // external module. Check them.
  483. EXPECT_EQ("Zonemgr", notify_session.msg_destination);
  484. EXPECT_EQ("notify",
  485. notify_session.sent_msg->get("command")->get(0)->stringValue());
  486. ConstElementPtr notify_args =
  487. notify_session.sent_msg->get("command")->get(1);
  488. EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
  489. EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
  490. notify_args->get("master")->stringValue());
  491. EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
  492. // On success, the server should return a response to the notify.
  493. headerCheck(parse_message, default_qid, Rcode::NOERROR(),
  494. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  495. // The question must be identical to that of the received notify
  496. ConstQuestionPtr question = *parse_message.beginQuestion();
  497. EXPECT_EQ(Name("example.com"), question->getName());
  498. EXPECT_EQ(RRClass::IN(), question->getClass());
  499. EXPECT_EQ(RRType::SOA(), question->getType());
  500. }
  501. TEST_F(AuthSrvTest, notifyForCHClass) {
  502. // Same as the previous test, but for the CH RRClass.
  503. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::CH(),
  504. RRType::SOA());
  505. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  506. createRequestPacket(IPPROTO_UDP);
  507. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  508. response_renderer));
  509. // Other conditions should be the same, so simply confirm the RR class is
  510. // set correctly.
  511. ConstElementPtr notify_args =
  512. notify_session.sent_msg->get("command")->get(1);
  513. EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
  514. }
  515. TEST_F(AuthSrvTest, notifyEmptyQuestion) {
  516. request_message.clear(Message::RENDER);
  517. request_message.setOpcode(Opcode::NOTIFY());
  518. request_message.setRcode(Rcode::NOERROR());
  519. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  520. request_message.setQid(default_qid);
  521. request_message.toWire(request_renderer);
  522. createRequestPacket(IPPROTO_UDP);
  523. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  524. response_renderer));
  525. headerCheck(parse_message, default_qid, Rcode::FORMERR(),
  526. Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
  527. }
  528. TEST_F(AuthSrvTest, notifyMultiQuestions) {
  529. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  530. RRType::SOA());
  531. // add one more SOA question
  532. request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
  533. RRType::SOA()));
  534. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  535. createRequestPacket(IPPROTO_UDP);
  536. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  537. response_renderer));
  538. headerCheck(parse_message, default_qid, Rcode::FORMERR(),
  539. Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
  540. }
  541. TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
  542. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  543. RRType::NS());
  544. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  545. createRequestPacket(IPPROTO_UDP);
  546. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  547. response_renderer));
  548. headerCheck(parse_message, default_qid, Rcode::FORMERR(),
  549. Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
  550. }
  551. TEST_F(AuthSrvTest, notifyWithoutAA) {
  552. // implicitly leave the AA bit off. our implementation will accept it.
  553. createRequestPacket(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  554. RRType::SOA());
  555. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  556. response_renderer));
  557. headerCheck(parse_message, default_qid, Rcode::NOERROR(),
  558. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  559. }
  560. TEST_F(AuthSrvTest, notifyWithErrorRcode) {
  561. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  562. RRType::SOA());
  563. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  564. request_message.setRcode(Rcode::SERVFAIL());
  565. createRequestPacket(IPPROTO_UDP);
  566. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  567. response_renderer));
  568. headerCheck(parse_message, default_qid, Rcode::NOERROR(),
  569. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  570. }
  571. TEST_F(AuthSrvTest, notifyWithoutSession) {
  572. server.setXfrinSession(NULL);
  573. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  574. RRType::SOA());
  575. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  576. createRequestPacket(IPPROTO_UDP);
  577. // we simply ignore the notify and let it be resent if an internal error
  578. // happens.
  579. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  580. response_renderer));
  581. }
  582. TEST_F(AuthSrvTest, notifySendFail) {
  583. notify_session.disableSend();
  584. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  585. RRType::SOA());
  586. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  587. createRequestPacket(IPPROTO_UDP);
  588. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  589. response_renderer));
  590. }
  591. TEST_F(AuthSrvTest, notifyReceiveFail) {
  592. notify_session.disableReceive();
  593. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  594. RRType::SOA());
  595. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  596. createRequestPacket(IPPROTO_UDP);
  597. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  598. response_renderer));
  599. }
  600. TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
  601. notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
  602. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  603. RRType::SOA());
  604. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  605. createRequestPacket(IPPROTO_UDP);
  606. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  607. response_renderer));
  608. }
  609. TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
  610. notify_session.setMessage(
  611. Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
  612. createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
  613. RRType::SOA());
  614. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  615. createRequestPacket(IPPROTO_UDP);
  616. EXPECT_FALSE(server.processMessage(*io_message, parse_message,
  617. response_renderer));
  618. }
  619. void
  620. updateConfig(AuthSrv* server, const char* const dbfile,
  621. const bool expect_success)
  622. {
  623. ConstElementPtr config_answer =
  624. server->updateConfig(Element::fromJSON(dbfile));
  625. EXPECT_EQ(Element::map, config_answer->getType());
  626. EXPECT_TRUE(config_answer->contains("result"));
  627. ConstElementPtr result = config_answer->get("result");
  628. EXPECT_EQ(Element::list, result->getType());
  629. EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
  630. }
  631. // Install a Sqlite3 data source with testing data.
  632. TEST_F(AuthSrvTest, updateConfig) {
  633. updateConfig(&server, CONFIG_TESTDB, true);
  634. // query for existent data in the installed data source. The resulting
  635. // response should have the AA flag on, and have an RR in each answer
  636. // and authority section.
  637. createDataFromFile("examplequery_fromWire.wire");
  638. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  639. response_renderer));
  640. headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
  641. QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  642. }
  643. TEST_F(AuthSrvTest, datasourceFail) {
  644. updateConfig(&server, CONFIG_TESTDB, true);
  645. // This query will hit a corrupted entry of the data source (the zoneload
  646. // tool and the data source itself naively accept it). This will result
  647. // in a SERVFAIL response, and the answer and authority sections should
  648. // be empty.
  649. createDataFromFile("badExampleQuery_fromWire.wire");
  650. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  651. response_renderer));
  652. headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
  653. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  654. }
  655. TEST_F(AuthSrvTest, updateConfigFail) {
  656. // First, load a valid data source.
  657. updateConfig(&server, CONFIG_TESTDB, true);
  658. // Next, try to update it with a non-existent one. This should fail.
  659. updateConfig(&server, BADCONFIG_TESTDB, false);
  660. // The original data source should still exist.
  661. createDataFromFile("examplequery_fromWire.wire");
  662. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  663. response_renderer));
  664. headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
  665. QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  666. }
  667. TEST_F(AuthSrvTest, useMemoryDataSrc) {
  668. // First, load a memory data source.
  669. updateConfig(&server, MEMORY_CONFIG_TESTDB, true);
  670. // The memory data source is empty, should return SERVFAIL rcode.
  671. createDataFromFile("examplequery_fromWire.wire");
  672. EXPECT_TRUE(server.processMessage(*io_message, parse_message,
  673. response_renderer));
  674. headerCheck(parse_message, default_qid, Rcode::SERVFAIL(), opcode.getCode(),
  675. QR_FLAG, 1, 0, 0, 0);
  676. }
  677. TEST_F(AuthSrvTest, cacheSlots) {
  678. // simple check for the get/set operations
  679. server.setCacheSlots(10); // 10 = arbitrary choice
  680. EXPECT_EQ(10, server.getCacheSlots());
  681. // 0 is a valid size
  682. server.setCacheSlots(0);
  683. EXPECT_EQ(00, server.getCacheSlots());
  684. }
  685. }