]>
Commit | Line | Data |
---|---|---|
886e2cf2 RG |
1 | #define BOOST_TEST_DYN_LINK |
2 | #define BOOST_TEST_NO_MAIN | |
3 | ||
4 | #include <boost/test/unit_test.hpp> | |
5 | ||
1ea747c0 | 6 | #include "dnsdist.hh" |
886e2cf2 | 7 | #include "iputils.hh" |
886e2cf2 | 8 | #include "dnswriter.hh" |
1ea747c0 | 9 | #include "dnsdist-cache.hh" |
886e2cf2 RG |
10 | |
11 | BOOST_AUTO_TEST_SUITE(dnsdistpacketcache_cc) | |
12 | ||
13 | BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { | |
14 | const size_t maxEntries = 150000; | |
15 | DNSDistPacketCache PC(maxEntries, 86400, 1); | |
16 | BOOST_CHECK_EQUAL(PC.getSize(), 0); | |
17 | ||
18 | size_t counter=0; | |
19 | size_t skipped=0; | |
1ea747c0 | 20 | ComboAddress remote; |
886e2cf2 RG |
21 | try { |
22 | for(counter = 0; counter < 100000; ++counter) { | |
490dc586 | 23 | DNSName a=DNSName(std::to_string(counter))+DNSName(" hello"); |
886e2cf2 RG |
24 | BOOST_CHECK_EQUAL(DNSName(a.toString()), a); |
25 | ||
26 | vector<uint8_t> query; | |
27 | DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); | |
28 | pwQ.getHeader()->rd = 1; | |
29 | ||
30 | vector<uint8_t> response; | |
31 | DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); | |
32 | pwR.getHeader()->rd = 1; | |
33 | pwR.getHeader()->ra = 1; | |
34 | pwR.getHeader()->qr = 1; | |
35 | pwR.getHeader()->id = pwQ.getHeader()->id; | |
36 | pwR.startRecord(a, QType::A, 100, QClass::IN, DNSResourceRecord::ANSWER); | |
37 | pwR.xfr32BitInt(0x01020304); | |
38 | pwR.commit(); | |
39 | uint16_t responseLen = response.size(); | |
40 | ||
41 | char responseBuf[4096]; | |
42 | uint16_t responseBufSize = sizeof(responseBuf); | |
43 | uint32_t key = 0; | |
1ea747c0 RG |
44 | DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false); |
45 | bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key); | |
886e2cf2 RG |
46 | BOOST_CHECK_EQUAL(found, false); |
47 | ||
2714396e | 48 | PC.insert(key, a, QType::A, QClass::IN, (const char*) response.data(), responseLen, false, 0); |
886e2cf2 | 49 | |
1ea747c0 | 50 | found = PC.get(dq, a.wirelength(), pwR.getHeader()->id, responseBuf, &responseBufSize, &key, 0, true); |
886e2cf2 RG |
51 | if (found == true) { |
52 | BOOST_CHECK_EQUAL(responseBufSize, responseLen); | |
53 | int match = memcmp(responseBuf, response.data(), responseLen); | |
54 | BOOST_CHECK_EQUAL(match, 0); | |
55 | } | |
56 | else { | |
57 | skipped++; | |
58 | } | |
59 | } | |
60 | ||
61 | BOOST_CHECK_EQUAL(skipped, PC.getInsertCollisions()); | |
62 | BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped); | |
63 | ||
64 | size_t deleted=0; | |
65 | size_t delcounter=0; | |
66 | for(delcounter=0; delcounter < counter/1000; ++delcounter) { | |
490dc586 | 67 | DNSName a=DNSName(std::to_string(delcounter))+DNSName(" hello"); |
886e2cf2 RG |
68 | vector<uint8_t> query; |
69 | DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); | |
70 | pwQ.getHeader()->rd = 1; | |
71 | char responseBuf[4096]; | |
72 | uint16_t responseBufSize = sizeof(responseBuf); | |
73 | uint32_t key = 0; | |
1ea747c0 RG |
74 | DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false); |
75 | bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key); | |
886e2cf2 | 76 | if (found == true) { |
4275aaba | 77 | PC.expungeByName(a); |
886e2cf2 RG |
78 | deleted++; |
79 | } | |
80 | } | |
81 | BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped - deleted); | |
82 | ||
490dc586 | 83 | |
886e2cf2 RG |
84 | size_t matches=0; |
85 | vector<DNSResourceRecord> entry; | |
86 | size_t expected=counter-skipped-deleted; | |
87 | for(; delcounter < counter; ++delcounter) { | |
490dc586 | 88 | DNSName a(DNSName(std::to_string(delcounter))+DNSName(" hello")); |
886e2cf2 RG |
89 | vector<uint8_t> query; |
90 | DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); | |
91 | pwQ.getHeader()->rd = 1; | |
92 | uint16_t len = query.size(); | |
93 | uint32_t key = 0; | |
94 | char response[4096]; | |
95 | uint16_t responseSize = sizeof(response); | |
1ea747c0 RG |
96 | DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), len, query.size(), false); |
97 | if(PC.get(dq, a.wirelength(), pwQ.getHeader()->id, response, &responseSize, &key)) { | |
490dc586 | 98 | matches++; |
886e2cf2 RG |
99 | } |
100 | } | |
101 | BOOST_CHECK_EQUAL(matches, expected); | |
490dc586 RG |
102 | |
103 | PC.expungeByName(DNSName(" hello"), QType::ANY, true); | |
104 | BOOST_CHECK_EQUAL(PC.getSize(), 0); | |
886e2cf2 RG |
105 | } |
106 | catch(PDNSException& e) { | |
107 | cerr<<"Had error: "<<e.reason<<endl; | |
108 | throw; | |
109 | } | |
110 | } | |
111 | ||
112 | static DNSDistPacketCache PC(500000); | |
113 | ||
af619119 | 114 | static void *threadMangler(void* off) |
886e2cf2 RG |
115 | { |
116 | try { | |
1ea747c0 | 117 | ComboAddress remote; |
af619119 | 118 | unsigned int offset=(unsigned int)(unsigned long)off; |
886e2cf2 RG |
119 | for(unsigned int counter=0; counter < 100000; ++counter) { |
120 | DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset)); | |
121 | vector<uint8_t> query; | |
122 | DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); | |
123 | pwQ.getHeader()->rd = 1; | |
124 | ||
125 | vector<uint8_t> response; | |
126 | DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); | |
127 | pwR.getHeader()->rd = 1; | |
128 | pwR.getHeader()->ra = 1; | |
129 | pwR.getHeader()->qr = 1; | |
130 | pwR.getHeader()->id = pwQ.getHeader()->id; | |
131 | pwR.startRecord(a, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER); | |
132 | pwR.xfr32BitInt(0x01020304); | |
133 | pwR.commit(); | |
134 | uint16_t responseLen = response.size(); | |
135 | ||
136 | char responseBuf[4096]; | |
137 | uint16_t responseBufSize = sizeof(responseBuf); | |
138 | uint32_t key = 0; | |
1ea747c0 RG |
139 | DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false); |
140 | PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key); | |
886e2cf2 | 141 | |
2714396e | 142 | PC.insert(key, a, QType::A, QClass::IN, (const char*) response.data(), responseLen, false, 0); |
886e2cf2 RG |
143 | } |
144 | } | |
145 | catch(PDNSException& e) { | |
146 | cerr<<"Had error: "<<e.reason<<endl; | |
147 | throw; | |
148 | } | |
149 | return 0; | |
150 | } | |
151 | ||
152 | AtomicCounter g_missing; | |
153 | ||
af619119 | 154 | static void *threadReader(void* off) |
886e2cf2 RG |
155 | { |
156 | try | |
157 | { | |
af619119 | 158 | unsigned int offset=(unsigned int)(unsigned long)off; |
886e2cf2 | 159 | vector<DNSResourceRecord> entry; |
1ea747c0 | 160 | ComboAddress remote; |
886e2cf2 RG |
161 | for(unsigned int counter=0; counter < 100000; ++counter) { |
162 | DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset)); | |
163 | vector<uint8_t> query; | |
164 | DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); | |
165 | pwQ.getHeader()->rd = 1; | |
166 | ||
167 | char responseBuf[4096]; | |
168 | uint16_t responseBufSize = sizeof(responseBuf); | |
169 | uint32_t key = 0; | |
1ea747c0 RG |
170 | DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false); |
171 | bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key); | |
886e2cf2 RG |
172 | if (!found) { |
173 | g_missing++; | |
174 | } | |
175 | } | |
176 | } | |
177 | catch(PDNSException& e) { | |
178 | cerr<<"Had error in threadReader: "<<e.reason<<endl; | |
179 | throw; | |
180 | } | |
181 | return 0; | |
182 | } | |
183 | ||
184 | BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) { | |
185 | try { | |
186 | pthread_t tid[4]; | |
187 | for(int i=0; i < 4; ++i) | |
188 | pthread_create(&tid[i], 0, threadMangler, (void*)(i*1000000UL)); | |
189 | void* res; | |
190 | for(int i=0; i < 4 ; ++i) | |
191 | pthread_join(tid[i], &res); | |
192 | ||
193 | BOOST_CHECK_EQUAL(PC.getSize() + PC.getDeferredInserts() + PC.getInsertCollisions(), 400000); | |
194 | BOOST_CHECK_SMALL(1.0*PC.getInsertCollisions(), 10000.0); | |
195 | ||
196 | for(int i=0; i < 4; ++i) | |
197 | pthread_create(&tid[i], 0, threadReader, (void*)(i*1000000UL)); | |
198 | for(int i=0; i < 4 ; ++i) | |
199 | pthread_join(tid[i], &res); | |
200 | ||
201 | BOOST_CHECK((PC.getDeferredInserts() + PC.getDeferredLookups() + PC.getInsertCollisions()) >= g_missing); | |
202 | } | |
203 | catch(PDNSException& e) { | |
204 | cerr<<"Had error: "<<e.reason<<endl; | |
205 | throw; | |
206 | } | |
207 | ||
208 | } | |
209 | ||
210 | BOOST_AUTO_TEST_SUITE_END() |