LCOV - code coverage report
Current view: top level - cache - resolver_cache.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 109 117 93.2 %
Date: 2012-05-15 Functions: 18 18 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 130 266 48.9 %

           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                 :            : #include <config.h>
      16                 :            : 
      17                 :            : #include "resolver_cache.h"
      18                 :            : #include "dns/message.h"
      19                 :            : #include "rrset_cache.h"
      20                 :            : #include "logger.h"
      21                 :            : #include <string>
      22                 :            : #include <algorithm>
      23                 :            : 
      24                 :            : using namespace isc::dns;
      25                 :            : using namespace std;
      26                 :            : 
      27                 :            : namespace isc {
      28                 :            : namespace cache {
      29                 :            : 
      30                 :         23 : ResolverClassCache::ResolverClassCache(const RRClass& cache_class) :
      31                 :         92 :     cache_class_(cache_class)
      32                 :            : {
      33 [ +  - ][ +  - ]:         23 :     LOG_DEBUG(logger, DBG_TRACE_BASIC, CACHE_RESOLVER_INIT).arg(cache_class);
         [ +  - ][ +  - ]
                 [ +  - ]
      34 [ +  - ][ +  - ]:         23 :     local_zone_data_ = LocalZoneDataPtr(new LocalZoneData(cache_class_.getCode()));
                 [ +  - ]
      35                 :            :     rrsets_cache_ = RRsetCachePtr(new RRsetCache(RRSET_CACHE_DEFAULT_SIZE,
      36 [ +  - ][ +  - ]:         23 :                                                  cache_class_.getCode()));
         [ +  - ][ +  - ]
      37                 :            :     // SOA rrset cache from negative response
      38                 :            :     negative_soa_cache_ = RRsetCachePtr(new RRsetCache(NEGATIVE_RRSET_CACHE_DEFAULT_SIZE,
      39 [ +  - ][ +  - ]:         23 :                                                        cache_class_.getCode()));
         [ +  - ][ +  - ]
      40                 :            : 
      41                 :            :     messages_cache_ = MessageCachePtr(new MessageCache(rrsets_cache_,
      42                 :            :                                       MESSAGE_CACHE_DEFAULT_SIZE,
      43                 :         23 :                                       cache_class_.getCode(),
      44 [ +  - ][ +  - ]:         23 :                                       negative_soa_cache_));
         [ +  - ][ +  - ]
      45                 :         23 : }
      46                 :            : 
      47                 :         13 : ResolverClassCache::ResolverClassCache(const CacheSizeInfo& cache_info) :
      48                 :         52 :     cache_class_(cache_info.cclass)
      49                 :            : {
      50 [ +  - ][ +  - ]:         26 :     LOG_DEBUG(logger, DBG_TRACE_BASIC, CACHE_RESOLVER_INIT_INFO).
                 [ +  - ]
      51 [ +  - ][ +  - ]:         13 :         arg(cache_class_);
      52                 :         26 :     uint16_t klass = cache_class_.getCode();
      53                 :            :     // TODO We should find one way to load local zone data.
      54 [ +  - ][ +  - ]:         13 :     local_zone_data_ = LocalZoneDataPtr(new LocalZoneData(klass));
                 [ +  - ]
      55                 :            :     rrsets_cache_ = RRsetCachePtr(new
      56 [ +  - ][ +  - ]:         13 :                         RRsetCache(cache_info.rrset_cache_size, klass));
         [ +  - ][ +  - ]
      57                 :            :     // SOA rrset cache from negative response
      58                 :            :     negative_soa_cache_ = RRsetCachePtr(new RRsetCache(cache_info.rrset_cache_size,
      59 [ +  - ][ +  - ]:         13 :                                                        klass));
         [ +  - ][ +  - ]
      60                 :            : 
      61                 :            :     messages_cache_ = MessageCachePtr(new MessageCache(rrsets_cache_,
      62                 :            :                                       cache_info.message_cache_size,
      63 [ +  - ][ +  - ]:         13 :                                       klass, negative_soa_cache_));
         [ +  - ][ +  - ]
      64                 :         13 : }
      65                 :            : 
      66                 :            : const RRClass&
      67                 :         75 : ResolverClassCache::getClass() const {
      68                 :         75 :     return (cache_class_);
      69                 :            : }
      70                 :            : 
      71                 :            : bool
      72                 :         22 : ResolverClassCache::lookup(const isc::dns::Name& qname,
      73                 :            :                       const isc::dns::RRType& qtype,
      74                 :            :                       isc::dns::Message& response) const
      75                 :            : {
      76         [ +  - ]:         44 :     LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_LOOKUP_MSG).
      77 [ +  - ][ +  - ]:         22 :         arg(qname).arg(qtype);
      78                 :            :     // message response should has question section already.
      79 [ +  - ][ +  - ]:         22 :     if (response.beginQuestion() == response.endQuestion()) {
         [ +  - ][ +  + ]
      80 [ +  - ][ +  - ]:          1 :         LOG_ERROR(logger, CACHE_RESOLVER_NO_QUESTION).arg(qname).arg(qtype);
                 [ +  - ]
      81         [ +  - ]:          2 :         isc_throw(MessageNoQuestionSection, "Message has no question section");
      82                 :            :     }
      83                 :            : 
      84                 :            :     // First, query in local zone, if the rrset(qname, qtype, qclass) can be
      85                 :            :     // found in local zone, generated reply message with only the rrset in
      86                 :            :     // answer section.
      87                 :         21 :     RRsetPtr rrset_ptr = local_zone_data_->lookup(qname, qtype);
      88         [ +  + ]:         21 :     if (rrset_ptr) {
      89 [ +  - ][ +  - ]:          2 :         LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_LOCAL_MSG).
                 [ +  - ]
      90 [ +  - ][ +  - ]:          1 :             arg(qname).arg(qtype);
                 [ +  - ]
      91         [ +  - ]:          1 :         response.addRRset(Message::SECTION_ANSWER, rrset_ptr);
      92                 :            :         return (true);
      93                 :            :     }
      94                 :            : 
      95                 :            :     // Search in class-specific message cache.
      96         [ +  - ]:         20 :     return (messages_cache_->lookup(qname, qtype, response));
      97                 :            : }
      98                 :            : 
      99                 :            : isc::dns::RRsetPtr
     100                 :         48 : ResolverClassCache::lookup(const isc::dns::Name& qname,
     101                 :            :                const isc::dns::RRType& qtype) const
     102                 :            : {
     103         [ +  - ]:         96 :     LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_LOOKUP_RRSET).
     104 [ +  - ][ +  - ]:         48 :         arg(qname).arg(qtype);
     105                 :            :     // Algorithm:
     106                 :            :     // 1. Search in local zone data first,
     107                 :            :     // 2. Then do search in rrsets_cache_.
     108                 :         48 :     RRsetPtr rrset_ptr = local_zone_data_->lookup(qname, qtype);
     109         [ +  + ]:         48 :     if (rrset_ptr) {
     110 [ +  - ][ +  - ]:         18 :         LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_LOCAL_RRSET).
                 [ +  - ]
     111 [ +  - ][ +  - ]:          9 :             arg(qname).arg(qtype);
                 [ +  - ]
     112                 :            :         return (rrset_ptr);
     113                 :            :     } else {
     114         [ +  - ]:         39 :         RRsetEntryPtr rrset_entry = rrsets_cache_->lookup(qname, qtype);
     115         [ +  + ]:         39 :         if (rrset_entry) {
     116         [ +  - ]:          2 :             return (rrset_entry->getRRset());
     117                 :            :         } else {
     118                 :            :             return (RRsetPtr());
     119                 :            :         }
     120                 :            :     }
     121                 :            : }
     122                 :            : 
     123                 :            : bool
     124                 :         16 : ResolverClassCache::update(const isc::dns::Message& msg) {
     125 [ +  - ][ +  - ]:         32 :     LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_UPDATE_MSG).
     126 [ +  - ][ +  - ]:         32 :         arg((*msg.beginQuestion())->getName()).
         [ +  - ][ +  - ]
                 [ +  - ]
     127 [ +  - ][ +  - ]:         48 :         arg((*msg.beginQuestion())->getType()).
         [ +  - ][ +  - ]
     128 [ +  - ][ +  - ]:         48 :         arg((*msg.beginQuestion())->getClass());
     129                 :         16 :     return (messages_cache_->update(msg));
     130                 :            : }
     131                 :            : 
     132                 :            : bool
     133                 :          4 : ResolverClassCache::updateRRsetCache(const isc::dns::ConstRRsetPtr& rrset_ptr,
     134                 :            :                                 RRsetCachePtr rrset_cache_ptr)
     135                 :            : {
     136                 :            :     RRsetTrustLevel level;
     137   [ +  +  -  + ]:          7 :     if (rrset_ptr->getType() == RRType::A() || 
                 [ +  + ]
     138                 :          3 :         rrset_ptr->getType() == RRType::AAAA()) {
     139                 :          1 :         level = RRSET_TRUST_PRIM_GLUE;
     140                 :            :     } else {
     141                 :          3 :         level = RRSET_TRUST_PRIM_ZONE_NONGLUE;
     142                 :            :     }
     143                 :            : 
     144                 :          4 :     rrset_cache_ptr->update((*rrset_ptr.get()), level);
     145                 :          4 :     return (true);
     146                 :            : }
     147                 :            : 
     148                 :            : bool
     149                 :          4 : ResolverClassCache::update(const isc::dns::ConstRRsetPtr& rrset_ptr) {
     150         [ +  - ]:          8 :     LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_UPDATE_RRSET).
     151 [ +  - ][ +  - ]:          4 :         arg(rrset_ptr->getName()).arg(rrset_ptr->getType()).
     152         [ +  - ]:          8 :         arg(rrset_ptr->getClass());
     153                 :            :     // First update local zone, then update rrset cache.
     154                 :          4 :     local_zone_data_->update((*rrset_ptr.get()));
     155         [ +  - ]:          4 :     updateRRsetCache(rrset_ptr, rrsets_cache_);
     156                 :          4 :     return (true);
     157                 :            : }
     158                 :            : 
     159                 :            : 
     160                 :          0 : ResolverCache::ResolverCache()
     161                 :            : {
     162 [ +  - ][ +  - ]:         23 :     class_caches_.push_back(new ResolverClassCache(RRClass::IN()));
                 [ +  - ]
     163                 :         23 : }
     164                 :            : 
     165                 :          0 : ResolverCache::ResolverCache(std::vector<CacheSizeInfo> caches_info)
     166                 :            : {
     167         [ +  + ]:         22 :     for (std::vector<CacheSizeInfo>::size_type i = 0;
     168                 :            :          i < caches_info.size(); ++i) {
     169 [ +  - ][ +  - ]:         13 :         class_caches_.push_back(new ResolverClassCache(caches_info[i]));
                 [ +  - ]
     170                 :            :     }
     171                 :          9 : }
     172                 :            : 
     173                 :         32 : ResolverCache::~ResolverCache()
     174                 :            : {
     175         [ +  + ]:         68 :     for (std::vector<ResolverClassCache*>::size_type i = 0;
     176                 :            :          i < class_caches_.size(); ++i) {
     177         [ +  - ]:         72 :         delete class_caches_[i];
     178                 :            :     }
     179                 :         32 : }
     180                 :            : 
     181                 :            : bool
     182                 :         22 : ResolverCache::lookup(const isc::dns::Name& qname,
     183                 :            :                       const isc::dns::RRType& qtype,
     184                 :            :                       const isc::dns::RRClass& qclass,
     185                 :            :                       isc::dns::Message& response) const
     186                 :            : {
     187                 :         22 :     ResolverClassCache* cc = getClassCache(qclass);
     188         [ +  - ]:         22 :     if (cc) {
     189                 :         22 :         return (cc->lookup(qname, qtype, response));
     190                 :            :     } else {
     191         [ #  # ]:         21 :         LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_UNKNOWN_CLASS_MSG).
     192         [ #  # ]:          0 :             arg(qclass);
     193                 :            :         return (false);
     194                 :            :     }
     195                 :            : }
     196                 :            : 
     197                 :            : isc::dns::RRsetPtr
     198                 :         18 : ResolverCache::lookup(const isc::dns::Name& qname,
     199                 :            :                const isc::dns::RRType& qtype,
     200                 :            :                const isc::dns::RRClass& qclass) const
     201                 :            : {
     202                 :         18 :     ResolverClassCache* cc = getClassCache(qclass);
     203         [ +  - ]:         18 :     if (cc) {
     204                 :         18 :         return (cc->lookup(qname, qtype));
     205                 :            :     } else {
     206         [ #  # ]:          0 :         LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_UNKNOWN_CLASS_RRSET).
     207         [ #  # ]:          0 :             arg(qclass);
     208                 :            :         return (RRsetPtr());
     209                 :            :     }
     210                 :            : }
     211                 :            : 
     212                 :            : isc::dns::RRsetPtr
     213                 :         13 : ResolverCache::lookupDeepestNS(const isc::dns::Name& qname,
     214                 :            :                                const isc::dns::RRClass& qclass) const
     215                 :            : {
     216 [ +  - ][ +  - ]:         26 :     LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_RESOLVER_DEEPEST).arg(qname).
     217         [ +  - ]:         13 :         arg(qclass);
     218                 :         13 :     isc::dns::RRType qtype = RRType::NS();
     219                 :         13 :     ResolverClassCache* cc = getClassCache(qclass);
     220         [ +  - ]:         13 :     if (cc) {
     221                 :         13 :         unsigned int count = qname.getLabelCount();
     222                 :         13 :         unsigned int level = 0;
     223         [ +  + ]:         34 :         while(level < count) {
     224                 :         60 :             Name close_name = qname.split(level);
     225         [ +  - ]:         30 :             RRsetPtr rrset_ptr = cc->lookup(close_name, qtype);
     226         [ +  + ]:         30 :             if (rrset_ptr) {
     227                 :            :                 return (rrset_ptr);
     228                 :            :             } else {
     229                 :         21 :                 ++level;
     230                 :            :             }
     231                 :            :         }
     232                 :            :     }
     233                 :            : 
     234                 :            :     return (RRsetPtr());
     235                 :            : }
     236                 :            : 
     237                 :            : bool
     238                 :         16 : ResolverCache::update(const isc::dns::Message& msg) {
     239                 :         32 :     QuestionIterator iter = msg.beginQuestion();
     240 [ +  - ][ +  - ]:         16 :     ResolverClassCache* cc = getClassCache((*iter)->getClass());
     241         [ +  - ]:         16 :     if (cc) {
     242         [ +  - ]:         16 :         return (cc->update(msg));
     243                 :            :     } else {
     244 [ #  # ][ #  # ]:          0 :         LOG_DEBUG(logger, DBG_TRACE_DATA,
                 [ #  # ]
     245                 :            :                   CACHE_RESOLVER_UPDATE_UNKNOWN_CLASS_MSG).
     246 [ #  # ][ #  # ]:          0 :             arg((*msg.beginQuestion())->getClass());
         [ #  # ][ #  # ]
                 [ #  # ]
     247                 :            :         return (false);
     248                 :            :     }
     249                 :            : }
     250                 :            : 
     251                 :            : bool
     252                 :          4 : ResolverCache::update(const isc::dns::ConstRRsetPtr& rrset_ptr) {
     253                 :          4 :     ResolverClassCache* cc = getClassCache(rrset_ptr->getClass());
     254         [ +  - ]:          4 :     if (cc) {
     255                 :          4 :         return (cc->update(rrset_ptr));
     256                 :            :     } else {
     257         [ #  # ]:          4 :         LOG_DEBUG(logger, DBG_TRACE_DATA,
     258                 :            :                   CACHE_RESOLVER_UPDATE_UNKNOWN_CLASS_RRSET).
     259         [ #  # ]:          0 :             arg(rrset_ptr->getClass());
     260                 :            :         return (false);
     261                 :            :     }
     262                 :            : }
     263                 :            : 
     264                 :            : ResolverClassCache*
     265                 :         73 : ResolverCache::getClassCache(const isc::dns::RRClass& cache_class) const {
     266         [ +  - ]:        148 :     for (std::vector<ResolverClassCache*>::size_type i = 0;
     267                 :            :          i < class_caches_.size(); ++i) {
     268         [ +  + ]:         75 :         if (class_caches_[i]->getClass() == cache_class) {
     269                 :         73 :             return (class_caches_[i]);
     270                 :            :         }
     271                 :            :     }
     272                 :            :     return (NULL);
     273                 :            : }
     274                 :            : 
     275                 :            : } // namespace cache
     276                 :          3 : } // namespace isc
     277                 :            : 

Generated by: LCOV version 1.9