summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/rrset_collection_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/rrset_collection_base.h')
-rw-r--r--src/lib/dns/rrset_collection_base.h214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/lib/dns/rrset_collection_base.h b/src/lib/dns/rrset_collection_base.h
new file mode 100644
index 0000000..a8ca255
--- /dev/null
+++ b/src/lib/dns/rrset_collection_base.h
@@ -0,0 +1,214 @@
+// Copyright (C) 2012-2022 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef RRSET_COLLECTION_BASE_H
+#define RRSET_COLLECTION_BASE_H 1
+
+#include <dns/rrset.h>
+#include <dns/name.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <iterator>
+
+namespace isc {
+namespace dns {
+
+/// \brief Error during RRsetCollectionBase find() operation
+///
+/// This exception is thrown when calling an implementation of
+/// \c RRsetCollectionBase::find() results in an error which is not due
+/// to unmatched data, but because of some other underlying error
+/// condition.
+class RRsetCollectionError : public Exception {
+public:
+ RRsetCollectionError(const char* file, size_t line, const char* what) :
+ Exception(file, line, what)
+ {}
+};
+
+/// \brief Generic class to represent a set of RRsets.
+///
+/// This is a generic container and the stored set of RRsets does not
+/// necessarily form a valid zone (e.g. there doesn't necessarily have
+/// to be an SOA at the "origin"). Instead, it will be used to represent
+/// a single zone for the purpose of zone loading/checking. It provides
+/// a simple find() method to find an RRset for the given name and type
+/// (and maybe class) and a way to iterate over all RRsets.
+///
+/// See \c RRsetCollection for a simple libdns++ implementation using an
+/// STL container. libdatasrc will have another implementation.
+class RRsetCollectionBase {
+public:
+ /// \brief Find a matching RRset in the collection.
+ ///
+ /// Returns the RRset in the collection that exactly matches the
+ /// given \c name, \c rrclass and \c rrtype. If no matching RRset
+ /// is found, \c NULL is returned.
+ ///
+ /// This method's implementations currently are not specified to
+ /// handle \c RRTypes such as RRSIG and NSEC3. This interface may be
+ /// refined to clarify this point in the future, and perhaps, provide
+ /// additional API for these RRType.
+ ///
+ /// As for RRSIG, there are some fundamental open questions. For
+ /// example, it's not clear whether we want to return all RRSIGs of
+ /// the given name covering any RR types (in which case, we need to
+ /// figure out how), or we need to extend the interface so we can
+ /// specify the covered type. A specific derived implementation may
+ /// return something if type RRSIG is specified, but this is not
+ /// specified here at the base class level. So, for RRSIGs the
+ /// behavior should be assumed as undefined.
+ ///
+ /// As for NSEC3, it's not clear whether owner names (which included
+ /// hashed labels) are the best choice of search key, because in many
+ /// cases, what the application wants to find is an NSEC3 that has the
+ /// hash of some particular "normal" domain names. Also, if the underlying
+ /// implementation encapsulates a single zone, NSEC3 records conceptually
+ /// belong to a separate name space, which may cause implementation
+ /// difficulty.
+ ///
+ /// Behavior with meta types such as ANY and AXFR are also
+ /// undefined. A specific implementation may return something for
+ /// these. But, unlike the case of RRSIGs, these types of RRsets
+ /// are not expected to be added to any implementation of
+ /// collection in the first place (by the definition of "meta
+ /// types"), so querying for such types is basically an invalid
+ /// operation. The API doesn't require implementations to check
+ /// this condition and reject it, so the behavior is
+ /// undefined. This interface will not be refined in future
+ /// versions for these meta types.
+ ///
+ /// \throw RRsetCollectionError if find() results in some
+ /// implementation-specific error.
+ /// \param name The name of the RRset to search for.
+ /// \param rrtype The type of the RRset to search for.
+ /// \param rrclass The class of the RRset to search for.
+ /// \return The RRset if found, \c NULL otherwise.
+ virtual isc::dns::ConstRRsetPtr find
+ (const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
+ const isc::dns::RRType& rrtype)
+ const = 0;
+
+ /// \brief Destructor
+ virtual ~RRsetCollectionBase() {}
+
+protected:
+ class Iter; // forward declaration
+
+ /// \brief Wraps Iter with a reference count.
+ typedef boost::shared_ptr<Iter> IterPtr;
+
+ /// \brief A helper iterator interface for \c RRsetCollectionBase.
+ ///
+ /// This is a protected iterator class that is a helper interface
+ /// used by the public iterator. Derived classes of
+ /// \c RRsetCollectionBase are supposed to implement this class and
+ /// the \c getBeginning() and \c getEnd() methods, so that the
+ /// public iterator interface can be provided. This is a forward
+ /// iterator only.
+ class Iter {
+ public:
+ virtual ~Iter() {};
+
+ /// \brief Returns the \c AbstractRRset currently pointed to by
+ /// the iterator.
+ virtual const isc::dns::AbstractRRset& getValue() = 0;
+
+ /// \brief Returns an \c IterPtr wrapping an Iter pointing to
+ /// the next \c AbstractRRset in sequence in the collection.
+ virtual IterPtr getNext() = 0;
+
+ /// \brief Check if another iterator is equal to this one.
+ ///
+ /// Returns \c true if this iterator is equal to \c other,
+ /// \c false otherwise. Note that if \c other is not the same
+ /// type as \c this, or cannot be compared meaningfully, the
+ /// method must return \c false.
+ ///
+ /// \param other The other iterator to compare against.
+ /// \return \c true if equal, \c false otherwise.
+ virtual bool equals(Iter& other) = 0;
+ };
+
+ /// \brief Returns an \c IterPtr wrapping an Iter pointing to the
+ /// beginning of the collection.
+ ///
+ /// \throw isc::dns::RRsetCollectionError if using the iterator
+ /// results in some underlying datasrc error.
+ virtual IterPtr getBeginning() = 0;
+
+ /// \brief Returns an \c IterPtr wrapping an Iter pointing past the
+ /// end of the collection.
+ ///
+ /// \throw isc::dns::RRsetCollectionError if using the iterator
+ /// results in some underlying datasrc error.
+ virtual IterPtr getEnd() = 0;
+
+public:
+ /// \brief A forward \c std::iterator for \c RRsetCollectionBase.
+ ///
+ /// It behaves like a \c std::iterator forward iterator, so please
+ /// see its documentation for usage.
+ class Iterator {
+ public:
+ // Aliases used to enable iterator behavior on this class
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = isc::dns::AbstractRRset const;
+ using difference_type = std::ptrdiff_t;
+ using pointer = isc::dns::AbstractRRset const*;
+ using reference = isc::dns::AbstractRRset const&;
+
+ explicit Iterator(IterPtr iter) :
+ iter_(iter)
+ {}
+
+ reference operator*() {
+ return (iter_->getValue());
+ }
+
+ Iterator& operator++() {
+ iter_ = iter_->getNext();
+ return (*this);
+ }
+
+ Iterator operator++(int) {
+ Iterator tmp(iter_);
+ ++*this;
+ return (tmp);
+ }
+
+ bool operator==(const Iterator& other) const {
+ return (iter_->equals(*other.iter_));
+ }
+
+ bool operator!=(const Iterator& other) const {
+ return (!iter_->equals(*other.iter_));
+ }
+
+ private:
+ IterPtr iter_;
+ };
+
+ /// \brief Returns an iterator pointing to the beginning of the
+ /// collection.
+ Iterator begin() {
+ return Iterator(getBeginning());
+ }
+
+ /// \brief Returns an iterator pointing past the end of the
+ /// collection.
+ Iterator end() {
+ return Iterator(getEnd());
+ }
+};
+
+typedef boost::shared_ptr<RRsetCollectionBase> RRsetCollectionPtr;
+
+} // end of namespace dns
+} // end of namespace isc
+
+#endif // RRSET_COLLECTION_BASE_H