Kea  2.3.5-git
isc::dns::AbstractRRset Class Referenceabstract

The AbstractRRset class is an abstract base class that models a DNS RRset. More...

#include <rrset.h>

+ Inheritance diagram for isc::dns::AbstractRRset:

Public Member Functions

Getter and Setter Methods

These methods are generally expected to be exception free, but it's not guaranteed at the interface level; for example, some performance optimized derived class may manage the information corresponding to the class "attributes" to get or set, and may require dynamic memory allocation to execute the method.

Consult the derived class description to see if a specific derived RRset class may throw an exception from these methods.

Note that setter methods are not provided for RRClass and RRType. This is intentional. Since the format and semantics of Rdata are dependent on the RR type (and RR class for some RR types), allowing dynamically modify these attributes can easily lead to a bug where the RDATA and type and/or class become inconsistent. We want to avoid that situation by restricting the access.

virtual unsigned int getRdataCount () const =0
 Returns the number of Rdata objects contained in the RRset. More...
 
virtual uint16_t getLength () const =0
 Get the wire format length of the AbstractRRset. More...
 
virtual const NamegetName () const =0
 Returns the owner name of the RRset. More...
 
virtual const RRClassgetClass () const =0
 Returns the RR Class of the RRset. More...
 
virtual const RRTypegetType () const =0
 Returns the RR Type of the RRset. More...
 
virtual const RRTTLgetTTL () const =0
 Returns the TTL of the RRset. More...
 
virtual void setTTL (const RRTTL &ttl)=0
 Updates the TTL of the RRset. More...
 
Converter Methods

These methods have the default implementation that can be reused by derived classes.

Since they are defined as pure virtual, derived classes that want to reuse the default implementation must explicitly invoke their base class version (see the description for addRdata(const rdata::Rdata&)).

Design Note: the default implementations are defined only using other public methods of the AbstractRRset class, and could be implemented as non member functions (as some C++ textbooks suggest). However, since derived classes may want to provide customized versions (especially of the toWire() method for performance reasons) we chose to define them as virtual functions, and, as a result, member functions.

virtual std::string toText () const =0
 Convert the RRset to a string. More...
 
virtual unsigned int toWire (AbstractMessageRenderer &renderer) const =0
 Render the RRset in the wire format with name compression and truncation handling. More...
 
virtual unsigned int toWire (isc::util::OutputBuffer &buffer) const =0
 Render the RRset in the wire format without any compression. More...
 
RDATA Manipulation Methods
virtual void addRdata (rdata::ConstRdataPtr rdata)=0
 Add an RDATA to the RRset (pointer version). More...
 
virtual void addRdata (const rdata::Rdata &rdata)=0
 Add an RDATA to the RRset (reference version). More...
 
virtual void addRdata (const std::string &rdata_str)=0
 Add an RDATA to the RRset (string version). More...
 
virtual RdataIteratorPtr getRdataIterator () const =0
 Return an iterator to go through all RDATA stored in the RRset. More...
 
Associated RRSIG methods

These methods access an "associated" RRset, that containing the DNSSEC signatures for this RRset.

It can be argued that this is not a fundamental part of the RRset abstraction, since RFC 2181 defined an RRset as a group of records with the same label, class and type but different data. However, BIND 10 had to deal with DNSSEC and in practice, including the information at the AbstractRRset level makes implementation easier. (If a class is ever needed that must be ignorant of the idea of an associated RRSIG RRset - e.g. a specialised RRSIG RRset class - these methods can just throw a "NotImplemented" exception.) DNSSEC is unlikely to be ever needed in Kea, but it does not make sense to redesign the abstract RRSet class now.

virtual RRsetPtr getRRsig () const =0
 Return pointer to this RRset's RRSIG RRset. More...
 
virtual unsigned int getRRsigDataCount () const =0
 Returns the number of RRSIG records associated with the RRset. More...
 
virtual void addRRsig (const rdata::ConstRdataPtr &rdata)=0
 Adds RRSIG RRset RRs to the associated RRSIG RRset. More...
 
virtual void addRRsig (const rdata::RdataPtr &rdata)=0
 Adds RRSIG RRset RRs to the associated RRSIG RRset. More...
 
virtual void addRRsig (const AbstractRRset &sigs)=0
 Adds RRSIG RRset RRs to the associated RRSIG RRset. More...
 
virtual void addRRsig (const ConstRRsetPtr &sigs)=0
 Adds RRSIG RRset RRs to the associated RRSIG RRset. More...
 
virtual void addRRsig (const RRsetPtr &sigs)=0
 Adds RRSIG RRset RRs to the associated RRSIG RRset. More...
 
virtual void removeRRsig ()=0
 Clear the RRSIGs for this RRset. More...
 
virtual bool isSameKind (const AbstractRRset &other) const
 Check whether two RRsets are of the same kind. More...
 

Constructors and Destructor

Note: The copy constructor and the assignment operator are intentionally defined as private to make it explicit that this is a pure base class.

 AbstractRRset ()
 The default constructor. More...
 
virtual ~AbstractRRset ()
 The destructor. More...
 

Detailed Description

The AbstractRRset class is an abstract base class that models a DNS RRset.

An object of (a specific derived class of) AbstractRRset models an RRset as described in the DNS standard: A set of DNS resource records (RRs) of the same type and class. The standard requires the TTL of all RRs in an RRset be the same; this class follows that requirement. Note about duplicate RDATA: RFC2181 states that it's meaningless that an RRset contains two identical RRs and that name servers should suppress such duplicates. This class is not responsible for ensuring this requirement: For example, addRdata() method doesn't check if there's already RDATA identical to the one being added. This is because such checks can be expensive, and it's often easy to ensure the uniqueness requirement at the data preparation phase (e.g. when loading a zone). When parsing an incoming DNS message, the uniqueness may not be guaranteed, so the application needs to detect and ignore any duplicate RDATA (the Message class of this library should provide this responsibility).

Another point to note is that AbstractRRset and its derived classes allow an object to have an empty set of RDATA. Even though there's no corresponding notion in the protocol specification, it would be more intuitive for a container-like data structure to allow an empty set.

Since AbstractRRset is an abstract class, it is generally used via a pointer (or pointer like object) or a reference. In particular, RRsetPtr, a pointer like type for AbstractRRset, is used for polymorphic RRset operations throughout this library.

The AbstractRRset class is also intended to be a major customization point. For example, a high performance server implementation may want to define an optimized "pre-compiled" RRset and provide an optimized implementation of the toWire() method.

Note about design choice: In BIND9, a set of RDATA with a common tuple of RR class, RR type, and TTL was represented in a structure named rdataset. Unlike the RRset classes, an rdataset did not contain the information of the owner name. This might be advantageous if we want to handle "RRsets", that is, a set of different types of RRset for the same owner name, because a single "name" structure can be used for multiple RRsets, minimizing data copy and memory footprint. On the other hand, it's inconvenient for API users since in many cases a pair of name and an rdataset must be maintained. It's also counter intuitive in implementing protocol operations as an RRset is often used as an atomic entity in DNS protocols while an rdataset is a component of an RRset.

We have therefore defined the notion of RRset explicitly in our initial API design. We believe memory footprint is not a big concern because RRsets are generally expected to be used as temporary objects, e.g. while parsing or constructing a DNS message, or searching a DNS data source; for longer term purposes such as in-memory data source entries, the corresponding data would be represented in a different, memory optimized format. As for the concern about data copy, we believe it can be mitigated by using copy-efficient implementation for the Name class implementation, such as reference counted objects. Later, We plan to perform benchmark tests later to see if this assumption is valid and to revisit the design if necessary.

Note about terminology: there has been a discussion at the IETF namedroppers ML about RRset vs RRSet (case of "s") [http://ops.ietf.org/lists/namedroppers/namedroppers.2009/msg02737.html]. While RFC2181 uses the latter, many other RFCs use the former, and most of the list members who showed their opinion seem to prefer "RRset". We follow that preference in this implementation.

The current design of AbstractRRset is still in flux. There are many open questions in design details:

  • support more set-like operations, e.g, merge two RRsets of the same type?
  • more convenient methods or non member utility functions, e.g. "sort" and "search(find)" method?
  • what about comparing two RRsets of the same type? If we need this, should it compare rdata's as a set or as a list (i.e. compare each rdata one by one or as a whole)? c.f. NLnet Labs' ldns (http://www.nlnetlabs.nl/projects/ldns/doc/index.html) has ldns_rr_list_compare(), which takes the latter approach (seemingly assuming the caller sorts the lists beforehand).
  • BIND9 libdns has some special DNSSEC-related methods such as addnoqname() or addclosest(). Do we need these? (Probably not. We wouldn't want to make the class design too monolithic.)
  • Do we need to allow the user to remove specific Rdata? Probably not, according to the current usage of the BIND9 code.

Definition at line 154 of file rrset.h.

Constructor & Destructor Documentation

◆ AbstractRRset()

isc::dns::AbstractRRset::AbstractRRset ( )
inlineprotected

The default constructor.

This is intentionally defined as protected as this base class should never be instantiated (except as part of a derived class).

Definition at line 169 of file rrset.h.

◆ ~AbstractRRset()

virtual isc::dns::AbstractRRset::~AbstractRRset ( )
inlinevirtual

The destructor.

Definition at line 172 of file rrset.h.

Member Function Documentation

◆ addRdata() [1/3]

virtual void isc::dns::AbstractRRset::addRdata ( rdata::ConstRdataPtr  rdata)
pure virtual

Add an RDATA to the RRset (pointer version).

This method adds the given RDATA (as a pointer-like type to a derived class object of rdata::Rdata) to the RRset.

Parameters
rdataA pointer (like) type of rdata::RdataPtr to be added to the RRset.

Implemented in isc::dns::BasicRRset.

◆ addRdata() [2/3]

void isc::dns::AbstractRRset::addRdata ( const rdata::Rdata rdata)
pure virtual

Add an RDATA to the RRset (reference version).

This method adds the given RDATA (as a reference to a derived class object of rdata::Rdata) to the RRset.

This method has the default implementation that can be reused by derived classes. Since this method is defined as pure virtual, derived classes that want to reuse the default implementation must explicitly invoke this base class version. For example, if the class CustomizedRRset, a derived class of AbstractRRset, wants to reuse the default implementation of addRdata() (reference version), it would be defined as follows:

void
CustomizedRRset::addRdata(const rdata::Rdata& rdata)
{
}

This method is more strictly typed than the pointer version: If rdata does not refer to the appropriate derived Rdata class for the RRType for this RRset, it throws an exception of class std::bad_cast. If resource allocation fails, a corresponding standard exception will be thrown. The RRset must contain some RDATA; otherwise, an exception of class EmptyRRset will be thrown. The default implementation may throw other exceptions if the toWire() method of the RDATA objects throws. If a derived class of AbstractRRset overrides the default implementation, the derived version may throw its own exceptions.

The default implementation simply constructs an rdata::RdataPtr object from a newly allocated RDATA object copying from parameter rdata, and calls the other version of addRdata(const rdata::RdataPtr). So it is inherently less efficient than the other version. Still, this version would offer a more intuitive interface and is provided as such.

NOTE: Because a new Rdata object is constructed, this method can throw a std::bad_cast exception if this RRset's class is NONE, or if some other error occurs. If you want to be able to add RDATA to an RRset whose class is NONE, please use the other variant of addRdata() which accepts a ConstRdataPtr argument.

Parameters
rdataA reference to a rdata::RdataPtr (derived) class object, a copy of which is to be added to the RRset.

Implemented in isc::dns::BasicRRset.

Definition at line 32 of file rrset.cc.

References isc::dns::rdata::createRdata().

+ Here is the call graph for this function:

◆ addRdata() [3/3]

virtual void isc::dns::AbstractRRset::addRdata ( const std::string &  rdata_str)
pure virtual

Add an RDATA to the RRset (string version).

This method constructs an Rdata object from the given rdata_str in presentation format and adds it to the RRset.

Parameters
rdata_strRDATA string in presentation format.
Exceptions
InvalidRdataTextif the rdata_str is invalid for this RRset.

Implemented in isc::dns::BasicRRset.

◆ addRRsig() [1/5]

virtual void isc::dns::AbstractRRset::addRRsig ( const rdata::ConstRdataPtr rdata)
pure virtual

Adds RRSIG RRset RRs to the associated RRSIG RRset.

Adds the (assumed) RRSIG rdata the RRSIG RRset associated with this RRset. If one does not exist, it is created using the data given.

Parameters
rdataPointer to RRSIG rdata to be added.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ addRRsig() [2/5]

virtual void isc::dns::AbstractRRset::addRRsig ( const rdata::RdataPtr rdata)
pure virtual

Adds RRSIG RRset RRs to the associated RRSIG RRset.

Adds the (assumed) RRSIG rdata the RRSIG RRset associated with this RRset. If one does not exist, it is created using the data given.

(This overload is for an older version of boost that doesn't support conversion from shared_ptr<X> to shared_ptr<const X>.)

Parameters
rdataPointer to RRSIG rdata to be added.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ addRRsig() [3/5]

virtual void isc::dns::AbstractRRset::addRRsig ( const AbstractRRset sigs)
pure virtual

Adds RRSIG RRset RRs to the associated RRSIG RRset.

Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG RRset associated with this RRset. If one does not exist, it is created using the data given.

Parameters
sigsRRSIG RRset containing signatures to be added to the RRSIG RRset associated with this class.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ addRRsig() [4/5]

virtual void isc::dns::AbstractRRset::addRRsig ( const ConstRRsetPtr sigs)
pure virtual

Adds RRSIG RRset RRs to the associated RRSIG RRset.

Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG RRset associated with this RRset. If one does not exist, it is created using the data given.

Parameters
sigsPointer to a RRSIG RRset containing signatures to be added to the RRSIG RRset associated with this class.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ addRRsig() [5/5]

virtual void isc::dns::AbstractRRset::addRRsig ( const RRsetPtr sigs)
pure virtual

Adds RRSIG RRset RRs to the associated RRSIG RRset.

Adds the signatures in the given (assumed) RRSIG RRset to the RRSIG RRset associated with this RRset. If one does not exist, it is created using the data given.

(This overload is for an older version of boost that doesn't support conversion from shared_ptr<X> to shared_ptr<const X>.)

Parameters
sigsPointer to a RRSIG RRset containing signatures to be added to the RRSIG RRset associated with this class.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ getClass()

virtual const RRClass& isc::dns::AbstractRRset::getClass ( ) const
pure virtual

Returns the RR Class of the RRset.

Returns
A reference to a RRClass class object corresponding to the RR class of the RRset.

Implemented in isc::dns::BasicRRset.

Referenced by isSameKind(), and toText().

◆ getLength()

virtual uint16_t isc::dns::AbstractRRset::getLength ( ) const
pure virtual

Get the wire format length of the AbstractRRset.

This method returns the wire format length of the AbstractRRset, which is calculated by summing the individual lengths of the various fields that make up each RR.

NOTE: When including name lengths, the allocation for uncompressed name wire format representation is used.

Returns
The length of the wire format representation of the AbstractRRset.
Exceptions
EmptyRRsetif the AbstractRRset is empty.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ getName()

virtual const Name& isc::dns::AbstractRRset::getName ( ) const
pure virtual

Returns the owner name of the RRset.

Returns
A reference to a Name class object corresponding to the RRset owner name.

Implemented in isc::dns::BasicRRset.

Referenced by isSameKind(), and toText().

◆ getRdataCount()

virtual unsigned int isc::dns::AbstractRRset::getRdataCount ( ) const
pure virtual

Returns the number of Rdata objects contained in the RRset.

Note that an RRset with an empty set of Rdata can exist, so this method may return 0.

Returns
The number of Rdata objects contained.

Implemented in isc::dns::BasicRRset.

◆ getRdataIterator()

virtual RdataIteratorPtr isc::dns::AbstractRRset::getRdataIterator ( ) const
pure virtual

Return an iterator to go through all RDATA stored in the RRset.

The rdata cursor of the returned iterator will point to the first RDATA, that is, it effectively calls RdataIterator::first() internally.

Using the design pattern terminology, getRdataIterator() is an example of a factory method.

Whether this method throws an exception depends on the actual implementation of the derived AbstractRRset class, but in general it will involve resource allocation and can throw a standard exception if it fails.

Returns
A pointer-like object pointing to the derived RdataIterator object.

Implemented in isc::dns::BasicRRset.

Referenced by isc::dns::RRset::addRRsig(), and toText().

◆ getRRsig()

virtual RRsetPtr isc::dns::AbstractRRset::getRRsig ( ) const
pure virtual

Return pointer to this RRset's RRSIG RRset.

Returns
Pointer to the associated RRSIG RRset or null if there is none.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ getRRsigDataCount()

virtual unsigned int isc::dns::AbstractRRset::getRRsigDataCount ( ) const
pure virtual

Returns the number of RRSIG records associated with the RRset.

Note that an RRset with no RRSIG records may exist, so this method may return 0.

Returns
The number of RRSIG records associated.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ getTTL()

virtual const RRTTL& isc::dns::AbstractRRset::getTTL ( ) const
pure virtual

Returns the TTL of the RRset.

Returns
A reference to a RRTTL class object corresponding to the TTL of the RRset.

Implemented in isc::dns::BasicRRset.

Referenced by toText().

◆ getType()

virtual const RRType& isc::dns::AbstractRRset::getType ( ) const
pure virtual

Returns the RR Type of the RRset.

Returns
A reference to a RRType class object corresponding to the RR type of the RRset.

Implemented in isc::dns::BasicRRset.

Referenced by isSameKind(), and toText().

◆ isSameKind()

bool isc::dns::AbstractRRset::isSameKind ( const AbstractRRset other) const
virtual

Check whether two RRsets are of the same kind.

Checks if two RRsets have the same name, RR type, and RR class.

Parameters
otherPointer to another AbstractRRset to compare against.

Definition at line 144 of file rrset.cc.

References getClass(), getName(), and getType().

+ Here is the call graph for this function:

◆ removeRRsig()

virtual void isc::dns::AbstractRRset::removeRRsig ( )
pure virtual

Clear the RRSIGs for this RRset.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ setTTL()

virtual void isc::dns::AbstractRRset::setTTL ( const RRTTL ttl)
pure virtual

Updates the TTL of the RRset.

Parameters
ttlA reference to a RRTTL class object to be copied as the new TTL.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

◆ toText()

string isc::dns::AbstractRRset::toText ( ) const
pure virtual

Convert the RRset to a string.

Unlike other similar methods of this library, this method terminates the resulting string with a trailing newline character. (following the BIND9 convention)

If any RRSIGs are associated with the RRset, they are also appended to the returned string.

If the class is not ANY or NONE, the RRset must contain some RDATA; otherwise, an exception of class EmptyRRset will be thrown. If resource allocation fails, a corresponding standard exception will be thrown. The default implementation may throw other exceptions if the toText() method of the RDATA objects throws. If a derived class of AbstractRRset overrides the default implementation, the derived version may throw its own exceptions.

Open issue: We may want to support multiple output formats as BIND9 does. For example, we might want to allow omitting the owner name when possible in the context of zone dump. This is a future TODO item.

Returns
A string representation of the RRset.

Implemented in isc::dns::BasicRRset.

Definition at line 37 of file rrset.cc.

References getClass(), getName(), getRdataIterator(), getTTL(), getType(), isc_throw, isc::log::NONE, isc::dns::RRTTL::toWire(), isc::dns::RRType::toWire(), isc::dns::RRClass::toWire(), and isc::dns::Name::toWire().

Referenced by isc::dns::operator<<().

+ Here is the call graph for this function:

◆ toWire() [1/2]

unsigned int isc::dns::AbstractRRset::toWire ( AbstractMessageRenderer renderer) const
pure virtual

Render the RRset in the wire format with name compression and truncation handling.

This method compresses the owner name of the RRset and domain names used in RDATA that should be compressed. In addition, this method detects the case where rendering the entire RRset would cause truncation, and handles the case appropriately (this is a TODO item, and not implemented in this version).

If any RRSIGs are associated with the RRset, they are also rendered.

Note: perhaps we may want to add more arguments to convey optional information such as an "rrset-order" policy or how to handle truncation case. This is a TODO item.

If resource allocation fails, a corresponding standard exception will be thrown. If the class is not ANY or NONE, the RRset must contain some RDATA; otherwise, an exception of class EmptyRRset will be thrown. The default implementation may throw other exceptions if the toWire() method of the RDATA objects throws. If a derived class of AbstractRRset overrides the default implementation, the derived version may throw its own exceptions.

Parameters
rendererDNS message rendering context that encapsulates the output buffer and name compression information.
Returns
The number of RRs rendered. If the truncation is necessary this value may be different from the number of RDATA objects contained in the RRset.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

Definition at line 134 of file rrset.cc.

References isc::dns::AbstractMessageRenderer::getLengthLimit().

+ Here is the call graph for this function:

◆ toWire() [2/2]

unsigned int isc::dns::AbstractRRset::toWire ( isc::util::OutputBuffer buffer) const
pure virtual

Render the RRset in the wire format without any compression.

See the other toWire() description about possible exceptions.

Parameters
bufferAn output buffer to store the wire data.
Returns
The number of RRs rendered.

Implemented in isc::dns::RRset, and isc::dns::BasicRRset.

Definition at line 129 of file rrset.cc.


The documentation for this class was generated from the following files: