rdata.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  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 RDATA_H
  15. #define RDATA_H 1
  16. #include <stdint.h>
  17. #include <boost/shared_ptr.hpp>
  18. #include <exceptions/exceptions.h>
  19. namespace isc {
  20. namespace util {
  21. class InputBuffer;
  22. class OutputBuffer;
  23. }
  24. namespace dns {
  25. class AbstractMessageRenderer;
  26. class RRType;
  27. class RRClass;
  28. class Name;
  29. namespace rdata {
  30. ///
  31. /// \brief A standard DNS module exception that is thrown if RDATA parser
  32. /// encounters an invalid or inconsistent data length.
  33. ///
  34. class InvalidRdataLength : public Exception {
  35. public:
  36. InvalidRdataLength(const char* file, size_t line, const char* what) :
  37. isc::Exception(file, line, what) {}
  38. };
  39. ///
  40. /// \brief A standard DNS module exception that is thrown if RDATA parser
  41. /// fails to recognize a given textual representation.
  42. ///
  43. class InvalidRdataText : public Exception {
  44. public:
  45. InvalidRdataText(const char* file, size_t line, const char* what) :
  46. isc::Exception(file, line, what) {}
  47. };
  48. ///
  49. /// \brief A standard DNS module exception that is thrown if RDATA parser
  50. /// parser encounters a character-string (as defined in RFC1035) exceeding
  51. /// the maximum allowable length (\c MAX_CHARSTRING_LEN).
  52. ///
  53. class CharStringTooLong : public Exception {
  54. public:
  55. CharStringTooLong(const char* file, size_t line, const char* what) :
  56. isc::Exception(file, line, what) {}
  57. };
  58. // Forward declaration to define RdataPtr.
  59. class Rdata;
  60. ///
  61. /// The \c RdataPtr type is a pointer-like type, pointing to an
  62. /// object of some concrete derived class of \c Rdata.
  63. ///
  64. typedef boost::shared_ptr<Rdata> RdataPtr;
  65. typedef boost::shared_ptr<const Rdata> ConstRdataPtr;
  66. /// \brief Possible maximum length of RDATA, which is the maximum unsigned
  67. /// 16 bit value.
  68. const size_t MAX_RDLENGTH = 65535;
  69. /// \brief The maximum allowable length of character-string containing in
  70. /// RDATA as defined in RFC1035, not including the 1-byte length field.
  71. const unsigned int MAX_CHARSTRING_LEN = 255;
  72. /// \brief The \c Rdata class is an abstract base class that provides
  73. /// a set of common interfaces to manipulate concrete RDATA objects.
  74. ///
  75. /// Generally, a separate derived class directly inherited from the base
  76. /// \c Rdata class is defined for each well known RDATA.
  77. /// Each of such classes will define the common logic based on the
  78. /// corresponding protocol standard.
  79. ///
  80. /// Since some types of RRs are class specific and the corresponding RDATA
  81. /// may have different semantics (e.g. type A for class IN and type A for
  82. /// class CH have different representations and semantics), we separate
  83. /// \c Rdata derived classes for such RR types in different namespaces.
  84. /// The namespace of types specific to a class is named the lower-cased class
  85. /// name; for example, RDATA of class IN-specific types are defined in the
  86. /// \c in namespace, and RDATA of class CH-specific types are defined in
  87. /// the \c ch namespace, and so on.
  88. /// The derived classes are named using the RR type name (upper cased) such as
  89. /// \c A or \c AAAA.
  90. /// Thus RDATA of type A RR for class IN and CH are defined as \c in::A and
  91. /// \c ch::A, respectively.
  92. /// Many other RR types are class independent; the derived \c Rdata classes
  93. /// for such RR types are defined in the \c generic namespace. Examples are
  94. /// \c generic::NS and \c generic::SOA.
  95. ///
  96. /// If applications need to refer to these derived classes, it is generally
  97. /// recommended to prepend at least some part of the namespace because the
  98. /// same class name can be used in different namespaces.
  99. /// So, instead of doing
  100. /// \code using namespace isc::dns::rdata::in;
  101. /// A& rdata_type_a; \endcode
  102. /// it is advisable to prepend at least \c in from the namespace:
  103. /// \code using namespace isc::dns::rdata;
  104. /// in::A& rdata_type_a; \endcode
  105. ///
  106. /// In many cases, however, an application doesn't have to care about such
  107. /// derived classes.
  108. /// For instance, to parse an incoming DNS message an application wouldn't
  109. /// have to perform type specific operation unless the application is
  110. /// specifically concerned about a particular type.
  111. /// So, this API generally handles \c Rdata in a polymorphic way through
  112. /// a pointer or reference to this base abstract class.
  113. class Rdata {
  114. ///
  115. /// \name Constructors and Destructor
  116. ///
  117. /// Note: The copy constructor and the assignment operator are intentionally
  118. /// defined as private. Concrete classes should generally specialize their
  119. /// own versions of these methods.
  120. //@{
  121. protected:
  122. /// The default constructor.
  123. ///
  124. /// This is intentionally defined as \c protected as this base class should
  125. /// never be instantiated (except as part of a derived class). In many
  126. /// cases, the derived class wouldn't define a public default constructor
  127. /// either, because an \c Rdata object without concrete data isn't
  128. /// meaningful.
  129. Rdata() {}
  130. private:
  131. Rdata(const Rdata& source);
  132. void operator=(const Rdata& source);
  133. public:
  134. /// The destructor.
  135. virtual ~Rdata() {};
  136. //@}
  137. ///
  138. /// \name Converter methods
  139. ///
  140. //@{
  141. /// \brief Convert an \c Rdata to a string.
  142. ///
  143. /// This method returns a \c std::string object representing the \c Rdata.
  144. ///
  145. /// This is a pure virtual method without the definition; the actual
  146. /// representation is specific to each derived concrete class and
  147. /// should be explicitly defined in the derived class.
  148. ///
  149. /// \return A string representation of \c Rdata.
  150. virtual std::string toText() const = 0;
  151. /// \brief Render the \c Rdata in the wire format into a buffer.
  152. ///
  153. /// This is a pure virtual method without the definition; the actual
  154. /// conversion is specific to each derived concrete class and
  155. /// should be explicitly defined in the derived class.
  156. ///
  157. /// \param buffer An output buffer to store the wire data.
  158. virtual void toWire(isc::util::OutputBuffer& buffer) const = 0;
  159. /// \brief Render the \c Rdata in the wire format into a
  160. /// \c MessageRenderer object.
  161. ///
  162. /// This is a pure virtual method without the definition; the actual
  163. /// conversion is specific to each derived concrete class and
  164. /// should be explicitly defined in the derived class.
  165. ///
  166. /// \param renderer DNS message rendering context that encapsulates the
  167. /// output buffer in which the \c Rdata is to be stored.
  168. virtual void toWire(AbstractMessageRenderer& renderer) const = 0;
  169. //@}
  170. ///
  171. /// \name Comparison method
  172. ///
  173. //@{
  174. /// \brief Compare two instances of \c Rdata.
  175. ///
  176. /// This method compares \c this and the \c other Rdata objects
  177. /// in terms of the DNSSEC sorting order as defined in RFC4034, and returns
  178. /// the result as an integer.
  179. ///
  180. /// This is a pure virtual method without the definition; the actual
  181. /// comparison logic is specific to each derived concrete class and
  182. /// should be explicitly defined in the derived class.
  183. ///
  184. /// Specific implementations of this method must confirm that \c this
  185. /// and the \c other are objects of the same concrete derived class of
  186. /// \c Rdata. This is normally done by \c dynamic_cast in the
  187. /// implementation. It also means if the assumption isn't met
  188. /// an exception of class \c std::bad_cast will be thrown.
  189. ///
  190. /// Here is an implementation choice: instead of relying on
  191. /// \c dynamic_cast, we could first convert the data into wire-format
  192. /// and compare the pair as opaque data. This would be more polymorphic,
  193. /// but might involve significant overhead, especially for a large size
  194. /// of RDATA.
  195. ///
  196. /// \param other the right-hand operand to compare against.
  197. /// \return < 0 if \c this would be sorted before \c other.
  198. /// \return 0 if \c this is identical to \c other in terms of sorting order.
  199. /// \return > 0 if \c this would be sorted after \c other.
  200. virtual int compare(const Rdata& other) const = 0;
  201. //@}
  202. };
  203. namespace generic {
  204. /// \brief The \c GenericImpl class is the actual implementation of the
  205. /// \c generic::Generic class.
  206. ///
  207. /// The implementation is hidden from applications. This approach requires
  208. /// dynamic memory allocation on construction, copy, or assignment, but
  209. /// we believe it should be acceptable as "unknown" RDATA should be pretty
  210. /// rare.
  211. struct GenericImpl;
  212. /// \brief The \c generic::Generic class represents generic "unknown" RDATA.
  213. ///
  214. /// This class is used as a placeholder for all non well-known type of RDATA.
  215. /// By definition, the stored data is regarded as opaque binary without
  216. /// assuming any structure.
  217. class Generic : public Rdata {
  218. public:
  219. ///
  220. /// \name Constructors, Assignment Operator and Destructor.
  221. ///
  222. //@{
  223. /// \brief Constructor from a string.
  224. ///
  225. /// This method constructs a \c generic::Generic object from a textual
  226. /// representation as defined in RFC3597.
  227. ///
  228. /// If \c rdata_string isn't a valid textual representation of this type
  229. /// of RDATA, an exception of class \c InvalidRdataText or
  230. /// \c InvalidRdataLength will be thrown.
  231. /// If resource allocation to store the data fails, a corresponding standard
  232. /// exception will be thrown.
  233. ///
  234. /// \param rdata_string A string of textual representation of generic
  235. /// RDATA.
  236. explicit Generic(const std::string& rdata_string);
  237. ///
  238. /// \brief Constructor from wire-format data.
  239. ///
  240. /// The \c buffer parameter normally stores a complete DNS message
  241. /// containing the generic RDATA to be constructed.
  242. /// The current read position of the buffer points to the head of the
  243. /// data.
  244. ///
  245. /// This method reads \c rdata_len bytes from the \c buffer, and internally
  246. /// stores the data as an opaque byte sequence.
  247. ///
  248. /// \c rdata_len must not exceed \c MAX_RDLENGTH; otherwise, an exception
  249. /// of class \c InvalidRdataLength will be thrown.
  250. /// If resource allocation to hold the data fails, a corresponding standard
  251. /// exception will be thrown; if the \c buffer doesn't contain \c rdata_len
  252. /// bytes of unread data, an exception of class \c InvalidBufferPosition
  253. /// will be thrown.
  254. ///
  255. /// \param buffer A reference to an \c InputBuffer object storing the
  256. /// \c Rdata to parse.
  257. /// \param rdata_len The length in buffer of the \c Rdata. In bytes.
  258. Generic(isc::util::InputBuffer& buffer, size_t rdata_len);
  259. ///
  260. /// \brief The destructor.
  261. virtual ~Generic();
  262. ///
  263. /// \brief The copy constructor.
  264. ///
  265. /// If resource allocation to copy the data fails, a corresponding standard
  266. /// exception will be thrown.
  267. ///
  268. /// \param source A reference to a \c generic::Generic object to copy from.
  269. Generic(const Generic& source);
  270. ///
  271. /// \brief The assignment operator.
  272. ///
  273. /// If resource allocation to copy the data fails, a corresponding standard
  274. /// exception will be thrown.
  275. ///
  276. /// \param source A reference to a \c generic::Generic object to copy from.
  277. Generic& operator=(const Generic& source);
  278. //@}
  279. ///
  280. /// \name Converter methods
  281. ///
  282. //@{
  283. /// \brief Convert an \c generic::Generic object to a string.
  284. ///
  285. /// This method converts a generic "unknown" RDATA object into a textual
  286. /// representation of such unknown data as defined in RFC3597.
  287. ///
  288. /// If resource allocation to copy the data fails, a corresponding standard
  289. /// exception will be thrown.
  290. ///
  291. /// \return A string representation of \c generic::Generic.
  292. virtual std::string toText() const;
  293. ///
  294. /// \brief Render the \c generic::Generic in the wire format into a buffer.
  295. ///
  296. /// This will require \c rdata_len bytes of remaining capacity in the
  297. /// \c buffer. If this is not the case and resource allocation for the
  298. /// necessary memory space fails, a corresponding standard exception will
  299. /// be thrown.
  300. ///
  301. /// \param buffer An output buffer to store the wire data.
  302. virtual void toWire(isc::util::OutputBuffer& buffer) const;
  303. /// \brief Render the \c generic::Generic in the wire format into a
  304. /// \c MessageRenderer object.
  305. ///
  306. /// This will require \c rdata_len bytes of remaining capacity in the
  307. /// \c buffer. If this is not the case and resource allocation for the
  308. /// necessary memory space fails, a corresponding standard exception will
  309. /// be thrown.
  310. ///
  311. /// \param renderer DNS message rendering context that encapsulates the
  312. /// output buffer in which the \c Generic object is to be stored.
  313. virtual void toWire(AbstractMessageRenderer& renderer) const;
  314. //@}
  315. ///
  316. /// \name Comparison method
  317. ///
  318. //@{
  319. /// \brief Compare two instances of \c generic::Generic objects.
  320. ///
  321. /// As defined in RFC4034, this method simply compares the wire-format
  322. /// representations of the two objects as left-justified unsigned octet
  323. /// sequences.
  324. ///
  325. /// The object referenced by \c other must have been instantiated as
  326. /// a c generic::Generic class object; otherwise, an exception of class
  327. /// \c std::bad_cast will be thrown.
  328. /// Note that the comparison is RR type/class agnostic: this method doesn't
  329. /// check whether the two \c Rdata objects to compare are of the comparable
  330. /// RR type/class. For example, \c this object may come from an \c RRset
  331. /// of \c RRType x, and the \c other may come from a different \c RRset
  332. /// of \c RRType y (where x != y). This situation would be considered a
  333. /// bug, but this method cannot detect this type of error.
  334. /// The caller must ensure this condition.
  335. ///
  336. /// \param other the right-hand operand to compare against.
  337. /// \return < 0 if \c this would be sorted before \c other.
  338. /// \return 0 if \c this is identical to \c other in terms of sorting order.
  339. /// \return > 0 if \c this would be sorted after \c other.
  340. virtual int compare(const Rdata& other) const;
  341. //@}
  342. private:
  343. GenericImpl* impl_;
  344. };
  345. ///
  346. /// \brief Insert the name as a string into stream.
  347. ///
  348. /// This method convert the \c rdata into a string and inserts it into the
  349. /// output stream \c os.
  350. ///
  351. /// This function overloads the global \c operator<< to behave as described in
  352. /// \c ostream::operator<< but applied to \c generic::Generic Rdata objects.
  353. ///
  354. /// \param os A \c std::ostream object on which the insertion operation is
  355. /// performed.
  356. /// \param rdata The \c Generic object output by the operation.
  357. /// \return A reference to the same \c std::ostream object referenced by
  358. /// parameter \c os after the insertion operation.
  359. std::ostream& operator<<(std::ostream& os, const Generic& rdata);
  360. } // end of namespace "generic"
  361. //
  362. // Non class-member functions related to Rdata
  363. //
  364. ///
  365. /// \name Parameterized Polymorphic RDATA Factories
  366. ///
  367. /// This set of global functions provide a unified interface to create an
  368. /// \c Rdata object in a parameterized polymorphic way,
  369. /// that is, these functions take a pair of \c RRType and \c RRClass
  370. /// objects and data specific to that pair, and create an object of
  371. /// the corresponding concrete derived class of \c Rdata.
  372. ///
  373. /// These will be useful when parsing/constructing a DNS message or
  374. /// parsing a master file, where information for a specific type of RDATA
  375. /// is given but the resulting object, once created, should better be used
  376. /// in a polymorphic way.
  377. ///
  378. /// For example, if a master file parser encounters an NS RR
  379. /// \verbatim example.com. 3600 IN NS ns.example.com.\endverbatim
  380. /// it stores the text fragments "IN", "NS", and "ns.example.com." in
  381. /// \c std::string objects \c class_txt, \c type_txt, and \c nsname_txt,
  382. /// respectively, then it would create a new \c RdataPtr object as follows:
  383. /// \code RdataPtr rdata = createRdata(RRType(type_txt), RRClass(class_txt),
  384. /// nsname_txt); \endcode
  385. /// On success, \c rdata will point to an object of the \c generic::NS class
  386. /// that internally holds a domain name of "ns.example.com."
  387. ///
  388. /// Internally, these functions uses the corresponding
  389. /// \c RRParamRegistry::createRdata methods of the \c RRParamRegistry.
  390. /// See also the description on these methods for related notes.
  391. //@{
  392. /// \brief Create RDATA of a given pair of RR type and class from a string.
  393. ///
  394. /// This method creates from a string an \c Rdata object of the given pair
  395. /// of RR type and class.
  396. ///
  397. /// \param rrtype An \c RRType object specifying the type/class pair.
  398. /// \param rrclass An \c RRClass object specifying the type/class pair.
  399. /// \param rdata_string A string of textual representation of the \c Rdata.
  400. /// \return An \c RdataPtr object pointing to the created \c Rdata
  401. /// object.
  402. RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  403. const std::string& rdata_string);
  404. /// \brief Create RDATA of a given pair of RR type and class from
  405. /// wire-format data.
  406. ///
  407. /// This method creates from wire-format binary data an \c Rdata object
  408. /// of the given pair of RR type and class.
  409. ///
  410. /// \c len must not exceed the protocol defined maximum value, \c MAX_RDLENGTH;
  411. /// otherwise, an exception of class \c InvalidRdataLength will be thrown.
  412. ///
  413. /// In some cases, the length of the RDATA is determined without the
  414. /// information of \c len. For example, the RDATA length of an IN/A RR
  415. /// must always be 4. If \c len is not equal to the actual length in such
  416. /// cases, an exception of class InvalidRdataLength will be thrown.
  417. ///
  418. /// \param rrtype An \c RRType object specifying the type/class pair.
  419. /// \param rrclass An \c RRClass object specifying the type/class pair.
  420. /// \param buffer A reference to an \c InputBuffer object storing the
  421. /// \c Rdata to parse.
  422. /// \param len The length in buffer of the \c Rdata. In bytes.
  423. /// \return An \c RdataPtr object pointing to the created \c Rdata
  424. /// object.
  425. RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  426. isc::util::InputBuffer& buffer, size_t len);
  427. /// \brief Create RDATA of a given pair of RR type and class, copying
  428. /// of another RDATA of same kind.
  429. ///
  430. /// This method creates an \c Rdata object of the given pair of
  431. /// RR type and class, copying the content of the given \c Rdata,
  432. /// \c source.
  433. ///
  434. /// \param rrtype An \c RRType object specifying the type/class pair.
  435. /// \param rrclass An \c RRClass object specifying the type/class pair.
  436. /// \param source A reference to an \c Rdata object whose content
  437. /// is to be copied to the created \c Rdata object.
  438. /// \return An \c RdataPtr object pointing to the created
  439. /// \c Rdata object.
  440. RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
  441. const Rdata& source);
  442. //@}
  443. ///
  444. /// \brief Gives relative ordering of two names in terms of DNSSEC RDATA
  445. /// ordering.
  446. ///
  447. /// This method compares two names as defined in Sections 6.2 and 6.3 of
  448. /// RFC4034: Comparing two names in their canonical form
  449. /// (i.e., converting upper case ASCII characters to lower ones) and
  450. /// as a left-justified unsigned octet sequence. Note that the ordering is
  451. /// different from that for owner names. For example, "a.example" should be
  452. /// sorted before "example" as RDATA, but the ordering is the opposite when
  453. /// compared as owner names.
  454. ///
  455. /// Normally, applications would not need this function directly.
  456. /// This is mostly an internal helper function for \c Rdata related classes
  457. /// to implement their \c compare() method.
  458. /// This function is publicly open, however, for the convenience of
  459. /// external developers who want to implement new or experimental RR types.
  460. ///
  461. /// This function never throws an exception as long as the given names are
  462. /// valid \c Name objects.
  463. ///
  464. /// Additional note about applicability: In fact, BIND9's similar function,
  465. /// \c dns_name_rdatacompare(), is only used in rdata implementations and
  466. /// for testing purposes.
  467. ///
  468. /// \param n1,n2 \c Name class objects to compare.
  469. /// \return -1 if \c n1 would be sorted before \c n2.
  470. /// \return 0 if \c n1 is identical to \c n2 in terms of sorting order.
  471. /// \return 1 if \c n1 would be sorted after \c n2.
  472. ///
  473. int compareNames(const Name& n1, const Name& n2);
  474. } // end of namespace "rdata"
  475. }
  476. }
  477. #endif // RDATA_H
  478. // Local Variables:
  479. // mode: c++
  480. // End: