masterload.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 __MASTERLOAD_H
  15. #define __MASTERLOAD_H 1
  16. #include <iosfwd>
  17. #include <boost/function.hpp>
  18. #include <exceptions/exceptions.h>
  19. #include <dns/rrset.h>
  20. namespace isc {
  21. namespace dns {
  22. class Name;
  23. class RRClass;
  24. /// \brief An exception that is thrown if an error occurs while loading a
  25. /// master zone data.
  26. class MasterLoadError : public isc::Exception {
  27. public:
  28. MasterLoadError(const char* file, size_t line, const char* what) :
  29. isc::Exception(file, line, what) {}
  30. };
  31. /// The type of the \c callback parameter of \c masterLoad().
  32. ///
  33. /// This represents a functor object or a function that takes one parameter
  34. /// of type \c RRsetPtr and returns nothing.
  35. typedef boost::function<void(RRsetPtr)> MasterLoadCallback;
  36. ///
  37. /// \name Master zone file loader functions.
  38. ///
  39. //@{
  40. /// Master zone file loader from a file.
  41. ///
  42. /// This function parses a given file as a master DNS zone file for
  43. /// the given origin name and RR class, constructs a sequence of \c RRset
  44. /// from the RRs containing in the file, and calls the given \c callback
  45. /// functor object or function with each \c RRset.
  46. ///
  47. /// The \c callback parameter is a functor object or a function that
  48. /// takes one parameter of type \c RRsetPtr and returns nothing,
  49. /// i.e. \c void (see below for specific examples).
  50. /// More precisely, it can be anything that this form of boost::function
  51. /// can represent, but the caller normally doesn't have to care about
  52. /// that level of details.
  53. ///
  54. /// The ownership of constructed RRsets is transferred to the callback
  55. /// and this function never uses it once it is called.
  56. /// The callback can freely modify the passed \c RRset.
  57. ///
  58. /// This function performs minimum level of validation on the input:
  59. /// - Each RR is a valid textual representation per the DNS protocol.
  60. /// - The class of each RR must be identical to the specified RR class.
  61. /// - The owner name of each RR must be a subdomain of the origin name
  62. /// (that can be equal to the origin).
  63. /// - If an SOA RR is included, its owner name must be the origin name.
  64. /// If any of these validation checks fails, this function throws an
  65. /// exception of class \c MasterLoadError.
  66. ///
  67. /// It does not perform other semantical checks, however. For example,
  68. /// it doesn't check if an NS RR of the origin name is included or if
  69. /// there is more than one SOA RR. Such further checks are the caller's
  70. /// (or the callback's) responsibility.
  71. ///
  72. /// <b>Acceptable Format</b>
  73. ///
  74. /// The current implementation only supports a restricted form of master files
  75. /// for simplicity. One easy way to ensure that a handwritten zone file is
  76. /// acceptable to this implementation is to preprocess it with BIND 9's
  77. /// named-compilezone tool with both the input and output formats being
  78. /// "text".
  79. /// Here is an example:
  80. /// \code % named-compilezone -f text -F text -o example.com.norm
  81. /// example.com example.com.zone
  82. /// \endcode
  83. /// where example.com.zone is the original zone file for the "example.com"
  84. /// zone. The output file is example.com.norm, which should be acceptable
  85. /// by this implementation.
  86. ///
  87. /// Below are specific restrictions that this implementation assumes.
  88. /// Basically, each RR must consist of exactly one line
  89. /// (so there shouldn't be a multi-line RR) in the following format:
  90. /// \code <owner name> <TTL> <RRCLASS> <RRTYPE> <RDATA (single line)>
  91. /// \endcode
  92. /// Here are some more details about the restrictions:
  93. /// - No special directives such as $TTL are supported.
  94. /// - The owner name must be absolute, that is, it must end with a period.
  95. /// - "@" is not recognized as a valid owner name.
  96. /// - Owner names, TTL and RRCLASS cannot be omitted.
  97. /// - As a corollary, a non blank line must not begin with a space character.
  98. /// - The order of the RR parameters is fixed, for example, this is acceptable:
  99. /// \code example.com. 3600 IN A 192.0.2.1
  100. /// \endcode
  101. /// but this is not even though it's valid per RFC1035:
  102. /// \code example.com. IN 3600 A 192.0.2.1
  103. /// \endcode
  104. /// - "TTL", "RRCLASS", and "RRTYPE" must be recognizable by the \c RRTTL,
  105. /// RRClass and RRType class implementations of this library. In particular,
  106. /// as of this writing TTL must be a decimal number (a convenient extension
  107. /// such as "1H" instead of 3600 cannot be used). Not all standard RR
  108. /// classes and RR types are supported yet, so the mnemonics of them will
  109. /// be rejected, too.
  110. /// - RR TTLs of the same RRset must be the same; even if they are different,
  111. /// this implementation simply uses the TTL of the first RR.
  112. ///
  113. /// Blank lines and lines beginning with a semi-colon are allowed, and will
  114. /// be simply ignored. Comments cannot coexist with an RR line, however.
  115. /// For example, this will be rejected:
  116. /// \code example.com. 3600 IN A 192.0.2.1 ; this is a comment
  117. /// \endcode
  118. ///
  119. /// This implementation assumes that RRs of a single RRset are not
  120. /// interleaved with RRs of a different RRset.
  121. /// That is, the following sequence shouldn't happen:
  122. /// \code example.com. 3600 IN A 192.0.2.1
  123. /// example.com. 3600 IN AAAA 2001:db8::1
  124. /// example.com. 3600 IN A 192.0.2.2
  125. /// \endcode
  126. /// But it does not consider this an error; it will simply regard each RR
  127. /// as a separate RRset and call the callback with them separately.
  128. /// It is up to the callback to merge multiple RRsets into one if possible
  129. /// and necessary.
  130. ///
  131. /// <b>Exceptions</b>
  132. ///
  133. /// This function throws an exception of class \c MasterLoadError in the
  134. /// following cases:
  135. /// - Any of the validation checks fails (see the class description).
  136. /// - The input data is not in the acceptable format (see the details of
  137. /// the format above).
  138. /// - The specified file cannot be opened for loading.
  139. /// - An I/O error occurs during the loading.
  140. ///
  141. /// In addition, this function requires resource allocation for parsing and
  142. /// constructing RRsets. If it fails, the corresponding standard exception
  143. /// will be thrown.
  144. ///
  145. /// The callback may throw its own function. This function doesn't catch it
  146. /// and will simply propagate it towards the caller.
  147. ///
  148. /// <b>Usage Examples</b>
  149. ///
  150. /// A simplest example usage of this function would be to parse a zone
  151. /// file and (after validation) dump the content to the standard output.
  152. /// This is an example functor object and a call to \c masterLoad
  153. /// that implements this scenario:
  154. /// \code struct ZoneDumper {
  155. /// void operator()(ConstRRsetPtr rrset) const {
  156. /// std::cout << *rrset;
  157. /// }
  158. /// };
  159. /// ...
  160. /// masterLoad(zone_file, Name("example.com"), RRClass::IN(), ZoneDumper());
  161. /// \endcode
  162. /// Alternatively, you can use a normal function instead of a functor:
  163. /// \code void zoneDumper(ConstRRsetPtr rrset) {
  164. /// std::cout << *rrset;
  165. /// }
  166. /// ...
  167. /// masterLoad(zone_file, Name("example.com"), RRClass::IN(), zoneDumper);
  168. /// \endcode
  169. /// Or, if you want to use it with a member function of some other class,
  170. /// wrapping things with \c boost::bind would be handy:
  171. /// \code class ZoneDumper {
  172. /// public:
  173. /// void dump(ConstRRsetPtr rrset) const {
  174. /// std::cout << *rrset;
  175. /// }
  176. /// };
  177. /// ...
  178. /// ZoneDumper dumper;
  179. /// masterLoad(rr_stream, Name("example.com"), RRClass::IN(),
  180. /// boost::bind(&ZoneDumper::dump, &dumper, _1));
  181. /// \endcode
  182. /// You can find a bit more complicated examples in the unit tests code for
  183. /// this function.
  184. ///
  185. /// <b>Implementation Notes</b>
  186. ///
  187. /// The current implementation is in a preliminary level and needs further
  188. /// extensions. Some design decisions may also have to be reconsidered as
  189. /// we gain experiences. Those include:
  190. /// - We should be more flexible about the input format.
  191. /// - We may want to allow optional conditions. For example, we may want to
  192. /// be generous about some validation failures and be able to continue
  193. /// parsing.
  194. /// - Especially if we allow to be generous, we may also want to support
  195. /// returning an error code instead of throwing an exception when we
  196. /// encounter validation failure.
  197. /// - We may want to support incremental loading.
  198. /// - If we add these optional features we may want to introduce a class
  199. /// that encapsulates loading status and options.
  200. /// - RRSIGs are handled as separate RRsets, i.e. they are not included in
  201. /// the RRset they cover.
  202. ///
  203. /// \param filename A path to a master zone file to be loaded.
  204. /// \param origin The origin name of the zone.
  205. /// \param zone_class The RR class of the zone.
  206. /// \param callback A callback functor or function that is to be called
  207. /// for each RRset.
  208. void masterLoad(const char* const filename, const Name& origin,
  209. const RRClass& zone_class, MasterLoadCallback callback);
  210. /// Master zone file loader from input stream.
  211. ///
  212. /// This function is same as the other version
  213. /// (\c masterLoad(const char* const, const Name&, const RRClass&, MasterLoadCallback))
  214. /// except that it takes a \c std::istream instead of a file.
  215. /// It extracts lines from the stream and handles each line just as a line
  216. /// of a file for the other version of function.
  217. /// All descriptions of the other version apply to this version except those
  218. /// specific to file I/O.
  219. ///
  220. /// \param input An input stream object that is to emit zone's RRs.
  221. /// \param origin The origin name of the zone.
  222. /// \param zone_class The RR class of the zone.
  223. /// \param callback A callback functor or function that is to be called for
  224. /// each RRset.
  225. void masterLoad(std::istream& input, const Name& origin,
  226. const RRClass& zone_class, MasterLoadCallback callback);
  227. }
  228. //@}
  229. }
  230. #endif // __MASTERLOAD_H
  231. // Local Variables:
  232. // mode: c++
  233. // End: