LCOV - code coverage report
Current view: top level - acl - check.h (source / functions) Hit Total Coverage
Test: report.info Lines: 14 17 82.4 %
Date: 2012-05-15 Functions: 3 34 8.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 6 10 60.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  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 ACL_CHECK_H
      16                 :            : #define ACL_CHECK_H
      17                 :            : 
      18                 :            : #include <vector>
      19                 :            : #include <typeinfo>
      20                 :            : #include <sstream>
      21                 :            : 
      22                 :            : namespace isc {
      23                 :            : namespace acl {
      24                 :            : 
      25                 :            : /**
      26                 :            :  * \brief ACL check base class.
      27                 :            :  *
      28                 :            :  * It is intended that all ACL checks are inherited (maybe indirectly) from
      29                 :            :  * this base class. This will allow us to define new types of checks without
      30                 :            :  * changing any of the code that is using it and with the correct
      31                 :            :  * implementation even without changing the thing that parses configuration
      32                 :            :  * and creates instances of the checks.
      33                 :            :  *
      34                 :            :  * It is implemented as a template. This allows easy reuse of the code for
      35                 :            :  * checking of different types of things (packets of different protocols, etc).
      36                 :            :  * We'll implement the loader and compound checks as templates as well (
      37                 :            :  * and just make sure they are instantiated for each type of thing we want
      38                 :            :  * to check). While most of concrete checks will be specific for one protocol
      39                 :            :  * (or whatever the entity we check is), it makes sense to implement some of
      40                 :            :  * these as templates as well (for example the IP address check, for whatever
      41                 :            :  * context that contains member called ip and has the right methods).
      42                 :            :  *
      43                 :            :  * The Context carries whatever information might be checked for that protocol
      44                 :            :  * (eg. the packet, information where it came from, to what port, ...).
      45                 :            :  */
      46                 :          0 : template<typename Context> class Check {
      47                 :            : protected:
      48                 :            :     /// \brief Constructor.
      49                 :            :     ///
      50                 :            :     /// Just to make sure this thing is not directly instantiated.
      51                 :        332 :     Check() { }
      52                 :            : public:
      53                 :            :     /**
      54                 :            :      * \brief The check itself.
      55                 :            :      *
      56                 :            :      * The actual check will be performed here. Every concrete child class
      57                 :            :      * will reimplement it and decide based on the context passed if it
      58                 :            :      * matches.
      59                 :            :      *
      60                 :            :      * The caller should expect this method can throw. The list of exceptions
      61                 :            :      * isn't restricted, as we don't know what kind of checks will be needed.
      62                 :            :      * An exception should be considered as it is impossible to check the
      63                 :            :      * condition. It should lead to either blackholing the packet or returning
      64                 :            :      * some 500-like error (ServFail).
      65                 :            :      *
      66                 :            :      * \param context The thing we are trying to match against this check.
      67                 :            :      * \return true if the context satisfies the check, false otherwise.
      68                 :            :      */
      69                 :            :     virtual bool matches(const Context& context) const = 0;
      70                 :            : 
      71                 :            :     /**
      72                 :            :      * \brief Cost for unknown cost estimate.
      73                 :            :      *
      74                 :            :      * This indicates that the estimate for cost is not provided. This
      75                 :            :      * is arbitrary large value, meaning "somehow longish time". To be
      76                 :            :      * on the safe side, we guess more and be just happily suprirised
      77                 :            :      * if it turns out to run faster.
      78                 :            :      */
      79                 :            :     static const unsigned UNKNOWN_COST;
      80                 :            : 
      81                 :            :     /**
      82                 :            :      * \brief The expected cost of single match.
      83                 :            :      *
      84                 :            :      * This is here to provide some kind of cost information to optimising
      85                 :            :      * routines. It is in units without any real size, just bigger number
      86                 :            :      * means the check takes longer time. It is expected to be linear scale.
      87                 :            :      * It doesn't need to be exact, but better accuracy might lead to better
      88                 :            :      * optimisations. As of writing this, no optimisations exist yet, but
      89                 :            :      * are expected to exist in future.
      90                 :            :      *
      91                 :            :      * The default is UNKNOWN_COST.
      92                 :            :      */
      93                 :          2 :     virtual unsigned cost() const {
      94                 :          2 :         return (UNKNOWN_COST);
      95                 :            :     }
      96                 :            : 
      97                 :            :     /// \brief Virtual destructor, as we're virtual
      98                 :        302 :     virtual ~ Check() { }
      99                 :            : 
     100                 :            :     /**
     101                 :            :      * \brief Conversion to text.
     102                 :            :      *
     103                 :            :      * This is meant for debugging purposes, it doesn't have to
     104                 :            :      * serialise the whole information stored in this Check.
     105                 :            :      *
     106                 :            :      * If the check is compound, it should not include the subexpressions
     107                 :            :      * (while we're able to build whatever treeish representation using
     108                 :            :      * CompoundCheck::subexpressions, we're not able to separate them
     109                 :            :      * automatically, as this may produce any kind of free-form string).
     110                 :            :      */
     111                 :          1 :     virtual std::string toText() const {
     112                 :          2 :         std::stringstream output;
     113 [ +  - ][ +  - ]:          1 :         output << typeid(*this).name() << "@" << this;
     114         [ +  - ]:          2 :         return (output.rdbuf()->str());
     115                 :            :     }
     116                 :            : };
     117                 :            : 
     118                 :            : // This seems to be the propper way for static template members
     119                 :            : template<typename Context> const unsigned Check<Context>::UNKNOWN_COST = 10000;
     120                 :            : 
     121                 :            : /**
     122                 :            :  * \brief Base class for compound checks.
     123                 :            :  *
     124                 :            :  * While some checks will be a match against some property of the information
     125                 :            :  * passed (eg. the sender's IP address must be in some range), others will
     126                 :            :  * combine results of more checks together to get their own. This is base class
     127                 :            :  * for the second type, allowing listing of the subexpressions (mostly for
     128                 :            :  * debugging purposes to print the whole tree of matches and possible future
     129                 :            :  * optimisations which would like to crawl the expression tree).
     130                 :            :  */
     131                 :          0 : template<typename Context> class CompoundCheck : public Check<Context> {
     132                 :            : public:
     133                 :            :     /// \brief Abbreviated name for list of subexpressions
     134                 :            :     typedef std::vector<const Check<Context>*> Checks;
     135                 :            : 
     136                 :            :     /**
     137                 :            :      * \brief Get the list of subexpressions.
     138                 :            :      *
     139                 :            :      * The result contains pointers to the all subexpressions this check holds
     140                 :            :      * (and therefore might call during its own match() function).
     141                 :            :      *
     142                 :            :      * Using shared pointers looks an overkill here. All the checks must be
     143                 :            :      * alive for the whole life of this one and this check will hold their
     144                 :            :      * ownership. Therefore the only thing the caller needs to do is to make
     145                 :            :      * sure this check is not deleted while it's still using the ones from the
     146                 :            :      * result.
     147                 :            :      *
     148                 :            :      * This method must not throw except for the standard allocation exceptions
     149                 :            :      * to allocate the result.
     150                 :            :      */
     151                 :            :     virtual Checks getSubexpressions() const = 0;
     152                 :            : 
     153                 :            :     /**
     154                 :            :      * \brief If the result depends only on results of subexpressions.
     155                 :            :      *
     156                 :            :      * Some optimisations might use the fact that a compound expression is
     157                 :            :      * a function of results of its subexpressions (subchecks) only. But
     158                 :            :      * some compound checks might want to look into the provided context in
     159                 :            :      * their match() as well as looking at the results of the subexpressions.
     160                 :            :      *
     161                 :            :      * This function informs the optimisation routines if it is safe to use
     162                 :            :      * these optimisations.
     163                 :            :      *
     164                 :            :      * \return true if the check depends only on results of subexpressions
     165                 :            :      *    only, false if it examines the context itself as well.
     166                 :            :      * \note The default implementation returns true, as it is expected to
     167                 :            :      *    be the case in majority of cases.
     168                 :            :      */
     169                 :          0 :     virtual bool pure() const { return (true); }
     170                 :            : 
     171                 :            :     /**
     172                 :            :      * \brief Default compound cost function.
     173                 :            :      *
     174                 :            :      * It is simply sum of all subexpressions, as an expected upper bound
     175                 :            :      * on the cost. This expects that the combining itself is cheap relatively
     176                 :            :      * to the checks performed by the subexpressions. In most cases, this
     177                 :            :      * should be good enough, but it can be reimplemented in situations
     178                 :            :      * where most of the subexpressions will be avoided in usual situations.
     179                 :            :      * Replacing the default of 10000 from Check.
     180                 :            :      */
     181                 :          1 :     virtual unsigned cost() const {
     182                 :          2 :         Checks checks(getSubexpressions());
     183                 :          1 :         unsigned result(0);
     184         [ +  + ]:          3 :         for (typename Checks::const_iterator i(checks.begin());
     185                 :            :              i != checks.end(); ++ i) {
     186         [ +  - ]:          2 :             result += (*i)->cost();
     187                 :            :         }
     188                 :          1 :         return (result);
     189                 :            :     }
     190                 :            : };
     191                 :            : 
     192                 :            : }
     193                 :            : }
     194                 :            : 
     195                 :            : #endif

Generated by: LCOV version 1.9