auth_srv_unittest.cc 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061
  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 <util/io/sockaddr_util.h>
  16. #include <util/memory_segment_local.h>
  17. #include <dns/message.h>
  18. #include <dns/messagerenderer.h>
  19. #include <dns/name.h>
  20. #include <dns/opcode.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrtype.h>
  23. #include <dns/rrttl.h>
  24. #include <dns/rdataclass.h>
  25. #include <dns/tsig.h>
  26. #include <server_common/portconfig.h>
  27. #include <server_common/keyring.h>
  28. #include <datasrc/memory_datasrc.h>
  29. #include <datasrc/client_list.h>
  30. #include <auth/auth_srv.h>
  31. #include <auth/command.h>
  32. #include <auth/common.h>
  33. #include <auth/statistics.h>
  34. #include <auth/statistics_items.h>
  35. #include <auth/datasrc_configurator.h>
  36. #include <util/unittests/mock_socketsession.h>
  37. #include <dns/tests/unittest_util.h>
  38. #include <testutils/dnsmessage_test.h>
  39. #include <testutils/srv_test.h>
  40. #include <testutils/mockups.h>
  41. #include <testutils/portconfig.h>
  42. #include <testutils/socket_request.h>
  43. #include "statistics_util.h"
  44. #include <gtest/gtest.h>
  45. #include <boost/lexical_cast.hpp>
  46. #include <boost/shared_ptr.hpp>
  47. #include <boost/scoped_ptr.hpp>
  48. #include <boost/foreach.hpp>
  49. #include <vector>
  50. #include <sys/types.h>
  51. #include <sys/socket.h>
  52. #include <netdb.h>
  53. using namespace std;
  54. using namespace isc::cc;
  55. using namespace isc::dns;
  56. using namespace isc::util;
  57. using namespace isc::util::io::internal;
  58. using namespace isc::util::unittests;
  59. using namespace isc::dns::rdata;
  60. using namespace isc::data;
  61. using namespace isc::xfr;
  62. using namespace isc::asiodns;
  63. using namespace isc::asiolink;
  64. using namespace isc::testutils;
  65. using namespace isc::server_common::portconfig;
  66. using namespace isc::auth::unittest;
  67. using isc::UnitTestUtil;
  68. using boost::scoped_ptr;
  69. using isc::auth::statistics::Counters;
  70. namespace {
  71. const char* const CONFIG_TESTDB =
  72. "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\"}";
  73. // The following file must be non existent and must be non"creatable" (see
  74. // the sqlite3 test).
  75. const char* const BADCONFIG_TESTDB =
  76. "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
  77. const char* const STATIC_DSRC_FILE = DSRC_DIR "/static.zone";
  78. // This is a configuration that uses the in-memory data source containing
  79. // a signed example zone.
  80. const char* const CONFIG_INMEMORY_EXAMPLE =
  81. TEST_DATA_DIR "/rfc5155-example.zone.signed";
  82. class AuthSrvTest : public SrvTestBase {
  83. protected:
  84. AuthSrvTest() :
  85. dnss_(),
  86. server(xfrout, ddns_forwarder),
  87. // The empty string is expected value of the parameter of
  88. // requestSocket, not the app_name (there's no fallback, it checks
  89. // the empty string is passed).
  90. sock_requestor_(dnss_, address_store_, 53210, "")
  91. {
  92. server.setDNSService(dnss_);
  93. server.setXfrinSession(&notify_session);
  94. server.createDDNSForwarder();
  95. checkCountersAreInitialized();
  96. }
  97. ~AuthSrvTest() {
  98. server.destroyDDNSForwarder();
  99. }
  100. virtual void processMessage() {
  101. // If processMessage has been called before, parse_message needs
  102. // to be reset. If it hasn't, there's no harm in doing so
  103. parse_message->clear(Message::PARSE);
  104. server.processMessage(*io_message, *parse_message, *response_obuffer,
  105. &dnsserv);
  106. }
  107. // Helper for checking Rcode statistic counters;
  108. // Checks for one specific Rcode statistics counter value
  109. void checkRcodeCounter(const std::string& rcode_name,
  110. const int rcode_value,
  111. const int expected_value) const
  112. {
  113. EXPECT_EQ(expected_value, rcode_value) <<
  114. "Expected Rcode count for " << rcode_name <<
  115. " " << expected_value << ", was: " <<
  116. rcode_value;
  117. }
  118. // Checks whether all Rcode counters are set to zero except the given
  119. // rcode (it is checked to be set to 'value')
  120. void checkAllRcodeCountersZeroExcept(const Rcode& rcode, int value) const {
  121. std::string target_rcode_name = rcode.toText();
  122. std::transform(target_rcode_name.begin(), target_rcode_name.end(),
  123. target_rcode_name.begin(), ::tolower);
  124. const std::map<std::string, ConstElementPtr>
  125. stats_map(server.getStatistics()->get("zones")->get("_SERVER_")->
  126. get("rcode")->mapValue());
  127. for (std::map<std::string, ConstElementPtr>::const_iterator
  128. i = stats_map.begin(), e = stats_map.end();
  129. i != e;
  130. ++i)
  131. {
  132. if (i->first.compare(target_rcode_name) == 0) {
  133. checkRcodeCounter(i->first, i->second->intValue(), value);
  134. } else {
  135. checkRcodeCounter(i->first, i->second->intValue(), 0);
  136. }
  137. }
  138. }
  139. // Convenience method for tests that expect to return SERVFAIL
  140. // It calls processMessage, checks if there is an answer, and
  141. // check the header for default SERVFAIL data
  142. void processAndCheckSERVFAIL() {
  143. processMessage();
  144. EXPECT_TRUE(dnsserv.hasAnswer());
  145. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  146. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  147. }
  148. // Convenient shortcut of creating a simple request and having the
  149. // server process it.
  150. void createAndSendRequest(RRType req_type, Opcode opcode = Opcode::QUERY(),
  151. const Name& req_name = Name("example.com"),
  152. RRClass req_class = RRClass::IN(),
  153. int protocol = IPPROTO_UDP,
  154. const char* const remote_address =
  155. DEFAULT_REMOTE_ADDRESS,
  156. uint16_t remote_port = DEFAULT_REMOTE_PORT)
  157. {
  158. UnitTestUtil::createRequestMessage(request_message, opcode,
  159. default_qid, req_name,
  160. req_class, req_type);
  161. createRequestPacket(request_message, protocol, NULL,
  162. remote_address, remote_port);
  163. parse_message->clear(Message::PARSE);
  164. server.processMessage(*io_message, *parse_message, *response_obuffer,
  165. &dnsserv);
  166. }
  167. // Check if the counters exist and are initialized to 0.
  168. void
  169. checkCountersAreInitialized() {
  170. const std::map<std::string, int> expect;
  171. ConstElementPtr stats = server.getStatistics()->
  172. get("zones")->get("_SERVER_");
  173. checkStatisticsCounters(stats, expect);
  174. }
  175. MockDNSService dnss_;
  176. MockXfroutClient xfrout;
  177. MockSocketSessionForwarder ddns_forwarder;
  178. AuthSrv server;
  179. vector<uint8_t> response_data;
  180. AddressList address_store_;
  181. TestSocketRequestor sock_requestor_;
  182. };
  183. // A helper function that builds a response to version.bind/TXT/CH that
  184. // should be identical to the response from our builtin (static) data source
  185. // by default. The resulting wire-format data will be stored in 'data'.
  186. void
  187. createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
  188. const Name version_name("VERSION.BIND.");
  189. const Name apex_name("BIND.");
  190. Message message(Message::RENDER);
  191. UnitTestUtil::createRequestMessage(message, Opcode::QUERY(),
  192. qid, version_name,
  193. RRClass::CH(), RRType::TXT());
  194. message.setHeaderFlag(Message::HEADERFLAG_QR);
  195. message.setHeaderFlag(Message::HEADERFLAG_AA);
  196. RRsetPtr rrset_version = RRsetPtr(new RRset(version_name, RRClass::CH(),
  197. RRType::TXT(), RRTTL(0)));
  198. rrset_version->addRdata(generic::TXT(PACKAGE_STRING));
  199. message.addRRset(Message::SECTION_ANSWER, rrset_version);
  200. RRsetPtr rrset_version_ns = RRsetPtr(new RRset(apex_name, RRClass::CH(),
  201. RRType::NS(), RRTTL(0)));
  202. rrset_version_ns->addRdata(generic::NS(apex_name));
  203. message.addRRset(Message::SECTION_AUTHORITY, rrset_version_ns);
  204. MessageRenderer renderer;
  205. message.toWire(renderer);
  206. data.clear();
  207. data.assign(static_cast<const uint8_t*>(renderer.getData()),
  208. static_cast<const uint8_t*>(renderer.getData()) +
  209. renderer.getLength());
  210. }
  211. // We did not configure any client lists. Therefore it should be REFUSED
  212. TEST_F(AuthSrvTest, noClientList) {
  213. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  214. default_qid, Name("version.bind"),
  215. RRClass::CH(), RRType::TXT());
  216. createRequestPacket(request_message, IPPROTO_UDP);
  217. server.processMessage(*io_message, *parse_message, *response_obuffer,
  218. &dnsserv);
  219. EXPECT_TRUE(dnsserv.hasAnswer());
  220. headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
  221. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  222. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  223. get("_SERVER_");
  224. std::map<std::string, int> expect;
  225. expect["request.v4"] = 1;
  226. expect["request.udp"] = 1;
  227. expect["opcode.query"] = 1;
  228. expect["responses"] = 1;
  229. expect["qrynoauthans"] = 1;
  230. expect["authqryrej"] = 1;
  231. expect["rcode.refused"] = 1;
  232. checkStatisticsCounters(stats_after, expect);
  233. }
  234. // Unsupported requests. Should result in NOTIMP.
  235. TEST_F(AuthSrvTest, unsupportedRequest) {
  236. unsupportedRequest();
  237. // unsupportedRequest tries 13 different opcodes
  238. checkAllRcodeCountersZeroExcept(Rcode::NOTIMP(), 13);
  239. }
  240. // Multiple questions. Should result in FORMERR.
  241. TEST_F(AuthSrvTest, multiQuestion) {
  242. multiQuestion();
  243. checkAllRcodeCountersZeroExcept(Rcode::FORMERR(), 1);
  244. }
  245. // Incoming data doesn't even contain the complete header. Must be silently
  246. // dropped.
  247. TEST_F(AuthSrvTest, shortMessage) {
  248. shortMessage();
  249. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  250. get("_SERVER_");
  251. std::map<std::string, int> expect;
  252. expect["request.v4"] = 1;
  253. expect["request.udp"] = 1;
  254. checkStatisticsCounters(stats_after, expect);
  255. }
  256. // Response messages. Must be silently dropped, whether it's a valid response
  257. // or malformed or could otherwise cause a protocol error.
  258. TEST_F(AuthSrvTest, response) {
  259. // isc::testutils::SrvTestBase::response() processes 3 messages.
  260. response();
  261. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  262. get("_SERVER_");
  263. std::map<std::string, int> expect;
  264. expect["request.v4"] = 3;
  265. expect["request.udp"] = 3;
  266. checkStatisticsCounters(stats_after, expect);
  267. }
  268. // Query with a broken question
  269. TEST_F(AuthSrvTest, shortQuestion) {
  270. shortQuestion();
  271. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  272. get("_SERVER_");
  273. std::map<std::string, int> expect;
  274. expect["request.v4"] = 1;
  275. expect["request.udp"] = 1;
  276. expect["opcode.query"] = 1;
  277. expect["responses"] = 1;
  278. expect["rcode.formerr"] = 1;
  279. expect["qrynoauthans"] = 1;
  280. checkStatisticsCounters(stats_after, expect);
  281. }
  282. // Query with a broken answer section
  283. TEST_F(AuthSrvTest, shortAnswer) {
  284. shortAnswer();
  285. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  286. get("_SERVER_");
  287. std::map<std::string, int> expect;
  288. expect["request.v4"] = 1;
  289. expect["request.udp"] = 1;
  290. expect["opcode.query"] = 1;
  291. expect["responses"] = 1;
  292. expect["rcode.formerr"] = 1;
  293. expect["qrynoauthans"] = 1;
  294. checkStatisticsCounters(stats_after, expect);
  295. }
  296. // Query with unsupported version of EDNS.
  297. TEST_F(AuthSrvTest, ednsBadVers) {
  298. ednsBadVers();
  299. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  300. get("_SERVER_");
  301. std::map<std::string, int> expect;
  302. expect["request.v4"] = 1;
  303. expect["request.badednsver"] = 1;
  304. expect["request.udp"] = 1;
  305. expect["opcode.query"] = 1;
  306. expect["responses"] = 1;
  307. expect["rcode.badvers"] = 1;
  308. expect["qrynoauthans"] = 1;
  309. checkStatisticsCounters(stats_after, expect);
  310. }
  311. TEST_F(AuthSrvTest, AXFROverUDP) {
  312. axfrOverUDP();
  313. }
  314. TEST_F(AuthSrvTest, AXFRSuccess) {
  315. EXPECT_FALSE(xfrout.isConnected());
  316. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  317. Name("example.com"), RRClass::IN(),
  318. RRType::AXFR());
  319. createRequestPacket(request_message, IPPROTO_TCP);
  320. // On success, the AXFR query has been passed to a separate process,
  321. // so we shouldn't have to respond.
  322. server.processMessage(*io_message, *parse_message, *response_obuffer,
  323. &dnsserv);
  324. EXPECT_FALSE(dnsserv.hasAnswer());
  325. EXPECT_TRUE(xfrout.isConnected());
  326. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  327. get("_SERVER_");
  328. std::map<std::string, int> expect;
  329. expect["request.v4"] = 1;
  330. expect["request.tcp"] = 1;
  331. expect["opcode.query"] = 1;
  332. checkStatisticsCounters(stats_after, expect);
  333. }
  334. // Give the server a signed request, but don't give it the key. It will
  335. // not be able to verify it, returning BADKEY
  336. TEST_F(AuthSrvTest, TSIGSignedBadKey) {
  337. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  338. TSIGContext context(key);
  339. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  340. Name("version.bind"), RRClass::CH(),
  341. RRType::TXT());
  342. createRequestPacket(request_message, IPPROTO_UDP, &context);
  343. // Process the message, but use a different key there
  344. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  345. server.setTSIGKeyRing(&keyring);
  346. server.processMessage(*io_message, *parse_message, *response_obuffer,
  347. &dnsserv);
  348. EXPECT_TRUE(dnsserv.hasAnswer());
  349. headerCheck(*parse_message, default_qid, TSIGError::BAD_KEY().toRcode(),
  350. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  351. // We need to parse the message ourself, or getTSIGRecord won't work
  352. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  353. Message m(Message::PARSE);
  354. m.fromWire(ib);
  355. const TSIGRecord* tsig = m.getTSIGRecord();
  356. ASSERT_TRUE(tsig != NULL) <<
  357. "Missing TSIG signature (we should have one even at error)";
  358. EXPECT_EQ(TSIGError::BAD_KEY_CODE, tsig->getRdata().getError());
  359. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  360. "It should be unsigned with this error";
  361. // check Rcode counters and TSIG counters
  362. checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
  363. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  364. get("_SERVER_");
  365. std::map<std::string, int> expect;
  366. expect["request.v4"] = 1;
  367. expect["request.tsig"] = 1;
  368. expect["request.badsig"] = 1;
  369. expect["request.udp"] = 1;
  370. expect["opcode.query"] = 1;
  371. expect["responses"] = 1;
  372. expect["response.tsig"] = 1;
  373. expect["rcode.notauth"] = 1;
  374. checkStatisticsCounters(stats_after, expect);
  375. }
  376. // Give the server a signed request, but signed by a different key
  377. // (with the same name). It should return BADSIG
  378. TEST_F(AuthSrvTest, TSIGBadSig) {
  379. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  380. TSIGContext context(key);
  381. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  382. Name("version.bind"), RRClass::CH(),
  383. RRType::TXT());
  384. createRequestPacket(request_message, IPPROTO_UDP, &context);
  385. // Process the message, but use a different key there
  386. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  387. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  388. server.setTSIGKeyRing(&keyring);
  389. server.processMessage(*io_message, *parse_message, *response_obuffer,
  390. &dnsserv);
  391. EXPECT_TRUE(dnsserv.hasAnswer());
  392. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  393. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  394. // We need to parse the message ourself, or getTSIGRecord won't work
  395. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  396. Message m(Message::PARSE);
  397. m.fromWire(ib);
  398. const TSIGRecord* tsig = m.getTSIGRecord();
  399. ASSERT_TRUE(tsig != NULL) <<
  400. "Missing TSIG signature (we should have one even at error)";
  401. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  402. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  403. "It should be unsigned with this error";
  404. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  405. get("_SERVER_");
  406. std::map<std::string, int> expect;
  407. expect["request.v4"] = 1;
  408. expect["request.tsig"] = 1;
  409. expect["request.badsig"] = 1;
  410. expect["request.udp"] = 1;
  411. expect["opcode.query"] = 1;
  412. expect["responses"] = 1;
  413. expect["response.tsig"] = 1;
  414. expect["rcode.notauth"] = 1;
  415. checkStatisticsCounters(stats_after, expect);
  416. }
  417. // Give the server a signed unsupported request with a bad signature.
  418. // This checks the server first verifies the signature before anything
  419. // else.
  420. TEST_F(AuthSrvTest, TSIGCheckFirst) {
  421. TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  422. TSIGContext context(key);
  423. // Pass a wrong opcode there. The server shouldn't know what to do
  424. // about it.
  425. UnitTestUtil::createRequestMessage(request_message, Opcode::RESERVED14(),
  426. default_qid, Name("version.bind"),
  427. RRClass::CH(), RRType::TXT());
  428. createRequestPacket(request_message, IPPROTO_UDP, &context);
  429. // Process the message, but use a different key there
  430. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  431. keyring->add(TSIGKey("key:QkFECg==:hmac-sha1"));
  432. server.setTSIGKeyRing(&keyring);
  433. server.processMessage(*io_message, *parse_message, *response_obuffer,
  434. &dnsserv);
  435. EXPECT_TRUE(dnsserv.hasAnswer());
  436. headerCheck(*parse_message, default_qid, TSIGError::BAD_SIG().toRcode(),
  437. Opcode::RESERVED14().getCode(), QR_FLAG, 0, 0, 0, 0);
  438. // We need to parse the message ourself, or getTSIGRecord won't work
  439. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  440. Message m(Message::PARSE);
  441. m.fromWire(ib);
  442. const TSIGRecord* tsig = m.getTSIGRecord();
  443. ASSERT_TRUE(tsig != NULL) <<
  444. "Missing TSIG signature (we should have one even at error)";
  445. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
  446. EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
  447. "It should be unsigned with this error";
  448. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  449. get("_SERVER_");
  450. std::map<std::string, int> expect;
  451. expect["request.v4"] = 1;
  452. expect["request.tsig"] = 1;
  453. expect["request.badsig"] = 1;
  454. expect["request.udp"] = 1;
  455. expect["opcode.other"] = 1;
  456. expect["responses"] = 1;
  457. expect["response.tsig"] = 1;
  458. expect["rcode.notauth"] = 1;
  459. checkStatisticsCounters(stats_after, expect);
  460. }
  461. TEST_F(AuthSrvTest, AXFRConnectFail) {
  462. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  463. xfrout.disableConnect();
  464. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  465. Name("example.com"), RRClass::IN(),
  466. RRType::AXFR());
  467. createRequestPacket(request_message, IPPROTO_TCP);
  468. server.processMessage(*io_message, *parse_message, *response_obuffer,
  469. &dnsserv);
  470. EXPECT_TRUE(dnsserv.hasAnswer());
  471. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  472. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  473. EXPECT_FALSE(xfrout.isConnected());
  474. }
  475. TEST_F(AuthSrvTest, AXFRSendFail) {
  476. // first send a valid query, making the connection with the xfr process
  477. // open.
  478. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  479. Name("example.com"), RRClass::IN(),
  480. RRType::AXFR());
  481. createRequestPacket(request_message, IPPROTO_TCP);
  482. server.processMessage(*io_message, *parse_message, *response_obuffer,
  483. &dnsserv);
  484. EXPECT_TRUE(xfrout.isConnected());
  485. xfrout.disableSend();
  486. parse_message->clear(Message::PARSE);
  487. response_obuffer->clear();
  488. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  489. Name("example.com"), RRClass::IN(),
  490. RRType::AXFR());
  491. createRequestPacket(request_message, IPPROTO_TCP);
  492. server.processMessage(*io_message, *parse_message, *response_obuffer,
  493. &dnsserv);
  494. EXPECT_TRUE(dnsserv.hasAnswer());
  495. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  496. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  497. // The connection should have been closed due to the send failure.
  498. EXPECT_FALSE(xfrout.isConnected());
  499. }
  500. TEST_F(AuthSrvTest, AXFRDisconnectFail) {
  501. // In our usage disconnect() shouldn't fail. But even if it does,
  502. // it should not disrupt service (so processMessage should have caught it)
  503. xfrout.disableSend();
  504. xfrout.disableDisconnect();
  505. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  506. Name("example.com"), RRClass::IN(),
  507. RRType::AXFR());
  508. createRequestPacket(request_message, IPPROTO_TCP);
  509. EXPECT_NO_THROW(server.processMessage(*io_message, *parse_message,
  510. *response_obuffer, &dnsserv));
  511. // Since the disconnect failed, we should still be 'connected'
  512. EXPECT_TRUE(xfrout.isConnected());
  513. // XXX: we need to re-enable disconnect. otherwise an exception would be
  514. // thrown via the destructor of the server.
  515. xfrout.enableDisconnect();
  516. }
  517. TEST_F(AuthSrvTest, IXFRConnectFail) {
  518. EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
  519. xfrout.disableConnect();
  520. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  521. Name("example.com"), RRClass::IN(),
  522. RRType::IXFR());
  523. createRequestPacket(request_message, IPPROTO_TCP);
  524. server.processMessage(*io_message, *parse_message, *response_obuffer,
  525. &dnsserv);
  526. EXPECT_TRUE(dnsserv.hasAnswer());
  527. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  528. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  529. EXPECT_FALSE(xfrout.isConnected());
  530. }
  531. TEST_F(AuthSrvTest, IXFRSendFail) {
  532. // first send a valid query, making the connection with the xfr process
  533. // open.
  534. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  535. Name("example.com"), RRClass::IN(),
  536. RRType::IXFR());
  537. createRequestPacket(request_message, IPPROTO_TCP);
  538. server.processMessage(*io_message, *parse_message, *response_obuffer,
  539. &dnsserv);
  540. EXPECT_TRUE(xfrout.isConnected());
  541. xfrout.disableSend();
  542. parse_message->clear(Message::PARSE);
  543. response_obuffer->clear();
  544. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  545. Name("example.com"), RRClass::IN(),
  546. RRType::IXFR());
  547. createRequestPacket(request_message, IPPROTO_TCP);
  548. server.processMessage(*io_message, *parse_message, *response_obuffer,
  549. &dnsserv);
  550. EXPECT_TRUE(dnsserv.hasAnswer());
  551. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  552. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  553. // The connection should have been closed due to the send failure.
  554. EXPECT_FALSE(xfrout.isConnected());
  555. }
  556. TEST_F(AuthSrvTest, IXFRDisconnectFail) {
  557. // In our usage disconnect() shouldn't fail, but even if it does,
  558. // procesMessage() should catch it.
  559. xfrout.disableSend();
  560. xfrout.disableDisconnect();
  561. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  562. Name("example.com"), RRClass::IN(),
  563. RRType::IXFR());
  564. createRequestPacket(request_message, IPPROTO_TCP);
  565. EXPECT_NO_THROW(server.processMessage(*io_message, *parse_message,
  566. *response_obuffer, &dnsserv));
  567. EXPECT_TRUE(xfrout.isConnected());
  568. // XXX: we need to re-enable disconnect. otherwise an exception would be
  569. // thrown via the destructor of the server.
  570. xfrout.enableDisconnect();
  571. }
  572. TEST_F(AuthSrvTest, notify) {
  573. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  574. default_qid, Name("example.com"),
  575. RRClass::IN(), RRType::SOA());
  576. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  577. createRequestPacket(request_message, IPPROTO_UDP);
  578. server.processMessage(*io_message, *parse_message, *response_obuffer,
  579. &dnsserv);
  580. EXPECT_TRUE(dnsserv.hasAnswer());
  581. // An internal command message should have been created and sent to an
  582. // external module. Check them.
  583. EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
  584. EXPECT_EQ("notify",
  585. notify_session.getSentMessage()->get("command")->get(0)->
  586. stringValue());
  587. ConstElementPtr notify_args =
  588. notify_session.getSentMessage()->get("command")->get(1);
  589. EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
  590. EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
  591. notify_args->get("master")->stringValue());
  592. EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
  593. // On success, the server should return a response to the notify.
  594. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  595. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  596. // The question must be identical to that of the received notify
  597. ConstQuestionPtr question = *parse_message->beginQuestion();
  598. EXPECT_EQ(Name("example.com"), question->getName());
  599. EXPECT_EQ(RRClass::IN(), question->getClass());
  600. EXPECT_EQ(RRType::SOA(), question->getType());
  601. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  602. get("_SERVER_");
  603. std::map<std::string, int> expect;
  604. expect["request.v4"] = 1;
  605. expect["request.udp"] = 1;
  606. expect["opcode.notify"] = 1;
  607. expect["responses"] = 1;
  608. expect["rcode.noerror"] = 1;
  609. checkStatisticsCounters(stats_after, expect);
  610. }
  611. TEST_F(AuthSrvTest, notifyForCHClass) {
  612. // Same as the previous test, but for the CH RRClass.
  613. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  614. default_qid, Name("example.com"),
  615. RRClass::CH(), RRType::SOA());
  616. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  617. createRequestPacket(request_message, IPPROTO_UDP);
  618. server.processMessage(*io_message, *parse_message, *response_obuffer,
  619. &dnsserv);
  620. EXPECT_TRUE(dnsserv.hasAnswer());
  621. // Other conditions should be the same, so simply confirm the RR class is
  622. // set correctly.
  623. ConstElementPtr notify_args =
  624. notify_session.getSentMessage()->get("command")->get(1);
  625. EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
  626. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  627. get("_SERVER_");
  628. std::map<std::string, int> expect;
  629. expect["request.v4"] = 1;
  630. expect["request.udp"] = 1;
  631. expect["opcode.notify"] = 1;
  632. expect["responses"] = 1;
  633. expect["rcode.noerror"] = 1;
  634. checkStatisticsCounters(stats_after, expect);
  635. }
  636. TEST_F(AuthSrvTest, notifyEmptyQuestion) {
  637. request_message.clear(Message::RENDER);
  638. request_message.setOpcode(Opcode::NOTIFY());
  639. request_message.setRcode(Rcode::NOERROR());
  640. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  641. request_message.setQid(default_qid);
  642. request_message.toWire(request_renderer);
  643. createRequestPacket(request_message, IPPROTO_UDP);
  644. server.processMessage(*io_message, *parse_message, *response_obuffer,
  645. &dnsserv);
  646. EXPECT_TRUE(dnsserv.hasAnswer());
  647. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  648. Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
  649. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  650. get("_SERVER_");
  651. std::map<std::string, int> expect;
  652. expect["request.v4"] = 1;
  653. expect["request.udp"] = 1;
  654. expect["opcode.notify"] = 1;
  655. expect["responses"] = 1;
  656. expect["rcode.formerr"] = 1;
  657. checkStatisticsCounters(stats_after, expect);
  658. }
  659. TEST_F(AuthSrvTest, notifyMultiQuestions) {
  660. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  661. default_qid, Name("example.com"),
  662. RRClass::IN(), RRType::SOA());
  663. // add one more SOA question
  664. request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
  665. RRType::SOA()));
  666. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  667. createRequestPacket(request_message, IPPROTO_UDP);
  668. server.processMessage(*io_message, *parse_message, *response_obuffer,
  669. &dnsserv);
  670. EXPECT_TRUE(dnsserv.hasAnswer());
  671. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  672. Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
  673. }
  674. TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
  675. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  676. default_qid, Name("example.com"),
  677. RRClass::IN(), RRType::NS());
  678. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  679. createRequestPacket(request_message, IPPROTO_UDP);
  680. server.processMessage(*io_message, *parse_message, *response_obuffer,
  681. &dnsserv);
  682. EXPECT_TRUE(dnsserv.hasAnswer());
  683. headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
  684. Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
  685. }
  686. TEST_F(AuthSrvTest, notifyWithoutAA) {
  687. // implicitly leave the AA bit off. our implementation will accept it.
  688. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  689. default_qid, Name("example.com"),
  690. RRClass::IN(), RRType::SOA());
  691. createRequestPacket(request_message, IPPROTO_UDP);
  692. server.processMessage(*io_message, *parse_message, *response_obuffer,
  693. &dnsserv);
  694. EXPECT_TRUE(dnsserv.hasAnswer());
  695. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  696. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  697. }
  698. TEST_F(AuthSrvTest, notifyWithErrorRcode) {
  699. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  700. default_qid, Name("example.com"),
  701. RRClass::IN(), RRType::SOA());
  702. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  703. request_message.setRcode(Rcode::SERVFAIL());
  704. createRequestPacket(request_message, IPPROTO_UDP);
  705. server.processMessage(*io_message, *parse_message, *response_obuffer,
  706. &dnsserv);
  707. EXPECT_TRUE(dnsserv.hasAnswer());
  708. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  709. Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
  710. }
  711. TEST_F(AuthSrvTest, notifyWithoutSession) {
  712. server.setXfrinSession(NULL);
  713. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  714. default_qid, Name("example.com"),
  715. RRClass::IN(), RRType::SOA());
  716. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  717. createRequestPacket(request_message, IPPROTO_UDP);
  718. // we simply ignore the notify and let it be resent if an internal error
  719. // happens.
  720. server.processMessage(*io_message, *parse_message, *response_obuffer,
  721. &dnsserv);
  722. EXPECT_FALSE(dnsserv.hasAnswer());
  723. }
  724. TEST_F(AuthSrvTest, notifySendFail) {
  725. notify_session.disableSend();
  726. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  727. default_qid, Name("example.com"),
  728. RRClass::IN(), RRType::SOA());
  729. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  730. createRequestPacket(request_message, IPPROTO_UDP);
  731. server.processMessage(*io_message, *parse_message, *response_obuffer,
  732. &dnsserv);
  733. EXPECT_FALSE(dnsserv.hasAnswer());
  734. }
  735. TEST_F(AuthSrvTest, notifyReceiveFail) {
  736. notify_session.disableReceive();
  737. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  738. default_qid, Name("example.com"),
  739. RRClass::IN(), RRType::SOA());
  740. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  741. createRequestPacket(request_message, IPPROTO_UDP);
  742. server.processMessage(*io_message, *parse_message, *response_obuffer,
  743. &dnsserv);
  744. EXPECT_FALSE(dnsserv.hasAnswer());
  745. }
  746. TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
  747. notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
  748. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  749. default_qid, Name("example.com"),
  750. RRClass::IN(), RRType::SOA());
  751. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  752. createRequestPacket(request_message, IPPROTO_UDP);
  753. server.processMessage(*io_message, *parse_message, *response_obuffer,
  754. &dnsserv);
  755. EXPECT_FALSE(dnsserv.hasAnswer());
  756. }
  757. TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
  758. notify_session.setMessage(
  759. Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
  760. UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
  761. default_qid, Name("example.com"),
  762. RRClass::IN(), RRType::SOA());
  763. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  764. createRequestPacket(request_message, IPPROTO_UDP);
  765. server.processMessage(*io_message, *parse_message, *response_obuffer,
  766. &dnsserv);
  767. EXPECT_FALSE(dnsserv.hasAnswer());
  768. }
  769. void
  770. updateDatabase(AuthSrv* server, const char* params) {
  771. const ConstElementPtr config(Element::fromJSON("{"
  772. "\"IN\": [{"
  773. " \"type\": \"sqlite3\","
  774. " \"params\": " + string(params) +
  775. "}]}"));
  776. DataSourceConfigurator::testReconfigure(server, config);
  777. }
  778. void
  779. updateInMemory(AuthSrv* server, const char* origin, const char* filename) {
  780. const ConstElementPtr config(Element::fromJSON("{"
  781. "\"IN\": [{"
  782. " \"type\": \"MasterFiles\","
  783. " \"params\": {"
  784. " \"" + string(origin) + "\": \"" + string(filename) + "\""
  785. " },"
  786. " \"cache-enable\": true"
  787. "}],"
  788. "\"CH\": [{"
  789. " \"type\": \"static\","
  790. " \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
  791. "}]}"));
  792. DataSourceConfigurator::testReconfigure(server, config);
  793. }
  794. void
  795. updateBuiltin(AuthSrv* server) {
  796. const ConstElementPtr config(Element::fromJSON("{"
  797. "\"CH\": [{"
  798. " \"type\": \"static\","
  799. " \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
  800. "}]}"));
  801. DataSourceConfigurator::testReconfigure(server, config);
  802. }
  803. // Try giving the server a TSIG signed request and see it can anwer signed as
  804. // well
  805. #ifdef USE_STATIC_LINK
  806. TEST_F(AuthSrvTest, DISABLED_TSIGSigned) { // Needs builtin
  807. #else
  808. TEST_F(AuthSrvTest, TSIGSigned) {
  809. #endif
  810. // Prepare key, the client message, etc
  811. updateBuiltin(&server);
  812. const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
  813. TSIGContext context(key);
  814. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  815. Name("VERSION.BIND."), RRClass::CH(),
  816. RRType::TXT());
  817. createRequestPacket(request_message, IPPROTO_UDP, &context);
  818. // Run the message through the server
  819. boost::shared_ptr<TSIGKeyRing> keyring(new TSIGKeyRing);
  820. keyring->add(key);
  821. server.setTSIGKeyRing(&keyring);
  822. server.processMessage(*io_message, *parse_message, *response_obuffer,
  823. &dnsserv);
  824. // What did we get?
  825. EXPECT_TRUE(dnsserv.hasAnswer());
  826. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  827. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  828. // We need to parse the message ourself, or getTSIGRecord won't work
  829. InputBuffer ib(response_obuffer->getData(), response_obuffer->getLength());
  830. Message m(Message::PARSE);
  831. m.fromWire(ib);
  832. const TSIGRecord* tsig = m.getTSIGRecord();
  833. ASSERT_TRUE(tsig != NULL) << "Missing TSIG signature";
  834. TSIGError error(context.verify(tsig, response_obuffer->getData(),
  835. response_obuffer->getLength()));
  836. EXPECT_EQ(TSIGError::NOERROR(), error) <<
  837. "The server signed the response, but it doesn't seem to be valid";
  838. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
  839. ConstElementPtr stats_after = server.getStatistics()->get("zones")->
  840. get("_SERVER_");
  841. std::map<std::string, int> expect;
  842. expect["request.v4"] = 1;
  843. expect["request.tsig"] = 1;
  844. expect["request.udp"] = 1;
  845. expect["opcode.query"] = 1;
  846. expect["responses"] = 1;
  847. expect["response.tsig"] = 1;
  848. expect["qrysuccess"] = 1;
  849. expect["qryauthans"] = 1;
  850. expect["rcode.noerror"] = 1;
  851. checkStatisticsCounters(stats_after, expect);
  852. }
  853. // Same test emulating the UDPServer class behavior (defined in libasiolink).
  854. // This is not a good test in that it assumes internal implementation details
  855. // of UDPServer, but we've encountered a regression due to the introduction
  856. // of that class, so we add a test for that case to prevent such a regression
  857. // in future.
  858. // Besides, the generalization of UDPServer is probably too much for the
  859. // authoritative only server in terms of performance, and it's quite likely
  860. // we need to drop it for the authoritative server implementation.
  861. // At that point we can drop this test, too.
  862. #ifdef USE_STATIC_LINK
  863. TEST_F(AuthSrvTest, DISABLED_builtInQueryViaDNSServer) {
  864. #else
  865. TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
  866. #endif
  867. updateBuiltin(&server);
  868. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  869. default_qid, Name("VERSION.BIND."),
  870. RRClass::CH(), RRType::TXT());
  871. createRequestPacket(request_message, IPPROTO_UDP);
  872. (*server.getDNSLookupProvider())(*io_message, parse_message,
  873. response_message,
  874. response_obuffer, &dnsserv);
  875. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  876. response_message, response_obuffer);
  877. createBuiltinVersionResponse(default_qid, response_data);
  878. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  879. response_obuffer->getData(),
  880. response_obuffer->getLength(),
  881. &response_data[0], response_data.size());
  882. // After it has been run, the message should be cleared
  883. EXPECT_EQ(0, parse_message->getRRCount(Message::SECTION_QUESTION));
  884. }
  885. // In the following tests we confirm the response data is rendered in
  886. // wire format in the expected way.
  887. // The most primitive check: checking the result of the processMessage()
  888. // method
  889. #ifdef USE_STATIC_LINK
  890. TEST_F(AuthSrvTest, DISABLED_builtInQuery) {
  891. #else
  892. TEST_F(AuthSrvTest, builtInQuery) {
  893. #endif
  894. updateBuiltin(&server);
  895. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  896. default_qid, Name("VERSION.BIND."),
  897. RRClass::CH(), RRType::TXT());
  898. createRequestPacket(request_message, IPPROTO_UDP);
  899. server.processMessage(*io_message, *parse_message, *response_obuffer,
  900. &dnsserv);
  901. createBuiltinVersionResponse(default_qid, response_data);
  902. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  903. response_obuffer->getData(),
  904. response_obuffer->getLength(),
  905. &response_data[0], response_data.size());
  906. checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
  907. }
  908. // Same type of test as builtInQueryViaDNSServer but for an error response.
  909. #ifdef USE_STATIC_LINK
  910. TEST_F(AuthSrvTest, DISABLED_iqueryViaDNSServer) { // Needs builtin
  911. #else
  912. TEST_F(AuthSrvTest, iqueryViaDNSServer) { // Needs builtin
  913. #endif
  914. updateBuiltin(&server);
  915. createDataFromFile("iquery_fromWire.wire");
  916. (*server.getDNSLookupProvider())(*io_message, parse_message,
  917. response_message,
  918. response_obuffer, &dnsserv);
  919. (*server.getDNSAnswerProvider())(*io_message, parse_message,
  920. response_message, response_obuffer);
  921. UnitTestUtil::readWireData("iquery_response_fromWire.wire",
  922. response_data);
  923. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  924. response_obuffer->getData(),
  925. response_obuffer->getLength(),
  926. &response_data[0], response_data.size());
  927. }
  928. // Install a Sqlite3 data source with testing data.
  929. #ifdef USE_STATIC_LINK
  930. TEST_F(AuthSrvTest, DISABLED_updateConfig) {
  931. #else
  932. TEST_F(AuthSrvTest, updateConfig) {
  933. #endif
  934. updateDatabase(&server, CONFIG_TESTDB);
  935. // query for existent data in the installed data source. The resulting
  936. // response should have the AA flag on, and have an RR in each answer
  937. // and authority section.
  938. createDataFromFile("examplequery_fromWire.wire");
  939. server.processMessage(*io_message, *parse_message, *response_obuffer,
  940. &dnsserv);
  941. EXPECT_TRUE(dnsserv.hasAnswer());
  942. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  943. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  944. }
  945. #ifdef USE_STATIC_LINK
  946. TEST_F(AuthSrvTest, DISABLED_datasourceFail) {
  947. #else
  948. TEST_F(AuthSrvTest, datasourceFail) {
  949. #endif
  950. updateDatabase(&server, CONFIG_TESTDB);
  951. // This query will hit a corrupted entry of the data source (the zoneload
  952. // tool and the data source itself naively accept it). This will result
  953. // in a SERVFAIL response, and the answer and authority sections should
  954. // be empty.
  955. createDataFromFile("badExampleQuery_fromWire.wire");
  956. server.processMessage(*io_message, *parse_message, *response_obuffer,
  957. &dnsserv);
  958. EXPECT_TRUE(dnsserv.hasAnswer());
  959. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  960. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  961. checkAllRcodeCountersZeroExcept(Rcode::SERVFAIL(), 1);
  962. ConstElementPtr stats = server.getStatistics()->get("zones")->
  963. get("_SERVER_");
  964. std::map<std::string, int> expect;
  965. expect["request.v4"] = 1;
  966. expect["request.udp"] = 1;
  967. expect["opcode.query"] = 1;
  968. expect["responses"] = 1;
  969. expect["qrynoauthans"] = 1;
  970. expect["rcode.servfail"] = 1;
  971. checkStatisticsCounters(stats, expect);
  972. }
  973. #ifdef USE_STATIC_LINK
  974. TEST_F(AuthSrvTest, DISABLED_updateConfigFail) {
  975. #else
  976. TEST_F(AuthSrvTest, updateConfigFail) {
  977. #endif
  978. // First, load a valid data source.
  979. updateDatabase(&server, CONFIG_TESTDB);
  980. // Next, try to update it with a non-existent one. This should fail.
  981. EXPECT_THROW(updateDatabase(&server, BADCONFIG_TESTDB),
  982. isc::datasrc::DataSourceError);
  983. // The original data source should still exist.
  984. createDataFromFile("examplequery_fromWire.wire");
  985. server.processMessage(*io_message, *parse_message, *response_obuffer,
  986. &dnsserv);
  987. EXPECT_TRUE(dnsserv.hasAnswer());
  988. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  989. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  990. }
  991. TEST_F(AuthSrvTest, updateWithInMemoryClient) {
  992. // Test configuring memory data source. Detailed test cases are covered
  993. // in the configuration tests. We only check the AuthSrv interface here.
  994. // Create an empty in-memory
  995. const ConstElementPtr config(Element::fromJSON("{"
  996. "\"IN\": [{"
  997. " \"type\": \"MasterFiles\","
  998. " \"params\": {},"
  999. " \"cache-enable\": true"
  1000. "}]}"));
  1001. DataSourceConfigurator::testReconfigure(&server, config);
  1002. // after successful configuration, we should have one (with empty zoneset).
  1003. // The memory data source is empty, should return REFUSED rcode.
  1004. createDataFromFile("examplequery_fromWire.wire");
  1005. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1006. &dnsserv);
  1007. EXPECT_TRUE(dnsserv.hasAnswer());
  1008. headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
  1009. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  1010. }
  1011. #ifdef USE_STATIC_LINK
  1012. TEST_F(AuthSrvTest, DISABLED_queryWithInMemoryClientNoDNSSEC) {
  1013. #else
  1014. TEST_F(AuthSrvTest, queryWithInMemoryClientNoDNSSEC) {
  1015. #endif
  1016. // In this example, we do simple check that query is handled from the
  1017. // query handler class, and confirm it returns no error and a non empty
  1018. // answer section. Detailed examination on the response content
  1019. // for various types of queries are tested in the query tests.
  1020. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1021. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  1022. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1023. &dnsserv);
  1024. EXPECT_TRUE(dnsserv.hasAnswer());
  1025. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1026. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  1027. }
  1028. #ifdef USE_STATIC_LINK
  1029. TEST_F(AuthSrvTest, DISABLED_queryWithInMemoryClientDNSSEC) {
  1030. #else
  1031. TEST_F(AuthSrvTest, queryWithInMemoryClientDNSSEC) {
  1032. #endif
  1033. // Similar to the previous test, but the query has the DO bit on.
  1034. // The response should contain RRSIGs, and should have more RRs than
  1035. // the previous case.
  1036. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1037. createDataFromFile("nsec3query_fromWire.wire");
  1038. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1039. &dnsserv);
  1040. EXPECT_TRUE(dnsserv.hasAnswer());
  1041. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1042. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 2, 3, 3);
  1043. }
  1044. TEST_F(AuthSrvTest,
  1045. #ifdef USE_STATIC_LINK
  1046. DISABLED_chQueryWithInMemoryClient
  1047. #else
  1048. chQueryWithInMemoryClient
  1049. #endif
  1050. )
  1051. {
  1052. // Set up the in-memory
  1053. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1054. // This shouldn't affect the result of class CH query
  1055. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1056. default_qid, Name("VERSION.BIND."),
  1057. RRClass::CH(), RRType::TXT());
  1058. createRequestPacket(request_message, IPPROTO_UDP);
  1059. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1060. &dnsserv);
  1061. EXPECT_TRUE(dnsserv.hasAnswer());
  1062. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1063. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
  1064. }
  1065. #ifdef USE_STATIC_LINK
  1066. TEST_F(AuthSrvTest, DISABLED_queryCounterTruncTest) {
  1067. #else
  1068. TEST_F(AuthSrvTest, queryCounterTruncTest) {
  1069. #endif
  1070. // use CONFIG_TESTDB for large-rdata.example.com.
  1071. updateDatabase(&server, CONFIG_TESTDB);
  1072. // Create UDP message and process.
  1073. // large-rdata.example.com. TXT; expect it exceeds 512 octet
  1074. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1075. default_qid,
  1076. Name("large-rdata.example.com."),
  1077. RRClass::IN(), RRType::TXT());
  1078. createRequestPacket(request_message, IPPROTO_UDP);
  1079. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1080. &dnsserv);
  1081. ConstElementPtr stats_after = server.getStatistics()->
  1082. get("zones")->get("_SERVER_");
  1083. std::map<std::string, int> expect;
  1084. expect["request.v4"] = 1;
  1085. expect["request.udp"] = 1;
  1086. expect["opcode.query"] = 1;
  1087. expect["responses"] = 1;
  1088. expect["response.truncated"] = 1;
  1089. expect["qrysuccess"] = 1;
  1090. expect["qryauthans"] = 1;
  1091. expect["rcode.noerror"] = 1;
  1092. checkStatisticsCounters(stats_after, expect);
  1093. }
  1094. // Submit UDP normal query and check query counter
  1095. TEST_F(AuthSrvTest, queryCounterUDPNormal) {
  1096. // Create UDP message and process.
  1097. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1098. default_qid, Name("example.com"),
  1099. RRClass::IN(), RRType::NS());
  1100. createRequestPacket(request_message, IPPROTO_UDP);
  1101. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1102. &dnsserv);
  1103. ConstElementPtr stats_after = server.getStatistics()->
  1104. get("zones")->get("_SERVER_");
  1105. std::map<std::string, int> expect;
  1106. expect["request.v4"] = 1;
  1107. expect["request.udp"] = 1;
  1108. expect["opcode.query"] = 1;
  1109. expect["responses"] = 1;
  1110. expect["qrynoauthans"] = 1;
  1111. expect["authqryrej"] = 1;
  1112. expect["rcode.refused"] = 1;
  1113. checkStatisticsCounters(stats_after, expect);
  1114. }
  1115. // Submit UDP normal query with DNSSEC and check query counter
  1116. TEST_F(AuthSrvTest, queryCounterUDPNormalWithDNSSEC) {
  1117. // Create UDP message and process.
  1118. UnitTestUtil::createDNSSECRequestMessage(request_message, Opcode::QUERY(),
  1119. default_qid, Name("example.com"),
  1120. RRClass::IN(), RRType::NS());
  1121. createRequestPacket(request_message, IPPROTO_UDP);
  1122. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1123. &dnsserv);
  1124. ConstElementPtr stats_after = server.getStatistics()->
  1125. get("zones")->get("_SERVER_");
  1126. std::map<std::string, int> expect;
  1127. expect["request.v4"] = 1;
  1128. expect["request.edns0"] = 1;
  1129. expect["request.udp"] = 1;
  1130. expect["request.dnssec_ok"] = 1;
  1131. expect["opcode.query"] = 1;
  1132. expect["responses"] = 1;
  1133. expect["qrynoauthans"] = 1;
  1134. expect["authqryrej"] = 1;
  1135. expect["rcode.refused"] = 1;
  1136. // XXX: with the current implementation, EDNS0 is omitted in
  1137. // makeErrorMessage.
  1138. expect["response.edns0"] = 0;
  1139. checkStatisticsCounters(stats_after, expect);
  1140. }
  1141. // Submit TCP normal query and check query counter
  1142. TEST_F(AuthSrvTest, queryCounterTCPNormal) {
  1143. // Create TCP message and process.
  1144. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1145. default_qid, Name("example.com"),
  1146. RRClass::IN(), RRType::NS());
  1147. createRequestPacket(request_message, IPPROTO_TCP);
  1148. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1149. &dnsserv);
  1150. ConstElementPtr stats_after = server.getStatistics()->
  1151. get("zones")->get("_SERVER_");
  1152. std::map<std::string, int> expect;
  1153. expect["request.v4"] = 1;
  1154. expect["request.tcp"] = 1;
  1155. expect["opcode.query"] = 1;
  1156. expect["responses"] = 1;
  1157. expect["qrynoauthans"] = 1;
  1158. expect["authqryrej"] = 1;
  1159. expect["rcode.refused"] = 1;
  1160. checkStatisticsCounters(stats_after, expect);
  1161. }
  1162. // Submit TCP AXFR query and check query counter
  1163. TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
  1164. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  1165. Name("example.com"), RRClass::IN(), RRType::AXFR());
  1166. createRequestPacket(request_message, IPPROTO_TCP);
  1167. // On success, the AXFR query has been passed to a separate process,
  1168. // so auth itself shouldn't respond.
  1169. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1170. &dnsserv);
  1171. EXPECT_FALSE(dnsserv.hasAnswer());
  1172. ConstElementPtr stats_after = server.getStatistics()->
  1173. get("zones")->get("_SERVER_");
  1174. std::map<std::string, int> expect;
  1175. expect["request.v4"] = 1;
  1176. expect["request.tcp"] = 1;
  1177. expect["opcode.query"] = 1;
  1178. checkStatisticsCounters(stats_after, expect);
  1179. }
  1180. // Submit TCP IXFR query and check query counter
  1181. TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
  1182. UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
  1183. Name("example.com"), RRClass::IN(), RRType::IXFR());
  1184. createRequestPacket(request_message, IPPROTO_TCP);
  1185. // On success, the IXFR query has been passed to a separate process,
  1186. // so auth itself shouldn't respond.
  1187. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1188. &dnsserv);
  1189. EXPECT_FALSE(dnsserv.hasAnswer());
  1190. ConstElementPtr stats_after = server.getStatistics()->
  1191. get("zones")->get("_SERVER_");
  1192. std::map<std::string, int> expect;
  1193. expect["request.v4"] = 1;
  1194. expect["request.tcp"] = 1;
  1195. expect["opcode.query"] = 1;
  1196. checkStatisticsCounters(stats_after, expect);
  1197. }
  1198. TEST_F(AuthSrvTest, queryCounterOpcodes) {
  1199. int other_expected = 0;
  1200. for (int i = 0; i < isc::auth::statistics::num_opcode_to_msgcounter; ++i) {
  1201. std::string item_name;
  1202. int expected;
  1203. if (isc::auth::statistics::opcode_to_msgcounter[i] ==
  1204. isc::auth::statistics::MSG_OPCODE_OTHER)
  1205. {
  1206. item_name = "OTHER";
  1207. other_expected += i + 1;
  1208. expected = other_expected;
  1209. } else {
  1210. item_name = Opcode(i).toText();
  1211. expected = i + 1;
  1212. }
  1213. std::transform(item_name.begin(), item_name.end(), item_name.begin(),
  1214. ::tolower);
  1215. // The counter should be initialized to expected value.
  1216. EXPECT_EQ(expected - (i + 1),
  1217. server.getStatistics()->get("zones")->get("_SERVER_")->
  1218. get("opcode")->get(item_name)->intValue());
  1219. // For each possible opcode, create a request message and send it
  1220. UnitTestUtil::createRequestMessage(request_message, Opcode(i),
  1221. default_qid, Name("example.com"),
  1222. RRClass::IN(), RRType::NS());
  1223. createRequestPacket(request_message, IPPROTO_UDP);
  1224. // "send" the request N-th times where N is i + 1 for i-th code.
  1225. // we intentionally use different values for each code
  1226. for (int j = 0; j <= i; ++j) {
  1227. parse_message->clear(Message::PARSE);
  1228. server.processMessage(*io_message, *parse_message,
  1229. *response_obuffer,
  1230. &dnsserv);
  1231. }
  1232. // Confirm the counter.
  1233. // This test only checks for opcodes; some part of the other items
  1234. // depends on the opcode.
  1235. EXPECT_EQ(expected,
  1236. server.getStatistics()->get("zones")->get("_SERVER_")->
  1237. get("opcode")->get(item_name)->intValue());
  1238. }
  1239. }
  1240. // class for queryCounterUnexpected test
  1241. // getProtocol() returns IPPROTO_IP
  1242. class DummyUnknownSocket : public IOSocket {
  1243. public:
  1244. DummyUnknownSocket() {}
  1245. virtual int getNative() const { return (0); }
  1246. virtual int getProtocol() const { return (IPPROTO_IP); }
  1247. };
  1248. // function for queryCounterUnexpected test
  1249. // returns a reference to a static object of DummyUnknownSocket
  1250. IOSocket&
  1251. getDummyUnknownSocket() {
  1252. static DummyUnknownSocket socket;
  1253. return (socket);
  1254. }
  1255. // Submit unexpected type of query and check it is ignored
  1256. TEST_F(AuthSrvTest, queryCounterUnexpected) {
  1257. // This code isn't exception safe, but we'd rather keep the code
  1258. // simpler and more readable as this is only for tests
  1259. // Create UDP query packet.
  1260. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1261. default_qid, Name("example.com"),
  1262. RRClass::IN(), RRType::NS());
  1263. createRequestPacket(request_message, IPPROTO_UDP);
  1264. // Modify the message.
  1265. delete io_message;
  1266. endpoint = IOEndpoint::create(IPPROTO_UDP,
  1267. IOAddress(DEFAULT_REMOTE_ADDRESS), 53210);
  1268. io_message = new IOMessage(request_renderer.getData(),
  1269. request_renderer.getLength(),
  1270. getDummyUnknownSocket(), *endpoint);
  1271. EXPECT_FALSE(dnsserv.hasAnswer());
  1272. }
  1273. TEST_F(AuthSrvTest, stop) {
  1274. // normal case is covered in command_unittest.cc. we should primarily
  1275. // test it here, but the current design of the stop test takes time,
  1276. // so we consolidate the cases in the command tests.
  1277. // If/when the interval timer has finer granularity we'll probably add
  1278. // our own tests here, so we keep this empty test case.
  1279. }
  1280. TEST_F(AuthSrvTest, listenAddresses) {
  1281. isc::testutils::portconfig::listenAddresses(server);
  1282. // Check it requests the correct addresses
  1283. const char* tokens[] = {
  1284. "TCP:127.0.0.1:53210:1",
  1285. "UDP:127.0.0.1:53210:2",
  1286. "TCP:::1:53210:3",
  1287. "UDP:::1:53210:4",
  1288. NULL
  1289. };
  1290. sock_requestor_.checkTokens(tokens, sock_requestor_.given_tokens_,
  1291. "Given tokens");
  1292. // It returns back to empty set of addresses afterwards, so
  1293. // they should be released
  1294. sock_requestor_.checkTokens(tokens, sock_requestor_.released_tokens_,
  1295. "Released tokens");
  1296. }
  1297. TEST_F(AuthSrvTest, processNormalQuery_reuseRenderer1) {
  1298. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1299. default_qid, Name("example.com"),
  1300. RRClass::IN(), RRType::NS());
  1301. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  1302. createRequestPacket(request_message, IPPROTO_UDP);
  1303. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1304. &dnsserv);
  1305. EXPECT_NE(request_message.getRcode(), parse_message->getRcode());
  1306. }
  1307. TEST_F(AuthSrvTest, processNormalQuery_reuseRenderer2) {
  1308. UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
  1309. default_qid, Name("example.com"),
  1310. RRClass::IN(), RRType::SOA());
  1311. request_message.setHeaderFlag(Message::HEADERFLAG_AA);
  1312. createRequestPacket(request_message, IPPROTO_UDP);
  1313. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1314. &dnsserv);
  1315. ConstQuestionPtr question = *parse_message->beginQuestion();
  1316. EXPECT_STRNE(question->getType().toText().c_str(),
  1317. RRType::NS().toText().c_str());
  1318. }
  1319. //
  1320. // Tests for catching exceptions in various stages of the query processing
  1321. //
  1322. // These tests work by defining two proxy classes, that act as an in-memory
  1323. // client by default, but can throw exceptions at various points.
  1324. //
  1325. namespace {
  1326. /// The possible methods to throw in, either in FakeClient or
  1327. /// FakeZoneFinder
  1328. enum ThrowWhen {
  1329. THROW_NEVER,
  1330. THROW_AT_FIND_ZONE,
  1331. THROW_AT_GET_ORIGIN,
  1332. THROW_AT_GET_CLASS,
  1333. THROW_AT_FIND,
  1334. THROW_AT_FIND_ALL,
  1335. THROW_AT_FIND_NSEC3
  1336. };
  1337. /// convenience function to check whether and what to throw
  1338. void
  1339. checkThrow(ThrowWhen method, ThrowWhen throw_at, bool isc_exception) {
  1340. if (method == throw_at) {
  1341. if (isc_exception) {
  1342. isc_throw(isc::Exception, "foo");
  1343. } else {
  1344. throw std::exception();
  1345. }
  1346. }
  1347. }
  1348. /// \brief proxy class for the ZoneFinder returned by the Client
  1349. /// proxied by FakeClient
  1350. ///
  1351. /// See the documentation for FakeClient for more information,
  1352. /// all methods simply check whether they should throw, and if not, call
  1353. /// their proxied equivalent.
  1354. class FakeZoneFinder : public isc::datasrc::ZoneFinder {
  1355. public:
  1356. FakeZoneFinder(isc::datasrc::ZoneFinderPtr zone_finder,
  1357. ThrowWhen throw_when, bool isc_exception,
  1358. ConstRRsetPtr fake_rrset) :
  1359. real_zone_finder_(zone_finder),
  1360. throw_when_(throw_when),
  1361. isc_exception_(isc_exception),
  1362. fake_rrset_(fake_rrset)
  1363. {}
  1364. virtual isc::dns::Name
  1365. getOrigin() const {
  1366. checkThrow(THROW_AT_GET_ORIGIN, throw_when_, isc_exception_);
  1367. return (real_zone_finder_->getOrigin());
  1368. }
  1369. virtual isc::dns::RRClass
  1370. getClass() const {
  1371. checkThrow(THROW_AT_GET_CLASS, throw_when_, isc_exception_);
  1372. return (real_zone_finder_->getClass());
  1373. }
  1374. virtual isc::datasrc::ZoneFinderContextPtr
  1375. find(const isc::dns::Name& name,
  1376. const isc::dns::RRType& type,
  1377. isc::datasrc::ZoneFinder::FindOptions options)
  1378. {
  1379. using namespace isc::datasrc;
  1380. checkThrow(THROW_AT_FIND, throw_when_, isc_exception_);
  1381. // If faked RRset was specified on construction and it matches the
  1382. // query, return it instead of searching the real data source.
  1383. if (fake_rrset_ && fake_rrset_->getName() == name &&
  1384. fake_rrset_->getType() == type)
  1385. {
  1386. return (ZoneFinderContextPtr(new ZoneFinder::Context(
  1387. *this, options,
  1388. ResultContext(SUCCESS,
  1389. fake_rrset_))));
  1390. }
  1391. return (real_zone_finder_->find(name, type, options));
  1392. }
  1393. virtual isc::datasrc::ZoneFinderContextPtr
  1394. findAll(const isc::dns::Name& name,
  1395. std::vector<isc::dns::ConstRRsetPtr> &target,
  1396. const FindOptions options = FIND_DEFAULT)
  1397. {
  1398. checkThrow(THROW_AT_FIND_ALL, throw_when_, isc_exception_);
  1399. return (real_zone_finder_->findAll(name, target, options));
  1400. }
  1401. virtual FindNSEC3Result
  1402. findNSEC3(const isc::dns::Name& name, bool recursive) {
  1403. checkThrow(THROW_AT_FIND_NSEC3, throw_when_, isc_exception_);
  1404. return (real_zone_finder_->findNSEC3(name, recursive));
  1405. }
  1406. private:
  1407. isc::datasrc::ZoneFinderPtr real_zone_finder_;
  1408. ThrowWhen throw_when_;
  1409. bool isc_exception_;
  1410. ConstRRsetPtr fake_rrset_;
  1411. };
  1412. /// \brief Proxy FakeClient that can throw exceptions at specified times
  1413. ///
  1414. /// Currently it is used as an 'InMemoryClient' using setInMemoryClient,
  1415. /// but it is in effect a general datasource client.
  1416. class FakeClient : public isc::datasrc::DataSourceClient {
  1417. public:
  1418. /// \brief Create a proxy memory client
  1419. ///
  1420. /// \param real_client The real (in-memory) client to proxy
  1421. /// \param throw_when if set to any value other than never, that is
  1422. /// the method that will throw an exception (either in this
  1423. /// class or the related FakeZoneFinder)
  1424. /// \param isc_exception if true, throw isc::Exception, otherwise,
  1425. /// throw std::exception
  1426. /// \param fake_rrset If non NULL, it will be used as an answer to
  1427. /// find() for that name and type.
  1428. FakeClient(const DataSourceClient* real_client,
  1429. ThrowWhen throw_when, bool isc_exception,
  1430. ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
  1431. real_client_ptr_(real_client),
  1432. throw_when_(throw_when),
  1433. isc_exception_(isc_exception),
  1434. fake_rrset_(fake_rrset)
  1435. {}
  1436. /// \brief proxy call for findZone
  1437. ///
  1438. /// if this instance was constructed with throw_when set to find_zone,
  1439. /// this method will throw. Otherwise, it will return a FakeZoneFinder
  1440. /// instance which will throw at the method specified at the
  1441. /// construction of this instance.
  1442. virtual FindResult
  1443. findZone(const isc::dns::Name& name) const {
  1444. checkThrow(THROW_AT_FIND_ZONE, throw_when_, isc_exception_);
  1445. const FindResult result =
  1446. real_client_ptr_->findZone(name);
  1447. return (FindResult(result.code, isc::datasrc::ZoneFinderPtr(
  1448. new FakeZoneFinder(result.zone_finder,
  1449. throw_when_,
  1450. isc_exception_,
  1451. fake_rrset_))));
  1452. }
  1453. isc::datasrc::ZoneUpdaterPtr
  1454. getUpdater(const isc::dns::Name&, bool, bool) const {
  1455. isc_throw(isc::NotImplemented,
  1456. "Update attempt on in fake data source");
  1457. }
  1458. std::pair<isc::datasrc::ZoneJournalReader::Result,
  1459. isc::datasrc::ZoneJournalReaderPtr>
  1460. getJournalReader(const isc::dns::Name&, uint32_t, uint32_t) const {
  1461. isc_throw(isc::NotImplemented, "Journaling isn't supported for "
  1462. "fake data source");
  1463. }
  1464. private:
  1465. const DataSourceClient* real_client_ptr_;
  1466. ThrowWhen throw_when_;
  1467. bool isc_exception_;
  1468. ConstRRsetPtr fake_rrset_;
  1469. };
  1470. class FakeList : public isc::datasrc::ConfigurableClientList {
  1471. public:
  1472. /// \brief Creates a fake list for the given in-memory client
  1473. ///
  1474. /// It will create a FakeClient for each client in the original list,
  1475. /// with the given arguments, which is used when searching for the
  1476. /// corresponding data source.
  1477. FakeList(const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1478. real_list, ThrowWhen throw_when, bool isc_exception,
  1479. ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
  1480. ConfigurableClientList(RRClass::IN()),
  1481. real_(real_list)
  1482. {
  1483. BOOST_FOREACH(const DataSourceInfo& info, real_->getDataSources()) {
  1484. const isc::datasrc::DataSourceClientPtr
  1485. client(new FakeClient(info.data_src_client_ != NULL ?
  1486. info.data_src_client_ :
  1487. info.getCacheClient(),
  1488. throw_when, isc_exception, fake_rrset));
  1489. clients_.push_back(client);
  1490. data_sources_.push_back(
  1491. DataSourceInfo(client.get(),
  1492. isc::datasrc::DataSourceClientContainerPtr(),
  1493. false, RRClass::IN(), mem_sgmt_));
  1494. }
  1495. }
  1496. private:
  1497. const boost::shared_ptr<isc::datasrc::ConfigurableClientList> real_;
  1498. vector<isc::datasrc::DataSourceClientPtr> clients_;
  1499. MemorySegmentLocal mem_sgmt_;
  1500. };
  1501. } // end anonymous namespace for throwing proxy classes
  1502. // Test for the tests
  1503. //
  1504. // Set the proxies to never throw, this should have the same result as
  1505. // queryWithInMemoryClientNoDNSSEC, and serves to test the two proxy classes
  1506. TEST_F(AuthSrvTest,
  1507. #ifdef USE_STATIC_LINK
  1508. DISABLED_queryWithInMemoryClientProxy
  1509. #else
  1510. queryWithInMemoryClientProxy
  1511. #endif
  1512. )
  1513. {
  1514. // Set real inmem client to proxy
  1515. updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1516. boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1517. list(new FakeList(server.getClientList(RRClass::IN()), THROW_NEVER,
  1518. false));
  1519. server.setClientList(RRClass::IN(), list);
  1520. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  1521. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1522. &dnsserv);
  1523. EXPECT_TRUE(dnsserv.hasAnswer());
  1524. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1525. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  1526. }
  1527. // Convenience function for the rest of the tests, set up a proxy
  1528. // to throw in the given method
  1529. // If isc_exception is true, it will throw isc::Exception, otherwise
  1530. // it will throw std::exception
  1531. // If non null rrset is given, it will be passed to the proxy so it can
  1532. // return some faked response.
  1533. void
  1534. setupThrow(AuthSrv* server, ThrowWhen throw_when, bool isc_exception,
  1535. ConstRRsetPtr rrset = ConstRRsetPtr())
  1536. {
  1537. updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
  1538. boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1539. list(new FakeList(server->getClientList(RRClass::IN()), throw_when,
  1540. isc_exception, rrset));
  1541. server->setClientList(RRClass::IN(), list);
  1542. }
  1543. TEST_F(AuthSrvTest,
  1544. #ifdef USE_STATIC_LINK
  1545. DISABLED_queryWithThrowingProxyServfails
  1546. #else
  1547. queryWithThrowingProxyServfails
  1548. #endif
  1549. )
  1550. {
  1551. // Test the common cases, all of which should simply return SERVFAIL
  1552. // Use THROW_NEVER as end marker
  1553. ThrowWhen throws[] = { THROW_AT_FIND_ZONE,
  1554. THROW_AT_GET_ORIGIN,
  1555. THROW_AT_FIND,
  1556. THROW_AT_FIND_NSEC3,
  1557. THROW_NEVER };
  1558. UnitTestUtil::createDNSSECRequestMessage(request_message, opcode,
  1559. default_qid, Name("foo.example."),
  1560. RRClass::IN(), RRType::TXT());
  1561. for (ThrowWhen* when(throws); *when != THROW_NEVER; ++when) {
  1562. createRequestPacket(request_message, IPPROTO_UDP);
  1563. setupThrow(&server, *when, true);
  1564. processAndCheckSERVFAIL();
  1565. // To be sure, check same for non-isc-exceptions
  1566. createRequestPacket(request_message, IPPROTO_UDP);
  1567. setupThrow(&server, *when, false);
  1568. processAndCheckSERVFAIL();
  1569. }
  1570. }
  1571. // Throw isc::Exception in getClass(). (Currently?) getClass is not called
  1572. // in the processMessage path, so this should result in a normal answer
  1573. TEST_F(AuthSrvTest,
  1574. #ifdef USE_STATIC_LINK
  1575. DISABLED_queryWithInMemoryClientProxyGetClass
  1576. #else
  1577. queryWithInMemoryClientProxyGetClass
  1578. #endif
  1579. )
  1580. {
  1581. createDataFromFile("nsec3query_nodnssec_fromWire.wire");
  1582. setupThrow(&server, THROW_AT_GET_CLASS, true);
  1583. // getClass is not called so it should just answer
  1584. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1585. &dnsserv);
  1586. EXPECT_TRUE(dnsserv.hasAnswer());
  1587. headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
  1588. opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 2, 1);
  1589. }
  1590. TEST_F(AuthSrvTest,
  1591. #ifdef USE_STATIC_LINK
  1592. DISABLED_queryWithThrowingInToWire
  1593. #else
  1594. queryWithThrowingInToWire
  1595. #endif
  1596. )
  1597. {
  1598. // Set up a faked data source. It will return an empty RRset for the
  1599. // query.
  1600. ConstRRsetPtr empty_rrset(new RRset(Name("foo.example"),
  1601. RRClass::IN(), RRType::TXT(),
  1602. RRTTL(0)));
  1603. setupThrow(&server, THROW_NEVER, true, empty_rrset);
  1604. // Repeat the query processing two times. Due to the faked RRset,
  1605. // toWire() should throw, and it should result in SERVFAIL.
  1606. OutputBufferPtr orig_buffer;
  1607. for (int i = 0; i < 2; ++i) {
  1608. UnitTestUtil::createDNSSECRequestMessage(request_message, opcode,
  1609. default_qid,
  1610. Name("foo.example."),
  1611. RRClass::IN(), RRType::TXT());
  1612. createRequestPacket(request_message, IPPROTO_UDP);
  1613. server.processMessage(*io_message, *parse_message, *response_obuffer,
  1614. &dnsserv);
  1615. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1616. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  1617. // Make a backup of the original buffer for latest tests and replace
  1618. // it with a new one
  1619. if (!orig_buffer) {
  1620. orig_buffer = response_obuffer;
  1621. response_obuffer.reset(new OutputBuffer(0));
  1622. }
  1623. request_message.clear(Message::RENDER);
  1624. parse_message->clear(Message::PARSE);
  1625. }
  1626. // Now check if the original buffer is intact
  1627. parse_message->clear(Message::PARSE);
  1628. InputBuffer ibuffer(orig_buffer->getData(), orig_buffer->getLength());
  1629. parse_message->fromWire(ibuffer);
  1630. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1631. opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
  1632. }
  1633. //
  1634. // DDNS related tests
  1635. //
  1636. // Helper subroutine to check if the given socket address has the expected
  1637. // address and port. It depends on specific output of getnameinfo() (while
  1638. // there can be multiple textual representation of the same address) but
  1639. // in practice it should be reliable.
  1640. void
  1641. checkAddrPort(const struct sockaddr& actual_sa,
  1642. const string& expected_addr, uint16_t expected_port)
  1643. {
  1644. char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
  1645. const int error = getnameinfo(&actual_sa, getSALength(actual_sa), hbuf,
  1646. sizeof(hbuf), sbuf, sizeof(sbuf),
  1647. NI_NUMERICHOST | NI_NUMERICSERV);
  1648. if (error != 0) {
  1649. isc_throw(isc::Unexpected, "getnameinfo failed: " <<
  1650. gai_strerror(error));
  1651. }
  1652. EXPECT_EQ(expected_addr, hbuf);
  1653. EXPECT_EQ(boost::lexical_cast<string>(expected_port), sbuf);
  1654. }
  1655. TEST_F(AuthSrvTest, DDNSForward) {
  1656. EXPECT_FALSE(ddns_forwarder.isConnected());
  1657. // Repeat sending an update request 4 times, differing some network
  1658. // parameters: UDP/IPv4, TCP/IPv4, UDP/IPv6, TCP/IPv6, in this order.
  1659. // By doing that we can also confirm the forwarder connection will be
  1660. // established exactly once, and kept established.
  1661. for (size_t i = 0; i < 4; ++i) {
  1662. // Use different names for some different cases
  1663. const Name zone_name = Name(i < 2 ? "example.com" : "example.org");
  1664. const socklen_t family = (i < 2) ? AF_INET : AF_INET6;
  1665. const char* const remote_addr =
  1666. (family == AF_INET) ? "192.0.2.1" : "2001:db8::1";
  1667. const uint16_t remote_port =
  1668. (family == AF_INET) ? 53214 : 53216;
  1669. const int protocol = ((i % 2) == 0) ? IPPROTO_UDP : IPPROTO_TCP;
  1670. createAndSendRequest(RRType::SOA(), Opcode::UPDATE(), zone_name,
  1671. RRClass::IN(), protocol, remote_addr,
  1672. remote_port);
  1673. EXPECT_FALSE(dnsserv.hasAnswer());
  1674. EXPECT_TRUE(ddns_forwarder.isConnected());
  1675. // Examine the pushed data (note: currently "local end" has a dummy
  1676. // value equal to remote)
  1677. EXPECT_EQ(family, ddns_forwarder.getPushedFamily());
  1678. const int expected_type =
  1679. (protocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
  1680. EXPECT_EQ(expected_type, ddns_forwarder.getPushedType());
  1681. EXPECT_EQ(protocol, ddns_forwarder.getPushedProtocol());
  1682. checkAddrPort(ddns_forwarder.getPushedRemoteend(),
  1683. remote_addr, remote_port);
  1684. checkAddrPort(ddns_forwarder.getPushedLocalend(),
  1685. remote_addr, remote_port);
  1686. EXPECT_EQ(io_message->getDataSize(),
  1687. ddns_forwarder.getPushedData().size());
  1688. EXPECT_EQ(0, memcmp(io_message->getData(),
  1689. &ddns_forwarder.getPushedData()[0],
  1690. ddns_forwarder.getPushedData().size()));
  1691. }
  1692. }
  1693. TEST_F(AuthSrvTest, DDNSForwardConnectFail) {
  1694. // make connect attempt fail. It should result in SERVFAIL. Note that
  1695. // the question (zone) section should be cleared for opcode of update.
  1696. ddns_forwarder.disableConnect();
  1697. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1698. EXPECT_TRUE(dnsserv.hasAnswer());
  1699. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1700. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1701. EXPECT_FALSE(ddns_forwarder.isConnected());
  1702. // Now make connect okay again. Despite the previous failure the new
  1703. // connection should now be established.
  1704. ddns_forwarder.enableConnect();
  1705. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1706. EXPECT_FALSE(dnsserv.hasAnswer());
  1707. EXPECT_TRUE(ddns_forwarder.isConnected());
  1708. }
  1709. TEST_F(AuthSrvTest, DDNSForwardPushFail) {
  1710. // Make first request succeed, which will establish the connection.
  1711. EXPECT_FALSE(ddns_forwarder.isConnected());
  1712. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1713. EXPECT_TRUE(ddns_forwarder.isConnected());
  1714. // make connect attempt fail. It should result in SERVFAIL. The
  1715. // connection should be closed. Use IPv6 address for varying log output.
  1716. ddns_forwarder.disablePush();
  1717. createAndSendRequest(RRType::SOA(), Opcode::UPDATE(), Name("example.com"),
  1718. RRClass::IN(), IPPROTO_UDP, "2001:db8::2");
  1719. EXPECT_TRUE(dnsserv.hasAnswer());
  1720. headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
  1721. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1722. EXPECT_FALSE(ddns_forwarder.isConnected());
  1723. // Allow push again. Connection will be reopened, and the request will
  1724. // be forwarded successfully.
  1725. ddns_forwarder.enablePush();
  1726. createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
  1727. EXPECT_FALSE(dnsserv.hasAnswer());
  1728. EXPECT_TRUE(ddns_forwarder.isConnected());
  1729. }
  1730. TEST_F(AuthSrvTest, DDNSForwardClose) {
  1731. scoped_ptr<AuthSrv> tmp_server(new AuthSrv(xfrout, ddns_forwarder));
  1732. tmp_server->createDDNSForwarder();
  1733. UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
  1734. default_qid, Name("example.com"),
  1735. RRClass::IN(), RRType::SOA());
  1736. createRequestPacket(request_message, IPPROTO_UDP);
  1737. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1738. &dnsserv);
  1739. EXPECT_FALSE(dnsserv.hasAnswer());
  1740. EXPECT_TRUE(ddns_forwarder.isConnected());
  1741. // Destroy the server. The forwarder should close the connection.
  1742. tmp_server.reset();
  1743. EXPECT_FALSE(ddns_forwarder.isConnected());
  1744. }
  1745. namespace {
  1746. // Send a basic command without arguments, and check the response has
  1747. // result code 0
  1748. void sendSimpleCommand(AuthSrv& server, const std::string& command) {
  1749. ConstElementPtr response = execAuthServerCommand(server, command,
  1750. ConstElementPtr());
  1751. int command_result = -1;
  1752. isc::config::parseAnswer(command_result, response);
  1753. EXPECT_EQ(0, command_result);
  1754. }
  1755. } // end anonymous namespace
  1756. TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
  1757. // Test that AuthSrv returns NOTIMP before ddns forwarder is created,
  1758. // that the ddns_forwarder is connected when the 'start_ddns_forwarder'
  1759. // command has been sent, and that it is no longer connected and auth
  1760. // returns NOTIMP after the stop_ddns_forwarding command is sent.
  1761. scoped_ptr<AuthSrv> tmp_server(new AuthSrv(xfrout, ddns_forwarder));
  1762. // Prepare update message to send
  1763. UnitTestUtil::createRequestMessage(request_message, Opcode::UPDATE(),
  1764. default_qid, Name("example.com"),
  1765. RRClass::IN(), RRType::SOA());
  1766. createRequestPacket(request_message, IPPROTO_UDP);
  1767. // before creating forwarder. isConnected() should be false and
  1768. // rcode to UPDATE should be NOTIMP
  1769. parse_message->clear(Message::PARSE);
  1770. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1771. &dnsserv);
  1772. EXPECT_FALSE(ddns_forwarder.isConnected());
  1773. EXPECT_TRUE(dnsserv.hasAnswer());
  1774. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1775. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1776. // now create forwarder
  1777. sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
  1778. // our mock does not respond, and since auth is supposed to send it on,
  1779. // there should now be no result when an UPDATE is sent
  1780. parse_message->clear(Message::PARSE);
  1781. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1782. &dnsserv);
  1783. EXPECT_FALSE(dnsserv.hasAnswer());
  1784. EXPECT_TRUE(ddns_forwarder.isConnected());
  1785. // If we send a start again, the connection should be recreated,
  1786. // visible because isConnected() reports false until an actual message
  1787. // has been forwarded
  1788. sendSimpleCommand(*tmp_server, "start_ddns_forwarder");
  1789. EXPECT_FALSE(ddns_forwarder.isConnected());
  1790. parse_message->clear(Message::PARSE);
  1791. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1792. &dnsserv);
  1793. EXPECT_FALSE(dnsserv.hasAnswer());
  1794. EXPECT_TRUE(ddns_forwarder.isConnected());
  1795. // Now tell it to stop forwarder, should respond with NOTIMP again
  1796. sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
  1797. parse_message->clear(Message::PARSE);
  1798. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1799. &dnsserv);
  1800. EXPECT_FALSE(ddns_forwarder.isConnected());
  1801. EXPECT_TRUE(dnsserv.hasAnswer());
  1802. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1803. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1804. // Sending stop again should make no difference
  1805. sendSimpleCommand(*tmp_server, "stop_ddns_forwarder");
  1806. parse_message->clear(Message::PARSE);
  1807. tmp_server->processMessage(*io_message, *parse_message, *response_obuffer,
  1808. &dnsserv);
  1809. EXPECT_FALSE(ddns_forwarder.isConnected());
  1810. EXPECT_TRUE(dnsserv.hasAnswer());
  1811. headerCheck(*parse_message, default_qid, Rcode::NOTIMP(),
  1812. Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
  1813. }
  1814. // Check the client list accessors
  1815. TEST_F(AuthSrvTest, clientList) {
  1816. // The lists don't exist. Therefore, the list of RRClasses is empty.
  1817. // We also have no IN list.
  1818. EXPECT_TRUE(server.getClientListClasses().empty());
  1819. EXPECT_EQ(boost::shared_ptr<const isc::datasrc::ClientList>(),
  1820. server.getClientList(RRClass::IN()));
  1821. // Put something in.
  1822. const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1823. list(new isc::datasrc::ConfigurableClientList(RRClass::IN()));
  1824. const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  1825. list2(new isc::datasrc::ConfigurableClientList(RRClass::CH()));
  1826. server.setClientList(RRClass::IN(), list);
  1827. server.setClientList(RRClass::CH(), list2);
  1828. // There are two things in the list and they are IN and CH
  1829. vector<RRClass> classes(server.getClientListClasses());
  1830. ASSERT_EQ(2, classes.size());
  1831. EXPECT_EQ(RRClass::IN(), classes[0]);
  1832. EXPECT_EQ(RRClass::CH(), classes[1]);
  1833. // And the lists can be retrieved.
  1834. EXPECT_EQ(list, server.getClientList(RRClass::IN()));
  1835. EXPECT_EQ(list2, server.getClientList(RRClass::CH()));
  1836. // Remove one of them
  1837. server.setClientList(RRClass::CH(),
  1838. boost::shared_ptr<isc::datasrc::ConfigurableClientList>());
  1839. // This really got deleted, including the class.
  1840. classes = server.getClientListClasses();
  1841. ASSERT_EQ(1, classes.size());
  1842. EXPECT_EQ(RRClass::IN(), classes[0]);
  1843. EXPECT_EQ(list, server.getClientList(RRClass::IN()));
  1844. }
  1845. }