]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdistdist/test-dnsdistrules_cc.cc
a402864068bb8e7b6e8b698b950cc5ad66b67db0
[thirdparty/pdns.git] / pdns / dnsdistdist / test-dnsdistrules_cc.cc
1
2 #define BOOST_TEST_DYN_LINK
3 #define BOOST_TEST_NO_MAIN
4
5 #include <thread>
6 #include <boost/test/unit_test.hpp>
7
8 #include "dnsdist-rules.hh"
9
10 BOOST_AUTO_TEST_SUITE(dnsdistluarules_cc)
11
12 BOOST_AUTO_TEST_CASE(test_MaxQPSIPRule) {
13 size_t maxQPS = 10;
14 size_t maxBurst = maxQPS;
15 unsigned int expiration = 300;
16 unsigned int cleanupDelay = 60;
17 unsigned int scanFraction = 10;
18 MaxQPSIPRule rule(maxQPS, maxBurst, 32, 64, expiration, cleanupDelay, scanFraction);
19
20 DNSName qname("powerdns.com.");
21 uint16_t qtype = QType::A;
22 uint16_t qclass = QClass::IN;
23 ComboAddress lc("127.0.0.1:53");
24 ComboAddress rem("192.0.2.1:42");
25 struct dnsheader* dh = nullptr;
26 size_t bufferSize = 0;
27 size_t queryLen = 0;
28 bool isTcp = false;
29 struct timespec queryRealTime;
30 gettime(&queryRealTime, true);
31 struct timespec expiredTime;
32 /* the internal QPS limiter does not use the real time */
33 gettime(&expiredTime);
34
35 DNSQuestion dq(&qname, qtype, qclass, qname.wirelength(), &lc, &rem, dh, bufferSize, queryLen, isTcp, &queryRealTime);
36
37 for (size_t idx = 0; idx < maxQPS; idx++) {
38 /* let's use different source ports, it shouldn't matter */
39 rem = ComboAddress("192.0.2.1:" + std::to_string(idx));
40 BOOST_CHECK_EQUAL(rule.matches(&dq), false);
41 BOOST_CHECK_EQUAL(rule.getEntriesCount(), 1);
42 }
43
44 /* maxQPS + 1, we should be blocked */
45 BOOST_CHECK_EQUAL(rule.matches(&dq), true);
46 BOOST_CHECK_EQUAL(rule.getEntriesCount(), 1);
47
48 expiredTime.tv_sec += 1;
49 rule.cleanup(expiredTime);
50
51 /* we should have been cleaned up */
52 BOOST_CHECK_EQUAL(rule.getEntriesCount(), 0);
53
54 /* we should not be blocked anymore */
55 BOOST_CHECK_EQUAL(rule.matches(&dq), false);
56 /* and we be back */
57 BOOST_CHECK_EQUAL(rule.getEntriesCount(), 1);
58
59
60 /* Let's insert a lot of different sources now */
61 struct timespec insertionTime;
62 gettime(&insertionTime);
63 for (size_t idxByte3 = 0; idxByte3 < 256; idxByte3++) {
64 for (size_t idxByte4 = 0; idxByte4 < 256; idxByte4++) {
65 rem = ComboAddress("10.0." + std::to_string(idxByte3) + "." + std::to_string(idxByte4));
66 BOOST_CHECK_EQUAL(rule.matches(&dq), false);
67 }
68 }
69
70 /* don't forget the existing entry */
71 size_t total = 1 + 256 * 256;
72 BOOST_CHECK_EQUAL(rule.getEntriesCount(), total);
73
74 /* make sure all entries are still valid */
75 struct timespec notExpiredTime = insertionTime;
76 notExpiredTime.tv_sec -= 1;
77
78 size_t scanned = 0;
79 auto removed = rule.cleanup(notExpiredTime, &scanned);
80 BOOST_CHECK_EQUAL(removed, 0);
81 /* the first entry should still have been valid, we should not have scanned more */
82 BOOST_CHECK_EQUAL(scanned, 1);
83 BOOST_CHECK_EQUAL(rule.getEntriesCount(), total);
84
85 /* make sure all entries are _not_ valid anymore */
86 expiredTime = insertionTime;
87 expiredTime.tv_sec += 1;
88
89 removed = rule.cleanup(expiredTime, &scanned);
90 BOOST_CHECK_EQUAL(removed, (total / scanFraction) + 1);
91 /* we should not have scanned more than scanFraction */
92 BOOST_CHECK_EQUAL(scanned, removed);
93 BOOST_CHECK_EQUAL(rule.getEntriesCount(), total - removed);
94
95 rule.clear();
96 BOOST_CHECK_EQUAL(rule.getEntriesCount(), 0);
97 removed = rule.cleanup(expiredTime, &scanned);
98 BOOST_CHECK_EQUAL(removed, 0);
99 BOOST_CHECK_EQUAL(scanned, 0);
100 }
101
102
103 BOOST_AUTO_TEST_SUITE_END()