rdata_reader.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // Copyright (C) 2012 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 DATASRC_MEMORY_RDATA_READER_H
  15. #define DATASRC_MEMORY_RDATA_READER_H 1
  16. #include "rdata_field.h"
  17. #include <boost/function.hpp>
  18. #include <dns/labelsequence.h>
  19. #include <dns/name.h>
  20. namespace isc {
  21. // Some forward declarations
  22. namespace dns{
  23. class RRClass;
  24. class RRType;
  25. }
  26. namespace datasrc {
  27. namespace memory {
  28. /// \brief Class to read serialized rdata
  29. ///
  30. /// This class allows you to read the data encoded by RDataEncoder.
  31. /// It is rather low-level -- it provides sequence of data fields
  32. /// and names. It does not give you convenient Rdata or RRset class.
  33. ///
  34. /// It allows two types of operation. First one is by providing callbacks
  35. /// to the constructor and then iterating by repeatedly calling next, or
  36. /// calling iterate once. The callbacks are then called with each part of
  37. /// the data.
  38. ///
  39. /// \code
  40. /// void handleLabel(const dns::LabelSequence& label, unsigned int flags) {
  41. /// ...
  42. /// }
  43. /// void handleData(const uint8_t* data, size_t size) {
  44. /// ...
  45. /// }
  46. ///
  47. /// RdataReader reader(RRClass::IN(), RRType::AAAA(), size, data,
  48. /// &handleLabel, handleData);
  49. /// reader.iterate();
  50. /// \endcode
  51. ///
  52. /// The other way is to use the return value of next() and loop through
  53. /// it manually. It has the inconvenience of having the type condition, but
  54. /// the code is in one place. The used way is matter of personal preferrence,
  55. /// there's no much difference on the technical side.
  56. ///
  57. /// \code
  58. /// RdataReader reader(RRClass::IN(), RRType::AAAA(), size, data,
  59. /// &handleLabel, handleData);
  60. /// RdataReader::Result data;
  61. /// while (data = reader.next()) {
  62. /// switch(data.type()) {
  63. /// case RdataReader::NAME:
  64. /// ...
  65. /// break;
  66. /// case RdataReader::DATA:
  67. /// ...
  68. /// break;
  69. /// default: assert(0); // Can not happen
  70. /// }
  71. /// }
  72. /// \endcode
  73. ///
  74. /// \note It is caller's responsibility to pass valid data here. This means
  75. /// the data returned by RdataEncoder and the corresponding class and type.
  76. /// If this is not the case, all the kinds of pointer hell might get loose.
  77. class RdataReader {
  78. public:
  79. /// \brief Function called on each name encountered in the data.
  80. typedef boost::function<void(const dns::LabelSequence&, unsigned)>
  81. NameAction;
  82. /// \brief Function called on each data field in the data.
  83. typedef boost::function<void(const uint8_t*, size_t)> DataAction;
  84. /// \brief a NameAction that does nothing.
  85. ///
  86. /// This is a NameAction function that does nothing. It is used
  87. /// as a default in the constructor.
  88. static void emptyNameAction(const dns::LabelSequence& label,
  89. unsigned attributes);
  90. /// \brief a DataAction that does nothing.
  91. ///
  92. /// This is a DataAction function that does nothing. It is used
  93. /// as a default in the constructor.
  94. static void emptyDataAction(const uint8_t* data, size_t size);
  95. /// \brief Constructor
  96. ///
  97. /// This constructs the reader on top of some serialized data.
  98. /// It does not copy the data, you have to make sure the data
  99. /// is valid for the whole life of this object and that they
  100. /// don't change.
  101. ///
  102. /// \param rrclass The class the encoded rdata belongs to.
  103. /// \param rrtype The type of the encode rdata.
  104. /// \param data The actual data.
  105. /// \param rdata_count The number of Rdata encoded in the data.
  106. /// \param sig_count The number of RRSig rdata bundled with the data.
  107. /// \param name_action The callback to be called on each encountered name.
  108. /// \param data_action The callback to be called on each data chunk.
  109. RdataReader(const dns::RRClass& rrclass, const dns::RRType& rrtype,
  110. const uint8_t* data, size_t rdata_count, size_t sig_count,
  111. const NameAction& name_action = &emptyNameAction,
  112. const DataAction& data_action = &emptyDataAction);
  113. /// \brief The type of data returned from this iteration.
  114. enum DataType {
  115. NAME, ///< This iteration returns domain label
  116. DATA, ///< This iteration returns unstructuder data
  117. END ///< No more data to return
  118. };
  119. /// \brief Data from one iteration
  120. ///
  121. /// Each time you call next() or nextSig(), it returns some data.
  122. /// This holds the data.
  123. ///
  124. /// It is valid only for as long as the RdataReader that returned it.
  125. ///
  126. /// All the methods can be called under any circumstances. However,
  127. /// if the required property is not valid for the given type (eg.
  128. /// when calling size() on type() == NAME), it returns some "empty"
  129. /// value (0, NULL, or the like).
  130. class Result {
  131. public:
  132. /// \brief Default constructor
  133. ///
  134. /// It creates an empty result (with no data) of type END.
  135. Result() :
  136. // TODO: Do we maybe want to have a static one to copy
  137. // instead of constructing new one from the root Name?
  138. label_(dns::Name::ROOT_NAME()),
  139. data_(NULL),
  140. size_(0),
  141. type_(END),
  142. compressible_(false),
  143. additional_(false)
  144. {}
  145. /// \brief Constructor from a domain label
  146. ///
  147. /// Creates the NAME type result. Used internally from RdataReader.
  148. ///
  149. /// \param label The label to hold
  150. /// \param attributes The attributes, as stored by the serialized
  151. /// data.
  152. Result(const dns::LabelSequence& label, unsigned attributes);
  153. /// \brief Constructor from data
  154. ///
  155. /// Creates the DATA type result. Used internally from RdataReader.
  156. ///
  157. /// \param data The data pointer to hold.
  158. /// \param size The size to hold.
  159. Result(const uint8_t* data, size_t size);
  160. /// \brief The type of data returned.
  161. DataType type() const { return (type_); }
  162. /// \brief The raw data.
  163. ///
  164. /// This is only valid if type() == DATA.
  165. const uint8_t* data() const { return (data_); }
  166. /// \brief The size of the raw data.
  167. ///
  168. /// This is the number of bytes the data takes. It is valid only
  169. /// if type() == DATA.
  170. size_t size() const { return (size_); }
  171. /// \brief The domain label.
  172. ///
  173. /// This holds the domain label. It is only valid if type() == NAME.
  174. const dns::LabelSequence& label() const { return (label_); }
  175. /// \brief Is the name in label() compressible?
  176. ///
  177. /// This is valid only if type() == NAME.
  178. bool compressible() const { return (compressible_); }
  179. /// \brief Does the name expect additional processing?
  180. ///
  181. /// This is valid only if type() == NAME.
  182. bool additional() const { return (additional_); }
  183. /// \brief If there are data returned.
  184. ///
  185. /// This returns if there are any data at all returned. This is
  186. /// equivalent to action != END, but it allows for more convenient
  187. /// code of a loop through the data.
  188. operator bool() const {
  189. return (type() != END);
  190. }
  191. private:
  192. dns::LabelSequence label_;
  193. const uint8_t* data_;
  194. size_t size_;
  195. DataType type_;
  196. bool compressible_;
  197. bool additional_;
  198. };
  199. /// \brief Step to next piece of data.
  200. ///
  201. /// This returns the next available data. Also, the apropriate hook
  202. /// (name_action or data_action, depending on the data type) as passed
  203. /// to the constructor is called.
  204. ///
  205. /// If there are no more data, a Result with type END is returned and
  206. /// no callback is called.
  207. Result next();
  208. /// \brief Call next() until the end.
  209. ///
  210. /// This is just convenience method to iterate through all the data.
  211. /// It calls next until it reaches the end (it does not revind before,
  212. /// therefore if you already called next() yourself, it does not start
  213. /// at the beginning).
  214. ///
  215. /// The method only makes sense if you set the callbacks in constructor.
  216. void iterate() {
  217. while (next()) { }
  218. }
  219. /// \brief Step to next piece of RRSig data.
  220. ///
  221. /// This is almost the same as next(), but it iterates through the
  222. /// associated RRSig data, not the data for the given RRType.
  223. Result nextSig();
  224. /// \brief Iterate through all RRSig data.
  225. ///
  226. /// This is almost the same as iterate(), but it iterates through the
  227. /// RRSig data instead.
  228. void iterateSig() {
  229. while (nextSig()) { }
  230. }
  231. /// \brief Rewind the iterator to the beginnig of data.
  232. ///
  233. /// The following next() and nextSig() will start iterating from the
  234. /// beginning again.
  235. void rewind();
  236. /// \brief Returns the size of associated data.
  237. ///
  238. /// This should be the same as the return value of
  239. /// RdataEncoder::getStorageLength() for the same set of data.
  240. /// The intended use of this method is to tell the caller the size of
  241. /// data that were possibly dynamically allocated so that the caller can
  242. /// use it for deallocation.
  243. ///
  244. /// This method only uses the parameters given at the construction of the
  245. /// object, and does not rely on or modify other mutable states.
  246. /// In practice, when the caller wants to call this method, that would be
  247. /// the only purpose of that RdataReader object (although it doesn't have
  248. /// to be so).
  249. size_t getSize() const;
  250. private:
  251. const NameAction name_action_;
  252. const DataAction data_action_;
  253. const RdataEncodeSpec& spec_;
  254. // Total number of var-length fields, count of signatures
  255. const size_t var_count_total_, sig_count_, spec_count_;
  256. // Pointer to the beginning of length fields
  257. const uint16_t* const lengths_;
  258. // Pointer to the beginning of the data (after the lengths)
  259. const uint8_t* const data_;
  260. // Pointer to the first data signature
  261. // Will be computed during the normal RR iteration
  262. const uint8_t* sigs_;
  263. // The positions in data.
  264. size_t data_pos_, spec_pos_, length_pos_;
  265. size_t sig_pos_, sig_data_pos_;
  266. Result nextInternal(const NameAction& name_action,
  267. const DataAction& data_action);
  268. };
  269. }
  270. }
  271. }
  272. #endif