123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- // $Id$
- #ifndef __RRPARAMREGISTRY_H
- #define __RRPARAMREGISTRY_H 1
- #include <string>
- #include <stdint.h>
- #include <boost/shared_ptr.hpp>
- #include <exceptions/exceptions.h>
- #include <dns/rdata.h>
- namespace isc {
- namespace dns {
- // forward declarations
- struct RRParamRegistryImpl;
- ///
- /// \brief A standard DNS module exception that is thrown if a new RR type is
- /// being registered with a different type string.
- ///
- class RRTypeExists : public Exception {
- public:
- RRTypeExists(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) {}
- };
- ///
- /// \brief A standard DNS module exception that is thrown if a new RR class is
- /// being registered with a different type string.
- ///
- class RRClassExists : public Exception {
- public:
- RRClassExists(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) {}
- };
- namespace rdata {
- /// \brief The \c AbstractRdataFactory class is an abstract base class to
- /// encapsulate a set of Rdata factory methods in a polymorphic way.
- ///
- /// An external developers who want to introduce a new or experimental RR type
- /// are expected to define a corresponding derived class of \c
- /// AbstractRdataFactory and register it via \c RRParamRegistry.
- ///
- /// For other users of this API normally do not have to care about this class
- /// or its derived classes; this class is generally intended to be used
- /// as an internal utility of the API implementation.
- class AbstractRdataFactory {
- ///
- /// \name Constructors and Destructor
- ///
- //@{
- protected:
- /// The default constructor
- ///
- /// This is intentionally defined as \c protected as this base class should
- /// never be instantiated (except as part of a derived class).
- AbstractRdataFactory() {}
- public:
- /// The destructor.
- virtual ~AbstractRdataFactory() {};
- //@}
- ///
- /// \name Factory methods for polymorphic creation.
- ///
- //@{
- ///
- /// \brief Create RDATA from a string.
- ///
- /// This method creates from a string an \c Rdata object of specific class
- /// corresponding to the specific derived class of \c AbstractRdataFactory.
- ///
- /// \param rdata_str A string of textual representation of the \c Rdata.
- /// \return An \c RdataPtr object pointing to the created \c Rdata object.
- virtual RdataPtr create(const std::string& rdata_str) const = 0;
- ///
- /// \brief Create RDATA from wire-format data.
- ///
- /// This method creates from wire-format binary data an \c Rdata object
- /// of specific class corresponding to the specific derived class of
- /// \c AbstractRdataFactory.
- ///
- /// \param buffer A reference to an \c InputBuffer object storing the
- /// \c Rdata to parse.
- /// \param rdata_len The length in buffer of the \c Rdata. In bytes.
- /// \return An \c RdataPtr object pointing to the created \c Rdata object.
- virtual RdataPtr create(InputBuffer& buffer, size_t rdata_len) const = 0;
- ///
- /// \brief Create RDATA from another \c Rdata object of the same type.
- ///
- /// This method creates an \c Rdata object of specific class corresponding
- /// to the specific derived class of \c AbstractRdataFactory, copying the
- /// content of the given \c Rdata, \c source.
- ///
- /// \c source must be an object of the concrete derived class corresponding
- /// to the specific derived class of \c AbstractRdataFactory;
- /// otherwise, an exception of class \c std::bad_cast will be thrown.
- ///
- /// \param source A reference to an \c Rdata object whose content is to
- /// be copied to the created \c Rdata object.
- /// \return An \c RdataPtr object pointing to the created \c Rdata object.
- virtual RdataPtr create(const rdata::Rdata& source) const = 0;
- //@}
- };
- ///
- /// The \c RdataFactoryPtr type is a pointer-like type, pointing to an
- /// object of some concrete derived class of \c AbstractRdataFactory.
- ///
- typedef boost::shared_ptr<AbstractRdataFactory> RdataFactoryPtr;
- } // end of namespace rdata
- ///
- /// The \c RRParamRegistry class represents a registry of parameters to
- /// manipulate DNS resource records (RRs).
- ///
- /// A \c RRParamRegistry class object stores a mapping between RR types or
- /// classes and their textual representations. It will also have knowledge of
- /// how to create an RDATA object for a specific pair of RR type and class
- /// (not implemented in this version).
- ///
- /// Normal applications that only handle standard DNS protocols won't have to
- /// care about this class. This is mostly an internal class to the DNS library
- /// to manage standard parameters. Some advanced applications may still need
- /// to use this class explicitly. For example, if an application wants to
- /// define and use an experimental non-standard RR type, it may want to register
- /// related protocol parameters for its convenience. This class is designed to
- /// allow such usage without modifying the library source code or rebuilding
- /// the library.
- ///
- /// It is assumed that at most one instance of this class can exist so that
- /// the application uses the consistent set of registered parameters. To ensure
- /// this, this class is designed and implemented as a "singleton class": the
- /// constructor is intentionally private, and applications must get access to
- /// the single instance via the \c getRegistry() static member function.
- ///
- /// In the current implementation, access to the singleton \c RRParamRegistry
- /// object is not thread safe.
- /// The application should ensure that multiple threads don't race in the
- /// first invocation of \c getRegistry(), and, if the registry needs to
- /// be changed dynamically, read and write operations are performed
- /// exclusively.
- /// Since this class should be static in common usage this restriction would
- /// be acceptable in practice.
- /// In the future, we may extend the implementation so that multiple threads can
- /// get access to the registry fully concurrently without any restriction.
- ///
- /// Note: the implementation of this class is incomplete: we should at least
- /// add RDATA related parameters. This will be done in a near future version,
- /// at which point some of method signatures will be changed.
- class RRParamRegistry {
- ///
- /// \name Constructors and Destructor
- ///
- /// These are intentionally hidden (see the class description).
- //@{
- private:
- RRParamRegistry();
- RRParamRegistry(const RRParamRegistry& orig);
- ~RRParamRegistry();
- //@}
- public:
- ///
- /// \brief Return the singleton instance of \c RRParamRegistry.
- ///
- /// This method is a unified access point to the singleton instance of
- /// the RR parameter registry (\c RRParamRegistry).
- /// On first invocation it internally constructs an instance of the
- /// \c RRParamRegistry class and returns a reference to it.
- /// This is a static object inside this method and will remain valid
- /// throughout the rest of the application lifetime.
- /// On subsequent calls this method simply returns a reference to the
- /// singleton object.
- ///
- /// If resource allocation fails in the first invocation,
- /// a corresponding standard exception will be thrown.
- /// This method never fails otherwise. In particular, this method
- /// doesn't throw an exception once the singleton instance is constructed.
- ///
- /// \return A reference to the singleton instance of \c RRParamRegistry.
- static RRParamRegistry& getRegistry();
- ///
- /// \name Registry Update Methods
- ///
- //@{
- ///
- /// \brief Add a set of parameters for a pair of RR type and class.
- ///
- /// This method adds to the registry a specified set of RR parameters,
- /// including mappings between type/class codes and their textual
- /// representations.
- ///
- /// Regarding the mappings between textual representations and integer
- /// codes, this method behaves in the same way as \c addType() and
- /// \c addClass(). That is, it ignores any overriding attempt as
- /// long as the mapping is the same; otherwise the corresponding exception
- /// will be thrown.
- ///
- /// This method provides the strong exception guarantee: unless an
- /// exception is thrown the entire specified set of parameters must be
- /// stored in the registry; if this method throws an exception the
- /// registry will remain in the state before this method is called.
- ///
- /// \param type_string The textual representation of the RR type.
- /// \param type_code The integer code of the RR type.
- /// \param class_string The textual representation of the RR class.
- /// \param class_code The integer code of the RR class.
- /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
- /// concrete RDATA factory.
- void add(const std::string& type_string, uint16_t type_code,
- const std::string& class_string, uint16_t class_code,
- rdata::RdataFactoryPtr rdata_factory);
- /// \brief Add a set of parameters for a class-independent RR type.
- ///
- /// This method behaves as exactly same as the other \c add method except
- /// that it handles class-independent types (such as NS, CNAME, or SOA).
- ///
- /// \param type_string The textual representation of the RR type.
- /// \param type_code The integer code of the RR type.
- /// \param rdata_factory An \c RdataFactoryPtr object pointing to a
- /// concrete RDATA factory.
- void add(const std::string& type_string, uint16_t type_code,
- rdata::RdataFactoryPtr rdata_factory);
- /// \brief Add mappings between RR type code and textual representation.
- ///
- /// This method adds a mapping from the type code of an RR to its textual
- /// representation and the reverse mapping in the registry.
- ///
- /// If the given RR type is already registered with the same textual
- /// representation, this method simply ignores the duplicate mapping;
- /// if the given type is registered and a new pair with a different
- /// textual representation is being added,an exception of class
- /// \c RRTypeExist will be thrown.
- /// To replace an existing mapping with a different textual representation,
- /// the existing one must be removed by the \c removeType() method
- /// beforehand.
- ///
- /// In addition, if resource allocation for the new mapping entries fails,
- /// a corresponding standard exception will be thrown.
- ///
- /// This method provides the strong exception guarantee: unless an exception
- /// is thrown the specified mappings must be stored in the registry
- /// (although it may be an already existing one) on completion of the
- /// method; if this method throws an exception the registry will remain
- /// in the state before this method is called.
- ///
- /// \param type_string The textual representation of the RR type.
- /// \param type_code The integer code of the RR type.
- /// \return \c true if a new mapping is added to the repository; \c false
- /// if the same mapping is already registered.
- bool addType(const std::string& type_string, uint16_t type_code);
- /// \brief Remove mappings between RR type code and textual representation
- /// for a given type.
- ///
- /// This method can safely be called whether or not the specified mappings
- /// exist in the registry. If not, this method simply ignores the attempt
- /// and returns \c false.
- ///
- /// This method never throws an exception.
- ///
- /// \param type_code The integer code of the RR type.
- /// \return \c true if mappings for the specified RR type exists and is
- /// removed; \c false if no such mapping is in the registry.
- bool removeType(uint16_t type_code);
- /// \brief Add mappings between RR class code and textual representation.
- ///
- /// This method adds a mapping from the class code of an RR to its textual
- /// representation and the reverse mapping in the registry.
- ///
- /// If the given RR class is already registered with the same textual
- /// representation, this method simply ignores the duplicate mapping;
- /// if the given class is registered and a new pair with a different
- /// textual representation is being added,an exception of class
- /// \c RRClassExist will be thrown.
- /// To replace an existing mapping with a different textual representation,
- /// the existing one must be removed by the \c removeClass() method
- /// beforehand.
- ///
- /// In addition, if resource allocation for the new mapping entries fails,
- /// a corresponding standard exception will be thrown.
- ///
- /// This method provides the strong exception guarantee: unless an exception
- /// is thrown the specified mappings must be stored in the registry
- /// (although it may be an already existing one) on completion of the
- /// method; if this method throws an exception the registry will remain
- /// in the state before this method is called.
- ///
- /// \param class_string The textual representation of the RR class.
- /// \param class_code The integer code of the RR class.
- /// \return \c true if a new mapping is added to the repository; \c false
- /// if the same mapping is already registered.
- bool addClass(const std::string& class_string, uint16_t class_code);
- /// \brief Remove mappings between RR class code and textual representation
- /// for a given class.
- ///
- /// This method can safely be called whether or not the specified mappings
- /// exist in the registry. If not, this method simply ignores the attempt
- /// and returns \c false.
- ///
- /// This method never throws an exception.
- ///
- /// \param class_code The integer code of the RR class.
- /// \return \c true if mappings for the specified RR type exists and is
- /// removed; \c false if no such mapping is in the registry.
- bool removeClass(uint16_t class_code);
- /// \brief Remove registered RDATA factory for the given pair of \c RRType
- /// and \c RRClass.
- ///
- /// This method can safely be called whether or not the specified factory
- /// object exist in the registry. If not, this method simply ignores the
- /// attempt and returns \c false.
- ///
- /// This method never throws an exception.
- ///
- /// \param rrtype An \c RRType object specifying the type/class pair.
- /// \param rrclass An \c RRClass object specifying the type/class pair.
- /// \return \c true if a factory object for the specified RR type/class
- /// pair exists and is removed; \c false if no such object is in the
- /// registry.
- bool removeRdataFactory(const RRType& rrtype, const RRClass& rrclass);
- /// \brief Remove registered RDATA factory for the given pair of \c RRType
- /// and \c RRClass.
- ///
- /// This method can safely be called whether or not the specified factory
- /// object exist in the registry. If not, this method simply ignores the
- /// attempt and returns \c false.
- ///
- /// This method never throws an exception.
- ///
- /// \param rrtype An \c RRType object specifying the type/class pair.
- /// \return \c true if a factory object for the specified RR type/class
- /// pair exists and is removed; \c false if no such object is in the
- /// registry.
- bool removeRdataFactory(const RRType& rrtype);
- //@}
- ///
- /// \name Parameter Conversion Methods
- ///
- //@{
- /// \brief Convert a textual representation of an RR type to the
- /// corresponding 16-bit integer code.
- ///
- /// This method searches the \c RRParamRegistry for the mapping from the
- /// given textual representation of RR type to the corresponding integer
- /// code. If a mapping is found, it returns the associated type code;
- /// otherwise, if the given string is in the form of "TYPEnnnn", it returns
- /// the corresponding number as the type code; otherwise, it throws an
- /// exception of class \c InvalidRRType.
- ///
- /// \param type_string The textual representation of the RR type.
- /// \return The RR type code for \c type_string.
- uint16_t textToTypeCode(const std::string& type_string) const;
- /// \brief Convert type code into its textual representation.
- ///
- /// This method searches the \c RRParamRegistry for the mapping from the
- /// given RR type code to its textual representation.
- /// If a mapping is found, it returns (a copy of) the associated string;
- /// otherwise, this method creates a new string in the form of "TYPEnnnn"
- /// where "nnnn" is the decimal representation of the type code, and
- /// returns the new string.
- ///
- /// If resource allocation for the returned string fails,
- /// a corresponding standard exception will be thrown.
- /// This method never fails otherwise.
- ///
- /// \param type_code The integer code of the RR type.
- /// \return A textual representation of the RR type for code \c type_code.
- std::string codeToTypeText(uint16_t type_code) const;
- /// \brief Convert a textual representation of an RR class to the
- /// corresponding 16-bit integer code.
- ///
- /// This method searches the \c RRParamRegistry for the mapping from the
- /// given textual representation of RR class to the corresponding integer
- /// code. If a mapping is found, it returns the associated class code;
- /// otherwise, if the given string is in the form of "CLASSnnnn", it returns
- /// the corresponding number as the class code; otherwise, it throws an
- /// exception of class \c InvalidRRClass.
- ///
- /// \param class_string The textual representation of the RR class.
- /// \return The RR class code for \c class_string.
- uint16_t textToClassCode(const std::string& class_string) const;
- /// \brief Convert class code into its textual representation.
- ///
- /// This method searches the \c RRParamRegistry for the mapping from the
- /// given RR class code to its textual representation.
- /// If a mapping is found, it returns (a copy of) the associated string;
- /// otherwise, this method creates a new string in the form of "CLASSnnnn"
- /// where "nnnn" is the decimal representation of the class code, and
- /// returns the new string.
- ///
- /// If resource allocation for the returned string fails,
- /// a corresponding standard exception will be thrown.
- /// This method never fails otherwise.
- ///
- /// \param class_code The integer code of the RR class.
- /// \return A textual representation of the RR class for code \c class_code.
- std::string codeToClassText(uint16_t class_code) const;
- //@}
- ///
- /// \name RDATA Factories
- ///
- /// This set of methods provide a unified interface to create an
- /// \c rdata::Rdata object in a parameterized polymorphic way,
- /// that is, these methods take a pair of \c RRType and \c RRClass
- /// objects and data specific to that pair, and create an object of
- /// the corresponding concrete derived class of \c rdata::Rdata.
- ///
- /// These methods first search the \c RRParamRegistry for a factory
- /// method (a member of a concrete derived class of
- /// \c AbstractRdataFactory) for the given RR type and class pair.
- /// If the search fails, they then search for a factory method for
- /// the given type ignoring the class, in case a RRClass independent
- /// factory method is registered.
- /// If it still fails, these methods assume the RDATA is of an "unknown"
- /// type, and creates a new object by calling a constructor of the
- /// \c rdata::generic::Generic class.
- ///
- //@{
- /// \brief Create RDATA of a given pair of RR type and class from a string.
- ///
- /// This method creates from a string an \c Rdata object of the given pair
- /// of RR type and class.
- ///
- /// \param rrtype An \c RRType object specifying the type/class pair.
- /// \param rrclass An \c RRClass object specifying the type/class pair.
- /// \param rdata_string A string of textual representation of the \c Rdata.
- /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
- /// object.
- rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
- const std::string& rdata_string);
- /// \brief Create RDATA of a given pair of RR type and class from
- /// wire-format data.
- ///
- /// This method creates from wire-format binary data an \c Rdata object
- /// of the given pair of RR type and class.
- ///
- /// \param rrtype An \c RRType object specifying the type/class pair.
- /// \param rrclass An \c RRClass object specifying the type/class pair.
- /// \param buffer A reference to an \c InputBuffer object storing the
- /// \c Rdata to parse.
- /// \param len The length in buffer of the \c Rdata. In bytes.
- /// \return An \c rdata::RdataPtr object pointing to the created \c Rdata
- /// object.
- rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
- InputBuffer& buffer, size_t len);
- /// \brief Create RDATA of a given pair of RR type and class, copying
- /// of another RDATA of same kind.
- ///
- /// This method creates an \c Rdata object of the given pair of
- /// RR type and class, copying the content of the given \c Rdata,
- /// \c source.
- ///
- /// \c source must be an object of the concrete derived class of
- /// \c rdata::Rdata for the given pair of RR type and class;
- /// otherwise, an exception of class \c std::bad_cast will be thrown.
- /// In case the \c RRParamRegistry doesn't have a factory method for
- /// the given pair and it is assumed to be of an "unknown" type,
- /// \c source must reference an object of class
- /// \c rdata::generic::Generic; otherwise, an exception of class
- /// \c std::bad_cast will be thrown.
- ///
- /// \param rrtype An \c RRType object specifying the type/class pair.
- /// \param rrclass An \c RRClass object specifying the type/class pair.
- /// \param source A reference to an \c rdata::Rdata object whose content
- /// is to be copied to the created \c rdata::Rdata object.
- /// \return An \c rdata::RdataPtr object pointing to the created
- /// \c rdata::Rdata object.
- rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
- const rdata::Rdata& source);
- //@}
- private:
- RRParamRegistryImpl* impl_;
- };
- }
- }
- #endif // __RRPARAMREGISTRY_H
- // Local Variables:
- // mode: c++
- // End:
|