message_entry_unittest.cc 13.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <config.h>
#include <string>
#include <gtest/gtest.h>
#include <dns/tests/unittest_util.h>
#include <dns/message.h>
18
#include <util/buffer.h>
19 20
#include "../message_entry.h"
#include "../rrset_cache.h"
zhanglikun's avatar
zhanglikun committed
21
#include "../resolver_cache.h"
Jelte Jansen's avatar
Jelte Jansen committed
22 23
#include "cache_test_messagefromfile.h"
#include "cache_test_sectioncount.h"
24 25 26 27 28 29

using namespace isc::cache;
using namespace isc;
using namespace isc::dns;
using namespace std;

30
static uint32_t MAX_UINT32 = numeric_limits<uint32_t>::max();
31 32 33 34 35 36 37 38

namespace {

/// \brief Derived from base class to make it easy to test
/// its internals.
class DerivedMessageEntry: public MessageEntry {
public:
    DerivedMessageEntry(const isc::dns::Message& message,
39 40
                        const RRsetCachePtr& rrset_cache_,
                        const RRsetCachePtr& negative_soa_cache_):
41
             MessageEntry(message, rrset_cache_, negative_soa_cache_)
42 43
    {}

44
    /// \brief Wrap the protected function so that it can be tested.
45
    void parseSectionForTest(const Message& msg,
46
                           const Message::Section& section,
47
                           uint32_t& smaller_ttl,
48 49
                           uint16_t& rrset_count)
    {
50
        parseSection(msg, section, smaller_ttl, rrset_count);
51 52 53 54 55 56 57 58 59
    }

    RRsetTrustLevel getRRsetTrustLevelForTest(const Message& message,
                                              const RRsetPtr rrset,
                                              const Message::Section& section) 
    {
        return getRRsetTrustLevel(message, rrset, section);
    }

60 61 62 63 64 65 66 67
    bool getRRsetEntriesForTest(vector<RRsetEntryPtr> vec, time_t now) {
        return getRRsetEntries(vec, now);
    }

    time_t getExpireTime() {
        return expire_time_;
    }

68 69 70 71 72 73 74 75 76
};

class MessageEntryTest: public testing::Test {
public:
    MessageEntryTest(): class_(1),
                        message_parse(Message::PARSE),
                        message_render(Message::RENDER)
    {
        rrset_cache_.reset(new RRsetCache(RRSET_CACHE_DEFAULT_SIZE, class_));
77
        negative_soa_cache_.reset(new RRsetCache(NEGATIVE_RRSET_CACHE_DEFAULT_SIZE, class_));
78 79 80 81 82
    }

protected:
    uint16_t class_;
    RRsetCachePtr rrset_cache_;
83
    RRsetCachePtr negative_soa_cache_;
84 85 86 87 88 89
    Message message_parse;
    Message message_render;
};

TEST_F(MessageEntryTest, testParseRRset) {
    messageFromFile(message_parse, "message_fromWire3");
90
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
91 92
    uint32_t ttl = MAX_UINT32;
    uint16_t rrset_count = 0;
93
    message_entry.parseSectionForTest(message_parse, Message::SECTION_ANSWER, ttl, rrset_count);
94 95 96 97
    EXPECT_EQ(ttl, 21600);
    EXPECT_EQ(rrset_count, 1);

    ttl = MAX_UINT32;
98
    message_entry.parseSectionForTest(message_parse, Message::SECTION_AUTHORITY, ttl, rrset_count);
99 100 101 102
    EXPECT_EQ(ttl, 21600);
    EXPECT_EQ(rrset_count, 1);

    ttl = MAX_UINT32;
103
    message_entry.parseSectionForTest(message_parse, Message::SECTION_ADDITIONAL, ttl, rrset_count);
104 105 106 107 108 109
    EXPECT_EQ(ttl, 10800);
    EXPECT_EQ(rrset_count, 5);
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_AA) {
    messageFromFile(message_parse, "message_fromWire3");
110
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);

    rrset_iter = message_parse.beginSection(Message::SECTION_AUTHORITY);
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_AUTHORITY);
    EXPECT_EQ(level, RRSET_TRUST_AUTHORITY_AA);

    rrset_iter = message_parse.beginSection(Message::SECTION_ADDITIONAL);
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_ADDITIONAL);
    EXPECT_EQ(level, RRSET_TRUST_ADDITIONAL_AA);
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_NONAA) {
    messageFromFile(message_parse, "message_fromWire4");
133
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_NONAA);

    rrset_iter = message_parse.beginSection(Message::SECTION_AUTHORITY);
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_AUTHORITY);
    EXPECT_EQ(level, RRSET_TRUST_AUTHORITY_NONAA);

    rrset_iter = message_parse.beginSection(Message::SECTION_ADDITIONAL);
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_ADDITIONAL);
    EXPECT_EQ(level, RRSET_TRUST_ADDITIONAL_NONAA);
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_CNAME) {
    messageFromFile(message_parse, "message_fromWire5");
155
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
156 157 158 159 160 161 162 163 164 165
    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);

    ++rrset_iter; // Get the rrset after the first cname rrset.
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_ANSWER);
166 167 168 169 170
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_NONAA);
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_CNAME_and_DNAME) {
    messageFromFile(message_parse, "message_fromWire7");
171
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);
    // All the left rrset are non-authoritative
    ++rrset_iter;
    while (rrset_iter != message_parse.endSection(Message::SECTION_ANSWER)) {
        level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                        *rrset_iter,
                                                        Message::SECTION_ANSWER);
        ++rrset_iter;
        EXPECT_EQ(level, RRSET_TRUST_ANSWER_NONAA);
    }
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_DNAME_and_CNAME) {
    messageFromFile(message_parse, "message_fromWire8");
190
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
191 192 193 194 195
    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    // Test the deepest DNAME
196
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);
197 198 199 200 201 202
    ++rrset_iter;
    // Test the synchronized CNAME
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                        *rrset_iter,
                                                        Message::SECTION_ANSWER);
    ++rrset_iter;
