zone_entry.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. #ifndef __ZONE_ENTRY_H
  16. #define __ZONE_ENTRY_H
  17. #include <string>
  18. #include <vector>
  19. #include <set>
  20. #include <boost/thread.hpp>
  21. #include <boost/shared_ptr.hpp>
  22. #include <boost/enable_shared_from_this.hpp>
  23. #include <dns/rrset.h>
  24. #include "hash_key.h"
  25. #include "nsas_entry.h"
  26. #include "asiolink.h"
  27. #include "fetchable.h"
  28. #include "resolver_interface.h"
  29. #include "nsas_types.h"
  30. namespace isc {
  31. namespace nsas {
  32. class NameserverEntry;
  33. class AddressRequestCallback;
  34. /// \brief Zone Entry
  35. ///
  36. /// The zone entry object describes a zone for which nameserver address
  37. /// information is held.
  38. ///
  39. /// Although the interface is simple, the internal processing is fairly
  40. /// complicated, in that the class takes account of triggering fetches for
  41. /// addresses of nameservers when the address records expire.
  42. ///
  43. /// It uses shared_from_this in its methods. It must live inside a shared_ptr.
  44. class ZoneEntry : public NsasEntry<ZoneEntry>, public Fetchable {
  45. public:
  46. /**
  47. * \brief Constructor.
  48. *
  49. * It asks the resolver any needed questions to get the nameservers.
  50. *
  51. * \param resolver The resolver used to ask for IP addresses
  52. * \param name Name of the zone
  53. * \param class_code Class of this zone (zones of different classes have
  54. * different objects.
  55. * \todo Move to cc file, include the lookup (if NSAS uses resolver for
  56. * everything)
  57. */
  58. ZoneEntry(boost::shared_ptr<ResolverInterface> resolver,
  59. const std::string& name, const isc::dns::RRClass& class_code,
  60. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
  61. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru);
  62. /// \return Name of the zone
  63. std::string getName() const {
  64. return name_;
  65. }
  66. /// \return Class of zone
  67. const isc::dns::RRClass& getClass() const {
  68. return class_code_;
  69. }
  70. /// \return Return Hash Key
  71. virtual HashKey hashKey() const {
  72. return HashKey(name_, class_code_);
  73. }
  74. /**
  75. * \short Put another callback inside.
  76. *
  77. * This callback is either executed right away, if it is possible,
  78. * or queued for later.
  79. *
  80. * \param callback The callback itself.
  81. * \param family Which address family is acceptable as an answer?
  82. */
  83. void addCallback(boost::shared_ptr<AddressRequestCallback>
  84. callback, AddressFamily family);
  85. /// \short Protected members, so they can be accessed by tests.
  86. //@{
  87. protected:
  88. // TODO Read-Write lock?
  89. typedef boost::shared_ptr<NameserverEntry> NameserverPtr;
  90. typedef std::vector<NameserverPtr> NameserverVector;
  91. NameserverVector nameservers_; ///< Nameservers
  92. // Which nameservers didn't have any of our callbacks yet
  93. std::set<NameserverPtr> nameservers_not_asked_;
  94. /*
  95. * Callbacks. For each fimily type one vector, so we can process
  96. * them separately.
  97. */
  98. std::vector<boost::shared_ptr<AddressRequestCallback> >
  99. callbacks_[ADDR_REQ_MAX];
  100. time_t expiry_; ///< Expiry time of this entry, 0 means not set
  101. //}@
  102. private:
  103. mutable boost::mutex mutex_; ///< Mutex protecting this zone entry
  104. std::string name_; ///< Canonical zone name
  105. isc::dns::RRClass class_code_; ///< Class code
  106. // Internal function that adds a callback (if there's one) and processes
  107. // the nameservers (if there's chance there's some info) and calls
  108. // callbacks. If nameserver is given, it is considered new and valid
  109. // even if its TTL is 0.
  110. // The family says which one changed or has any update.
  111. // If the familly is ADDR_REQ_MAX, then it means process all callbacks.
  112. // However, you must not provide callback.
  113. // If lock is provided, it is locked mutex_ and will be used. If not,
  114. // will use its own. It will unlock the lock if it terminates without
  115. // an exception.
  116. void process(boost::shared_ptr<AddressRequestCallback> callback,
  117. AddressFamily family, boost::shared_ptr<NameserverEntry> nameserver,
  118. boost::shared_ptr<boost::mutex::scoped_lock> lock =
  119. boost::shared_ptr<boost::mutex::scoped_lock>());
  120. // Resolver we use
  121. boost::shared_ptr<ResolverInterface> resolver_;
  122. // We store the nameserver table and lru, so we can look up when there's
  123. // update
  124. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table_;
  125. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru_;
  126. // Resolver callback class
  127. class ResolverCallback;
  128. // It has direct access to us
  129. friend class ResolverCallback;
  130. // Guard class to eliminate missing finally
  131. class ProcessGuard;
  132. friend class ProcessGuard;
  133. // Are we in the process method?
  134. bool in_process_[ADDR_REQ_MAX];
  135. // Callback from nameserver entry
  136. class NameserverCallback;
  137. // And it can get into our internals as well (call process)
  138. friend class NameserverCallback;
  139. // This dispatches callbacks of given family with failures (and unlocks)
  140. // The lock is mandatory
  141. void dispatchFailures(AddressFamily family,
  142. boost::shared_ptr<boost::mutex::scoped_lock> lock);
  143. // Put a callback into the nameserver entry. Same ADDR_REQ_MAX means for
  144. // all families
  145. void insertCallback(NameserverPtr nameserver, AddressFamily family);
  146. };
  147. } // namespace nsas
  148. } // namespace isc
  149. #endif // __ZONE_ENTRY_H