LCOV - code coverage report
Current view: top level - datasrc - data_source.h (source / functions) Hit Total Coverage
Test: report.info Lines: 15 22 68.2 %
Date: 2012-05-15 Functions: 5 18 27.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 19 36 52.8 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2009  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 __DATA_SOURCE_H
      16                 :            : #define __DATA_SOURCE_H
      17                 :            : 
      18                 :            : #include <stdint.h>
      19                 :            : 
      20                 :            : #include <vector>
      21                 :            : 
      22                 :            : #include <boost/shared_ptr.hpp>
      23                 :            : 
      24                 :            : #include <exceptions/exceptions.h>
      25                 :            : 
      26                 :            : #include <dns/name.h>
      27                 :            : #include <dns/rrclass.h>
      28                 :            : #include <cc/data.h>
      29                 :            : 
      30                 :            : namespace isc {
      31                 :            : 
      32                 :            : namespace dns {
      33                 :            : class Name;
      34                 :            : class RRType;
      35                 :            : class RRset;
      36                 :            : class RRsetList;
      37                 :            : }
      38                 :            : 
      39                 :            : namespace datasrc {
      40                 :            : 
      41                 :            : class DataSrcMatch;
      42                 :            : class Query;
      43                 :            : 
      44                 :            : class DataSrc;
      45                 :            : typedef boost::shared_ptr<DataSrc> DataSrcPtr;
      46                 :            : typedef boost::shared_ptr<const DataSrc> ConstDataSrcPtr;
      47                 :            : 
      48                 :            : /// This exception represents Backend-independent errors relating to
      49                 :            : /// data source operations.
      50                 :        187 : class DataSourceError : public Exception {
      51                 :            : public:
      52                 :         96 :     DataSourceError(const char* file, size_t line, const char* what) :
      53 [ +  - ][ +  + ]:        187 :         isc::Exception(file, line, what) {}
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
      54                 :            : };
      55                 :            : 
      56                 :            : /// \brief No such serial number when obtaining difference iterator
      57                 :            : ///
      58                 :            : /// Thrown if either the zone/start serial number or zone/end serial number
      59                 :            : /// combination does not exist in the differences table.  (Note that this
      60                 :            : /// includes the case where the differences table contains no records related
      61                 :            : /// to that zone.)
      62                 :          9 : class NoSuchSerial : public DataSourceError {
      63                 :            : public:
      64                 :            :     NoSuchSerial(const char* file, size_t line, const char* what) :
      65         [ -  + ]:         10 :         DataSourceError(file, line, what) {}
      66                 :            : };
      67                 :            : 
      68                 :            : 
      69                 :            : class AbstractDataSrc {
      70                 :            :     ///
      71                 :            :     /// \name Constructors, Assignment Operator and Destructor.
      72                 :            :     ///
      73                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
      74                 :            :     /// defined as private to make it explicit that this is a pure base class.
      75                 :            : private:
      76                 :            :     AbstractDataSrc(const AbstractDataSrc& source);
      77                 :            :     AbstractDataSrc& operator=(const AbstractDataSrc& source);
      78                 :            : protected:
      79                 :            :     /// \brief The default constructor.
      80                 :            :     ///
      81                 :            :     /// This is intentionally defined as \c protected as this base class should
      82                 :            :     /// never be instantiated (except as part of a derived class).
      83                 :        459 :     AbstractDataSrc() {}
      84                 :            : public:
      85                 :            :     /// \brief The destructor.
      86                 :        451 :     virtual ~AbstractDataSrc() {};
      87                 :            :     //@}
      88                 :            : 
      89                 :            :     enum Result {
      90                 :            :         SUCCESS,
      91                 :            :         ERROR,
      92                 :            :         NOT_IMPLEMENTED
      93                 :            :     };
      94                 :            : 
      95                 :            :     // These flags indicate conditions encountered while processing a query.
      96                 :            :     //
      97                 :            :     // REFERRAL:       The node contains an NS record
      98                 :            :     // CNAME_FOUND:    The node contains a CNAME record
      99                 :            :     // NAME_NOT_FOUND: The node does not exist in the data source.
     100                 :            :     // TYPE_NOT_FOUND: The node does not contain the requested RRType
     101                 :            :     // NO_SUCH_ZONE:   The zone does not exist in this data source.
     102                 :            :     //
     103                 :            :     // DATA_NOT_FOUND: A combination of the last three, for coding convenience
     104                 :            :     enum QueryResponseFlags {
     105                 :            :         REFERRAL = 0x01,
     106                 :            :         CNAME_FOUND = 0x02,
     107                 :            :         NAME_NOT_FOUND = 0x04,
     108                 :            :         TYPE_NOT_FOUND = 0x08,
     109                 :            :         NO_SUCH_ZONE = 0x10,
     110                 :            :         DATA_NOT_FOUND = (NAME_NOT_FOUND|TYPE_NOT_FOUND|NO_SUCH_ZONE)
     111                 :            :     };
     112                 :            : 
     113                 :            :     // 'High-level' methods.  These will be implemented by the
     114                 :            :     // general DataSrc class, and SHOULD NOT be overwritten by subclasses.
     115                 :            :     virtual void doQuery(Query& query) = 0;
     116                 :            : 
     117                 :            :     // XXX: High-level methods to be implemented later:
     118                 :            :     // virtual void doUpdate(Update update) = 0;
     119                 :            :     // virtual void doXfr(Query query) = 0;
     120                 :            : 
     121                 :            :     // 'Medium-level' methods.  This will be implemented by the general
     122                 :            :     // DataSrc class but MAY be overwritten by subclasses.
     123                 :            :     virtual void findClosestEnclosure(DataSrcMatch& match) const = 0;
     124                 :            : 
     125                 :            :     // Optional 'low-level' methods.  These will have stub implementations
     126                 :            :     // in the general DataSrc class but MAY be overwritten by subclasses
     127                 :            :     virtual Result init() = 0;
     128                 :            :     virtual Result init(isc::data::ConstElementPtr config) = 0;
     129                 :            :     virtual Result close() = 0;
     130                 :            : 
     131                 :            :     // Mandatory 'low-level' methods: These will NOT be implemented by
     132                 :            :     // the general DataSrc class; subclasses MUST implement them.
     133                 :            :     virtual Result findRRset(const isc::dns::Name& qname,
     134                 :            :                              const isc::dns::RRClass& qclass,
     135                 :            :                              const isc::dns::RRType& qtype,
     136                 :            :                              isc::dns::RRsetList& target,
     137                 :            :                              uint32_t& flags,
     138                 :            :                              const isc::dns::Name* zonename) const = 0;
     139                 :            : 
     140                 :            :     virtual Result findExactRRset(const isc::dns::Name& qname,
     141                 :            :                                   const isc::dns::RRClass& qclass,
     142                 :            :                                   const isc::dns::RRType& qtype,
     143                 :            :                                   isc::dns::RRsetList& target,
     144                 :            :                                   uint32_t& flags,
     145                 :            :                                   const isc::dns::Name* zonename) const = 0;
     146                 :            : 
     147                 :            :     // These will have dumb implementations in the general DataSrc
     148                 :            :     // class, and SHOULD be overwritten by subclasses.
     149                 :            :     virtual Result findAddrs(const isc::dns::Name& qname,
     150                 :            :                              const isc::dns::RRClass& qclass,
     151                 :            :                              isc::dns::RRsetList& target,
     152                 :            :                              uint32_t& flags,
     153                 :            :                              const isc::dns::Name* zonename) const = 0;
     154                 :            : 
     155                 :            :      virtual Result findReferral(const isc::dns::Name& qname,
     156                 :            :                                  const isc::dns::RRClass& qclass,
     157                 :            :                                  isc::dns::RRsetList& target,
     158                 :            :                                  uint32_t& flags,
     159                 :            :                                  const isc::dns::Name* zonename) const = 0;
     160                 :            : 
     161                 :            :     // This MUST be implemented by concrete data sources which support
     162                 :            :     // DNSSEC, but is optional for others (e.g., the static data source).
     163                 :            :     virtual Result findPreviousName(const isc::dns::Name& qname,
     164                 :            :                                     isc::dns::Name& target,
     165                 :            :                                     const isc::dns::Name* zonename) const = 0;
     166                 :            : 
     167                 :            :    // This MUST be implemented by concrete data sources which support
     168                 :            :    // NSEC3, but is optional for others
     169                 :            :    virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
     170                 :            :                                     std::string& hash,
     171                 :            :                                     isc::dns::RRsetList& target) const = 0;
     172                 :            : };
     173                 :            : 
     174                 :            : // Base class for a DNS Data Source
     175                 :            : class DataSrc : public AbstractDataSrc {
     176                 :            :     ///
     177                 :            :     /// \name Constructors, Assignment Operator and Destructor.
     178                 :            :     ///
     179                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
     180                 :            :     /// defined as private.
     181                 :            : private:
     182                 :            :     DataSrc(const DataSrc& source);
     183                 :            :     DataSrc& operator=(const DataSrc& source);
     184                 :            : public:
     185                 :        833 :     DataSrc() : rrclass(isc::dns::RRClass::IN()) {}
     186                 :        280 :     DataSrc(const isc::dns::RRClass& c) : rrclass(c) {}
     187                 :            :     /// \brief The destructor.
     188                 :          0 :     virtual ~DataSrc() {};
     189                 :            :     //@}
     190                 :            : 
     191                 :            :     virtual void doQuery(Query& q);
     192                 :            : 
     193                 :            :     virtual void findClosestEnclosure(DataSrcMatch& match) const = 0;
     194                 :            : 
     195                 :            :     const isc::dns::RRClass& getClass() const { return (rrclass); }
     196                 :            :     void setClass(isc::dns::RRClass& c) { rrclass = c; }
     197                 :          0 :     void setClass(const isc::dns::RRClass& c) { rrclass = c; }
     198                 :            : 
     199                 :          0 :     virtual Result init() { return (NOT_IMPLEMENTED); }
     200                 :            :     virtual Result init(isc::data::ConstElementPtr config);
     201                 :          0 :     virtual Result close() { return (NOT_IMPLEMENTED); }
     202                 :            : 
     203                 :            :     virtual Result findRRset(const isc::dns::Name& qname,
     204                 :            :                              const isc::dns::RRClass& qclass,
     205                 :            :                              const isc::dns::RRType& qtype,
     206                 :            :                              isc::dns::RRsetList& target,
     207                 :            :                              uint32_t& flags,
     208                 :            :                              const isc::dns::Name* zonename) const = 0;
     209                 :            : 
     210                 :            :     virtual Result findExactRRset(const isc::dns::Name& qname,
     211                 :            :                                   const isc::dns::RRClass& qclass,
     212                 :            :                                   const isc::dns::RRType& qtype,
     213                 :            :                                   isc::dns::RRsetList& target,
     214                 :            :                                   uint32_t& flags,
     215                 :            :                                   const isc::dns::Name* zonename) const = 0;
     216                 :            : 
     217                 :            :     virtual Result findAddrs(const isc::dns::Name& qname,
     218                 :            :                              const isc::dns::RRClass& qclass,
     219                 :            :                              isc::dns::RRsetList& target,
     220                 :            :                              uint32_t& flags,
     221                 :            :                              const isc::dns::Name* zonename) const;
     222                 :            : 
     223                 :            :     virtual Result findReferral(const isc::dns::Name& qname,
     224                 :            :                                 const isc::dns::RRClass& qclass,
     225                 :            :                                 isc::dns::RRsetList& target,
     226                 :            :                                 uint32_t& flags,
     227                 :            :                                 const isc::dns::Name* zonename) const;
     228                 :            : 
     229                 :            :     virtual Result findPreviousName(const isc::dns::Name& qname,
     230                 :            :                                     isc::dns::Name& target,
     231                 :            :                                     const isc::dns::Name* zonename) const = 0;
     232                 :            : 
     233                 :            :    virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
     234                 :            :                                     std::string& hash,
     235                 :            :                                     isc::dns::RRsetList& target) const = 0;
     236                 :            : 
     237                 :            : private:
     238                 :            :     isc::dns::RRClass rrclass;
     239                 :            : };
     240                 :            : 
     241                 :            : class MetaDataSrc : public DataSrc {
     242                 :            :     ///
     243                 :            :     /// \name Constructors, Assignment Operator and Destructor.
     244                 :            :     ///
     245                 :            :     /// Note: The copy constructor and the assignment operator are intentionally
     246                 :            :     /// defined as private.
     247                 :            :     //@{
     248                 :            : private:
     249                 :            :     MetaDataSrc(const MetaDataSrc& source);
     250                 :            :     MetaDataSrc& operator=(const MetaDataSrc& source);
     251                 :            : public:
     252                 :        234 :     MetaDataSrc() : DataSrc(isc::dns::RRClass::ANY()) {}
     253                 :            :     MetaDataSrc(const isc::dns::RRClass& c) : DataSrc(c) {}
     254                 :            :     /// \brief The destructor.
     255                 :        140 :     virtual ~MetaDataSrc() {}
     256                 :            :     //@}
     257                 :            : 
     258                 :            :     void addDataSrc(ConstDataSrcPtr data_src);
     259                 :            :     void removeDataSrc(ConstDataSrcPtr data_src);
     260                 :            :     size_t dataSrcCount() { return (data_sources.size()); }
     261                 :            : 
     262                 :            :     void findClosestEnclosure(DataSrcMatch& match) const;
     263                 :            : 
     264                 :            :     // Actual queries for data should not be sent to a MetaDataSrc object,
     265                 :            :     // so we return NOT_IMPLEMENTED if we receive any.
     266                 :            :     //
     267                 :            :     // The proper way to use the MetaDataSrc is to run findClosestEnclosure()
     268                 :            :     // to get a pointer to the best concrete data source for the specified
     269                 :            :     // zone, then send all queries directly to that data source.
     270                 :            : 
     271                 :            :     Result findRRset(const isc::dns::Name& qname,
     272                 :            :                      const isc::dns::RRClass& qclass,
     273                 :            :                      const isc::dns::RRType& qtype,
     274                 :            :                      isc::dns::RRsetList& target,
     275                 :            :                      uint32_t& flags,
     276                 :            :                      const isc::dns::Name* zonename) const;
     277                 :            : 
     278                 :            :     Result findExactRRset(const isc::dns::Name& qname,
     279                 :            :                           const isc::dns::RRClass& qclass,
     280                 :            :                           const isc::dns::RRType& qtype,
     281                 :            :                           isc::dns::RRsetList& target,
     282                 :            :                           uint32_t& flags,
     283                 :            :                           const isc::dns::Name* zonename) const;
     284                 :            : 
     285                 :            :     Result findAddrs(const isc::dns::Name& qname,
     286                 :            :                      const isc::dns::RRClass& qclass,
     287                 :            :                      isc::dns::RRsetList& target,
     288                 :            :                      uint32_t& flags,
     289                 :            :                      const isc::dns::Name* zonename) const;
     290                 :            : 
     291                 :            :     Result findReferral(const isc::dns::Name& qname,
     292                 :            :                         const isc::dns::RRClass& qclass,
     293                 :            :                         isc::dns::RRsetList& target,
     294                 :            :                         uint32_t& flags,
     295                 :            :                         const isc::dns::Name* zonename) const;
     296                 :            : 
     297                 :            :     virtual Result findPreviousName(const isc::dns::Name& qname,
     298                 :            :                                     isc::dns::Name& target,
     299                 :            :                                     const isc::dns::Name* zonename) const;
     300                 :            : 
     301                 :            :    virtual Result findCoveringNSEC3(const isc::dns::Name& zonename,
     302                 :            :                                     std::string& hash,
     303                 :            :                                     isc::dns::RRsetList& target) const;
     304                 :            : 
     305                 :            : private:
     306                 :            :     std::vector<ConstDataSrcPtr> data_sources;
     307                 :            : };
     308                 :            : 
     309                 :            : /// \brief Information about the zone along with the %data source that best
     310                 :            : /// matches a give name and RR class.
     311                 :            : ///
     312                 :            : /// A \c DataSrcMatch object is created with a domain name and RR class to
     313                 :            : /// hold the search state of looking for the zone and the %data source that
     314                 :            : /// stores the zone that best match the given name and RR class.
     315                 :            : /// The application of this class passes an object of \c DataSrcMatch to
     316                 :            : /// one or more ^data sources via their \c findClosestEnclosure() method.
     317                 :            : /// The %data source searches its content for the given key, and update
     318                 :            : /// the state if it finds a better zone than the currently recorded one.
     319                 :            : ///
     320                 :            : /// The state of a \c DataSrcMatch object should be updated if and only if:
     321                 :            : ///  - The specified RR class and the RR class of the %data source are the
     322                 :            : //     same, or the specified RR class is ANY; and
     323                 :            : ///  - There is no matching %data source and name found (which is probably
     324                 :            : ///    wrong, see below), or the given enclosing name gives a longer match
     325                 :            : ///    than the currently stored enclosing name against the specified name.
     326                 :            : class DataSrcMatch {
     327                 :            :     ///
     328                 :            :     /// \name Constructors, Assignment Operator and Destructor.
     329                 :            :     ///
     330                 :            :     /// Note: The copy constructor and the assignment operator are
     331                 :            :     /// intentionally defined as private.
     332                 :            :     //@{
     333                 :            : private:
     334                 :            :     DataSrcMatch(const DataSrcMatch& source);
     335                 :            :     DataSrcMatch& operator=(const DataSrcMatch& source);
     336                 :            : public:
     337                 :            :     /// \brief The constructor.
     338                 :            :     ///
     339                 :            :     /// This constructor normally doesn't throw an exception.  However,
     340                 :            :     /// it creates a copy of the given name object, which may require memory
     341                 :            :     /// allocation, and if it fails the corresponding standard exception will
     342                 :            :     /// be thrown.
     343                 :            :     ///
     344                 :            :     /// \param name The domain name to be matched.
     345                 :            :     /// \param rrclass The RR class to be matched
     346                 :          7 :     DataSrcMatch(const isc::dns::Name& name,
     347                 :            :                  const isc::dns::RRClass& rrclass) :
     348                 :            :         closest_name_(NULL), best_source_(NULL),
     349 [ +  - ][ +  - ]:        202 :         name_(name), rrclass_(rrclass)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     350                 :          7 :     {}
     351                 :            :     ~DataSrcMatch();
     352                 :            :     //@}
     353                 :            : 
     354                 :            :     /// \name Getter and Setter Methods
     355                 :            :     //@{
     356                 :            :     /// \brief Returns the name to be matched.
     357                 :            :     const isc::dns::Name& getName() const { return (name_); }
     358                 :            : 
     359                 :            :     /// \brief Returns the RR class to be matched.
     360                 :            :     ///
     361                 :            :     /// This method never throws an exception.
     362                 :          0 :     const isc::dns::RRClass& getClass() const { return (rrclass_); }
     363                 :            : 
     364                 :            :     /// \brief Returns the best enclosing zone name found for the given
     365                 :            :     // name and RR class so far.
     366                 :            :     ///
     367                 :            :     /// \return A pointer to the zone apex \c Name, NULL if none found yet.
     368                 :            :     ///
     369                 :            :     /// This method never throws an exception.
     370                 :          0 :     const isc::dns::Name* getEnclosingZone() const { return (closest_name_); }
     371                 :            : 
     372                 :            :     /// \brief Returns the best %data source found for the given name and
     373                 :            :     /// RR class so far.
     374                 :            :     ///
     375                 :            :     /// This method never throws an exception.
     376                 :            :     ///
     377                 :            :     /// \return A pointer to a concrete %data source, NULL if none found yet.
     378                 :          0 :     const DataSrc* getDataSource() const { return (best_source_); }
     379                 :            :     //@}
     380                 :            : 
     381                 :            :     /// \brief Update the object state with better information if possible.
     382                 :            :     ///
     383                 :            :     /// This method is intended to be called by a concrete %data source's
     384                 :            :     /// \c findClosestEnclosure() method to store the best match for
     385                 :            :     /// the given name and class that has been found so far.
     386                 :            :     ///
     387                 :            :     /// It compares the best name (if found) and \c container, and if the
     388                 :            :     /// latter gives a longer match, it will install the given %data source
     389                 :            :     /// and the enclosing name as the best match;
     390                 :            :     /// if there is no known pair of %data source and enclosing name,
     391                 :            :     /// this method will install the given pair unconditionally.
     392                 :            :     /// (which is probably BAD);
     393                 :            :     /// otherwise this method does nothing.
     394                 :            :     ///
     395                 :            :     /// In any case, if a new pair of %data source and enclosing name are
     396                 :            :     /// installed, a new name object will be internally allocated.
     397                 :            :     /// And, if memory allocation fails the corresponding standard exception
     398                 :            :     /// will be thrown.
     399                 :            :     ///
     400                 :            :     /// \param new_source A candidate %data source that gives a better match.
     401                 :            :     /// \param container The enclosing name of the matching zone in
     402                 :            :     /// \c new_source.
     403                 :            :     void update(const DataSrc& new_source, const isc::dns::Name& container);
     404                 :            : 
     405                 :            : private:
     406                 :            :     isc::dns::Name* closest_name_;
     407                 :            :     const DataSrc* best_source_;
     408                 :            :     const isc::dns::Name name_;
     409                 :            :     const isc::dns::RRClass& rrclass_;
     410                 :            : };
     411                 :            : 
     412                 :          1 : class Nsec3Param {
     413                 :            : public:
     414                 :            :     Nsec3Param(uint8_t a, uint8_t f, uint16_t i, const std::vector<uint8_t>& s);
     415                 :            :     std::string getHash(const isc::dns::Name& name) const;
     416                 :            : private:
     417                 :            :     const uint8_t algorithm_;
     418                 :            :     const uint8_t flags_;
     419                 :            :     const uint16_t iterations_;
     420                 :            :     const std::vector<uint8_t> salt_;
     421                 :            : };
     422                 :            : 
     423                 :            : }
     424                 :            : }
     425                 :            : 
     426                 :            : #endif
     427                 :            : 
     428                 :            : // Local Variables:
     429                 :            : // mode: c++
     430                 :            : // End:

Generated by: LCOV version 1.9