]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/nsecrecords.cc
poll events are bitmasks, not values
[thirdparty/pdns.git] / pdns / nsecrecords.cc
CommitLineData
12471842
PL
1/*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
e64fccad
BH
25#include "dnsrecords.hh"
26
27d4a65b 27class NSECBitmapGenerator
e64fccad 28{
27d4a65b
RG
29public:
30 NSECBitmapGenerator(DNSPacketWriter& pw_): pw(pw_)
31 {
e64fccad 32 }
27d4a65b
RG
33 void set(uint16_t type)
34 {
35 uint16_t bit = type % 256;
36 int window = static_cast<int>(type / 256);
e64fccad 37
5b7f6546
PD
38 if (window != oldWindow) {
39 if (oldWindow > -1) {
27d4a65b
RG
40 res[0] = static_cast<unsigned char>(oldWindow);
41 res[1] = static_cast<unsigned char>(len);
42 tmp.assign(res, res+len+2);
43 pw.xfrBlob(tmp);
5b7f6546
PD
44 }
45 memset(res, 0, 34);
46 oldWindow = window;
47 }
48 res[2+bit/8] |= 1 << (7-(bit%8));
49 len=1+bit/8;
50 }
51
27d4a65b
RG
52 void finish()
53 {
54 res[0] = static_cast<unsigned char>(oldWindow);
55 res[1] = static_cast<unsigned char>(len);
56 if (len) {
57 tmp.assign(res, res+len+2);
58 pw.xfrBlob(tmp);
59 }
60 }
61
62private:
63 DNSPacketWriter& pw;
64 /* one byte for the window,
65 one for the length,
66 then the maximum of 32 bytes */
67 uint8_t res[34];
68 int oldWindow{-1};
69 int len{0};
70 string tmp;
71};
72
73void NSECBitmap::toPacket(DNSPacketWriter& pw)
74{
75 NSECBitmapGenerator nbg(pw);
76 if (d_bitset) {
77 size_t count = d_bitset->count();
78 size_t found = 0;
9f607f21 79 for(size_t idx = 0; idx < nbTypes && found < count; ++idx){
27d4a65b
RG
80 if (!d_bitset->test(idx)) {
81 continue;
82 }
83 found++;
84 nbg.set(idx);
85 }
86 }
87 else {
88 for (const auto& type : d_set) {
89 nbg.set(type);
90 }
91 }
92
93 nbg.finish();
e64fccad
BH
94}
95
27d4a65b 96void NSECBitmap::fromPacket(PacketReader& pr)
e64fccad 97{
e64fccad
BH
98 string bitmap;
99 pr.xfrBlob(bitmap);
27d4a65b 100
e64fccad 101 // 00 06 20 00 00 00 00 03 -> NS RRSIG NSEC ( 2, 46, 47 ) counts from left
27d4a65b
RG
102 if(bitmap.empty()) {
103 return;
104 }
5b7f6546 105
27d4a65b 106 if(bitmap.size() < 2) {
e64fccad 107 throw MOADNSException("NSEC record with impossibly small bitmap");
27d4a65b 108 }
e64fccad 109
5b7f6546
PD
110 for(unsigned int n = 0; n+1 < bitmap.size();) {
111 unsigned int window=static_cast<unsigned char>(bitmap[n++]);
dd079764 112 unsigned int blen=static_cast<unsigned char>(bitmap[n++]);
5b7f6546
PD
113
114 // end if zero padding and ensure packet length
27d4a65b
RG
115 if(window == 0 && blen == 0) {
116 break;
117 }
118
119 if(n + blen > bitmap.size()) {
5b7f6546 120 throw MOADNSException("NSEC record with bitmap length > packet length");
27d4a65b 121 }
5b7f6546 122
dd079764 123 for(unsigned int k=0; k < blen; k++) {
5b7f6546 124 uint8_t val=bitmap[n++];
27d4a65b 125 for(int bit = 0; bit < 8 ; ++bit , val>>=1) {
dd079764 126 if(val & 1) {
27d4a65b 127 set((7-bit) + 8*(k) + 256*window);
5b7f6546 128 }
e64fccad 129 }
27d4a65b
RG
130 }
131 }
132}
133
134string NSECBitmap::getZoneRepresentation() const
135{
136 string ret;
137
138 if (d_bitset) {
139 size_t count = d_bitset->count();
140 size_t found = 0;
9f607f21 141 for(size_t idx = 0; idx < nbTypes && found < count; ++idx) {
27d4a65b
RG
142 if (!d_bitset->test(idx)) {
143 continue;
144 }
145 found++;
146
147 ret+=" ";
148 ret+=DNSRecordContent::NumberToType(idx);
149 }
150 }
151 else {
152 for(const auto& type : d_set) {
153 ret+=" ";
154 ret+=DNSRecordContent::NumberToType(type);
155 }
156 }
157
158 return ret;
159}
160
161void NSECRecordContent::report(void)
162{
163 regist(1, 47, &make, &make, "NSEC");
164}
165
166std::shared_ptr<DNSRecordContent> NSECRecordContent::make(const string& content)
167{
168 return std::make_shared<NSECRecordContent>(content);
169}
170
171NSECRecordContent::NSECRecordContent(const string& content, const string& zone)
172{
173 RecordTextReader rtr(content, DNSName(zone));
174 rtr.xfrName(d_next);
175
176 while(!rtr.eof()) {
177 uint16_t type;
178 rtr.xfrType(type);
179 set(type);
e64fccad 180 }
27d4a65b
RG
181}
182
183void NSECRecordContent::toPacket(DNSPacketWriter& pw)
184{
185 pw.xfrName(d_next);
186 d_bitmap.toPacket(pw);
187}
188
189std::shared_ptr<NSECRecordContent::DNSRecordContent> NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr)
190{
191 auto ret=std::make_shared<NSECRecordContent>();
192 pr.xfrName(ret->d_next);
193
194 ret->d_bitmap.fromPacket(pr);
195
e64fccad
BH
196 return ret;
197}
198
f21fc0aa 199string NSECRecordContent::getZoneRepresentation(bool noDot) const
e64fccad
BH
200{
201 string ret;
202 RecordTextWriter rtw(ret);
ad8fa726 203 rtw.xfrName(d_next);
27d4a65b
RG
204
205 return ret + d_bitmap.getZoneRepresentation();
e64fccad
BH
206}
207
208////// begin of NSEC3
209
210void NSEC3RecordContent::report(void)
211{
212 regist(1, 50, &make, &make, "NSEC3");
213}
214
32122aab 215std::shared_ptr<DNSRecordContent> NSEC3RecordContent::make(const string& content)
e64fccad 216{
32122aab 217 return std::make_shared<NSEC3RecordContent>(content);
e64fccad
BH
218}
219
5a1f298f 220NSEC3RecordContent::NSEC3RecordContent(const string& content, const string& zone)
e64fccad 221{
3716f081 222 RecordTextReader rtr(content, DNSName(zone));
e64fccad
BH
223 rtr.xfr8BitInt(d_algorithm);
224 rtr.xfr8BitInt(d_flags);
225 rtr.xfr16BitInt(d_iterations);
226
227 rtr.xfrHexBlob(d_salt);
8b606f6e
BH
228 rtr.xfrBase32HexBlob(d_nexthash);
229
e64fccad
BH
230 while(!rtr.eof()) {
231 uint16_t type;
232 rtr.xfrType(type);
27d4a65b 233 set(type);
e64fccad
BH
234 }
235}
236
237void NSEC3RecordContent::toPacket(DNSPacketWriter& pw)
238{
239 pw.xfr8BitInt(d_algorithm);
240 pw.xfr8BitInt(d_flags);
241 pw.xfr16BitInt(d_iterations);
242 pw.xfr8BitInt(d_salt.length());
243 pw.xfrBlob(d_salt);
244
245 pw.xfr8BitInt(d_nexthash.length());
246 pw.xfrBlob(d_nexthash);
e64fccad 247
27d4a65b 248 d_bitmap.toPacket(pw);
e64fccad
BH
249}
250
32122aab 251std::shared_ptr<NSEC3RecordContent::DNSRecordContent> NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr)
e64fccad 252{
32122aab 253 auto ret=std::make_shared<NSEC3RecordContent>();
e64fccad
BH
254 pr.xfr8BitInt(ret->d_algorithm);
255 pr.xfr8BitInt(ret->d_flags);
256 pr.xfr16BitInt(ret->d_iterations);
257 uint8_t len;
258 pr.xfr8BitInt(len);
259 pr.xfrBlob(ret->d_salt, len);
260
261 pr.xfr8BitInt(len);
262 pr.xfrBlob(ret->d_nexthash, len);
5b7f6546 263
27d4a65b 264 ret->d_bitmap.fromPacket(pr);
e64fccad
BH
265 return ret;
266}
267
f21fc0aa 268string NSEC3RecordContent::getZoneRepresentation(bool noDot) const
e64fccad
BH
269{
270 string ret;
271 RecordTextWriter rtw(ret);
272 rtw.xfr8BitInt(d_algorithm);
273 rtw.xfr8BitInt(d_flags);
274 rtw.xfr16BitInt(d_iterations);
275
276 rtw.xfrHexBlob(d_salt);
1c4d88c5 277 rtw.xfrBase32HexBlob(d_nexthash);
27d4a65b
RG
278
279 return ret + d_bitmap.getZoneRepresentation();
e64fccad
BH
280}
281
282
827634f0
BH
283void NSEC3PARAMRecordContent::report(void)
284{
285 regist(1, 51, &make, &make, "NSEC3PARAM");
dff32e09 286 regist(254, 51, &make, &make, "NSEC3PARAM");
827634f0
BH
287}
288
32122aab 289std::shared_ptr<DNSRecordContent> NSEC3PARAMRecordContent::make(const string& content)
827634f0 290{
32122aab 291 return std::make_shared<NSEC3PARAMRecordContent>(content);
827634f0
BH
292}
293
5a1f298f 294NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const string& zone)
827634f0 295{
3716f081 296 RecordTextReader rtr(content, DNSName(zone));
827634f0 297 rtr.xfr8BitInt(d_algorithm);
8b606f6e
BH
298 rtr.xfr8BitInt(d_flags);
299 rtr.xfr16BitInt(d_iterations);
827634f0
BH
300 rtr.xfrHexBlob(d_salt);
301}
302
303void NSEC3PARAMRecordContent::toPacket(DNSPacketWriter& pw)
304{
305 pw.xfr8BitInt(d_algorithm);
232f0877
CH
306 pw.xfr8BitInt(d_flags);
307 pw.xfr16BitInt(d_iterations);
827634f0 308 pw.xfr8BitInt(d_salt.length());
c68cc098 309 // cerr<<"salt: '"<<makeHexDump(d_salt)<<"', "<<d_salt.length()<<endl;
827634f0
BH
310 pw.xfrBlob(d_salt);
311}
312
32122aab 313std::shared_ptr<NSEC3PARAMRecordContent::DNSRecordContent> NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
827634f0 314{
32122aab 315 auto ret=std::make_shared<NSEC3PARAMRecordContent>();
827634f0 316 pr.xfr8BitInt(ret->d_algorithm);
232f0877
CH
317 pr.xfr8BitInt(ret->d_flags);
318 pr.xfr16BitInt(ret->d_iterations);
a82f68f0
RG
319 uint8_t len;
320 pr.xfr8BitInt(len);
321 pr.xfrHexBlob(ret->d_salt, len);
827634f0
BH
322 return ret;
323}
324
f21fc0aa 325string NSEC3PARAMRecordContent::getZoneRepresentation(bool noDot) const
827634f0
BH
326{
327 string ret;
328 RecordTextWriter rtw(ret);
329 rtw.xfr8BitInt(d_algorithm);
232f0877
CH
330 rtw.xfr8BitInt(d_flags);
331 rtw.xfr16BitInt(d_iterations);
827634f0
BH
332 rtw.xfrHexBlob(d_salt);
333 return ret;
334}
335