zone_entry.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. // Workaround for a problem with boost and sunstudio 5.10
  18. // There is a version check in there that appears wrong,
  19. // which makes including boost/thread.hpp fail
  20. // This will probably be fixed in a future version of boost,
  21. // in which case this part can be removed then
  22. #ifdef NEED_SUNPRO_WORKAROUND
  23. #if defined(__SUNPRO_CC) && __SUNPRO_CC == 0x5100
  24. #undef __SUNPRO_CC
  25. #define __SUNPRO_CC 0x5090
  26. #endif
  27. #endif // NEED_SUNPRO_WORKAROUND
  28. #include <string>
  29. #include <vector>
  30. #include <set>
  31. #include <boost/thread.hpp>
  32. #include <boost/shared_ptr.hpp>
  33. #include <boost/enable_shared_from_this.hpp>
  34. #include <dns/rrset.h>
  35. #include "hash_key.h"
  36. #include "nsas_entry.h"
  37. #include "asiolink.h"
  38. #include "fetchable.h"
  39. #include "resolver_interface.h"
  40. #include "nsas_types.h"
  41. #include "random_number_generator.h"
  42. namespace isc {
  43. namespace nsas {
  44. class NameserverEntry;
  45. class AddressRequestCallback;
  46. /// \brief Zone Entry
  47. ///
  48. /// The zone entry object describes a zone for which nameserver address
  49. /// information is held.
  50. ///
  51. /// Although the interface is simple, the internal processing is fairly
  52. /// complicated, in that the class takes account of triggering fetches for
  53. /// addresses of nameservers when the address records expire.
  54. ///
  55. /// It uses shared_from_this in its methods. It must live inside a shared_ptr.
  56. class ZoneEntry : public NsasEntry<ZoneEntry>, public Fetchable {
  57. public:
  58. /**
  59. * \brief Constructor.
  60. *
  61. * It asks the resolver any needed questions to get the nameservers.
  62. *
  63. * \param resolver The resolver used to ask for IP addresses
  64. * \param name Name of the zone
  65. * \param class_code Class of this zone (zones of different classes have
  66. * different objects.
  67. * \todo Move to cc file, include the lookup (if NSAS uses resolver for
  68. * everything)
  69. */
  70. ZoneEntry(boost::shared_ptr<ResolverInterface> resolver,
  71. const std::string& name, const isc::dns::RRClass& class_code,
  72. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
  73. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru);
  74. /// \return Name of the zone
  75. std::string getName() const {
  76. return name_;
  77. }
  78. /// \return Class of zone
  79. const isc::dns::RRClass& getClass() const {
  80. return class_code_;
  81. }
  82. /// \return Return Hash Key
  83. virtual HashKey hashKey() const {
  84. return HashKey(name_, class_code_);
  85. }
  86. /**
  87. * \short Put another callback inside.
  88. *
  89. * This callback is either executed right away, if it is possible,
  90. * or queued for later.
  91. *
  92. * \param callback The callback itself.
  93. * \param family Which address family is acceptable as an answer?
  94. */
  95. void addCallback(boost::shared_ptr<AddressRequestCallback>
  96. callback, AddressFamily family);
  97. /// \short Protected members, so they can be accessed by tests.
  98. //@{
  99. protected:
  100. // TODO Read-Write lock?
  101. typedef boost::shared_ptr<NameserverEntry> NameserverPtr;
  102. typedef std::vector<NameserverPtr> NameserverVector;
  103. NameserverVector nameservers_; ///< Nameservers
  104. // Which nameservers didn't have any of our callbacks yet
  105. std::set<NameserverPtr> nameservers_not_asked_;
  106. /*
  107. * Callbacks. For each fimily type one vector, so we can process
  108. * them separately.
  109. */
  110. std::vector<boost::shared_ptr<AddressRequestCallback> >
  111. callbacks_[ADDR_REQ_MAX];
  112. time_t expiry_; ///< Expiry time of this entry, 0 means not set
  113. //}@
  114. private:
  115. mutable boost::recursive_mutex mutex_; ///< Mutex protecting this zone entry
  116. std::string name_; ///< Canonical zone name
  117. isc::dns::RRClass class_code_; ///< Class code
  118. /**
  119. * \short Process all the callbacks that can be processed
  120. *
  121. * The purpose of this funtion is to ask all nameservers for their IP
  122. * addresses and execute all callbacks that can be executed. It is
  123. * called whenever new callback appears and there's a chance it could
  124. * be answered or when new information is available (list of nameservers,
  125. * nameserver is unreachable or has an address).
  126. * \param family Which is the interesting address family where the change
  127. * happened. ADDR_REQ_MAX means it could be any of them and it will
  128. * trigger processing of all callbacks no matter what their family
  129. * was.
  130. * \param nameserver Pass a nameserver if the change was triggered by
  131. * the nameserver (if it wasn't triggered by a nameserver, pass empty
  132. * pointer). This one will be accepted even with 0 TTL, the information
  133. * just arrived and we are allowed to use it just now.
  134. * \todo With the recursive locks now, we might want to simplify executing
  135. * callbacks (here and other functions as well);
  136. */
  137. void process(AddressFamily family,
  138. const boost::shared_ptr<NameserverEntry>& nameserver);
  139. // Resolver we use
  140. boost::shared_ptr<ResolverInterface> resolver_;
  141. // We store the nameserver table and lru, so we can look up when there's
  142. // update
  143. boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table_;
  144. boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru_;
  145. // Resolver callback class, documentation with the class declaration
  146. class ResolverCallback;
  147. // It has direct access to us
  148. friend class ResolverCallback;
  149. // Guard class to eliminate missing finally
  150. class ProcessGuard;
  151. friend class ProcessGuard;
  152. // Are we in the process method?
  153. bool in_process_[ADDR_REQ_MAX];
  154. // Callback from nameserver entry (documented with the class)
  155. class NameserverCallback;
  156. // And it can get into our internals as well (call process)
  157. friend class NameserverCallback;
  158. // This dispatches callbacks of given family with failures
  159. void dispatchFailures(AddressFamily family);
  160. // Put a callback into the nameserver entry. Same ADDR_REQ_MAX means for
  161. // all families
  162. void insertCallback(NameserverPtr nameserver, AddressFamily family);
  163. // A random generator for this zone entry
  164. // TODO: A more global one? Per thread one?
  165. WeightedRandomIntegerGenerator address_selector;
  166. };
  167. } // namespace nsas
  168. } // namespace isc
  169. #endif // __ZONE_ENTRY_H