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