LCOV - code coverage report
Current view: top level - dns - rrset.h (source / functions) Hit Total Coverage
Test: report.info Lines: 36 51 70.6 %
Date: 2012-05-15 Functions: 10 22 45.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 29 78 37.2 %

           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 __RRSET_H
      16                 :            : #define __RRSET_H 1
      17                 :            : 
      18                 :            : #include <iostream>
      19                 :            : #include <string>
      20                 :            : 
      21                 :            : #include <boost/shared_ptr.hpp>
      22                 :            : 
      23                 :            : #include <exceptions/exceptions.h>
      24                 :            : 
      25                 :            : #include <dns/rdata.h>
      26                 :            : #include <dns/rrtype.h>
      27                 :            : 
      28                 :            : namespace isc {
      29                 :            : namespace util {
      30                 :            : class OututBuffer;
      31                 :            : }
      32                 :            : 
      33                 :            : namespace dns {
      34                 :            : 
      35                 :            : ///
      36                 :            : /// \brief A standard DNS module exception that is thrown if an RRset object
      37                 :            : /// does not contain any RDATA where required.
      38                 :            : ///
      39                 :         10 : class EmptyRRset : public Exception {
      40                 :            : public:
      41                 :            :     EmptyRRset(const char* file, size_t line, const char* what) :
      42 [ +  - ][ +  - ]:         10 :         isc::Exception(file, line, what) {}
                 [ +  - ]
      43                 :            : };
      44                 :            : 
      45                 :            : // forward declarations
      46                 :            : class Name;
      47                 :            : class RRType;
      48                 :            : class RRClass;
      49                 :            : class RRTTL;
      50                 :            : class AbstractMessageRenderer;
      51                 :            : class AbstractRRset;
      52                 :            : class BasicRRset;
      53                 :            : class RdataIterator;
      54                 :            : class BasicRRsetImpl;
      55                 :            : class RRset;
      56                 :            : 
      57                 :            : /// \brief A pointer-like type pointing to an \c RRset object.
      58                 :            : ///
      59                 :            : /// This type is commonly used as an argument of various functions defined
      60                 :            : /// in this library in order to handle RRsets in a polymorphic manner.
      61                 :            : typedef boost::shared_ptr<AbstractRRset> RRsetPtr;
      62                 :            : 
      63                 :            : /// \brief A pointer-like type pointing to an (immutable) \c RRset
      64                 :            : /// object.
      65                 :            : ///
      66                 :            : /// This type is commonly used as an argument of various functions defined
      67                 :            : /// in this library in order to handle RRsets in a polymorphic manner.
      68                 :            : typedef boost::shared_ptr<const AbstractRRset> ConstRRsetPtr;
      69                 :            : 
      70                 :            : /// \brief A pointer-like type point to an \c RdataIterator object.
      71                 :            : typedef boost::shared_ptr<RdataIterator> RdataIteratorPtr;
      72                 :            : 
      73                 :            : /// \brief The \c AbstractRRset class is an abstract base class that
      74                 :            : /// models a DNS RRset.
      75                 :            : ///
      76                 :            : /// An object of (a specific derived class of) \c AbstractRRset
      77                 :            : /// models an RRset as described in the DNS standard:
      78                 :            : /// A set of DNS resource records (RRs) of the same type and class.
      79                 :            : /// The standard requires the TTL of all RRs in an RRset be the same;
      80                 :            : /// this class follows that requirement.
      81                 :            : 
      82                 :            : /// Note about duplicate RDATA: RFC2181 states that it's meaningless that an
      83                 :            : /// RRset contains two identical RRs and that name servers should suppress
      84                 :            : /// such duplicates.
      85                 :            : /// This class is not responsible for ensuring this requirement: For example,
      86                 :            : /// \c addRdata() method doesn't check if there's already RDATA identical
      87                 :            : /// to the one being added.
      88                 :            : /// This is because such checks can be expensive, and it's often easy to
      89                 :            : /// ensure the uniqueness requirement at the %data preparation phase
      90                 :            : /// (e.g. when loading a zone).
      91                 :            : /// When parsing an incoming DNS message, the uniqueness may not be guaranteed,
      92                 :            : /// so the application needs to detect and ignore any duplicate RDATA
      93                 :            : /// (the \c Message class of this library should provide this responsibility).
      94                 :            : ///
      95                 :            : /// Another point to note is that \c AbstractRRset and its derived classes
      96                 :            : /// allow an object to have an empty set of RDATA.
      97                 :            : /// Even though there's no corresponding notion in the protocol specification,
      98                 :            : /// it would be more intuitive for a container-like %data structure
      99                 :            : /// to allow an empty set.
     100                 :            : ///
     101                 :            : /// Since \c AbstractRRset is an abstract class, it is generally used
     102                 :            : /// via a pointer (or pointer like object) or a reference.
     103                 :            : /// In particular, \c RRsetPtr, a pointer like type for \c AbstractRRset,
     104                 :            : /// is used for polymorphic RRset operations throughout this library.
     105                 :            : ///
     106                 :            : /// The \c AbstractRRset class is also intended to be a major customization
     107                 :            : /// point.  For example, a high performance server implementation may want
     108                 :            : /// to define an optimized "pre-compiled" RRset and provide an optimized
     109                 :            : /// implementation of the \c toWire() method.
     110                 :            : ///
     111                 :            : /// Note about design choice: In BIND9, a set of RDATA with a common tuple
     112                 :            : /// of RR class, RR type, and TTL was represented in a structure named
     113                 :            : /// \c rdataset.  Unlike the RRset classes, an \c rdataset did not contain
     114                 :            : /// the information of the owner name.
     115                 :            : /// This might be advantageous if we want to handle "RRsets", that is,
     116                 :            : /// a set of different types of RRset for the same owner name, because
     117                 :            : /// a single "name" structure can be used for multiple RRsets, minimizing
     118                 :            : /// %data copy and memory footprint.
     119                 :            : /// On the other hand, it's inconvenient for API users since in many cases
     120                 :            : /// a pair of name and an \c rdataset must be maintained.  It's also counter
     121                 :            : /// intuitive in implementing protocol operations as an RRset is often used
     122                 :            : /// as an atomic entity in DNS protocols while an \c rdataset is a component
     123                 :            : /// of an RRset.
     124                 :            : ///
     125                 :            : /// We have therefore defined the notion of RRset explicitly in our initial
     126                 :            : /// API design.  We believe memory footprint is not a big concern because
     127                 :            : /// RRsets are generally expected to be used as temporary objects, e.g.
     128                 :            : /// while parsing or constructing a DNS message, or searching a DNS %data
     129                 :            : /// source; for longer term purposes such as in-memory %data source entries,
     130                 :            : /// the corresponding %data would be represented in a different, memory
     131                 :            : /// optimized format.  As for the concern about %data copy, we believe
     132                 :            : /// it can be mitigated by using copy-efficient implementation for the
     133                 :            : /// \c Name class implementation, such as reference counted objects.
     134                 :            : /// Later, We plan to perform benchmark tests later to see if this assumption
     135                 :            : /// is valid and to revisit the design if necessary.
     136                 :            : ///
     137                 :            : /// Note about terminology: there has been a discussion at the IETF
     138                 :            : /// namedroppers ML about RRset vs RRSet (case of "s")
     139                 :            : /// [http://ops.ietf.org/lists/namedroppers/namedroppers.2009/msg02737.html].
     140                 :            : /// While RFC2181 uses the latter, many other RFCs use the former,
     141                 :            : /// and most of the list members who showed their opinion seem to prefer
     142                 :            : /// "RRset".  We follow that preference in this implementation.
     143                 :            : ///
     144                 :            : /// The current design of \c AbstractRRset is still in flux.
     145                 :            : /// There are many open questions in design details:
     146                 :            : ///   - support more set-like operations, e.g, merge two RRsets of the same
     147                 :            : ///     type?
     148                 :            : ///   - more convenient methods or non member utility functions, e.g.
     149                 :            : ///      "sort" and "search(find)" method?
     150                 :            : ///   - what about comparing two RRsets of the same type?  If we need this,
     151                 :            : ///     should it compare rdata's as a set or as a list (i.e. compare
     152                 :            : ///     each rdata one by one or as a whole)?  c.f. NLnet Labs' ldns
     153                 :            : ///     (http://www.nlnetlabs.nl/projects/ldns/doc/index.html)
     154                 :            : ///     has \c ldns_rr_list_compare(), which takes the latter approach
     155                 :            : ///     (seemingly assuming the caller sorts the lists beforehand).
     156                 :            : ///   - BIND9 libdns has some special DNSSEC-related methods
     157                 :            : ///     such as \c addnoqname() or \c addclosest().  Do we need these?
     158                 :            : ///     (Probably not.  We wouldn't want to make the class design too
     159                 :            : ///     monolithic.)
     160                 :            : ///   - Do we need to allow the user to remove specific Rdata?
     161                 :            : ///     Probably not, according to the current usage of the BIND9 code.
     162                 :            : class AbstractRRset {
     163                 :            :     ///
     164                 :            :     /// \name Constructors and Destructor
     165                 :            :     ///
     166                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
     167                 :            :     /// defined as private to make it explicit that this is a pure base class.
     168                 :            :     //@{
     169                 :            : private:
     170                 :            :     AbstractRRset(const AbstractRRset& source);
     171                 :            :     AbstractRRset& operator=(const AbstractRRset& source);
     172                 :            : protected:
     173                 :            :     /// \brief The default constructor.
     174                 :            :     ///
     175                 :            :     /// This is intentionally defined as \c protected as this base class should
     176                 :            :     /// never be instantiated (except as part of a derived class).
     177                 :      26752 :     AbstractRRset() {}
     178                 :            : public:
     179                 :            :     /// The destructor.
     180                 :      26746 :     virtual ~AbstractRRset() {}
     181                 :            :     //@}
     182                 :            : 
     183                 :            :     ///
     184                 :            :     /// \name Getter and Setter Methods
     185                 :            :     ///
     186                 :            :     /// These methods are generally expected to be exception free, but it's
     187                 :            :     /// not guaranteed at the interface level;
     188                 :            :     /// for example, some performance optimized derived class may manage
     189                 :            :     /// the information corresponding to the class "attributes" to get or set,
     190                 :            :     /// and may require dynamic memory allocation to execute the method.
     191                 :            :     /// Consult the derived class description to see if a specific derived
     192                 :            :     /// \c RRset class may throw an exception from these methods.
     193                 :            :     ///
     194                 :            :     /// Note that setter methods are not provided for \c RRClass and
     195                 :            :     /// \c RRType.  This is intentional.  Since the format and semantics of
     196                 :            :     /// \c Rdata are dependent on the RR type (and RR class for some RR types),
     197                 :            :     /// allowing dynamically modify these attributes can easily lead to a
     198                 :            :     /// bug where the RDATA and type and/or class become inconsistent.
     199                 :            :     /// We want to avoid that situation by restricting the access.
     200                 :            :     //@{
     201                 :            :     /// \brief Returns the number of \c Rdata objects contained in the \c RRset.
     202                 :            :     ///
     203                 :            :     /// Note that an \c RRset with an empty set of \c Rdata can exist, so
     204                 :            :     /// this method may return 0.
     205                 :            :     ///
     206                 :            :     /// \return The number of \c Rdata objects contained.
     207                 :            :     virtual unsigned int getRdataCount() const = 0;
     208                 :            : 
     209                 :            :     /// \brief Returns the owner name of the \c RRset.
     210                 :            :     ///
     211                 :            :     /// \return A reference to a \c Name class object corresponding to the
     212                 :            :     /// \c RRset owner name.
     213                 :            :     virtual const Name& getName() const = 0;
     214                 :            : 
     215                 :            :     /// \brief Returns the RR Class of the \c RRset.
     216                 :            :     ///
     217                 :            :     /// \return A reference to a \c RRClass class object corresponding to the
     218                 :            :     /// RR class of the \c RRset.
     219                 :            :     virtual const RRClass& getClass() const = 0;
     220                 :            : 
     221                 :            :     /// \brief Returns the RR Type of the \c RRset.
     222                 :            :     ///
     223                 :            :     /// \return A reference to a \c RRType class object corresponding to the
     224                 :            :     /// RR type of the \c RRset.
     225                 :            :     virtual const RRType& getType() const = 0;
     226                 :            : 
     227                 :            :     /// \brief Returns the TTL of the RRset.
     228                 :            :     ///
     229                 :            :     /// \return A reference to a \c RRTTL class object corresponding to the
     230                 :            :     /// TTL of the \c RRset.
     231                 :            :     virtual const RRTTL& getTTL() const = 0;
     232                 :            : 
     233                 :            :     /// \brief Updates the owner name of the \c RRset.
     234                 :            :     ///
     235                 :            :     /// \param name A reference to a \c Name class object to be copied as the
     236                 :            :     /// new name.
     237                 :            :     virtual void setName(const Name& name) = 0;
     238                 :            : 
     239                 :            :     /// \brief Updates the TTL of the \c RRset.
     240                 :            :     ///
     241                 :            :     /// \param ttl A reference to a \c RRTTL class object to be copied as the
     242                 :            :     /// new TTL.
     243                 :            :     virtual void setTTL(const RRTTL& ttl) = 0;
     244                 :            :     //@}
     245                 :            : 
     246                 :            :     ///
     247                 :            :     /// \name Converter Methods
     248                 :            :     ///
     249                 :            :     /// These methods have the default implementation that can be reused by
     250                 :            :     /// derived classes.
     251                 :            :     /// Since they are defined as pure virtual, derived classes
     252                 :            :     /// that want to reuse the default implementation must explicitly
     253                 :            :     /// invoke their base class version (see the description for
     254                 :            :     /// <code>addRdata(const rdata::Rdata&)</code>).
     255                 :            :     ///
     256                 :            :     /// Design Note: the default implementations are defined only using
     257                 :            :     /// other public methods of the \c AbstractRRset class, and could be
     258                 :            :     /// implemented as non member functions (as some C++ textbooks suggest).
     259                 :            :     /// However, since derived classes may want to provide customized versions
     260                 :            :     /// (especially of the \c toWire() method for performance reasons)
     261                 :            :     /// we chose to define them as virtual functions, and, as a result,
     262                 :            :     /// member functions.
     263                 :            :     //@{
     264                 :            :     /// \brief Convert the RRset to a string.
     265                 :            :     ///
     266                 :            :     /// Unlike other similar methods of this library, this method terminates
     267                 :            :     /// the resulting string with a trailing newline character.
     268                 :            :     /// (following the BIND9 convention)
     269                 :            :     ///
     270                 :            :     /// The RRset must contain some RDATA; otherwise, an exception of class
     271                 :            :     /// \c EmptyRRset will be thrown.
     272                 :            :     /// If resource allocation fails, a corresponding standard exception
     273                 :            :     /// will be thrown.
     274                 :            :     /// The default implementation may throw other exceptions if the
     275                 :            :     /// \c toText() method of the RDATA objects throws.
     276                 :            :     /// If a derived class of \c AbstractRRset overrides the default
     277                 :            :     /// implementation, the derived version may throw its own exceptions.
     278                 :            :     ///
     279                 :            :     /// Open issue: We may want to support multiple output formats as
     280                 :            :     /// BIND9 does.  For example, we might want to allow omitting the owner
     281                 :            :     /// name when possible in the context of zone dump.  This is a future
     282                 :            :     /// TODO item.
     283                 :            :     ///
     284                 :            :     /// \return A string representation of the RRset.
     285                 :            :     virtual std::string toText() const = 0;
     286                 :            : 
     287                 :            :     /// \brief Render the RRset in the wire format with name compression and
     288                 :            :     /// truncation handling.
     289                 :            :     ///
     290                 :            :     /// This method compresses the owner name of the RRset and domain names
     291                 :            :     /// used in RDATA that should be compressed.
     292                 :            :     /// In addition, this method detects the case where rendering the entire
     293                 :            :     /// RRset would cause truncation, and handles the case appropriately
     294                 :            :     /// (this is a TODO item, and not implemented in this version).
     295                 :            :     ///
     296                 :            :     /// Note: perhaps we may want to add more arguments to convey optional
     297                 :            :     /// information such as an "rrset-order" policy or how to handle truncation
     298                 :            :     /// case.  This is a TODO item.
     299                 :            :     ///
     300                 :            :     /// If resource allocation fails, a corresponding standard exception
     301                 :            :     /// will be thrown.
     302                 :            :     /// The RRset must contain some RDATA; otherwise, an exception of class
     303                 :            :     /// \c EmptyRRset will be thrown.
     304                 :            :     /// The default implementation may throw other exceptions if the
     305                 :            :     /// \c toWire() method of the RDATA objects throws.
     306                 :            :     /// If a derived class of \c AbstractRRset overrides the default
     307                 :            :     /// implementation, the derived version may throw its own exceptions.
     308                 :            :     ///
     309                 :            :     /// \param renderer DNS message rendering context that encapsulates the
     310                 :            :     /// output buffer and name compression information.
     311                 :            :     /// \return The number of RRs rendered.  If the truncation is necessary
     312                 :            :     /// this value may be different from the number of RDATA objects contained
     313                 :            :     /// in the RRset.
     314                 :            :     virtual unsigned int toWire(AbstractMessageRenderer& renderer) const = 0;
     315                 :            : 
     316                 :            :     /// \brief Render the RRset in the wire format without any compression.
     317                 :            :     ///
     318                 :            :     /// See the other toWire() description about possible exceptions.
     319                 :            :     ///
     320                 :            :     /// \param buffer An output buffer to store the wire data.
     321                 :            :     /// \return The number of RRs rendered.
     322                 :            :     virtual unsigned int toWire(isc::util::OutputBuffer& buffer) const = 0;
     323                 :            :     //@}
     324                 :            : 
     325                 :            :     ///
     326                 :            :     /// \name RDATA Manipulation Methods
     327                 :            :     ///
     328                 :            :     //@{
     329                 :            :     /// \brief Add an RDATA to the RRset (pointer version).
     330                 :            :     ///
     331                 :            :     /// This method adds the given RDATA (as a pointer-like type to a
     332                 :            :     /// derived class object of \c rdata::Rdata) to the \c RRset.
     333                 :            :     ///
     334                 :            :     /// \param rdata A pointer (like) type of \c rdata::RdataPtr to be added
     335                 :            :     /// to the \c RRset.
     336                 :            :     virtual void addRdata(rdata::ConstRdataPtr rdata) = 0;
     337                 :            : 
     338                 :            :     /// \brief Add an RDATA to the RRset (reference version).
     339                 :            :     ///
     340                 :            :     /// This method adds the given RDATA (as a reference to a
     341                 :            :     /// derived class object of \c rdata::Rdata) to the \c RRset.
     342                 :            :     ///
     343                 :            :     /// This method has the default implementation that can be reused by
     344                 :            :     /// derived classes.
     345                 :            :     /// Since this method is defined as pure virtual, derived classes
     346                 :            :     /// that want to reuse the default implementation must explicitly
     347                 :            :     /// invoke this base class version.
     348                 :            :     /// For example, if the class \c CustomizedRRset, a derived class of
     349                 :            :     /// \c AbstractRRset, wants to reuse the default implementation of
     350                 :            :     /// \c %addRdata() (reference version), it would be defined as follows:
     351                 :            :     /// \code void
     352                 :            :     /// CustomizedRRset::addRdata(const rdata::Rdata& rdata)
     353                 :            :     /// {
     354                 :            :     ///     AbstractRRset::addRdata(rdata);
     355                 :            :     /// }
     356                 :            :     /// \endcode
     357                 :            :     ///
     358                 :            :     /// This method is more strictly typed than the pointer version:
     359                 :            :     /// If \c rdata does not refer to the appropriate derived
     360                 :            :     /// \c Rdata class
     361                 :            :     /// for the \c RRType for this \c RRset, it throws an exception of class
     362                 :            :     /// \c std::bad_cast.
     363                 :            :     /// If resource allocation fails, a corresponding standard exception
     364                 :            :     /// will be thrown.
     365                 :            :     /// The RRset must contain some RDATA; otherwise, an exception of class
     366                 :            :     /// \c EmptyRRset will be thrown.
     367                 :            :     /// The default implementation may throw other exceptions if the
     368                 :            :     /// \c toWire() method of the RDATA objects throws.
     369                 :            :     /// If a derived class of \c AbstractRRset overrides the default
     370                 :            :     /// implementation, the derived version may throw its own exceptions.
     371                 :            :     ///
     372                 :            :     /// The default implementation simply constructs an \c rdata::RdataPtr
     373                 :            :     /// object from a newly allocated RDATA object copying from parameter
     374                 :            :     /// \c rdata, and calls the other version of
     375                 :            :     /// \c addRdata(const rdata::RdataPtr).
     376                 :            :     /// So it is inherently less efficient than the other version.
     377                 :            :     /// Still, this version would offer a more intuitive interface and is
     378                 :            :     /// provided as such.
     379                 :            :     ///
     380                 :            :     /// \param rdata A reference to a \c rdata::RdataPtr (derived) class
     381                 :            :     /// object, a copy of which is to be added to the \c RRset.
     382                 :            :     virtual void addRdata(const rdata::Rdata& rdata) = 0;
     383                 :            : 
     384                 :            :     /// \brief Return an iterator to go through all RDATA stored in the
     385                 :            :     /// \c RRset.
     386                 :            :     ///
     387                 :            :     /// The rdata cursor of the returned iterator will point to the first
     388                 :            :     /// RDATA, that is, it effectively calls \c RdataIterator::first()
     389                 :            :     /// internally.
     390                 :            :     ///
     391                 :            :     /// Using the design pattern terminology, \c getRdataIterator()
     392                 :            :     /// is an example of a <em>factory method</em>.
     393                 :            :     ///
     394                 :            :     /// Whether this method throws an exception depends on the actual
     395                 :            :     /// implementation of the derived \c AbstractRRset class, but in general
     396                 :            :     /// it will involve resource allocation and can throw a standard exception
     397                 :            :     /// if it fails.
     398                 :            :     ///
     399                 :            :     /// \return A pointer-like object pointing to the derived \c RdataIterator
     400                 :            :     /// object.
     401                 :            :     virtual RdataIteratorPtr getRdataIterator() const = 0;
     402                 :            :     //@}
     403                 :            : 
     404                 :            :     ///
     405                 :            :     /// \name Associated RRSIG methods
     406                 :            :     ///
     407                 :            :     /// These methods access an "associated" RRset, that containing the DNSSEC
     408                 :            :     /// signatures for this RRset.  It can be argued that this is not a
     409                 :            :     /// fundamental part of the RRset abstraction, since RFC 2181 defined an
     410                 :            :     /// RRset as a group of records with the same label, class and type but
     411                 :            :     /// different data.  However, BIND 10 has to deal with DNSSEC and in
     412                 :            :     /// practice, including the information at the AbstractRRset level makes
     413                 :            :     /// implementation easier.  (If a class is ever needed that must be
     414                 :            :     /// ignorant of the idea of an associated RRSIG RRset - e.g. a specialised
     415                 :            :     /// RRSIG RRset class - these methods can just throw a "NotImplemented"
     416                 :            :     /// exception.)
     417                 :            :     //@{
     418                 :            :     /// \brief Return pointer to this RRset's RRSIG RRset
     419                 :            :     ///
     420                 :            :     /// \return Pointer to the associated RRSIG RRset or null if there is none.
     421                 :            :     virtual RRsetPtr getRRsig() const = 0;
     422                 :            : 
     423                 :            :     /// \brief Adds RRSIG RRset RRs to the associated RRSIG RRset
     424                 :            :     ///
     425                 :            :     /// Adds the (assumed) RRSIG rdata the RRSIG RRset associated with this
     426                 :            :     /// RRset.  If one does not exist, it is created using the data given.
     427                 :            :     ///
     428                 :            :     /// \param rdata Pointer to RRSIG rdata to be added.
     429                 :            :     virtual void addRRsig(const rdata::ConstRdataPtr& rdata) = 0;
     430                 :            : 
     431                 :            :     /// \brief Adds RRSIG RRset RRs to the associated RRSIG RRset
     432                 :            :     ///
     433                 :            :     /// Adds the (assumed) RRSIG rdata the RRSIG RRset associated with this
     434                 :            :     /// RRset.  If one does not exist, it is created using the data given.
     435                 :            :     ///
     436                 :            :     /// (This overload is for an older version of boost that doesn't support
     437                 :            :     /// conversion from shared_ptr<X> to shared_ptr<const X>.)
     438                 :            :     ///
     439                 :            :     /// \param rdata Pointer to RRSIG rdata to be added.
     440                 :            :     virtual void addRRsig(const rdata::RdataPtr& rdata) = 0;
     441                 :            : 
     442                 :            :     /// \brief Adds RRSIG RRset RRs to the associated RRSIG RRset
     443                 :            :     ///
     444                 :            :     /// Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG
     445                 :            :     /// RRset associated with this RRset.  If one does not exist, it is created
     446                 :            :     /// using the data given.
     447                 :            :     ///
     448                 :            :     /// \param sigs RRSIG RRset containing signatures to be added to the
     449                 :            :     ///             RRSIG RRset associated with this class.
     450                 :            :     virtual void addRRsig(const AbstractRRset& sigs) = 0;
     451                 :            : 
     452                 :            :     /// \brief Adds RRSIG RRset RRs to the associated RRSIG RRset
     453                 :            :     ///
     454                 :            :     /// Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG
     455                 :            :     /// RRset associated with this RRset.  If one does not exist, it is created
     456                 :            :     /// using the data given.
     457                 :            :     ///
     458                 :            :     /// \param sigs Pointer to a RRSIG RRset containing signatures to be added
     459                 :            :     ///             to the RRSIG RRset associated with this class.
     460                 :            :     virtual void addRRsig(const ConstRRsetPtr& sigs) = 0;
     461                 :            : 
     462                 :            :     /// \brief Adds RRSIG RRset RRs to the associated RRSIG RRset
     463                 :            :     ///
     464                 :            :     /// Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG
     465                 :            :     /// RRset associated with this RRset.  If one does not exist, it is created
     466                 :            :     /// using the data given.
     467                 :            :     ///
     468                 :            :     /// (This overload is for an older version of boost that doesn't support
     469                 :            :     /// conversion from shared_ptr<X> to shared_ptr<const X>.)
     470                 :            :     ///
     471                 :            :     /// \param sigs Pointer to a RRSIG RRset containing signatures to be added
     472                 :            :     ///             to the RRSIG RRset associated with this class.
     473                 :            :     virtual void addRRsig(const RRsetPtr& sigs) = 0;
     474                 :            : 
     475                 :            :     /// \brief Clear the RRSIGs for this RRset
     476                 :            :     virtual void removeRRsig() = 0;
     477                 :            : 
     478                 :            :     /// \brief Check whether two RRsets are of the same kind
     479                 :            :     ///
     480                 :            :     /// Checks if two RRsets have the same name, RR type, and RR class.
     481                 :            :     ///
     482                 :            :     /// \param other Pointer to another AbstractRRset to compare
     483                 :            :     ///              against.
     484                 :            :     virtual bool isSameKind(const AbstractRRset& other) const;
     485                 :            :     //@}
     486                 :            : 
     487                 :            : };
     488                 :            : 
     489                 :            : /// \brief The \c RdataIterator class is an abstract base class that
     490                 :            : /// provides an interface for accessing RDATA objects stored in an RRset.
     491                 :            : ///
     492                 :            : /// While different derived classes of \c AbstractRRset may maintain the RDATA
     493                 :            : /// objects in different ways, the \c RdataIterator class provides a
     494                 :            : /// unified interface to iterate over the RDATA objects in a polymorphic
     495                 :            : /// manner.
     496                 :            : ///
     497                 :            : /// Each derived class of \c AbstractRRset is expected to provide a concrete
     498                 :            : /// derived class of \c RdataIterator, and each derived \c RdataIterator
     499                 :            : /// class implements the unified interface in a way specific to the
     500                 :            : /// implementation of the corresponding derived \c AbstractRRset class.
     501                 :            : /// Using the design pattern terminology, this is a typical example of
     502                 :            : /// the \e Iterator pattern.
     503                 :            : ///
     504                 :            : /// The RDATA objects stored in the \c RRset are considered to form
     505                 :            : /// a unidirectional list from the \c RdataIterator point of view (while
     506                 :            : /// the actual implementation in the derived \c RRset may not use a list).
     507                 :            : /// We call this unidirectional list the <em>rdata list</em>.
     508                 :            : ///
     509                 :            : /// An \c RdataIterator object internally (and conceptually) holds a
     510                 :            : /// <em>rdata cursor</em>, which points to a specific item of the rdata list.
     511                 :            : ///
     512                 :            : /// Note about design choice: as is clear from the interface, \c RdataIterator
     513                 :            : /// is not compatible with the standard iterator classes.
     514                 :            : /// Although it would be useful (for example, we could then use STL algorithms)
     515                 :            : /// and is not necessarily impossible, it would make the iterator implementation
     516                 :            : /// much more complicated.
     517                 :            : /// For instance, any standard iterator must be assignable and
     518                 :            : /// copy-constructible.
     519                 :            : /// So we'd need to implement \c RdataIterator::operator=() in a polymorphic
     520                 :            : /// way.  This will require non-trivial implementation tricks.
     521                 :            : /// We believe the simplified iterator interface as provided by the
     522                 :            : /// \c RdataIterator class is sufficient in practice:
     523                 :            : /// Most applications will simply go through the RDATA objects contained in
     524                 :            : /// an RRset, examining (and possibly using) each object, as one path
     525                 :            : /// operation.
     526                 :            : class RdataIterator {
     527                 :            :     ///
     528                 :            :     /// \name Constructors and Destructor
     529                 :            :     ///
     530                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
     531                 :            :     /// defined as private to make it explicit that this is a pure base class.
     532                 :            :     //@{
     533                 :            : protected:
     534                 :            :     /// \brief The default constructor.
     535                 :            :     ///
     536                 :            :     /// This is intentionally defined as \c protected as this base class should
     537                 :            :     /// never be instantiated (except as part of a derived class).
     538                 :      14929 :     RdataIterator() {}
     539                 :            : public:
     540                 :            :     /// \brief Destructor
     541                 :      14929 :     virtual ~RdataIterator() {}
     542                 :            : private:
     543                 :            :     RdataIterator(const RdataIterator& source);
     544                 :            :     RdataIterator& operator=(const RdataIterator& source);
     545                 :            :     //@}
     546                 :            : 
     547                 :            : public:
     548                 :            :     /// \brief Move the rdata cursor to the first RDATA in the rdata list
     549                 :            :     /// (if any).
     550                 :            :     ///
     551                 :            :     /// This method can safely be called multiple times, even after moving
     552                 :            :     /// the rdata cursor forward by the \c next() method.
     553                 :            :     ///
     554                 :            :     /// This method should never throw an exception.
     555                 :            :     virtual void first() = 0;
     556                 :            : 
     557                 :            :     /// \brief Move the rdata cursor to the next RDATA in the rdata list
     558                 :            :     /// (if any).
     559                 :            :     ///
     560                 :            :     /// This method should never throw an exception.
     561                 :            :     virtual void next() = 0;
     562                 :            : 
     563                 :            :     /// \brief Return the current \c Rdata corresponding to the rdata cursor.
     564                 :            :     ///
     565                 :            :     /// \return A reference to an \c rdata::Rdata object corresponding
     566                 :            :     /// to the rdata cursor.
     567                 :            :     virtual const rdata::Rdata& getCurrent() const = 0;
     568                 :            : 
     569                 :            :     /// \brief Return true iff the rdata cursor has reached the end of the
     570                 :            :     /// rdata list.
     571                 :            :     ///
     572                 :            :     /// Once this method returns \c true, the behavior of any subsequent
     573                 :            :     /// call to \c next() or \c getCurrent() is undefined.
     574                 :            :     /// Likewise, the result of \c isLast() call followed by such undefined
     575                 :            :     /// operations is also undefined.
     576                 :            :     ///
     577                 :            :     /// This method should never throw an exception.
     578                 :            :     ///
     579                 :            :     /// \return \c true if the rdata cursor has reached the end of the
     580                 :            :     /// rdata list; otherwise \c false.
     581                 :            :     virtual bool isLast() const = 0;
     582                 :            : };
     583                 :            : 
     584                 :            : /// \brief The \c BasicRRset class is a concrete derived class of
     585                 :            : /// \c AbstractRRset that defines a straightforward RRset implementation.
     586                 :            : ///
     587                 :            : /// This class is designed to be as portable as possible, and so it adopts
     588                 :            : /// the Pimpl idiom to hide as many details as possible.
     589                 :            : /// Performance is a secondary concern for this class.
     590                 :            : ///
     591                 :            : /// This class is intended to be used by applications that only need
     592                 :            : /// moderate level of performance with full functionality provided by
     593                 :            : /// the \c AbstractRRset interfaces.
     594                 :            : /// Highly performance-sensitive applications, such as a large scale
     595                 :            : /// authoritative or caching name servers will implement and use a customized
     596                 :            : /// version of derived \c AbstractRRset class.
     597                 :            : class BasicRRset : public AbstractRRset {
     598                 :            :     ///
     599                 :            :     /// \name Constructors and Destructor
     600                 :            :     ///
     601                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
     602                 :            :     /// defined as private.  The intended use case wouldn't require copies of
     603                 :            :     /// a \c BasicRRset object; once created, it would normally be used
     604                 :            :     /// as a \c const object (via references).
     605                 :            :     //@{
     606                 :            : private:
     607                 :            :     BasicRRset(const BasicRRset& source);
     608                 :            :     BasicRRset& operator=(const BasicRRset& source);
     609                 :            : public:
     610                 :            :     /// \brief Constructor from (mostly) fixed parameters of the RRset.
     611                 :            :     ///
     612                 :            :     /// This constructor is normally expected to be exception free, but
     613                 :            :     /// copying the name may involve resource allocation, and if it fails
     614                 :            :     /// the corresponding standard exception will be thrown.
     615                 :            :     ///
     616                 :            :     /// \param name The owner name of the RRset.
     617                 :            :     /// \param rrclass The RR class of the RRset.
     618                 :            :     /// \param rrtype The RR type of the RRset.
     619                 :            :     /// \param ttl The TTL of the RRset.
     620                 :            :     BasicRRset(const Name& name, const RRClass& rrclass,
     621                 :            :                const RRType& rrtype, const RRTTL& ttl);
     622                 :            :     /// \brief The destructor.
     623                 :            :     virtual ~BasicRRset();
     624                 :            :     //@}
     625                 :            : 
     626                 :            :     ///
     627                 :            :     /// \name Getter and Setter Methods
     628                 :            :     ///
     629                 :            :     //@{
     630                 :            :     /// \brief Returns the number of \c Rdata objects contained in the \c RRset.
     631                 :            :     ///
     632                 :            :     /// This method never throws an exception.
     633                 :            :     ///
     634                 :            :     /// \return The number of \c Rdata objects contained.
     635                 :            :     virtual unsigned int getRdataCount() const;
     636                 :            : 
     637                 :            :     /// \brief Returns the owner name of the \c RRset.
     638                 :            :     ///
     639                 :            :     /// This method never throws an exception.
     640                 :            :     ///
     641                 :            :     /// \return A reference to a \c Name class object corresponding to the
     642                 :            :     /// \c RRset owner name.
     643                 :            :     virtual const Name& getName() const;
     644                 :            : 
     645                 :            :     /// \brief Returns the RR Class of the \c RRset.
     646                 :            :     ///
     647                 :            :     /// This method never throws an exception.
     648                 :            :     ///
     649                 :            :     /// \return A reference to a \c RRClass class object corresponding to the
     650                 :            :     /// RR class of the \c RRset.
     651                 :            :     virtual const RRClass& getClass() const;
     652                 :            : 
     653                 :            :     /// \brief Returns the RR Type of the \c RRset.
     654                 :            :     ///
     655                 :            :     /// This method never throws an exception.
     656                 :            :     ///
     657                 :            :     /// \return A reference to a \c RRType class object corresponding to the
     658                 :            :     /// RR type of the \c RRset.
     659                 :            :     virtual const RRType& getType() const;
     660                 :            : 
     661                 :            :     /// \brief Returns the TTL of the \c RRset.
     662                 :            :     ///
     663                 :            :     /// This method never throws an exception.
     664                 :            :     ///
     665                 :            :     /// \return A reference to a \c RRTTL class object corresponding to the
     666                 :            :     /// TTL of the \c RRset.
     667                 :            :     virtual const RRTTL& getTTL() const;
     668                 :            : 
     669                 :            :     /// \brief Updates the owner name of the \c RRset.
     670                 :            :     ///
     671                 :            :     /// This method normally does not throw an exception, but could throw
     672                 :            :     /// some standard exception on resource allocation failure if the
     673                 :            :     /// internal copy of the \c name involves resource allocation and it
     674                 :            :     /// fails.
     675                 :            :     ///
     676                 :            :     /// \param name A reference to a \c Name class object to be copied as the
     677                 :            :     /// new name.
     678                 :            :     virtual void setName(const Name& name);
     679                 :            : 
     680                 :            :     /// \brief Updates the TTL of the \c RRset.
     681                 :            :     ///
     682                 :            :     /// This method never throws an exception.
     683                 :            :     ///
     684                 :            :     /// \param ttl A reference to a \c RRTTL class object to be copied as the
     685                 :            :     /// new TTL.
     686                 :            :     virtual void setTTL(const RRTTL& ttl);
     687                 :            :     //@}
     688                 :            : 
     689                 :            :     ///
     690                 :            :     /// \name Converter Methods
     691                 :            :     ///
     692                 :            :     //@{
     693                 :            :     /// \brief Convert the RRset to a string.
     694                 :            :     ///
     695                 :            :     /// This method simply uses the default implementation.
     696                 :            :     /// See \c AbstractRRset::toText().
     697                 :            :     virtual std::string toText() const;
     698                 :            : 
     699                 :            :     /// \brief Render the RRset in the wire format with name compression and
     700                 :            :     /// truncation handling.
     701                 :            :     ///
     702                 :            :     /// This method simply uses the default implementation.
     703                 :            :     /// See \c AbstractRRset::toWire(MessageRenderer&)const.
     704                 :            :     virtual unsigned int toWire(AbstractMessageRenderer& renderer) const;
     705                 :            : 
     706                 :            :     /// \brief Render the RRset in the wire format without any compression.
     707                 :            :     ///
     708                 :            :     /// This method simply uses the default implementation.
     709                 :            :     /// See \c AbstractRRset::toWire(OutputBuffer&)const.
     710                 :            :     virtual unsigned int toWire(isc::util::OutputBuffer& buffer) const;
     711                 :            :     //@}
     712                 :            : 
     713                 :            :     ///
     714                 :            :     /// \name RDATA manipulation methods
     715                 :            :     ///
     716                 :            :     //@{
     717                 :            :     /// \brief Add an RDATA to the RRset (pointer version).
     718                 :            :     ///
     719                 :            :     /// This method is normally expected to be exception free, but it may
     720                 :            :     /// involve resource allocation, and if it fails the corresponding
     721                 :            :     /// standard exception will be thrown.
     722                 :            :     ///
     723                 :            :     /// \param rdata A pointer (like) type of \c rdata::RdataPtr to be added
     724                 :            :     /// to the \c BasicRRset.
     725                 :            :     virtual void addRdata(rdata::ConstRdataPtr rdata);
     726                 :            : 
     727                 :            :     /// \brief Add an RDATA to the RRset (reference version).
     728                 :            :     ///
     729                 :            :     /// This method simply uses the default implementation.
     730                 :            :     /// See \c AbstractRRset::addRdata(const rdata::Rdata&).
     731                 :            :     virtual void addRdata(const rdata::Rdata& rdata);
     732                 :            : 
     733                 :            :     /// \brief Return an iterator to go through all RDATA stored in the
     734                 :            :     /// \c BasicRRset.
     735                 :            :     ///
     736                 :            :     /// This is a concrete derived implementation of
     737                 :            :     /// \c AbstractRRset::getRdataIterator().
     738                 :            :     ///
     739                 :            :     /// This method dynamically allocates resources.  If it fails it will
     740                 :            :     /// throw the corresponding standard exception.
     741                 :            :     /// The iterator methods for the \c BasicRRset class are exception free.
     742                 :            :     ///
     743                 :            :     /// \return A pointer-like object pointing to the derived \c RdataIterator
     744                 :            :     /// object for the \c BasicRRset class.
     745                 :            :     virtual RdataIteratorPtr getRdataIterator() const;
     746                 :            :     //@}
     747                 :            : 
     748                 :            :     ///
     749                 :            :     /// \name Associated RRSIG methods
     750                 :            :     ///
     751                 :            :     /// The associated RRSIG RRset is not supported in BasicRRset.  For
     752                 :            :     /// ease of use, getRRsig() returns a null pointer (indicating no RRset).
     753                 :            :     /// The addRRsig()/removeRRsig() methods throw a "NotImplemented"
     754                 :            :     /// exception - if you are using a BasicRRset, you should not be trying
     755                 :            :     /// to modify signatures on it.
     756                 :            :     //@{
     757                 :            :     /// \brief Return pointer to this RRset's RRSIG RRset
     758                 :            :     ///
     759                 :            :     /// \exception NotImplemented Always thrown.  Associated RRSIG RRsets are
     760                 :            :     ///            not supported in this class.
     761                 :            :     ///
     762                 :            :     /// \return Null pointer, as this class does not support RRSIG records.
     763                 :          0 :     virtual RRsetPtr getRRsig() const {
     764                 :          0 :         return (RRsetPtr());
     765                 :            :     }
     766                 :            : 
     767                 :          0 :     virtual void addRRsig(const rdata::ConstRdataPtr&) {
     768 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     769                 :            :                   "BasicRRset does not implement the addRRsig() method");
     770                 :            :     }
     771                 :            : 
     772                 :          0 :     virtual void addRRsig(const rdata::RdataPtr&) {
     773 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     774                 :            :                   "BasicRRset does not implement the addRRsig() method");
     775                 :            :     }
     776                 :            : 
     777                 :          0 :     virtual void addRRsig(const AbstractRRset&) {
     778 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     779                 :            :                   "BasicRRset does not implement the addRRsig() method");
     780                 :            :     }
     781                 :            : 
     782                 :          0 :     virtual void addRRsig(const ConstRRsetPtr&) {
     783 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     784                 :            :                   "BasicRRset does not implement the addRRsig() method");
     785                 :            :     }
     786                 :            : 
     787                 :          0 :     virtual void addRRsig(const RRsetPtr&) {
     788 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     789                 :            :                   "BasicRRset does not implement the addRRsig() method");
     790                 :            :     }
     791                 :            : 
     792                 :          0 :     virtual void removeRRsig() {
     793 [ #  # ][ #  # ]:          0 :         isc_throw(NotImplemented,
     794                 :            :                   "BasicRRset does not implement the removeRRsig() method");
     795                 :            :     }
     796                 :            :     //@}
     797                 :            : private:
     798                 :            :     BasicRRsetImpl* impl_;
     799                 :            : };
     800                 :            : 
     801                 :            : /// \brief The \c RRset class is a concrete derived class of
     802                 :            : /// \c BasicRRset which contains a pointer to an additional RRset
     803                 :            : /// containing associated RRSIG records.  This allows DNSSEC aware
     804                 :            : /// applications to treat data associated with a particular
     805                 :            : /// QNAME/QTYPE/QCLASS as a single object.
     806                 :            : class RRset : public BasicRRset {
     807                 :            : public:
     808                 :            :     RRset(const Name& name, const RRClass& rrclass,
     809                 :            :           const RRType& rrtype, const RRTTL& ttl);
     810                 :            : 
     811                 :            :     virtual ~RRset();
     812                 :            : 
     813                 :            :     /// \brief Updates the owner name of the \c RRset, including RRSIGs if any
     814                 :         17 :     virtual void setName(const Name& n) {
     815                 :         18 :         BasicRRset::setName(n);
     816 [ +  + ][ #  # ]:         18 :         if (rrsig_) {
     817                 :          5 :             rrsig_->setName(n);
     818                 :            :         }
     819                 :         17 :     }
     820                 :            : 
     821                 :            :     /// \brief Updates the owner name of the \c RRset, including RRSIGs if any
     822                 :        374 :     virtual void setTTL(const RRTTL& ttl) {
     823                 :        374 :         BasicRRset::setTTL(ttl);
     824         [ -  + ]:        374 :         if (rrsig_) {
     825                 :          0 :             rrsig_->setTTL(ttl);
     826                 :            :         }
     827                 :        374 :     }
     828                 :            : 
     829                 :            :     /// \brief Adds an RRSIG RR to this RRset's signatures
     830                 :       4572 :     virtual void addRRsig(const rdata::ConstRdataPtr& rdata) {
     831         [ +  + ]:       4572 :         if (!rrsig_) {
     832                 :       9136 :             rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
     833   [ +  -  #  # ]:       4568 :                                         RRType::RRSIG(), getTTL()));
                 [ +  - ]
     834                 :            :         }
     835         [ +  - ]:       9144 :         rrsig_->addRdata(rdata);
     836                 :       4572 :     }
     837                 :            : 
     838                 :            :     // Workaround for older versions of boost: some don't support implicit
     839                 :            :     // conversion from shared_ptr<X> to shared_ptr<const X>.  Note: we should
     840                 :            :     // revisit the interface of managing RRset signatures, at which point this
     841                 :            :     // problem may go away.
     842                 :       4571 :     virtual void addRRsig(const rdata::RdataPtr& rdata) {
     843                 :            :         // Don't try to convert as a reference here.  SunStudio will reject it.
     844         [ +  - ]:       4571 :         addRRsig(static_cast<const rdata::ConstRdataPtr>(rdata));
     845                 :       4571 :     }
     846                 :            : 
     847                 :            :     /// \brief Adds an RRSIG RRset to this RRset
     848                 :        776 :     virtual void addRRsig(const AbstractRRset& sigs) {
     849                 :        776 :         RdataIteratorPtr it = sigs.getRdataIterator();
     850                 :            : 
     851         [ +  + ]:        776 :         if (!rrsig_) {
     852                 :       1550 :             rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
     853 [ +  - ][ +  - ]:        775 :                                         RRType::RRSIG(), getTTL()));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     854                 :            :         }
     855                 :            : 
     856 [ +  - ][ +  - ]:       1555 :         for (it->first(); !it->isLast(); it->next()) {
         [ +  - ][ +  + ]
     857 [ +  - ][ +  - ]:        779 :             rrsig_->addRdata(it->getCurrent());
     858                 :            :         }
     859                 :        776 :     }
     860                 :            : 
     861                 :        469 :     virtual void addRRsig(const ConstRRsetPtr& sigs) { addRRsig(*sigs); }
     862                 :            : 
     863                 :            :     // Another workaround for older boost (see above)
     864                 :        301 :     virtual void addRRsig(const RRsetPtr& sigs) { addRRsig(*sigs); }
     865                 :            : 
     866                 :            :     /// \brief Clear the RRSIGs for this RRset
     867         [ +  - ]:          6 :     virtual void removeRRsig() { rrsig_ = RRsetPtr(); }
     868                 :            : 
     869                 :            :     /// \brief Return a pointer to this RRset's RRSIG RRset
     870                 :       5800 :     RRsetPtr getRRsig() const { return (rrsig_); }
     871                 :            : private:
     872                 :            :     RRsetPtr rrsig_;
     873                 :            : };
     874                 :            : 
     875                 :            : 
     876                 :            : /// \brief Insert the \c RRset as a string into stream.
     877                 :            : ///
     878                 :            : /// This method convert the \c rrset into a string and inserts it into the
     879                 :            : /// output stream \c os.
     880                 :            : ///
     881                 :            : /// This function overloads the global \c operator<< to behave as described in
     882                 :            : /// \c %ostream::%operator<< but applied to RRset objects.
     883                 :            : ///
     884                 :            : /// \param os A \c std::ostream object on which the insertion operation is
     885                 :            : /// performed.
     886                 :            : /// \param rrset A reference to a (derived class of) \c AbstractRRset object
     887                 :            : /// output by the operation.
     888                 :            : /// \return A reference to the same \c std::ostream object referenced by
     889                 :            : /// parameter \c os after the insertion operation.
     890                 :            : std::ostream& operator<<(std::ostream& os, const AbstractRRset& rrset);
     891                 :            : } // end of namespace dns
     892                 :            : } // end of namespace isc
     893                 :            : #endif  // __RRSET_H
     894                 :            : 
     895                 :            : // Local Variables: 
     896                 :            : // mode: c++
     897                 :            : // End: 

Generated by: LCOV version 1.9