rrparamregistry.h 23 KB

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