auth_srv_unittest.cc 75 KB

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