zone_entry_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  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 <gtest/gtest.h>
  16. #include <boost/shared_ptr.hpp>
  17. #include <boost/foreach.hpp>
  18. #include <boost/lexical_cast.hpp>
  19. #include <cmath>
  20. #include <dns/rrclass.h>
  21. #include <dns/rdataclass.h>
  22. #include "../asiolink.h"
  23. #include "../zone_entry.h"
  24. #include "../nameserver_entry.h"
  25. #include "../address_request_callback.h"
  26. #include "../nsas_entry_compare.h"
  27. #include "../hash_deleter.h"
  28. #include "nsas_test.h"
  29. using namespace isc::nsas;
  30. using namespace asiolink;
  31. using namespace std;
  32. using namespace isc::dns;
  33. namespace {
  34. /// \brief Inherited version with access into its internals for tests
  35. class InheritedZoneEntry : public ZoneEntry {
  36. public:
  37. InheritedZoneEntry(
  38. boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
  39. const std::string& name, const RRClass& class_code,
  40. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
  41. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru) :
  42. ZoneEntry(resolver, name, class_code, nameserver_table,
  43. nameserver_lru)
  44. { }
  45. NameserverVector& nameservers() { return nameservers_; }
  46. };
  47. /// \brief Test Fixture Class
  48. class ZoneEntryTest : public TestWithRdata {
  49. protected:
  50. /// \brief Constructor
  51. ZoneEntryTest() :
  52. nameserver_table_(new HashTable<NameserverEntry>(
  53. new NsasEntryCompare<NameserverEntry>)),
  54. nameserver_lru_(new LruList<NameserverEntry>(
  55. (3 * nameserver_table_->tableSize()),
  56. new HashDeleter<NameserverEntry>(*nameserver_table_))),
  57. resolver_(new TestResolver),
  58. callback_(new Callback)
  59. { }
  60. /// \brief Tables of nameservers to pass into zone entry constructor
  61. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table_;
  62. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru_;
  63. /// \brief The resolver
  64. boost::shared_ptr<TestResolver> resolver_;
  65. /**
  66. * \short A callback we use into the zone.
  67. *
  68. * It counts failures and stores successufll results.
  69. */
  70. struct Callback : public AddressRequestCallback {
  71. Callback() : unreachable_count_(0) {}
  72. size_t unreachable_count_;
  73. vector<NameserverAddress> successes_;
  74. virtual void unreachable() { unreachable_count_ ++; }
  75. virtual void success(const NameserverAddress& address) {
  76. successes_.push_back(address);
  77. }
  78. };
  79. boost::shared_ptr<Callback> callback_;
  80. // Empty callback to pass to nameserver entry, to do injection of them
  81. struct NseCallback : public NameserverEntry::Callback {
  82. virtual void operator()(boost::shared_ptr<NameserverEntry>) { }
  83. };
  84. boost::shared_ptr<NseCallback> nseCallback() {
  85. return (boost::shared_ptr<NseCallback>(new NseCallback));
  86. }
  87. /**
  88. * \short Function returning a new zone.
  89. *
  90. * Convenience funcion, just creating a new zone, to shorten the code.
  91. */
  92. boost::shared_ptr<InheritedZoneEntry> getZone() {
  93. return (boost::shared_ptr<InheritedZoneEntry>(new InheritedZoneEntry(
  94. resolver_, EXAMPLE_CO_UK, RRClass::IN(), nameserver_table_,
  95. nameserver_lru_)));
  96. }
  97. /**
  98. * \short Creates and injects a NameserverEntry
  99. *
  100. * This is used by few tests checking it works when the nameserver
  101. * hash table already contains the NameserverEntry. This function
  102. * creates one and puts it into the hash table.
  103. */
  104. boost::shared_ptr<NameserverEntry> injectEntry() {
  105. boost::shared_ptr<NameserverEntry> nse(new NameserverEntry(ns_name_.toText(),
  106. RRClass::IN()));
  107. nameserver_table_->add(nse, HashKey(ns_name_.toText(), RRClass::IN()));
  108. EXPECT_EQ(Fetchable::NOT_ASKED, nse->getState());
  109. return (nse);
  110. }
  111. /**
  112. * \short Common part of few tests.
  113. *
  114. * All the tests NameserverEntryReady, NameserverEntryNotAsked,
  115. * NameserverEntryInProgress, NameserverEntryExpired,
  116. * NameserverEntryUnreachable check that it does not break
  117. * when the nameserver hash table already contains the nameserver
  118. * in one of the Fetchable::State.
  119. *
  120. * All the tests prepare the NameserverEntry and then call this
  121. * to see if the zone really works. This asks and checks if it
  122. * asks for the IP addresses or not and if it succeeds or fails.
  123. *
  124. * \param answer Should it ask for IP addresses of the nameserver?
  125. * If not, it expects it already asked during the preparation
  126. * (therefore the request count in resolver is 2).
  127. * \param success_count How many callbacks to the zone should
  128. * succeed.
  129. * \param failure_count How many callbacks to the zone should
  130. * fail.
  131. */
  132. void checkInjected(bool answer, size_t success_count = 1,
  133. size_t failure_count = 0)
  134. {
  135. // Create the zone and check it acts correctly
  136. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  137. resolver_->addPresetAnswer(Question(Name(EXAMPLE_CO_UK), RRClass::IN(),
  138. RRType::NS()), rr_single_);
  139. zone->addCallback(callback_, ANY_OK);
  140. EXPECT_EQ(2, resolver_->requests.size());
  141. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
  142. if (answer) {
  143. EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
  144. rdata::in::A("192.0.2.1")));
  145. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
  146. rdata::in::AAAA("2001:db8::1")));
  147. }
  148. // Check the answers
  149. EXPECT_EQ(Fetchable::READY, zone->getState());
  150. EXPECT_EQ(failure_count, callback_->unreachable_count_);
  151. EXPECT_EQ(success_count, callback_->successes_.size());
  152. for (size_t i = 0; i < callback_->successes_.size(); ++ i) {
  153. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  154. callback_->successes_[i].getAddress()) ||
  155. IOAddress("2001:db8::1").equal(
  156. callback_->successes_[i].getAddress()));
  157. }
  158. }
  159. };
  160. /// Tests of the default constructor
  161. TEST_F(ZoneEntryTest, DefaultConstructor) {
  162. // Default constructor should not create any RRsets
  163. InheritedZoneEntry alpha(resolver_, EXAMPLE_CO_UK,
  164. RRClass::IN(), nameserver_table_, nameserver_lru_);
  165. EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
  166. EXPECT_EQ(RRClass::IN(), alpha.getClass());
  167. EXPECT_TRUE(alpha.nameservers().empty());
  168. }
  169. /**
  170. * \short Test with no nameservers.
  171. *
  172. * When we create a zone that does not have any nameservers,
  173. * it should return failures right away (eg. no queries to nameservers
  174. * should be generated anywhere and the failure should be provided).
  175. */
  176. TEST_F(ZoneEntryTest, CallbackNoNS) {
  177. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  178. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  179. // feed it with a callback
  180. zone->addCallback(callback_, ANY_OK);
  181. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  182. // Give it the (empty) nameserver list
  183. EXPECT_NO_THROW(resolver_->provideNS(0, rr_empty_));
  184. // It should tell us it is unreachable.
  185. EXPECT_TRUE(callback_->successes_.empty());
  186. EXPECT_EQ(1, callback_->unreachable_count_);
  187. }
  188. /**
  189. * \short Test how the zone behaves when the list of nameserves change.
  190. *
  191. * We use TTL of 0, so it asks every time for new list of nameservers.
  192. * This allows us to pass a different list each time.
  193. *
  194. * So, this implicitly tests that it behaves correctly with 0 TTL as well,
  195. * it means that it answers even with 0 TTL and that it answers only
  196. * one query (or, all queries queued at that time).
  197. *
  198. * We change the list twice, to see it can ask for another nameserver and
  199. * then to see if it can return to the previous (already cached) nameserver.
  200. */
  201. TEST_F(ZoneEntryTest, ChangedNS) {
  202. // Make it zero TTL, so it expires right away
  203. rr_single_->setTTL(RRTTL(0));
  204. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  205. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  206. // Feed it with callback
  207. zone->addCallback(callback_, ANY_OK);
  208. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  209. EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
  210. // It should not be answered yet, it should ask for the IP addresses
  211. // (trough the NameserverEntry there)
  212. EXPECT_TRUE(callback_->successes_.empty());
  213. EXPECT_EQ(0, callback_->unreachable_count_);
  214. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
  215. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
  216. rdata::in::A("192.0.2.1")));
  217. ASSERT_EQ(1, callback_->successes_.size());
  218. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  219. callback_->successes_[0].getAddress()));
  220. EXPECT_NO_THROW(resolver_->answer(2, ns_name_, RRType::AAAA(),
  221. rdata::in::AAAA("2001:db8::1")));
  222. EXPECT_EQ(1, callback_->successes_.size());
  223. // It should request the NSs again, as TTL is 0
  224. zone->addCallback(callback_, ANY_OK);
  225. EXPECT_EQ(4, resolver_->requests.size());
  226. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  227. Name different_name("ns.example.com");
  228. // Create a different answer
  229. RRsetPtr different_ns(new RRset(Name(EXAMPLE_CO_UK), RRClass::IN(),
  230. RRType::NS(), RRTTL(0)));
  231. different_ns->addRdata(rdata::generic::NS(different_name));
  232. EXPECT_NO_THROW(resolver_->provideNS(3, different_ns));
  233. // It should become ready and ask for the new nameserver addresses
  234. EXPECT_EQ(Fetchable::READY, zone->getState());
  235. // Answer one of the IP addresses, we should get an address now
  236. EXPECT_TRUE(resolver_->asksIPs(different_name, 4, 5));
  237. EXPECT_NO_THROW(resolver_->answer(4, different_name, RRType::A(),
  238. rdata::in::A("192.0.2.2")));
  239. ASSERT_EQ(2, callback_->successes_.size());
  240. EXPECT_TRUE(IOAddress("192.0.2.2").equal(
  241. callback_->successes_[1].getAddress()));
  242. // And now, switch back, as it timed out again
  243. zone->addCallback(callback_, ANY_OK);
  244. EXPECT_EQ(7, resolver_->requests.size());
  245. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  246. // When we answer with the original, it should still be cached and
  247. // we should get the answer
  248. EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
  249. EXPECT_EQ(7, resolver_->requests.size());
  250. EXPECT_EQ(Fetchable::READY, zone->getState());
  251. ASSERT_EQ(3, callback_->successes_.size());
  252. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  253. callback_->successes_[0].getAddress()));
  254. }
  255. /**
  256. * \short Check it works when everything is answered.
  257. *
  258. * This test emulates a situation when all queries for NS rrsets and
  259. * IP addresses (of the NameserverEntry objects inside) are answered
  260. * positively. All the callbacks should be called and answer to them
  261. * provided.
  262. */
  263. TEST_F(ZoneEntryTest, CallbacksAnswered) {
  264. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  265. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  266. // Feed it with a callback
  267. zone->addCallback(callback_, ANY_OK);
  268. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  269. EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
  270. // It should not be answered yet, its NameserverEntry should ask for the
  271. // IP addresses
  272. EXPECT_TRUE(callback_->successes_.empty());
  273. EXPECT_EQ(0, callback_->unreachable_count_);
  274. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
  275. // We should be READY, as it marks we have nameservers
  276. // (not that they are ready)
  277. EXPECT_EQ(Fetchable::READY, zone->getState());
  278. // Give two more callbacks, with different address families
  279. zone->addCallback(callback_, V4_ONLY);
  280. zone->addCallback(callback_, V6_ONLY);
  281. // Nothing more is asked
  282. EXPECT_EQ(3, resolver_->requests.size());
  283. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
  284. rdata::in::A("192.0.2.1")));
  285. // Two are answered (ANY and V4)
  286. ASSERT_EQ(2, callback_->successes_.size());
  287. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  288. callback_->successes_[0].getAddress()));
  289. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  290. callback_->successes_[1].getAddress()));
  291. // None are rejected
  292. EXPECT_EQ(0, callback_->unreachable_count_);
  293. // Answer the IPv6 one as well
  294. EXPECT_NO_THROW(resolver_->answer(2, ns_name_, RRType::AAAA(),
  295. rdata::in::AAAA("2001:db8::1")));
  296. // This should answer the third callback
  297. EXPECT_EQ(0, callback_->unreachable_count_);
  298. ASSERT_EQ(3, callback_->successes_.size());
  299. EXPECT_TRUE(IOAddress("2001:db8::1").equal(
  300. callback_->successes_[2].getAddress()));
  301. // It should think it is ready
  302. EXPECT_EQ(Fetchable::READY, zone->getState());
  303. // When we ask something more, it should be answered right away
  304. zone->addCallback(callback_, V4_ONLY);
  305. EXPECT_EQ(3, resolver_->requests.size());
  306. ASSERT_EQ(4, callback_->successes_.size());
  307. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  308. callback_->successes_[3].getAddress()));
  309. EXPECT_EQ(0, callback_->unreachable_count_);
  310. }
  311. /**
  312. * \short Test zone reachable only on IPv4.
  313. *
  314. * This test simulates a zone with its nameservers reachable only
  315. * over IPv4. It means we answer the NS query, the A query, but
  316. * we generate a failure for AAAA.
  317. *
  318. * The callbacks asking for any address and IPv4 address should be
  319. * called successfully, while the ones asking for IPv6 addresses should
  320. * fail.
  321. */
  322. TEST_F(ZoneEntryTest, CallbacksAOnly) {
  323. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  324. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  325. zone->addCallback(callback_, ANY_OK);
  326. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  327. EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
  328. // It should not be answered yet, it should ask for the IP addresses
  329. EXPECT_TRUE(callback_->successes_.empty());
  330. EXPECT_EQ(0, callback_->unreachable_count_);
  331. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
  332. EXPECT_EQ(Fetchable::READY, zone->getState());
  333. // Give two more callbacks, with different address families
  334. zone->addCallback(callback_, V4_ONLY);
  335. zone->addCallback(callback_, V6_ONLY);
  336. ASSERT_GE(resolver_->requests.size(), 3);
  337. // We tell its NameserverEntry we can't get IPv6 address
  338. resolver_->requests[2].second->failure();
  339. // One should be rejected (V6_ONLY one), but two still stay
  340. EXPECT_EQ(0, callback_->successes_.size());
  341. EXPECT_EQ(1, callback_->unreachable_count_);
  342. // Answer the A one and see it answers what can be answered
  343. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
  344. rdata::in::A("192.0.2.1")));
  345. ASSERT_EQ(2, callback_->successes_.size());
  346. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  347. callback_->successes_[0].getAddress()));
  348. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  349. callback_->successes_[1].getAddress()));
  350. EXPECT_EQ(1, callback_->unreachable_count_);
  351. // Everything arriwed, so we are ready
  352. EXPECT_EQ(Fetchable::READY, zone->getState());
  353. // Try asking something more and see it asks no more
  354. zone->addCallback(callback_, V4_ONLY);
  355. EXPECT_EQ(3, resolver_->requests.size());
  356. ASSERT_EQ(3, callback_->successes_.size());
  357. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  358. callback_->successes_[2].getAddress()));
  359. EXPECT_EQ(1, callback_->unreachable_count_);
  360. zone->addCallback(callback_, V6_ONLY);
  361. EXPECT_EQ(3, resolver_->requests.size());
  362. EXPECT_EQ(3, callback_->successes_.size());
  363. EXPECT_EQ(2, callback_->unreachable_count_);
  364. }
  365. /**
  366. * \short Test with unreachable and v6-reachable nameserver.
  367. *
  368. * In this test we have a zone with two nameservers. The first one of them
  369. * is unreachable, it will not have any addresses. We check that the ZoneEntry
  370. * is patient and asks and waits for the second one and then returns the
  371. * (successful) answers to us.
  372. */
  373. TEST_F(ZoneEntryTest, CallbackTwoNS) {
  374. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  375. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  376. zone->addCallback(callback_, V4_ONLY);
  377. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  378. EXPECT_NO_THROW(resolver_->provideNS(0, rrns_));
  379. EXPECT_EQ(Fetchable::READY, zone->getState());
  380. // It asks a question (we do not know which nameserver)
  381. boost::shared_ptr<Name> name;
  382. ASSERT_NO_THROW(name.reset(new Name((*resolver_)[1]->getName())));
  383. ASSERT_TRUE(resolver_->asksIPs(*name, 1, 2));
  384. resolver_->requests[1].second->failure();
  385. // Nothing should be answered or failed yet, there's second one
  386. EXPECT_EQ(0, callback_->unreachable_count_);
  387. EXPECT_EQ(0, callback_->successes_.size());
  388. ASSERT_TRUE(resolver_->asksIPs((*resolver_)[3]->getName(), 3, 4));
  389. // Fail the second one
  390. resolver_->requests[3].second->failure();
  391. // The callback should be failed now, as there is no chance of getting
  392. // v4 address
  393. EXPECT_EQ(1, callback_->unreachable_count_);
  394. EXPECT_EQ(0, callback_->successes_.size());
  395. // And question for v6 or any should still wait while v4 should be failed
  396. // right away
  397. zone->addCallback(callback_, V6_ONLY);
  398. EXPECT_EQ(1, callback_->unreachable_count_);
  399. EXPECT_EQ(0, callback_->successes_.size());
  400. zone->addCallback(callback_, ANY_OK);
  401. EXPECT_EQ(1, callback_->unreachable_count_);
  402. EXPECT_EQ(0, callback_->successes_.size());
  403. zone->addCallback(callback_, V4_ONLY);
  404. EXPECT_EQ(2, callback_->unreachable_count_);
  405. EXPECT_EQ(0, callback_->successes_.size());
  406. // Answer the IPv6 one
  407. EXPECT_NO_THROW(resolver_->answer(2, (*resolver_)[2]->getName(),
  408. RRType::AAAA(), rdata::in::AAAA("2001:db8::1")));
  409. // Ready, as we have at last some address
  410. EXPECT_EQ(Fetchable::READY, zone->getState());
  411. // The other callbacks should be answered now
  412. EXPECT_EQ(2, callback_->unreachable_count_);
  413. ASSERT_EQ(2, callback_->successes_.size());
  414. EXPECT_TRUE(IOAddress("2001:db8::1").equal(
  415. callback_->successes_[0].getAddress()));
  416. EXPECT_TRUE(IOAddress("2001:db8::1").equal(
  417. callback_->successes_[1].getAddress()));
  418. }
  419. /**
  420. * \short This test checks it works with answers from cache.
  421. *
  422. * The resolver might provide the answer by calling the callback both sometime
  423. * later or directly from its resolve method, causing recursion back inside
  424. * the ZoneEntry. This test checks it works even in the second case (eg. that
  425. * the ZoneEntry is able to handle callback called directly from the
  426. * resolve). Tries checking both positive and negative answers.
  427. */
  428. TEST_F(ZoneEntryTest, DirectAnswer) {
  429. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  430. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  431. // One unsuccessfull attempt, nameservers fail
  432. resolver_->addPresetAnswer(Question(Name(EXAMPLE_CO_UK), RRClass::IN(),
  433. RRType::NS()), RRsetPtr());
  434. zone->addCallback(callback_, ANY_OK);
  435. EXPECT_EQ(0, callback_->successes_.size());
  436. EXPECT_EQ(1, callback_->unreachable_count_);
  437. EXPECT_EQ(0, resolver_->requests.size());
  438. EXPECT_EQ(Fetchable::UNREACHABLE, zone->getState());
  439. // Successfull attempt now
  440. zone = getZone();
  441. // First, fill the answers to all the questions it should ask
  442. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  443. resolver_->addPresetAnswer(Question(Name(EXAMPLE_CO_UK), RRClass::IN(),
  444. RRType::NS()), rr_single_);
  445. Name ns_name("ns.example.net");
  446. rrv4_->setName(ns_name);
  447. resolver_->addPresetAnswer(Question(ns_name, RRClass::IN(), RRType::A()),
  448. rrv4_);
  449. rrv6_->setName(ns_name);
  450. resolver_->addPresetAnswer(Question(ns_name, RRClass::IN(),
  451. RRType::AAAA()), rrv6_);
  452. // Reset the results
  453. callback_->unreachable_count_ = 0;
  454. // Ask for the IP address
  455. zone->addCallback(callback_, ANY_OK);
  456. // It should be answered right away, positively
  457. EXPECT_EQ(1, callback_->successes_.size());
  458. EXPECT_EQ(0, callback_->unreachable_count_);
  459. EXPECT_EQ(0, resolver_->requests.size());
  460. EXPECT_EQ(Fetchable::READY, zone->getState());
  461. // Reset the results
  462. callback_->successes_.clear();
  463. // Now, pretend we do not have IP addresses
  464. resolver_->addPresetAnswer(Question(ns_name, RRClass::IN(), RRType::A()),
  465. RRsetPtr());
  466. resolver_->addPresetAnswer(Question(ns_name, RRClass::IN(),
  467. RRType::AAAA()), RRsetPtr());
  468. // Get another zone and ask it again. It should fail.
  469. // Clean the table first, though, so it does not find the old nameserver
  470. nameserver_table_->remove(HashKey(ns_name.toText(), RRClass::IN()));
  471. zone = getZone();
  472. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  473. zone->addCallback(callback_, ANY_OK);
  474. EXPECT_EQ(0, callback_->successes_.size());
  475. EXPECT_EQ(1, callback_->unreachable_count_);
  476. EXPECT_EQ(0, resolver_->requests.size());
  477. // It should be ready, but have no IP addresses on the nameservers
  478. EXPECT_EQ(Fetchable::READY, zone->getState());
  479. }
  480. /**
  481. * \short Test it works with timeouting NameserverEntries.
  482. *
  483. * In this test we have a zone with nameserver addresses at TTL 0.
  484. * So, the NameserverEntry expires each time the ZoneEntry tries to get
  485. * its addresses and must ask it again.
  486. */
  487. TEST_F(ZoneEntryTest, AddressTimeout) {
  488. boost::shared_ptr<InheritedZoneEntry> zone(getZone());
  489. EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
  490. zone->addCallback(callback_, ANY_OK);
  491. EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
  492. EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
  493. // It should not be answered yet, it should ask for the IP addresses
  494. EXPECT_TRUE(callback_->successes_.empty());
  495. EXPECT_EQ(0, callback_->unreachable_count_);
  496. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
  497. // We should be READY, as it marks we have nameservers
  498. // (not that they are ready)
  499. EXPECT_EQ(Fetchable::READY, zone->getState());
  500. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
  501. rdata::in::A("192.0.2.1"), 0));
  502. // It answers, not rejects
  503. ASSERT_EQ(1, callback_->successes_.size());
  504. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  505. callback_->successes_[0].getAddress()));
  506. EXPECT_EQ(0, callback_->unreachable_count_);
  507. // As well with IPv6
  508. EXPECT_NO_THROW(resolver_->answer(2, ns_name_, RRType::AAAA(),
  509. rdata::in::AAAA("2001:db8::1"), 0));
  510. EXPECT_EQ(1, callback_->successes_.size());
  511. EXPECT_EQ(Fetchable::READY, zone->getState());
  512. // When we ask for another one, it should ask for the addresses again
  513. zone->addCallback(callback_, ANY_OK);
  514. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 3, 4));
  515. EXPECT_EQ(0, callback_->unreachable_count_);
  516. EXPECT_EQ(1, callback_->successes_.size());
  517. EXPECT_NO_THROW(resolver_->answer(3, ns_name_, RRType::A(),
  518. rdata::in::A("192.0.2.1"), 0));
  519. EXPECT_EQ(0, callback_->unreachable_count_);
  520. ASSERT_EQ(2, callback_->successes_.size());
  521. EXPECT_TRUE(IOAddress("192.0.2.1").equal(
  522. callback_->successes_[1].getAddress()));
  523. }
  524. /**
  525. * \short Injection tests.
  526. *
  527. * These tests check the ZoneEntry does not break when the nameserver hash
  528. * table already contains a NameserverEntry in some given state. Each test
  529. * for a different state.
  530. */
  531. //@{
  532. /// \short Test how the zone reacts to a nameserver entry in ready state
  533. TEST_F(ZoneEntryTest, NameserverEntryReady) {
  534. // Inject the entry
  535. boost::shared_ptr<NameserverEntry> nse(injectEntry());
  536. // Fill it with data
  537. nse->askIP(resolver_, nseCallback(), ANY_OK);
  538. EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
  539. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
  540. EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
  541. rdata::in::A("192.0.2.1")));
  542. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
  543. rdata::in::AAAA("2001:db8::1")));
  544. EXPECT_EQ(Fetchable::READY, nse->getState());
  545. checkInjected(false);
  546. }
  547. /// \short Test how the zone reacts to a nameserver in not asked state
  548. TEST_F(ZoneEntryTest, NameserverEntryNotAsked) {
  549. // Inject the entry
  550. injectEntry();
  551. // We do not need it, nothing to modify on it
  552. checkInjected(true);
  553. }
  554. /// \short What if the zone finds a nameserver in progress?
  555. TEST_F(ZoneEntryTest, NameserverEntryInProgress) {
  556. // Prepare the nameserver entry
  557. boost::shared_ptr<NameserverEntry> nse(injectEntry());
  558. nse->askIP(resolver_, nseCallback(), ANY_OK);
  559. EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
  560. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
  561. checkInjected(true);
  562. }
  563. /// \short Check Zone's reaction to found expired nameserver
  564. TEST_F(ZoneEntryTest, NameserverEntryExpired) {
  565. boost::shared_ptr<NameserverEntry> nse(injectEntry());
  566. nse->askIP(resolver_, nseCallback(), ANY_OK);
  567. EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
  568. EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
  569. EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
  570. rdata::in::A("192.0.2.1"), 0));
  571. EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
  572. rdata::in::AAAA("2001:db8::1"), 0));
  573. EXPECT_EQ(Fetchable::READY, nse->getState());
  574. NameserverEntry::AddressVector addresses;
  575. EXPECT_EQ(Fetchable::EXPIRED, nse->getAddresses(addresses));
  576. EXPECT_EQ(Fetchable::EXPIRED, nse->getState());
  577. resolver_->requests.clear();
  578. checkInjected(true);
  579. }
  580. /// \short Check how it reacts to an unreachable zone already in the table
  581. TEST_F(ZoneEntryTest, NameserverEntryUnreachable) {
  582. boost::shared_ptr<NameserverEntry> nse(injectEntry());
  583. nse->askIP(resolver_, nseCallback(), ANY_OK);
  584. ASSERT_EQ(2, resolver_->requests.size());
  585. resolver_->requests[0].second->failure();
  586. resolver_->requests[1].second->failure();
  587. EXPECT_EQ(Fetchable::UNREACHABLE, nse->getState());
  588. checkInjected(false, 0, 1);
  589. }
  590. //@}
  591. // Count hits of each address
  592. void
  593. countHits(size_t *counts, const vector<NameserverAddress>& successes) {
  594. BOOST_FOREACH(const NameserverAddress& address, successes) {
  595. // We use the last digit as an index
  596. string address_string(address.getAddress().toText());
  597. size_t index(address_string[address_string.size() - 1] - '0' - 1);
  598. ASSERT_LT(index, 3);
  599. counts[index] ++;
  600. }
  601. }
  602. // Select one address from the address list
  603. TEST_F(ZoneEntryTest, AddressSelection) {
  604. const size_t repeats = 100000;
  605. // Create the zone, give it 2 nameservers and total of 3 addresses
  606. // (one of them is ipv6)
  607. boost::shared_ptr<ZoneEntry> zone(getZone());
  608. zone->addCallback(callback_, ANY_OK);
  609. EXPECT_NO_THROW(resolver_->provideNS(0, rrns_));
  610. ASSERT_GT(resolver_->requests.size(), 1);
  611. Name name1(resolver_->requests[1].first->getName());
  612. EXPECT_TRUE(resolver_->asksIPs(name1, 1, 2));
  613. resolver_->answer(1, name1, RRType::A(), rdata::in::A("192.0.2.1"));
  614. resolver_->answer(2, name1, RRType::AAAA(),
  615. rdata::in::AAAA("2001:db8::2"));
  616. ASSERT_GT(resolver_->requests.size(), 3);
  617. Name name2(resolver_->requests[3].first->getName());
  618. EXPECT_TRUE(resolver_->asksIPs(name2, 3, 4));
  619. resolver_->answer(3, name2, RRType::A(), rdata::in::A("192.0.2.3"));
  620. resolver_->requests[4].second->failure();
  621. boost::shared_ptr<NameserverEntry> ns1(nameserver_table_->get(HashKey(
  622. name1.toText(), RRClass::IN()))),
  623. ns2(nameserver_table_->get(HashKey(name2.toText(), RRClass::IN())));
  624. size_t counts[3] = {0, 0, 0};
  625. callback_->successes_.clear();
  626. // Test they have the same probabilities when they have the same RTT
  627. for (size_t i(0); i < repeats; ++ i) {
  628. zone->addCallback(callback_, ANY_OK);
  629. }
  630. countHits(counts, callback_->successes_);
  631. // We repeat the simulation for N=repeats times
  632. // for each address, the probability is p = 1/3, the average mu = N*p
  633. // variance sigma^2 = N * p * (1-p) = N * 1/3 * 2/3 = N*2/9
  634. // sigma = sqrt(N*2/9)
  635. // we should make sure that mu - 4sigma < c < mu + 4sigma
  636. // which means for 99.99366% of the time this should be true
  637. double p = 1.0 / 3.0;
  638. double mu = repeats * p;
  639. double sigma = sqrt(repeats * p * (1 - p));
  640. for (size_t i(0); i < 3; ++ i) {
  641. ASSERT_TRUE(fabs(counts[i] - mu) < 4*sigma);
  642. }
  643. // reset the environment
  644. callback_->successes_.clear();
  645. counts[0] = counts[1] = counts[2] = 0;
  646. // Test when the RTT is not the same
  647. ns1->setAddressRTT(IOAddress("192.0.2.1"), 1);
  648. ns1->setAddressRTT(IOAddress("2001:db8::2"), 2);
  649. ns2->setAddressRTT(IOAddress("192.0.2.3"), 3);
  650. for (size_t i(0); i < repeats; ++ i) {
  651. zone->addCallback(callback_, ANY_OK);
  652. }
  653. countHits(counts, callback_->successes_);
  654. // We expect that the selection probability for each address that
  655. // it will be in the range of [mu-4Sigma, mu+4Sigma]
  656. double ps[3];
  657. ps[0] = 1.0/(1.0 + 1.0/4.0 + 1.0/9.0);
  658. ps[1] = (1.0/4.0)/(1.0 + 1.0/4.0 + 1.0/9.0);
  659. ps[2] = (1.0/9.0)/(1.0 + 1.0/4.0 + 1.0/9.0);
  660. for (size_t i(0); i < 3; ++ i) {
  661. double mu = repeats * ps[i];
  662. double sigma = sqrt(repeats * ps[i] * (1 - ps[i]));
  663. ASSERT_TRUE(fabs(counts[i] - mu) < 4 * sigma);
  664. }
  665. // reset the environment
  666. callback_->successes_.clear();
  667. counts[0] = counts[1] = counts[2] = 0;
  668. // Test with unreachable address
  669. ns1->setAddressRTT(IOAddress("192.0.2.1"), 1);
  670. ns1->setAddressRTT(IOAddress("2001:db8::2"), 100);
  671. ns2->setAddressUnreachable(IOAddress("192.0.2.3"));
  672. for (size_t i(0); i < repeats; ++ i) {
  673. zone->addCallback(callback_, ANY_OK);
  674. }
  675. countHits(counts, callback_->successes_);
  676. // The unreachable one shouldn't be called
  677. EXPECT_EQ(0, counts[2]);
  678. // reset the environment
  679. callback_->successes_.clear();
  680. counts[0] = counts[1] = counts[2] = 0;
  681. // Test with all unreachable
  682. ns1->setAddressUnreachable(IOAddress("192.0.2.1"));
  683. ns1->setAddressUnreachable(IOAddress("2001:db8::2"));
  684. ns2->setAddressUnreachable(IOAddress("192.0.2.3"));
  685. for (size_t i(0); i < repeats; ++ i) {
  686. zone->addCallback(callback_, ANY_OK);
  687. }
  688. countHits(counts, callback_->successes_);
  689. // They should have about the same probability
  690. for (size_t i(0); i < 3; ++ i) {
  691. ASSERT_TRUE(fabs(counts[i] - mu) < 4*sigma);
  692. }
  693. // TODO: The unreachable server should be changed to reachable after 5minutes, but how to test?
  694. }
  695. } // namespace