Branch data Line data Source code
1 : : // Copyright (C) 2009 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 __DATA_SOURCE_H
16 : : #define __DATA_SOURCE_H
17 : :
18 : : #include <stdint.h>
19 : :
20 : : #include <vector>
21 : :
22 : : #include <boost/shared_ptr.hpp>
23 : :
24 : : #include <exceptions/exceptions.h>
25 : :
26 : : #include <dns/name.h>
27 : : #include <dns/rrclass.h>
28 : : #include <cc/data.h>
29 : :
30 : : namespace isc {
31 : :
32 : : namespace dns {
33 : : class Name;
34 : : class RRType;
35 : : class RRset;
36 : : class RRsetList;
37 : : }
38 : :
39 : : namespace datasrc {
40 : :
41 : : class DataSrcMatch;
42 : : class Query;
43 : :
44 : : class DataSrc;
45 : : typedef boost::shared_ptr<DataSrc> DataSrcPtr;
46 : : typedef boost::shared_ptr<const DataSrc> ConstDataSrcPtr;
47 : :
48 : : /// This exception represents Backend-independent errors relating to
49 : : /// data source operations.
50 : 187 : class DataSourceError : public Exception {
51 : : public:
52 : 96 : DataSourceError(const char* file, size_t line, const char* what) :
53 [ + - ][ + + ]: 187 : isc::Exception(file, line, what) {}
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
54 : : };
55 : :
56 : : /// \brief No such serial number when obtaining difference iterator
57 : : ///
58 : : /// Thrown if either the zone/start serial number or zone/end serial number
59 : : /// combination does not exist in the differences table. (Note that this
60 : : /// includes the case where the differences table contains no records related
61 : : /// to that zone.)
62 : 9 : class NoSuchSerial : public DataSourceError {
63 : : public:
64 : : NoSuchSerial(const char* file, size_t line, const char* what) :
65 [ - + ]: 10 : DataSourceError(file, line, what) {}
66 : : };
67 : :
68 : :
69 : : class AbstractDataSrc {
70 : : ///
71 : : /// \name Constructors, Assignment Operator and Destructor.
72 : : ///
73 : : /// Note: The copy constructor and the assignment operator are intentionally
74 : : /// defined as private to make it explicit that this is a pure base class.
75 : : private:
76 : : AbstractDataSrc(const AbstractDataSrc& source);
77 : : AbstractDataSrc& operator=(const AbstractDataSrc& source);
78 : : protected:
79 : : /// \brief The default constructor.
80 : : ///
81 : : /// This is intentionally defined as \c protected as this base class should
82 : : /// never be instantiated (except as part of a derived class).
83 : 459 : AbstractDataSrc() {}
84 : : public:
85 : : /// \brief The destructor.
86 : 451 : virtual ~AbstractDataSrc() {};
87 : : //@}
88 : :
89 : : enum Result {
90 : : SUCCESS,
91 : : ERROR,
92 : : NOT_IMPLEMENTED
93 : : };
94 : :
95 : : // These flags indicate conditions encountered while processing a query.
96 : : //
97 : : // REFERRAL: The node contains an NS record
98 : : // CNAME_FOUND: The node contains a CNAME record
99 : : // NAME_NOT_FOUND: The node does not exist in the data source.
100 : : // TYPE_NOT_FOUND: The node does not contain the requested RRType
101 : : // NO_SUCH_ZONE: The zone does not exist in this data source.
102 : : //
103 : : // DATA_NOT_FOUND: A combination of the last three, for coding convenience
104 : : enum QueryResponseFlags {
105 : : REFERRAL = 0x01,
106 : : CNAME_FOUND = 0x02,
107 : : NAME_NOT_FOUND = 0x04,
108 : : TYPE_NOT_FOUND = 0x08,
109 : : NO_SUCH_ZONE = 0x10,
110 : : DATA_NOT_FOUND = (NAME_NOT_FOUND|TYPE_NOT_FOUND|NO_SUCH_ZONE)
111 : : };
112 : :
113 : : // 'High-level' methods. These will be implemented by the
114 : : // general DataSrc class, and SHOULD NOT be overwritten by subclasses.
115 : : virtual void doQuery(Query& query) = 0;
116 : :
117 : : // XXX: High-level methods to be implemented later:
118 : : // virtual void doUpdate(Update update) = 0;
119 : : // virtual void doXfr(Query query) = 0;
120 : :
121 : : // 'Medium-level' methods. This will be implemented by the general
122 : : // DataSrc class but MAY be overwritten by subclasses.
123 : : virtual void findClosestEnclosure(DataSrcMatch& match) const = 0;
124 : :
125 : : // Optional 'low-level' methods. These will have stub implementations
126 : : // in the general DataSrc class but MAY be overwritten by subclasses
127 : : virtual Result init() = 0;
128 : : virtual Result init(isc::data::ConstElementPtr config) = 0;
129 : : virtual Result close() = 0;
130 : :
131 : : // Mandatory 'low-level' methods: These will NOT be implemented by
132 : : // the general DataSrc class; subclasses MUST implement them.
133 : : virtual Result findRRset(const isc::dns::Name& qname,
134 : : const isc::dns::RRClass& qclass,
135 : : const isc::dns::RRType& qtype,
136 : : isc::dns::RRsetList& target,
137 : : uint32_t& flags,
138 : : const isc::dns::Name* zonename) const = 0;
139 : :
140 : : virtual Result findExactRRset(const isc::dns::Name& qname,
141 : : const isc::dns::RRClass& qclass,
142 : : const isc::dns::RRType& qtype,
143 : : isc::dns::RRsetList& target,
144 : : uint32_t& flags,
145 : : const isc::dns::Name* zonename) const = 0;
146 : :
147 : : // These will have dumb implementations in the general DataSrc
148 : : // class, and SHOULD be overwritten by subclasses.
149 : : virtual Result findAddrs(const isc::dns::Name& qname,
150 : : const isc::dns::RRClass& qclass,
151 : : isc::dns::RRsetList& target,
152 : : uint32_t& flags,
153 : : const isc::dns::Name* zonename) const = 0;
154 : :
155 : : virtual Result findReferral(const isc::dns::Name& qname,
156 : : const isc::dns::RRClass& qclass,
157 : : isc::dns::RRsetList& target,
158 : : uint32_t& flags,
159 : : const isc::dns::Name* zonename) const = 0;
160 : :
161 : : // This MUST be implemented by concrete data sources which support
162 : : // DNSSEC, but is optional for others (e.g., the static data source).
163 : : virtual Result findPreviousName(const isc::dns::Name& qname,
164 : : isc::dns::Name& target,
165 : : const isc::dns::Name* zonename) const = 0;
166 : :
167 : : // This MUST be implemented by concrete data sources which support
168 : : // NSEC3, but is optional for others
169 : : virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
170 : : std::string& hash,
171 : : isc::dns::RRsetList& target) const = 0;
172 : : };
173 : :
174 : : // Base class for a DNS Data Source
175 : : class DataSrc : public AbstractDataSrc {
176 : : ///
177 : : /// \name Constructors, Assignment Operator and Destructor.
178 : : ///
179 : : /// Note: The copy constructor and the assignment operator are intentionally
180 : : /// defined as private.
181 : : private:
182 : : DataSrc(const DataSrc& source);
183 : : DataSrc& operator=(const DataSrc& source);
184 : : public:
185 : 833 : DataSrc() : rrclass(isc::dns::RRClass::IN()) {}
186 : 280 : DataSrc(const isc::dns::RRClass& c) : rrclass(c) {}
187 : : /// \brief The destructor.
188 : 0 : virtual ~DataSrc() {};
189 : : //@}
190 : :
191 : : virtual void doQuery(Query& q);
192 : :
193 : : virtual void findClosestEnclosure(DataSrcMatch& match) const = 0;
194 : :
195 : : const isc::dns::RRClass& getClass() const { return (rrclass); }
196 : : void setClass(isc::dns::RRClass& c) { rrclass = c; }
197 : 0 : void setClass(const isc::dns::RRClass& c) { rrclass = c; }
198 : :
199 : 0 : virtual Result init() { return (NOT_IMPLEMENTED); }
200 : : virtual Result init(isc::data::ConstElementPtr config);
201 : 0 : virtual Result close() { return (NOT_IMPLEMENTED); }
202 : :
203 : : virtual Result findRRset(const isc::dns::Name& qname,
204 : : const isc::dns::RRClass& qclass,
205 : : const isc::dns::RRType& qtype,
206 : : isc::dns::RRsetList& target,
207 : : uint32_t& flags,
208 : : const isc::dns::Name* zonename) const = 0;
209 : :
210 : : virtual Result findExactRRset(const isc::dns::Name& qname,
211 : : const isc::dns::RRClass& qclass,
212 : : const isc::dns::RRType& qtype,
213 : : isc::dns::RRsetList& target,
214 : : uint32_t& flags,
215 : : const isc::dns::Name* zonename) const = 0;
216 : :
217 : : virtual Result findAddrs(const isc::dns::Name& qname,
218 : : const isc::dns::RRClass& qclass,
219 : : isc::dns::RRsetList& target,
220 : : uint32_t& flags,
221 : : const isc::dns::Name* zonename) const;
222 : :
223 : : virtual Result findReferral(const isc::dns::Name& qname,
224 : : const isc::dns::RRClass& qclass,
225 : : isc::dns::RRsetList& target,
226 : : uint32_t& flags,
227 : : const isc::dns::Name* zonename) const;
228 : :
229 : : virtual Result findPreviousName(const isc::dns::Name& qname,
230 : : isc::dns::Name& target,
231 : : const isc::dns::Name* zonename) const = 0;
232 : :
233 : : virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
234 : : std::string& hash,
235 : : isc::dns::RRsetList& target) const = 0;
236 : :
237 : : private:
238 : : isc::dns::RRClass rrclass;
239 : : };
240 : :
241 : : class MetaDataSrc : public DataSrc {
242 : : ///
243 : : /// \name Constructors, Assignment Operator and Destructor.
244 : : ///
245 : : /// Note: The copy constructor and the assignment operator are intentionally
246 : : /// defined as private.
247 : : //@{
248 : : private:
249 : : MetaDataSrc(const MetaDataSrc& source);
250 : : MetaDataSrc& operator=(const MetaDataSrc& source);
251 : : public:
252 : 234 : MetaDataSrc() : DataSrc(isc::dns::RRClass::ANY()) {}
253 : : MetaDataSrc(const isc::dns::RRClass& c) : DataSrc(c) {}
254 : : /// \brief The destructor.
255 : 140 : virtual ~MetaDataSrc() {}
256 : : //@}
257 : :
258 : : void addDataSrc(ConstDataSrcPtr data_src);
259 : : void removeDataSrc(ConstDataSrcPtr data_src);
260 : : size_t dataSrcCount() { return (data_sources.size()); }
261 : :
262 : : void findClosestEnclosure(DataSrcMatch& match) const;
263 : :
264 : : // Actual queries for data should not be sent to a MetaDataSrc object,
265 : : // so we return NOT_IMPLEMENTED if we receive any.
266 : : //
267 : : // The proper way to use the MetaDataSrc is to run findClosestEnclosure()
268 : : // to get a pointer to the best concrete data source for the specified
269 : : // zone, then send all queries directly to that data source.
270 : :
271 : : Result findRRset(const isc::dns::Name& qname,
272 : : const isc::dns::RRClass& qclass,
273 : : const isc::dns::RRType& qtype,
274 : : isc::dns::RRsetList& target,
275 : : uint32_t& flags,
276 : : const isc::dns::Name* zonename) const;
277 : :
278 : : Result findExactRRset(const isc::dns::Name& qname,
279 : : const isc::dns::RRClass& qclass,
280 : : const isc::dns::RRType& qtype,
281 : : isc::dns::RRsetList& target,
282 : : uint32_t& flags,
283 : : const isc::dns::Name* zonename) const;
284 : :
285 : : Result findAddrs(const isc::dns::Name& qname,
286 : : const isc::dns::RRClass& qclass,
287 : : isc::dns::RRsetList& target,
288 : : uint32_t& flags,
289 : : const isc::dns::Name* zonename) const;
290 : :
291 : : Result findReferral(const isc::dns::Name& qname,
292 : : const isc::dns::RRClass& qclass,
293 : : isc::dns::RRsetList& target,
294 : : uint32_t& flags,
295 : : const isc::dns::Name* zonename) const;
296 : :
297 : : virtual Result findPreviousName(const isc::dns::Name& qname,
298 : : isc::dns::Name& target,
299 : : const isc::dns::Name* zonename) const;
300 : :
301 : : virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
302 : : std::string& hash,
303 : : isc::dns::RRsetList& target) const;
304 : :
305 : : private:
306 : : std::vector<ConstDataSrcPtr> data_sources;
307 : : };
308 : :
309 : : /// \brief Information about the zone along with the %data source that best
310 : : /// matches a give name and RR class.
311 : : ///
312 : : /// A \c DataSrcMatch object is created with a domain name and RR class to
313 : : /// hold the search state of looking for the zone and the %data source that
314 : : /// stores the zone that best match the given name and RR class.
315 : : /// The application of this class passes an object of \c DataSrcMatch to
316 : : /// one or more ^data sources via their \c findClosestEnclosure() method.
317 : : /// The %data source searches its content for the given key, and update
318 : : /// the state if it finds a better zone than the currently recorded one.
319 : : ///
320 : : /// The state of a \c DataSrcMatch object should be updated if and only if:
321 : : /// - The specified RR class and the RR class of the %data source are the
322 : : // same, or the specified RR class is ANY; and
323 : : /// - There is no matching %data source and name found (which is probably
324 : : /// wrong, see below), or the given enclosing name gives a longer match
325 : : /// than the currently stored enclosing name against the specified name.
326 : : class DataSrcMatch {
327 : : ///
328 : : /// \name Constructors, Assignment Operator and Destructor.
329 : : ///
330 : : /// Note: The copy constructor and the assignment operator are
331 : : /// intentionally defined as private.
332 : : //@{
333 : : private:
334 : : DataSrcMatch(const DataSrcMatch& source);
335 : : DataSrcMatch& operator=(const DataSrcMatch& source);
336 : : public:
337 : : /// \brief The constructor.
338 : : ///
339 : : /// This constructor normally doesn't throw an exception. However,
340 : : /// it creates a copy of the given name object, which may require memory
341 : : /// allocation, and if it fails the corresponding standard exception will
342 : : /// be thrown.
343 : : ///
344 : : /// \param name The domain name to be matched.
345 : : /// \param rrclass The RR class to be matched
346 : 7 : DataSrcMatch(const isc::dns::Name& name,
347 : : const isc::dns::RRClass& rrclass) :
348 : : closest_name_(NULL), best_source_(NULL),
349 [ + - ][ + - ]: 202 : name_(name), rrclass_(rrclass)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
350 : 7 : {}
351 : : ~DataSrcMatch();
352 : : //@}
353 : :
354 : : /// \name Getter and Setter Methods
355 : : //@{
356 : : /// \brief Returns the name to be matched.
357 : : const isc::dns::Name& getName() const { return (name_); }
358 : :
359 : : /// \brief Returns the RR class to be matched.
360 : : ///
361 : : /// This method never throws an exception.
362 : 0 : const isc::dns::RRClass& getClass() const { return (rrclass_); }
363 : :
364 : : /// \brief Returns the best enclosing zone name found for the given
365 : : // name and RR class so far.
366 : : ///
367 : : /// \return A pointer to the zone apex \c Name, NULL if none found yet.
368 : : ///
369 : : /// This method never throws an exception.
370 : 0 : const isc::dns::Name* getEnclosingZone() const { return (closest_name_); }
371 : :
372 : : /// \brief Returns the best %data source found for the given name and
373 : : /// RR class so far.
374 : : ///
375 : : /// This method never throws an exception.
376 : : ///
377 : : /// \return A pointer to a concrete %data source, NULL if none found yet.
378 : 0 : const DataSrc* getDataSource() const { return (best_source_); }
379 : : //@}
380 : :
381 : : /// \brief Update the object state with better information if possible.
382 : : ///
383 : : /// This method is intended to be called by a concrete %data source's
384 : : /// \c findClosestEnclosure() method to store the best match for
385 : : /// the given name and class that has been found so far.
386 : : ///
387 : : /// It compares the best name (if found) and \c container, and if the
388 : : /// latter gives a longer match, it will install the given %data source
389 : : /// and the enclosing name as the best match;
390 : : /// if there is no known pair of %data source and enclosing name,
391 : : /// this method will install the given pair unconditionally.
392 : : /// (which is probably BAD);
393 : : /// otherwise this method does nothing.
394 : : ///
395 : : /// In any case, if a new pair of %data source and enclosing name are
396 : : /// installed, a new name object will be internally allocated.
397 : : /// And, if memory allocation fails the corresponding standard exception
398 : : /// will be thrown.
399 : : ///
400 : : /// \param new_source A candidate %data source that gives a better match.
401 : : /// \param container The enclosing name of the matching zone in
402 : : /// \c new_source.
403 : : void update(const DataSrc& new_source, const isc::dns::Name& container);
404 : :
405 : : private:
406 : : isc::dns::Name* closest_name_;
407 : : const DataSrc* best_source_;
408 : : const isc::dns::Name name_;
409 : : const isc::dns::RRClass& rrclass_;
410 : : };
411 : :
412 : 1 : class Nsec3Param {
413 : : public:
414 : : Nsec3Param(uint8_t a, uint8_t f, uint16_t i, const std::vector<uint8_t>& s);
415 : : std::string getHash(const isc::dns::Name& name) const;
416 : : private:
417 : : const uint8_t algorithm_;
418 : : const uint8_t flags_;
419 : : const uint16_t iterations_;
420 : : const std::vector<uint8_t> salt_;
421 : : };
422 : :
423 : : }
424 : : }
425 : :
426 : : #endif
427 : :
428 : : // Local Variables:
429 : : // mode: c++
430 : : // End:
|