LCOV - code coverage report
Current view: top level - dns - masterload.h (source / functions) Hit Total Coverage
Test: report.info Lines: 3 3 100.0 %
Date: 2012-05-15 Functions: 2 3 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 2 50.0 %

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

Generated by: LCOV version 1.9