203
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);
204 205 206 207 208 209 210 211 212 213

    ++rrset_iter;
    // All the left rrset are non-authoritative
    while (rrset_iter != message_parse.endSection(Message::SECTION_ANSWER)) {
        level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                        *rrset_iter,
                                                        Message::SECTION_ANSWER);
        ++rrset_iter;
        EXPECT_EQ(level, RRSET_TRUST_ANSWER_NONAA);
    }
214 215 216 217
}

TEST_F(MessageEntryTest, testGetRRsetTrustLevel_DNAME) {
    messageFromFile(message_parse, "message_fromWire6");
218
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    RRsetIterator rrset_iter = message_parse.beginSection(Message::SECTION_ANSWER);
    RRsetTrustLevel level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                                    *rrset_iter,
                                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);

    ++rrset_iter; // Get the rrset after the first dname rrset.
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_ANSWER);
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_AA);

    ++rrset_iter; // Get the second cname rrset
    level = message_entry.getRRsetTrustLevelForTest(message_parse,
                                                    *rrset_iter,
                                                    Message::SECTION_ANSWER);
235
    EXPECT_EQ(level, RRSET_TRUST_ANSWER_NONAA);
236 237
}

238 239 240
// We only test the expire_time of the message entry.
// The test for genMessage() will make sure whether InitMessageEntry()
// is right
241 242
TEST_F(MessageEntryTest, testInitMessageEntry) {
    messageFromFile(message_parse, "message_fromWire3");
243
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
244 245 246 247 248 249 250
    time_t expire_time = message_entry.getExpireTime();
    // 1 second should be enough to do the compare
    EXPECT_TRUE((time(NULL) + 10801) > expire_time);
}

TEST_F(MessageEntryTest, testGetRRsetEntries) {
    messageFromFile(message_parse, "message_fromWire3");
251
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
252
    vector<RRsetEntryPtr> vec;
253 254

    // the time is bigger than the smallest expire time of
255 256 257
    // the rrset in message.
    time_t expire_time = time(NULL) + 10802;
    EXPECT_FALSE(message_entry.getRRsetEntriesForTest(vec, expire_time));
258 259
}

260 261
TEST_F(MessageEntryTest, testGenMessage) {
    messageFromFile(message_parse, "message_fromWire3");
262
    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);
263
    time_t expire_time = message_entry.getExpireTime();
264

265 266 267 268
    Message msg(Message::RENDER);
    EXPECT_FALSE(message_entry.genMessage(expire_time + 2, msg));
    message_entry.genMessage(time(NULL), msg);
    // Check whether the generated message is same with cached one.
269
    EXPECT_FALSE(msg.getHeaderFlag(Message::HEADERFLAG_AA));
270
    EXPECT_FALSE(msg.getHeaderFlag(Message::HEADERFLAG_TC));
271 272 273
    EXPECT_EQ(1, sectionRRsetCount(msg, Message::SECTION_ANSWER));
    EXPECT_EQ(1, sectionRRsetCount(msg, Message::SECTION_AUTHORITY));
    EXPECT_EQ(5, sectionRRsetCount(msg, Message::SECTION_ADDITIONAL));
274 275 276 277 278 279

    // Check the rrset in answer section.
    EXPECT_EQ(1, msg.getRRCount(Message::SECTION_ANSWER));
    EXPECT_EQ(5, msg.getRRCount(Message::SECTION_AUTHORITY));
    EXPECT_EQ(7, msg.getRRCount(Message::SECTION_ADDITIONAL));
}
280

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
TEST_F(MessageEntryTest, testMaxTTL) {
    messageFromFile(message_parse, "message_large_ttl.wire");

    // The ttl of rrset from Answer and Authority sections are both 604801 seconds
    RRsetIterator iter = message_parse.beginSection(Message::SECTION_ANSWER);
    EXPECT_EQ(604801, (*iter)->getTTL().getValue());
    iter = message_parse.beginSection(Message::SECTION_AUTHORITY);
    EXPECT_EQ(604801, (*iter)->getTTL().getValue());

    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);

    // The ttl is limited to 604800 seconds (7days)
    EXPECT_EQ(time(NULL) + 604800, message_entry.getExpireTime());
}

TEST_F(MessageEntryTest, testMaxNegativeTTL) {
    messageFromFile(message_parse, "message_nxdomain_large_ttl.wire");

    // The ttl of rrset Authority sections are 10801 seconds
    RRsetIterator iter = message_parse.beginSection(Message::SECTION_AUTHORITY);
    EXPECT_EQ(10801, (*iter)->getTTL().getValue());

    DerivedMessageEntry message_entry(message_parse, rrset_cache_, negative_soa_cache_);

    // The ttl is limited to 10800 seconds (3 hours)
    EXPECT_EQ(time(NULL) + 10800, message_entry.getExpireTime());
}

309
}   // namespace