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 : : //
5 : : // purpose with or without fee is hereby granted, provided that the above
6 : : // copyright notice and this permission notice appear in all copies.
7 : : //
8 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 : : // PERFORMANCE OF THIS SOFTWARE.
15 : :
16 : : #include <config.h>
17 : :
18 : : #include <nsas/nsas_entry_compare.h>
19 : : #include <nsas/hash_table.h>
20 : : #include <nsas/hash_deleter.h>
21 : : #include "message_cache.h"
22 : : #include "message_utility.h"
23 : : #include "cache_entry_key.h"
24 : : #include "logger.h"
25 : :
26 : : namespace isc {
27 : : namespace cache {
28 : :
29 : : using namespace isc::nsas;
30 : : using namespace isc::dns;
31 : : using namespace std;
32 : : using namespace MessageUtility;
33 : :
34 : 39 : MessageCache::MessageCache(const RRsetCachePtr& rrset_cache,
35 : : uint32_t cache_size, uint16_t message_class,
36 : : const RRsetCachePtr& negative_soa_cache):
37 : : message_class_(message_class),
38 : : rrset_cache_(rrset_cache),
39 : : negative_soa_cache_(negative_soa_cache),
40 : : message_table_(new NsasEntryCompare<MessageEntry>, cache_size),
41 : : message_lru_((3 * cache_size),
42 [ + - ][ + - ]: 39 : new HashDeleter<MessageEntry>(message_table_))
[ + - ]
43 : : {
44 [ + - ][ + - ]: 78 : LOG_DEBUG(logger, DBG_TRACE_BASIC, CACHE_MESSAGES_INIT).arg(cache_size).
[ + - ][ + - ]
[ + - ]
45 [ + - ]: 39 : arg(RRClass(message_class));
46 : 39 : }
47 : :
48 [ + - ][ + - ]: 39 : MessageCache::~MessageCache() {
49 : : // Destroy all the message entries in the cache.
50 [ + - ]: 39 : message_lru_.clear();
51 [ + - ][ + - ]: 39 : LOG_DEBUG(logger, DBG_TRACE_BASIC, CACHE_MESSAGES_DEINIT);
[ + - ][ + - ]
52 : 75 : }
53 : :
54 : : bool
55 : 28 : MessageCache::lookup(const isc::dns::Name& qname,
56 : : const isc::dns::RRType& qtype,
57 : : isc::dns::Message& response)
58 : : {
59 : 56 : std::string entry_name = genCacheEntryName(qname, qtype);
60 : 28 : HashKey entry_key = HashKey(entry_name, RRClass(message_class_));
61 : 28 : MessageEntryPtr msg_entry = message_table_.get(entry_key);
62 [ + + ]: 28 : if(msg_entry) {
63 : : // Check whether the message entry has expired.
64 [ + + ]: 19 : if (msg_entry->getExpireTime() > time(NULL)) {
65 [ + - ][ + - ]: 36 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_FOUND).
[ + - ]
66 [ + - ][ + - ]: 18 : arg(entry_name);
67 [ + - ]: 18 : message_lru_.touch(msg_entry);
68 [ + - ]: 18 : return (msg_entry->genMessage(time(NULL), response));
69 : : } else {
70 : : // message entry expires, remove it from hash table and lru list.
71 [ + - ][ + - ]: 2 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_EXPIRED).
[ + - ]
72 [ + - ][ + - ]: 1 : arg(entry_name);
73 [ + - ]: 1 : message_table_.remove(entry_key);
74 [ + - ]: 1 : message_lru_.remove(msg_entry);
75 : : return (false);
76 : : }
77 : : }
78 : :
79 [ + - ][ + - ]: 9 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_UNKNOWN).arg(entry_name);
[ + - ][ + - ]
[ + - ]
80 : : return (false);
81 : : }
82 : :
83 : : bool
84 : 25 : MessageCache::update(const Message& msg) {
85 [ + + ]: 25 : if (!canMessageBeCached(msg)){
86 [ + - ][ + - ]: 2 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_UNCACHEABLE).
87 [ + - ][ + - ]: 2 : arg((*msg.beginQuestion())->getName()).
[ + - ][ + - ]
[ + - ]
88 [ + - ][ + - ]: 3 : arg((*msg.beginQuestion())->getType()).
[ + - ][ + - ]
89 [ + - ][ + - ]: 3 : arg((*msg.beginQuestion())->getClass());
90 : : return (false);
91 : : }
92 : :
93 : 49 : QuestionIterator iter = msg.beginQuestion();
94 [ + - ][ + - ]: 48 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_UPDATE).
[ + - ]
95 [ + - ][ + - ]: 24 : arg((*iter)->getName()).arg((*iter)->getType()).
[ + - ][ + - ]
[ + - ]
96 [ + - ][ + - ]: 48 : arg((*iter)->getClass());
97 [ + - ]: 24 : std::string entry_name = genCacheEntryName((*iter)->getName(),
98 [ + - ][ + - ]: 72 : (*iter)->getType());
99 : 24 : HashKey entry_key = HashKey(entry_name, RRClass(message_class_));
100 : :
101 : : // The simplest way to update is removing the old message entry directly.
102 : : // We have find the existed message entry, since we need to delete it
103 : : // from lru list too.
104 : : // TODO, but there should be a better way, since we here have to remove and
105 : : // add the message entry, maybe there is one way to touch it once.
106 : 24 : MessageEntryPtr old_msg_entry = message_table_.get(entry_key);
107 [ + + ]: 24 : if (old_msg_entry) {
108 [ + - ][ + - ]: 8 : LOG_DEBUG(logger, DBG_TRACE_DATA, CACHE_MESSAGES_REMOVE).
[ + - ]
109 [ + - ][ + - ]: 4 : arg((*iter)->getName()).arg((*iter)->getType()).
[ + - ][ + - ]
[ + - ]
110 [ + - ][ + - ]: 8 : arg((*iter)->getClass());
111 [ + - ]: 4 : message_lru_.remove(old_msg_entry);
112 : : }
113 : :
114 : : MessageEntryPtr msg_entry(new MessageEntry(msg, rrset_cache_,
115 [ + - ][ + - ]: 24 : negative_soa_cache_));
[ + - ]
116 [ + - ]: 24 : message_lru_.add(msg_entry);
117 : 48 : return (message_table_.add(msg_entry, entry_key, true));
118 : : }
119 : :
120 : : } // namespace cache
121 : 3 : } // namespace isc
122 : :
|