auth_srv_unittest.cc 84 KB

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