LCOV - code coverage report
Current view: top level - cache - resolver_cache.h (source / functions) Hit Total Coverage
Test: report.info Lines: 4 5 80.0 %
Date: 2012-05-15 Functions: 1 3 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 2 50.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  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 __RESOLVER_CACHE_H
      16                 :            : #define __RESOLVER_CACHE_H
      17                 :            : 
      18                 :            : #include <map>
      19                 :            : #include <string>
      20                 :            : #include <boost/shared_ptr.hpp>
      21                 :            : #include <dns/rrclass.h>
      22                 :            : #include <dns/message.h>
      23                 :            : #include <exceptions/exceptions.h>
      24                 :            : #include "message_cache.h"
      25                 :            : #include "rrset_cache.h"
      26                 :            : #include "local_zone_data.h"
      27                 :            : 
      28                 :            : namespace isc {
      29                 :            : namespace cache {
      30                 :            : class RRsetCache;
      31                 :            : 
      32                 :            : //TODO a better proper default cache size
      33                 :            : #define MESSAGE_CACHE_DEFAULT_SIZE 10000
      34                 :            : #define RRSET_CACHE_DEFAULT_SIZE   20000
      35                 :            : #define NEGATIVE_RRSET_CACHE_DEFAULT_SIZE   10000
      36                 :            : 
      37                 :            : /// \brief Cache Size Information.
      38                 :            : ///
      39                 :            : /// Used to initialize the size of class-specific rrset/message cache.
      40                 :          0 : struct CacheSizeInfo
      41                 :            : {
      42                 :            : public:
      43                 :            :     /// \brief Constructor
      44                 :            :     ///
      45                 :            :     /// \param cls The RRClass code
      46                 :            :     /// \param msg_cache_size The size for the message cache
      47                 :            :     /// \param rst_cache_size The size for the RRset cache
      48                 :            :     CacheSizeInfo(const isc::dns::RRClass& cls,
      49                 :            :                   uint32_t msg_cache_size,
      50                 :            :                   uint32_t rst_cache_size):
      51                 :            :                     cclass(cls),
      52                 :            :                     message_cache_size(msg_cache_size),
      53                 :         13 :                     rrset_cache_size(rst_cache_size)
      54                 :            :     {}
      55                 :            : 
      56                 :            :     isc::dns::RRClass cclass; // class of the cache.
      57                 :            :     uint32_t message_cache_size; // the size for message cache.
      58                 :            :     uint32_t rrset_cache_size; // The size for rrset cache.
      59                 :            : };
      60                 :            : 
      61                 :            : /// \brief  Message has no question section.
      62                 :            : ///
      63                 :            : /// Thrown if the given message has no question section when looking up
      64                 :            : /// the message in cache.
      65                 :          1 : class MessageNoQuestionSection : public isc::Exception {
      66                 :            : public:
      67                 :            :     MessageNoQuestionSection(const char*file, size_t line, const char*what) :
      68         [ +  - ]:          1 :         isc::Exception(file, line, what)
      69                 :            :     {}
      70                 :            : };
      71                 :            : 
      72                 :            : /// \brief Class-specific Resolver Cache.
      73                 :            : ///
      74                 :            : /// The object of ResolverCache represents the cache of the resolver. It may hold
      75                 :            : /// a list of message/rrset cache which are in different class.
      76                 :            : ///
      77                 :            : /// \note Public interaction with the cache should be through ResolverCache,
      78                 :            : /// not directly with this one. (TODO: make this private/hidden/local to the .cc?)
      79                 :            : ///
      80                 :            : /// \todo The resolver cache class should provide the interfaces for
      81                 :            : ///       loading, dumping and resizing.
      82                 :        144 : class ResolverClassCache {
      83                 :            : public:
      84                 :            :     /// \brief Default Constructor.
      85                 :            :     ///
      86                 :            :     /// Only support for class "IN", and message cache size is
      87                 :            :     /// MESSAGE_CACHE_DEFAULT_SIZE, rrset cache size is
      88                 :            :     /// RRSET_CACHE_DEFAULT_SIZE
      89                 :            :     ResolverClassCache(const isc::dns::RRClass& cache_class);
      90                 :            : 
      91                 :            :     /// \brief Construct Function.
      92                 :            :     /// \param cache_info Cache size information for each message/rrsets of
      93                 :            :     ///        different classes.
      94                 :            :     ResolverClassCache(const CacheSizeInfo& cache_info);
      95                 :            : 
      96                 :            :     /// \name Lookup Interfaces
      97                 :            :     //@{
      98                 :            :     /// \brief Look up message in cache.
      99                 :            :     ///
     100                 :            :     /// \param qname The query name to look up
     101                 :            :     /// \param qtype The query type to look up
     102                 :            :     /// \param response the query message (must be in RENDER mode)
     103                 :            :     ///        which has question section already (exception
     104                 :            :     ///        MessageNoQeustionSection will be thrown if it has
     105                 :            :     ///        no question section). If the message can be found
     106                 :            :     ///        in cache, rrsets for the message will be added to
     107                 :            :     ///        different sections(answer, authority, additional).
     108                 :            :     /// \return return true if the message can be found, or else,
     109                 :            :     ///         return false.
     110                 :            :     bool lookup(const isc::dns::Name& qname,
     111                 :            :                 const isc::dns::RRType& qtype,
     112                 :            :                 isc::dns::Message& response) const;
     113                 :            : 
     114                 :            :     /// \brief Look up rrset in cache.
     115                 :            :     ///
     116                 :            :     /// \param qname The query name to look up
     117                 :            :     /// \param qtype The query type to look up
     118                 :            :     ///
     119                 :            :     /// \return return the shared_ptr of rrset if it can be found,
     120                 :            :     ///         or else, return NULL. When looking up, local zone
     121                 :            :     ///         data will be searched first, if not found, then
     122                 :            :     ///         search in rrset cache.
     123                 :            :     ///
     124                 :            :     /// \overload
     125                 :            :     ///
     126                 :            :     isc::dns::RRsetPtr lookup(const isc::dns::Name& qname,
     127                 :            :                               const isc::dns::RRType& qtype) const;
     128                 :            : 
     129                 :            :     /// \brief Update the message in the cache with the new one.
     130                 :            :     ///
     131                 :            :     /// \param msg The message to update
     132                 :            :     ///
     133                 :            :     /// \return return true if the message is updated successfully,
     134                 :            :     ///         or else, return false.
     135                 :            :     ///
     136                 :            :     /// \note the function doesn't do any message validation check,
     137                 :            :     ///       the user should make sure the message is valid, and of
     138                 :            :     ///       the right class
     139                 :            :     /// TODO: Share the NXDOMAIN info between different type queries
     140                 :            :     ///       current implementation can only cache for the type that
     141                 :            :     ///       user quired, for example, if user query A record of
     142                 :            :     ///       a.example. and the server replied with NXDOMAIN, this
     143                 :            :     ///       should be cached for all the types queries of a.example.
     144                 :            :     bool update(const isc::dns::Message& msg);
     145                 :            : 
     146                 :            :     /// \brief Update the rrset in the cache with the new one.
     147                 :            :     ///
     148                 :            :     /// local zone data and rrset cache will be updated together.
     149                 :            :     /// If the rrset doesn't exist in both of them, then the rrset
     150                 :            :     /// will be added into both of them.
     151                 :            :     ///
     152                 :            :     /// \param rrset_ptr The RRset to update
     153                 :            :     ///
     154                 :            :     /// \return return false, if the class of the parameter rrset is
     155                 :            :     ///        allowed to be cached.
     156                 :            :     ///
     157                 :            :     /// \overload
     158                 :            :     ///
     159                 :            :     /// \note The class of the RRset must have been checked. It is not
     160                 :            :     /// here.
     161                 :            :     bool update(const isc::dns::ConstRRsetPtr& rrset_ptr);
     162                 :            : 
     163                 :            :     /// \brief Get the RRClass this cache is for
     164                 :            :     ///
     165                 :            :     /// \return The RRClass of this cache
     166                 :            :     const isc::dns::RRClass& getClass() const;
     167                 :            : 
     168                 :            : private:
     169                 :            :     /// \brief Update rrset cache.
     170                 :            :     ///
     171                 :            :     /// \param rrset_ptr The rrset to update with
     172                 :            :     /// \param rrset_cache_ptr the rrset cache to update
     173                 :            :     ///
     174                 :            :     /// \return return true if the rrset is updated in the rrset cache,
     175                 :            :     ///         or else return false if failed.
     176                 :            :     /// \param rrset_cache_ptr The rrset cache need to be updated.
     177                 :            :     bool updateRRsetCache(const isc::dns::ConstRRsetPtr& rrset_ptr,
     178                 :            :                           RRsetCachePtr rrset_cache_ptr);
     179                 :            : 
     180                 :            :     /// \brief Class this cache is for.
     181                 :            :     const isc::dns::RRClass cache_class_;
     182                 :            : 
     183                 :            :     /// \brief map of message caches for configured classes(each message
     184                 :            :     /// cache is class-specific)
     185                 :            :     MessageCachePtr messages_cache_;
     186                 :            : 
     187                 :            :     /// \name rrset caches
     188                 :            :     //@{
     189                 :            :     /// \brief Local Zone data cache
     190                 :            :     /// Cache for rrsets in local zones, rrsets
     191                 :            :     /// in it never expire.
     192                 :            :     LocalZoneDataPtr local_zone_data_;
     193                 :            :     //@}
     194                 :            : 
     195                 :            :     /// \brief cache the rrsets parsed from the received message.
     196                 :            :     RRsetCachePtr rrsets_cache_;
     197                 :            : 
     198                 :            :     /// \brief cache the SOA rrset parsed from the negative response message.
     199                 :            :     RRsetCachePtr negative_soa_cache_;
     200                 :            : };
     201                 :            : 
     202                 :            : class ResolverCache {
     203                 :            : public:
     204                 :            :     /// \brief Default Constructor.
     205                 :            :     ///
     206                 :            :     /// Right now, only support for class "IN", and message cache size is
     207                 :            :     /// MESSAGE_CACHE_DEFAULT_SIZE, rrset cache size is
     208                 :            :     /// RRSET_CACHE_DEFAULT_SIZE
     209                 :            :     ResolverCache();
     210                 :            : 
     211                 :            :     /// \brief Construct Function.
     212                 :            :     /// \param caches_size cache size information for each
     213                 :            :     ///        messages/rrsets of different classes.
     214                 :            :     ResolverCache(std::vector<CacheSizeInfo> caches_size);
     215                 :            : 
     216                 :            :     /// \brief Destructor
     217                 :            :     ~ResolverCache();
     218                 :            : 
     219                 :            :     /// \name Lookup Interfaces
     220                 :            :     //@{
     221                 :            :     /// \brief Look up message in cache.
     222                 :            :     ///
     223                 :            :     /// \param qname The query name to look up
     224                 :            :     /// \param qtype The query type to look up
     225                 :            :     /// \param qclass The query class to look up
     226                 :            :     /// \param response the query message (must be in RENDER mode)
     227                 :            :     ///        which has question section already (exception
     228                 :            :     ///        MessageNoQeustionSection will be thrown if it has
     229                 :            :     ///        no question section). If the message can be found
     230                 :            :     ///        in cache, rrsets for the message will be added to
     231                 :            :     ///        different sections(answer, authority, additional).
     232                 :            :     /// \return return true if the message can be found, or else,
     233                 :            :     ///         return false.
     234                 :            :     bool lookup(const isc::dns::Name& qname,
     235                 :            :                 const isc::dns::RRType& qtype,
     236                 :            :                 const isc::dns::RRClass& qclass,
     237                 :            :                 isc::dns::Message& response) const;
     238                 :            : 
     239                 :            :     /// \brief Look up rrset in cache.
     240                 :            :     ///
     241                 :            :     /// \param qname The query name to look up
     242                 :            :     /// \param qtype The query type to look up
     243                 :            :     /// \param qclass The query class to look up
     244                 :            :     ///
     245                 :            :     /// \return return the shared_ptr of rrset if it can be found,
     246                 :            :     ///         or else, return NULL. When looking up, local zone
     247                 :            :     ///         data will be searched first, if not found, then
     248                 :            :     ///         search in rrset cache.
     249                 :            :     ///
     250                 :            :     /// \overload
     251                 :            :     ///
     252                 :            :     isc::dns::RRsetPtr lookup(const isc::dns::Name& qname,
     253                 :            :                               const isc::dns::RRType& qtype,
     254                 :            :                               const isc::dns::RRClass& qclass) const;
     255                 :            : 
     256                 :            :     /// \brief Look up closest enclosing NS rrset in cache.
     257                 :            :     ///
     258                 :            :     /// \param qname The query name to look up
     259                 :            :     /// \param qclass The query class to look up
     260                 :            :     ///
     261                 :            :     /// \return return the shared_ptr of closest enclosing ns rrset
     262                 :            :     ///         if it can be found in cache, or else return NULL.
     263                 :            :     ///
     264                 :            :     /// Currently the implementation is: search exact ns rrset
     265                 :            :     /// label by lable, If the ns rrset can't be found, remove the last
     266                 :            :     /// label, then search again. The efficiency may be very low when
     267                 :            :     /// the name is very long but it's closest rrset's name is very short.
     268                 :            :     ///
     269                 :            :     /// If a good perfermance is needed when looking up the closest
     270                 :            :     /// enclosing ns rrset, cache structure(HashTable) should be
     271                 :            :     /// redesigned. By using HashTable, it can only garantee the
     272                 :            :     /// performance for looking up exact rrset.
     273                 :            :     ///
     274                 :            :     /// So here there is another question, which rrset looking up interface
     275                 :            :     /// is used frequently? Exact or closest enclosing ns looking up.
     276                 :            :     isc::dns::RRsetPtr lookupDeepestNS(const isc::dns::Name& qname,
     277                 :            :                               const isc::dns::RRClass& qclass) const;
     278                 :            :     //@}
     279                 :            : 
     280                 :            :     /// \brief Update the message in the cache with the new one.
     281                 :            :     ///
     282                 :            :     /// \param msg The message to update
     283                 :            :     ///
     284                 :            :     /// \return return true if the message is updated successfully,
     285                 :            :     ///         or else, return false.
     286                 :            :     ///
     287                 :            :     /// \note the function doesn't do any message validation check,
     288                 :            :     ///       the user should make sure the message is valid.
     289                 :            :     bool update(const isc::dns::Message& msg);
     290                 :            : 
     291                 :            :     /// \brief Update the rrset in the cache with the new one.
     292                 :            :     ///
     293                 :            :     /// local zone data and rrset cache will be updated together.
     294                 :            :     /// If the rrset doesn't exist in both of them, then the rrset
     295                 :            :     /// will be added into both of them.
     296                 :            :     ///
     297                 :            :     /// \param rrset_ptr The RRset to update
     298                 :            :     ///
     299                 :            :     /// \return return false, if the class of the parameter rrset is
     300                 :            :     ///        allowed to be cached.
     301                 :            :     ///
     302                 :            :     /// \overload
     303                 :            :     ///
     304                 :            :     bool update(const isc::dns::ConstRRsetPtr& rrset_ptr);
     305                 :            : 
     306                 :            : private:
     307                 :            :     /// \brief Returns the class-specific subcache
     308                 :            :     ///
     309                 :            :     /// \param cache_class the class to get the subcache for
     310                 :            :     /// \return The subcache, or NULL if there is no cache for this class
     311                 :            :     ResolverClassCache* getClassCache(const isc::dns::RRClass& cache_class) const;
     312                 :            : 
     313                 :            :     /// The class-specific caches.
     314                 :            :     /// TODO: I think we can optimize for IN, and always have that
     315                 :            :     /// one directly available, use the vector for the rest?
     316                 :            :     std::vector<ResolverClassCache*> class_caches_;
     317                 :            : };
     318                 :            : 
     319                 :            : } // namespace cache
     320                 :            : } // namespace isc
     321                 :            : 
     322                 :            : #endif // __RESOLVER_CACHE_H
     323                 :            : 

Generated by: LCOV version 1.9