data_source.h 16 KB

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