rrparamregistry.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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. #ifndef RRPARAMREGISTRY_H
  15. #define RRPARAMREGISTRY_H 1
  16. #include <string>
  17. #include <stdint.h>
  18. #include <boost/shared_ptr.hpp>
  19. #include <exceptions/exceptions.h>
  20. #include <dns/rdata.h>
  21. namespace isc {
  22. namespace dns {
  23. // forward declarations
  24. struct RRParamRegistryImpl;
  25. ///
  26. /// \brief A standard DNS module exception that is thrown if a new RR type is
  27. /// being registered with a different type string.
  28. ///
  29. class RRTypeExists : public Exception {
  30. public:
  31. RRTypeExists(const char* file, size_t line, const char* what) :
  32. isc::Exception(file, line, what) {}
  33. };
  34. ///
  35. /// \brief A standard DNS module exception that is thrown if a new RR class is
  36. /// being registered with a different type string.
  37. ///
  38. class RRClassExists : public Exception {
  39. public:
  40. RRClassExists(const char* file, size_t line, const char* what) :
  41. isc::Exception(file, line, what) {}
  42. };
  43. namespace rdata {
  44. /// \brief The \c AbstractRdataFactory class is an abstract base class to
  45. /// encapsulate a set of Rdata factory methods in a polymorphic way.
  46. ///
  47. /// An external developers who want to introduce a new or experimental RR type
  48. /// are expected to define a corresponding derived class of \c
  49. /// AbstractRdataFactory and register it via \c RRParamRegistry.
  50. ///
  51. /// For other users of this API normally do not have to care about this class
  52. /// or its derived classes; this class is generally intended to be used
  53. /// as an internal utility of the API implementation.
  54. class AbstractRdataFactory {
  55. ///
  56. /// \name Constructors and Destructor
  57. ///
  58. //@{
  59. protected:
  60. /// The default constructor
  61. ///
  62. /// This is intentionally defined as \c protected as this base class should
  63. /// never be instantiated (except as part of a derived class).
  64. AbstractRdataFactory() {}
  65. public:
  66. /// The destructor.
  67. virtual ~AbstractRdataFactory() {};
  68. //@}
  69. ///
  70. /// \name Factory methods for polymorphic creation.
  71. ///
  72. //@{
  73. ///
  74. /// \brief Create RDATA from a string.
  75. ///
  76. /// This method creates from a string an \c Rdata object of specific class
  77. /// corresponding to the specific derived class of \c AbstractRdataFactory.
  78. ///
  79. /// \param rdata_str A string of textual representation of the \c Rdata.
  80. /// \return An \c RdataPtr object pointing to the created \c Rdata object.
  81. virtual RdataPtr create(const std::string& rdata_str) const = 0;
  82. ///
  83. /// \brief Create RDATA from wire-format data.
  84. ///
  85. /// This method creates from wire-format binary data an \c Rdata object
  86. /// of specific class corresponding to the specific derived class of
  87. /// \c AbstractRdataFactory.
  88. ///
  89. /// \param buffer A reference to an \c InputBuffer object storing the
  90. /// \c Rdata to parse.
  91. /// \param rdata_len The length in buffer of the \c Rdata. In bytes.
  92. /// \return An \c RdataPtr object pointing to the created \c Rdata object.
  93. virtual RdataPtr create(isc::util::InputBuffer& buffer, size_t rdata_len) const = 0;
  94. ///
  95. /// \brief Create RDATA from another \c Rdata object of the same type.
  96. ///
  97. /// This method creates an \c Rdata object of specific class corresponding
  98. /// to the specific derived class of \c AbstractRdataFactory, copying the
  99. /// content of the given \c Rdata, \c source.
  100. ///
  101. /// \c source must be an object of the concrete derived class corresponding
  102. /// to the specific derived class of \c AbstractRdataFactory;
  103. /// otherwise, an exception of class \c std::bad_cast will be thrown.
  104. ///
  105. /// \param source A reference to an \c Rdata object whose content is to
  106. /// be copied to the created \c Rdata object.
  107. /// \return An \c RdataPtr object pointing to the created \c Rdata object.
  108. virtual RdataPtr create(const rdata::Rdata& source) const = 0;
  109. //@}
  110. };
  111. ///
  112. /// The \c RdataFactoryPtr type is a pointer-like type, pointing to an
  113. /// object of some concrete derived class of \c AbstractRdataFactory.
  114. ///
  115. typedef boost::shared_ptr<AbstractRdataFactory> RdataFactoryPtr;
  116. } // end of namespace rdata
  117. ///
  118. /// The \c RRParamRegistry class represents a registry of parameters to
  119. /// manipulate DNS resource records (RRs).
  120. ///
  121. /// A \c RRParamRegistry class object stores a mapping between RR types or
  122. /// classes and their textual representations. It will also have knowledge of
  123. /// how to create an RDATA object for a specific pair of RR type and class
  124. /// (not implemented in this version).
  125. ///
  126. /// Normal applications that only handle standard DNS protocols won't have to
  127. /// care about this class. This is mostly an internal class to the DNS library
  128. /// to manage standard parameters. Some advanced applications may still need
  129. /// to use this class explicitly. For example, if an application wants to
  130. /// define and use an experimental non-standard RR type, it may want to register
  131. /// related protocol parameters for its convenience. This class is designed to
  132. /// allow such usage without modifying the library source code or rebuilding
  133. /// the library.
  134. ///
  135. /// It is assumed that at most one instance of this class can exist so that
  136. /// the application uses the consistent set of registered parameters. To ensure
  137. /// this, this class is designed and implemented as a "singleton class": the
  138. /// constructor is intentionally private, and applications must get access to
  139. /// the single instance via the \c getRegistry() static member function.
  140. ///
  141. /// In the current implementation, access to the singleton \c RRParamRegistry
  142. /// object is not thread safe.
  143. /// The application should ensure that multiple threads don't race in the
  144. /// first invocation of \c getRegistry(), and, if the registry needs to
  145. /// be changed dynamically, read and write operations are performed
  146. /// exclusively.
  147. /// Since this class should be static in common usage this restriction would
  148. /// be acceptable in practice.
  149. /// In the future, we may extend the implementation so that multiple threads can
  150. /// get access to the registry fully concurrently without any restriction.
  151. ///
  152. /// Note: the implementation of this class is incomplete: we should at least
  153. /// add RDATA related parameters. This will be done in a near future version,
  154. /// at which point some of method signatures will be changed.
  155. class RRParamRegistry {
  156. ///
  157. /// \name Constructors and Destructor
  158. ///
  159. /// These are intentionally hidden (see the class description).
  160. //@{
  161. private:
  162. RRParamRegistry();
  163. RRParamRegistry(const RRParamRegistry& orig);
  164. ~RRParamRegistry();
  165. //@}
  166. public:
  167. ///
  168. /// \brief Return the singleton instance of \c RRParamRegistry.
  169. ///
  170. /// This method is a unified access point to the singleton instance of
  171. /// the RR parameter registry (\c RRParamRegistry).
  172. /// On first invocation it internally constructs an instance of the
  173. /// \c RRParamRegistry class and returns a reference to it.
  174. /// This is a static object inside this method and will remain valid
  175. /// throughout the rest of the application lifetime.
  176. /// On subsequent calls this method simply returns a reference to the
  177. /// singleton object.
  178. ///
  179. /// If resource allocation fails in the first invocation,
  180. /// a corresponding standard exception will be thrown.
  181. /// This method never fails otherwise. In particular, this method
  182. /// doesn't throw an exception once the singleton instance is constructed.
  183. ///
  184. /// \return A reference to the singleton instance of \c RRParamRegistry.
  185. static RRParamRegistry& getRegistry();
  186. ///
  187. /// \name Registry Update Methods
  188. ///
  189. //@{
  190. ///
  191. /// \brief Add a set of parameters for a pair of RR type and class.
  192. ///
  193. /// This method adds to the registry a specified set of RR parameters,
  194. /// including mappings between type/class codes and their textual
  195. /// representations.
  196. ///
  197. /// Regarding the mappings between textual representations and integer
  198. /// codes, this method behaves in the same way as \c addType() and
  199. /// \c addClass(). That is, it ignores any overriding attempt as
  200. /// long as the mapping is the same; otherwise the corresponding exception
  201. /// will be thrown.
  202. ///
  203. /// This method provides the strong exception guarantee: unless an
  204. /// exception is thrown the entire specified set of parameters must be
  205. /// stored in the registry; if this method throws an exception the
  206. /// registry will remain in the state before this method is called.
  207. ///
  208. /// \param type_string The textual representation of the RR type.
  209. /// \param type_code The integer code of the RR type.
  210. /// \param class_string The textual representation of the RR class.
  211. /// \param class_code The integer code of the RR class.
  212. /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
  213. /// concrete RDATA factory.
  214. void add(const std::string& type_string, uint16_t type_code,
  215. const std::string& class_string, uint16_t class_code,
  216. rdata::RdataFactoryPtr rdata_factory);
  217. /// \brief Add a set of parameters for a class-independent RR type.
  218. ///
  219. /// This method behaves as exactly same as the other \c add method except
  220. /// that it handles class-independent types (such as NS, CNAME, or SOA).
  221. ///
  222. /// \param type_string The textual representation of the RR type.
  223. /// \param type_code The integer code of the RR type.
  224. /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
  225. /// concrete RDATA factory.
  226. void add(const std::string& type_string, uint16_t type_code,
  227. rdata::RdataFactoryPtr rdata_factory);
  228. /// \brief Add mappings between RR type code and textual representation.
  229. ///
  230. /// This method adds a mapping from the type code of an RR to its textual
  231. /// representation and the reverse mapping in the registry.
  232. ///
  233. /// If the given RR type is already registered with the same textual
  234. /// representation, this method simply ignores the duplicate mapping;
  235. /// if the given type is registered and a new pair with a different
  236. /// textual representation is being added,an exception of class
  237. /// \c RRTypeExist will be thrown.
  238. /// To replace an existing mapping with a different textual representation,
  239. /// the existing one must be removed by the \c removeType() method
  240. /// beforehand.
  241. ///
  242. /// In addition, if resource allocation for the new mapping entries fails,
  243. /// a corresponding standard exception will be thrown.
  244. ///
  245. /// This method provides the strong exception guarantee: unless an exception
  246. /// is thrown the specified mappings must be stored in the registry
  247. /// (although it may be an already existing one) on completion of the
  248. /// method; if this method throws an exception the registry will remain
  249. /// in the state before this method is called.
  250. ///
  251. /// \param type_string The textual representation of the RR type.
  252. /// \param type_code The integer code of the RR type.
  253. /// \return \c true if a new mapping is added to the repository; \c false
  254. /// if the same mapping is already registered.
  255. bool addType(const std::string& type_string, uint16_t type_code);
  256. /// \brief Remove mappings between RR type code and textual representation
  257. /// for a given type.
  258. ///
  259. /// This method can safely be called whether or not the specified mappings
  260. /// exist in the registry. If not, this method simply ignores the attempt
  261. /// and returns \c false.
  262. ///
  263. /// This method never throws an exception.
  264. ///
  265. /// \param type_code The integer code of the RR type.
  266. /// \return \c true if mappings for the specified RR type exists and is
  267. /// removed; \c false if no such mapping is in the registry.
  268. bool removeType(uint16_t type_code);
  269. /// \brief Add mappings between RR class code and textual representation.
  270. ///
  271. /// This method adds a mapping from the class code of an RR to its textual
  272. /// representation and the reverse mapping in the registry.
  273. ///
  274. /// If the given RR class is already registered with the same textual
  275. /// representation, this method simply ignores the duplicate mapping;
  276. /// if the given class is registered and a new pair with a different
  277. /// textual representation is being added,an exception of class
  278. /// \c RRClassExist will be thrown.
  279. /// To replace an existing mapping with a different textual representation,
  280. /// the existing one must be removed by the \c removeClass() method
  281. /// beforehand.
  282. ///
  283. /// In addition, if resource allocation for the new mapping entries fails,
  284. /// a corresponding standard exception will be thrown.
  285. ///
  286. /// This method provides the strong exception guarantee: unless an exception
  287. /// is thrown the specified mappings must be stored in the registry
  288. /// (although it may be an already existing one) on completion of the
  289. /// method; if this method throws an exception the registry will remain
  290. /// in the state before this method is called.
  291. ///
  292. /// \param class_string The textual representation of the RR class.
  293. /// \param class_code The integer code of the RR class.
  294. /// \return \c true if a new mapping is added to the repository; \c false
  295. /// if the same mapping is already registered.
  296. bool addClass(const std::string& class_string, uint16_t class_code);
  297. /// \brief Remove mappings between RR class code and textual representation
  298. /// for a given class.
  299. ///
  300. /// This method can safely be called whether or not the specified mappings
  301. /// exist in the registry. If not, this method simply ignores the attempt
  302. /// and returns \c false.
  303. ///
  304. /// This method never throws an exception.
  305. ///
  306. /// \param class_code The integer code of the RR class.
  307. /// \return \c true if mappings for the specified RR type exists and is
  308. /// removed; \c false if no such mapping is in the registry.
  309. bool removeClass(uint16_t class_code);
  310. /// \brief Remove registered RDATA factory for the given pair of \c RRType
  311. /// and \c RRClass.
  312. ///
  313. /// This method can safely be called whether or not the specified factory
  314. /// object exist in the registry. If not, this method simply ignores the
  315. /// attempt and returns \c false.
  316. ///
  317. /// This method never throws an exception.
  318. ///
  319. /// \param rrtype An \c RRType object specifying the type/class pair.
  320. /// \param rrclass An \c RRClass object specifying the type/class pair.
  321. /// \return \c true if a factory object for the specified RR type/class
  322. /// pair exists and is removed; \c false if no such object is in the
  323. /// registry.
  324. bool removeRdataFactory(const RRType& rrtype, const RRClass& rrclass);
  325. /// \brief Remove registered RDATA factory for the given pair of \c RRType
  326. /// and \c RRClass.
  327. ///
  328. /// This method can safely be called whether or not the specified factory
  329. /// object exist in the registry. If not, this method simply ignores the
  330. /// attempt and returns \c false.
  331. ///
  332. /// This method never throws an exception.
  333. ///
  334. /// \param rrtype An \c RRType object specifying the type/class pair.
  335. /// \return \c true if a factory object for the specified RR type/class
  336. /// pair exists and is removed; \c false if no such object is in the
  337. /// registry.
  338. bool removeRdataFactory(const RRType& rrtype);
  339. //@}
  340. ///
  341. /// \name Parameter Conversion Methods
  342. ///
  343. //@{
  344. /// \brief Convert a textual representation of an RR type to the
  345. /// corresponding 16-bit integer code.
  346. ///
  347. /// This method searches the \c RRParamRegistry for the mapping from the
  348. /// given textual representation of RR type to the corresponding integer
  349. /// code. If a mapping is found, it returns the associated type code;
  350. /// otherwise, if the given string is in the form of "TYPEnnnn", it returns
  351. /// the corresponding number as the type code; otherwise, it throws an
  352. /// exception of class \c InvalidRRType.
  353. ///
  354. /// \param type_string The textual representation of the RR type.
  355. /// \return The RR type code for \c type_string.
  356. uint16_t textToTypeCode(const std::string& type_string) const;
  357. /// \brief Convert type code into its textual representation.
  358. ///
  359. /// This method searches the \c RRParamRegistry for the mapping from the
  360. /// given RR type code to its textual representation.
  361. /// If a mapping is found, it returns (a copy of) the associated string;
  362. /// otherwise, this method creates a new string in the form of "TYPEnnnn"
  363. /// where "nnnn" is the decimal representation of the type code, and
  364. /// returns the new string.
  365. ///
  366. /// If resource allocation for the returned string fails,
  367. /// a corresponding standard exception will be thrown.
  368. /// This method never fails otherwise.
  369. ///
  370. /// \param type_code The integer code of the RR type.
  371. /// \return A textual representation of the RR type for code \c type_code.
  372. std::string codeToTypeText(uint16_t type_code) const;
  373. /// \brief Convert a textual representation of an RR class to the
  374. /// corresponding 16-bit integer code.
  375. ///
  376. /// This method searches the \c RRParamRegistry for the mapping from the
  377. /// given textual representation of RR class to the corresponding integer
  378. /// code. If a mapping is found, it returns the associated class code;
  379. /// otherwise, if the given string is in the form of "CLASSnnnn", it returns
  380. /// the corresponding number as the class code; otherwise, it throws an
  381. /// exception of class \c InvalidRRClass.
  382. ///
  383. /// \param class_string The textual representation of the RR class.
  384. /// \return The RR class code for \c class_string.
  385. uint16_t textToClassCode(const std::string& class_string) const;
  386. /// \brief Convert class code into its textual representation.
  387. ///
  388. /// This method searches the \c RRParamRegistry for the mapping from the
  389. /// given RR class code to its textual representation.
  390. /// If a mapping is found, it returns (a copy of) the associated string;
  391. /// otherwise, this method creates a new string in the form of "CLASSnnnn"
  392. /// where "nnnn" is the decimal representation of the class code, and
  393. /// returns the new string.
  394. ///
  395. /// If resource allocation for the returned string fails,
  396. /// a corresponding standard exception will be thrown.
  397. /// This method never fails otherwise.
  398. ///
  399. /// \param class_code The integer code of the RR class.
  400. /// \return A textual representation of the RR class for code \c class_code.
  401. std::string codeToClassText(uint16_t class_code) const;
  402. //@}
  403. ///
  404. /// \name RDATA Factories
  405. ///
  406. /// This set of methods provide a unified interface to create an
  407. /// \c rdata::Rdata object in a parameterized polymorphic way,
  408. /// that is, these methods take a pair of \c RRType and \c RRClass
  409. /// objects and data specific to that pair, and create an object of
  410. /// the corresponding concrete derived class of \c rdata::Rdata.
  411. ///
  412. /// These methods first search the \c RRParamRegistry for a factory
  413. /// method (a member of a concrete derived class of
  414. /// \c AbstractRdataFactory) for the given RR type and class pair.
  415. /// If the search fails, they then search for a factory method for
  416. /// the given type ignoring the class, in case a RRClass independent
  417. /// factory method is registered.
  418. /// If it still fails, these methods assume the RDATA is of an "unknown"
  419. /// type, and creates a new object by calling a constructor of the
  420. /// \c rdata::generic::Generic class.
  421. ///
  422. //@{
  423. /// \brief Create RDATA of a given pair of RR type and class from a string.
  424. ///
  425. /// This method creates from a string an \c Rdata object of the given pair
  426. /// of RR type and class.
  427. ///
  428. /// \param rrtype An \c RRType object specifying the type/class pair.
  429. /// \param rrclass An \c RRClass object specifying the type/class pair.
  430. /// \param rdata_string A string of textual representation of the \c Rdata.
  431. /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
  432. /// object.
  433. rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  434. const std::string& rdata_string);
  435. /// \brief Create RDATA of a given pair of RR type and class from
  436. /// wire-format data.
  437. ///
  438. /// This method creates from wire-format binary data an \c Rdata object
  439. /// of the given pair of RR type and class.
  440. ///
  441. /// \param rrtype An \c RRType object specifying the type/class pair.
  442. /// \param rrclass An \c RRClass object specifying the type/class pair.
  443. /// \param buffer A reference to an \c InputBuffer object storing the
  444. /// \c Rdata to parse.
  445. /// \param len The length in buffer of the \c Rdata. In bytes.
  446. /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
  447. /// object.
  448. rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  449. isc::util::InputBuffer& buffer, size_t len);
  450. /// \brief Create RDATA of a given pair of RR type and class, copying
  451. /// of another RDATA of same kind.
  452. ///
  453. /// This method creates an \c Rdata object of the given pair of
  454. /// RR type and class, copying the content of the given \c Rdata,
  455. /// \c source.
  456. ///
  457. /// \c source must be an object of the concrete derived class of
  458. /// \c rdata::Rdata for the given pair of RR type and class;
  459. /// otherwise, an exception of class \c std::bad_cast will be thrown.
  460. /// In case the \c RRParamRegistry doesn't have a factory method for
  461. /// the given pair and it is assumed to be of an "unknown" type,
  462. /// \c source must reference an object of class
  463. /// \c rdata::generic::Generic; otherwise, an exception of class
  464. /// \c std::bad_cast will be thrown.
  465. ///
  466. /// \param rrtype An \c RRType object specifying the type/class pair.
  467. /// \param rrclass An \c RRClass object specifying the type/class pair.
  468. /// \param source A reference to an \c rdata::Rdata object whose content
  469. /// is to be copied to the created \c rdata::Rdata object.
  470. /// \return An \c rdata::RdataPtr object pointing to the created
  471. /// \c rdata::Rdata object.
  472. rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  473. const rdata::Rdata& source);
  474. //@}
  475. private:
  476. RRParamRegistryImpl* impl_;
  477. };
  478. }
  479. }
  480. #endif // RRPARAMREGISTRY_H
  481. // Local Variables:
  482. // mode: c++
  483. // End: