]>
Commit | Line | Data |
---|---|---|
4192ca66 | 1 | /* |
12471842 PL |
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 | */ | |
a0a276c2 BH |
22 | #ifndef PDNS_DNSRECORDS_HH |
23 | #define PDNS_DNSRECORDS_HH | |
24 | ||
8900e2e3 CHB |
25 | #ifdef HAVE_CONFIG_H |
26 | #include "config.h" | |
27 | #endif | |
28 | ||
a0a276c2 BH |
29 | #include "dnsparser.hh" |
30 | #include "dnswriter.hh" | |
cbf0e7f3 | 31 | #include "rcpgenerator.hh" |
8c1c9170 | 32 | #include <set> |
51083cab | 33 | #include <bitset> |
61b26744 | 34 | #include "namespaces.hh" |
f4352636 | 35 | #include "iputils.hh" |
a0a276c2 | 36 | |
2770fad0 BH |
37 | #define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \ |
38 | RNAME##RecordContent(const string& zoneData); \ | |
39 | static void report(void); \ | |
ee1ada80 | 40 | static void unreport(void); \ |
32122aab RG |
41 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); \ |
42 | static std::shared_ptr<DNSRecordContent> make(const string& zonedata); \ | |
f21fc0aa | 43 | string getZoneRepresentation(bool noDot=false) const override; \ |
2cca142e | 44 | void toPacket(DNSPacketWriter& pw) override; \ |
5a1f298f | 45 | uint16_t getType() const override { return QType::RNAME; } \ |
f21fc0aa | 46 | template<class Convertor> void xfrPacket(Convertor& conv, bool noDot=false); |
a0a276c2 BH |
47 | |
48 | class NAPTRRecordContent : public DNSRecordContent | |
49 | { | |
50 | public: | |
4a51ff72 | 51 | NAPTRRecordContent(uint16_t order, uint16_t preference, string flags, string services, string regexp, DNSName replacement); |
a0a276c2 | 52 | |
1d1d688a | 53 | includeboilerplate(NAPTR) |
cbf0e7f3 | 54 | template<class Convertor> void xfrRecordContent(Convertor& conv); |
a0a276c2 BH |
55 | private: |
56 | uint16_t d_order, d_preference; | |
4a51ff72 PD |
57 | string d_flags, d_services, d_regexp; |
58 | DNSName d_replacement; | |
a0a276c2 BH |
59 | }; |
60 | ||
2770fad0 | 61 | |
a0a276c2 BH |
62 | class ARecordContent : public DNSRecordContent |
63 | { | |
64 | public: | |
447e0cff | 65 | explicit ARecordContent(const ComboAddress& ca); |
efb265e3 | 66 | explicit ARecordContent(uint32_t ip); |
1d1d688a | 67 | includeboilerplate(A) |
2770fad0 | 68 | void doRecordCheck(const DNSRecord& dr); |
447e0cff | 69 | ComboAddress getCA(int port=0) const; |
f18e430f | 70 | bool operator==(const DNSRecordContent& rhs) const override |
71 | { | |
72 | if(typeid(*this) != typeid(rhs)) | |
73 | return false; | |
74 | return d_ip == dynamic_cast<const ARecordContent&>(rhs).d_ip; | |
75 | } | |
2770fad0 BH |
76 | private: |
77 | uint32_t d_ip; | |
78 | }; | |
a0a276c2 | 79 | |
fc465b41 AT |
80 | class AAAARecordContent : public DNSRecordContent |
81 | { | |
82 | public: | |
83 | AAAARecordContent(std::string &val); | |
447e0cff | 84 | explicit AAAARecordContent(const ComboAddress& ca); |
1d1d688a | 85 | includeboilerplate(AAAA) |
447e0cff | 86 | ComboAddress getCA(int port=0) const; |
f18e430f | 87 | bool operator==(const DNSRecordContent& rhs) const override |
88 | { | |
89 | if(typeid(*this) != typeid(rhs)) | |
90 | return false; | |
91 | return d_ip6 == dynamic_cast<const decltype(this)>(&rhs)->d_ip6; | |
92 | } | |
fc465b41 | 93 | private: |
447e0cff | 94 | string d_ip6; // why?? |
fc465b41 AT |
95 | }; |
96 | ||
2770fad0 BH |
97 | class MXRecordContent : public DNSRecordContent |
98 | { | |
99 | public: | |
89735451 | 100 | MXRecordContent(uint16_t preference, const DNSName& mxname); |
a0a276c2 | 101 | |
2770fad0 | 102 | includeboilerplate(MX) |
a0a276c2 | 103 | |
2770fad0 | 104 | uint16_t d_preference; |
89735451 | 105 | DNSName d_mxname; |
f18e430f | 106 | |
107 | bool operator==(const DNSRecordContent& rhs) const override | |
108 | { | |
109 | if(typeid(*this) != typeid(rhs)) | |
110 | return false; | |
111 | auto rrhs =dynamic_cast<const decltype(this)>(&rhs); | |
112 | return std::tie(d_preference, d_mxname) == std::tie(rrhs->d_preference, rrhs->d_mxname); | |
113 | } | |
114 | ||
2770fad0 BH |
115 | }; |
116 | ||
9fd71f2e BH |
117 | class KXRecordContent : public DNSRecordContent |
118 | { | |
119 | public: | |
89735451 | 120 | KXRecordContent(uint16_t preference, const DNSName& exchanger); |
9fd71f2e BH |
121 | |
122 | includeboilerplate(KX) | |
123 | ||
124 | private: | |
125 | uint16_t d_preference; | |
89735451 | 126 | DNSName d_exchanger; |
9fd71f2e BH |
127 | }; |
128 | ||
129 | class IPSECKEYRecordContent : public DNSRecordContent | |
130 | { | |
131 | public: | |
c2f3be9d | 132 | IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const string& publickey); |
9fd71f2e BH |
133 | |
134 | includeboilerplate(IPSECKEY) | |
135 | ||
136 | private: | |
d0793109 | 137 | uint32_t d_ip4; |
c2f3be9d PD |
138 | DNSName d_gateway; |
139 | string d_publickey; | |
1cafb958 | 140 | string d_ip6; |
adc18742 | 141 | uint8_t d_preference, d_gatewaytype, d_algorithm; |
9fd71f2e BH |
142 | }; |
143 | ||
144 | class DHCIDRecordContent : public DNSRecordContent | |
145 | { | |
146 | public: | |
147 | includeboilerplate(DHCID) | |
148 | ||
149 | private: | |
150 | string d_content; | |
151 | }; | |
152 | ||
153 | ||
2770fad0 BH |
154 | class SRVRecordContent : public DNSRecordContent |
155 | { | |
156 | public: | |
89735451 | 157 | SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const DNSName& target); |
2770fad0 BH |
158 | |
159 | includeboilerplate(SRV) | |
160 | ||
a2d7c36a | 161 | uint16_t d_weight, d_port; |
89735451 | 162 | DNSName d_target; |
a2d7c36a | 163 | uint16_t d_preference; |
2770fad0 BH |
164 | }; |
165 | ||
06ffdc52 BH |
166 | class TSIGRecordContent : public DNSRecordContent |
167 | { | |
168 | public: | |
169 | includeboilerplate(TSIG) | |
5a1f298f | 170 | TSIGRecordContent() {} |
06ffdc52 | 171 | |
34c513f9 RG |
172 | uint16_t d_origID{0}; |
173 | uint16_t d_fudge{0}; | |
c3a81a30 | 174 | |
0b6fa0eb | 175 | DNSName d_algoName; |
483d2f10 PL |
176 | string d_mac; |
177 | string d_otherData; | |
34c513f9 | 178 | uint64_t d_time{0}; |
06ffdc52 | 179 | // uint16_t d_macSize; |
34c513f9 | 180 | uint16_t d_eRcode{0}; |
06ffdc52 | 181 | // uint16_t d_otherLen |
06ffdc52 BH |
182 | }; |
183 | ||
2770fad0 BH |
184 | |
185 | class TXTRecordContent : public DNSRecordContent | |
186 | { | |
187 | public: | |
188 | includeboilerplate(TXT) | |
189 | ||
2770fad0 | 190 | string d_text; |
a0a276c2 BH |
191 | }; |
192 | ||
8900e2e3 | 193 | #ifdef HAVE_LUA_RECORDS |
6b547a53 | 194 | class LUARecordContent : public DNSRecordContent |
195 | { | |
196 | public: | |
197 | includeboilerplate(LUA) | |
98fa3598 | 198 | string getCode() const; |
5dbd408c | 199 | uint16_t d_type; |
6b547a53 | 200 | string d_code; |
201 | }; | |
8900e2e3 | 202 | #endif |
6b547a53 | 203 | |
acedb99e | 204 | class ENTRecordContent : public DNSRecordContent |
205 | { | |
206 | public: | |
207 | includeboilerplate(ENT) | |
208 | }; | |
209 | ||
8c1c9170 BH |
210 | class SPFRecordContent : public DNSRecordContent |
211 | { | |
212 | public: | |
213 | includeboilerplate(SPF) | |
0bd2e252 RG |
214 | const std::string& getText() const |
215 | { | |
216 | return d_text; | |
217 | } | |
8c1c9170 BH |
218 | |
219 | private: | |
220 | string d_text; | |
221 | }; | |
222 | ||
223 | ||
cbf0e7f3 BH |
224 | class NSRecordContent : public DNSRecordContent |
225 | { | |
226 | public: | |
227 | includeboilerplate(NS) | |
5a1f298f | 228 | explicit NSRecordContent(const DNSName& content) : d_content(content){} |
f18e430f | 229 | const DNSName& getNS() const { return d_content; } |
230 | bool operator==(const DNSRecordContent& rhs) const override | |
231 | { | |
232 | if(typeid(*this) != typeid(rhs)) | |
233 | return false; | |
234 | auto rrhs =dynamic_cast<const decltype(this)>(&rhs); | |
235 | return d_content == rrhs->d_content; | |
236 | } | |
237 | ||
cbf0e7f3 | 238 | private: |
89735451 | 239 | DNSName d_content; |
cbf0e7f3 BH |
240 | }; |
241 | ||
242 | class PTRRecordContent : public DNSRecordContent | |
243 | { | |
244 | public: | |
245 | includeboilerplate(PTR) | |
98cda0a9 | 246 | explicit PTRRecordContent(const DNSName& content) : d_content(content){} |
0bd2e252 | 247 | const DNSName& getContent() const { return d_content; } |
cbf0e7f3 | 248 | private: |
89735451 | 249 | DNSName d_content; |
cbf0e7f3 BH |
250 | }; |
251 | ||
252 | class CNAMERecordContent : public DNSRecordContent | |
253 | { | |
254 | public: | |
255 | includeboilerplate(CNAME) | |
90ba52e0 | 256 | CNAMERecordContent(const DNSName& content) : d_content(content){} |
447e0cff | 257 | DNSName getTarget() const { return d_content; } |
cbf0e7f3 | 258 | private: |
89735451 | 259 | DNSName d_content; |
cbf0e7f3 BH |
260 | }; |
261 | ||
d59b894d | 262 | class ALIASRecordContent : public DNSRecordContent |
263 | { | |
264 | public: | |
265 | includeboilerplate(ALIAS) | |
266 | ||
89735451 | 267 | DNSName d_content; |
d59b894d | 268 | }; |
269 | ||
270 | ||
8dee0750 | 271 | class DNAMERecordContent : public DNSRecordContent |
272 | { | |
273 | public: | |
274 | includeboilerplate(DNAME) | |
c3491dd6 | 275 | DNAMERecordContent(const DNSName& content) : d_content(content){} |
dc0d34db | 276 | const DNSName& getTarget() const { return d_content; } |
c3491dd6 | 277 | private: |
89735451 | 278 | DNSName d_content; |
8dee0750 | 279 | }; |
280 | ||
281 | ||
fa552262 CHB |
282 | class MBRecordContent : public DNSRecordContent |
283 | { | |
284 | public: | |
285 | includeboilerplate(MB) | |
286 | ||
287 | private: | |
288 | DNSName d_madname; | |
289 | }; | |
290 | ||
291 | class MGRecordContent : public DNSRecordContent | |
292 | { | |
293 | public: | |
294 | includeboilerplate(MG) | |
295 | ||
296 | private: | |
297 | DNSName d_mgmname; | |
298 | }; | |
299 | ||
4e0805a6 BH |
300 | class MRRecordContent : public DNSRecordContent |
301 | { | |
302 | public: | |
303 | includeboilerplate(MR) | |
304 | ||
305 | private: | |
89735451 | 306 | DNSName d_alias; |
4e0805a6 BH |
307 | }; |
308 | ||
7c0b8593 | 309 | class MINFORecordContent : public DNSRecordContent |
310 | { | |
311 | public: | |
312 | includeboilerplate(MINFO) | |
313 | ||
314 | private: | |
89735451 PD |
315 | DNSName d_rmailbx; |
316 | DNSName d_emailbx; | |
7c0b8593 | 317 | }; |
cbf0e7f3 | 318 | |
878435ce BH |
319 | class OPTRecordContent : public DNSRecordContent |
320 | { | |
321 | public: | |
c541004c | 322 | OPTRecordContent(){} |
878435ce | 323 | includeboilerplate(OPT) |
7f7b8d55 | 324 | void getData(vector<pair<uint16_t, string> > &opts); |
878435ce BH |
325 | private: |
326 | string d_data; | |
327 | }; | |
328 | ||
329 | ||
cbf0e7f3 BH |
330 | class HINFORecordContent : public DNSRecordContent |
331 | { | |
332 | public: | |
333 | includeboilerplate(HINFO) | |
334 | ||
335 | private: | |
336 | string d_cpu, d_host; | |
337 | }; | |
338 | ||
339 | class RPRecordContent : public DNSRecordContent | |
340 | { | |
341 | public: | |
342 | includeboilerplate(RP) | |
343 | ||
344 | private: | |
89735451 | 345 | DNSName d_mbox, d_info; |
cbf0e7f3 BH |
346 | }; |
347 | ||
348 | ||
8c1c9170 BH |
349 | class DNSKEYRecordContent : public DNSRecordContent |
350 | { | |
351 | public: | |
1c4d88c5 | 352 | DNSKEYRecordContent(); |
8c1c9170 | 353 | includeboilerplate(DNSKEY) |
523c312b | 354 | uint16_t getTag() const; |
354ccf4e | 355 | uint16_t getTag(); |
8c1c9170 | 356 | |
34c513f9 RG |
357 | uint16_t d_flags{0}; |
358 | uint8_t d_protocol{0}; | |
359 | uint8_t d_algorithm{0}; | |
8c1c9170 | 360 | string d_key; |
523c312b | 361 | bool operator<(const DNSKEYRecordContent& rhs) const |
362 | { | |
363 | return tie(d_flags, d_protocol, d_algorithm, d_key) < | |
364 | tie(rhs.d_flags, rhs.d_protocol, rhs.d_algorithm, rhs.d_key); | |
365 | } | |
8c1c9170 BH |
366 | }; |
367 | ||
882de365 PL |
368 | class CDNSKEYRecordContent : public DNSRecordContent |
369 | { | |
370 | public: | |
371 | CDNSKEYRecordContent(); | |
372 | includeboilerplate(CDNSKEY) | |
373 | uint16_t getTag(); | |
374 | ||
34c513f9 RG |
375 | uint16_t d_flags{0}; |
376 | uint8_t d_protocol{0}; | |
377 | uint8_t d_algorithm{0}; | |
882de365 PL |
378 | string d_key; |
379 | }; | |
380 | ||
8c1c9170 BH |
381 | class DSRecordContent : public DNSRecordContent |
382 | { | |
383 | public: | |
1c4d88c5 | 384 | DSRecordContent(); |
0b062478 | 385 | bool operator==(const DNSRecordContent& rhs) const override |
a820bc34 | 386 | { |
0b062478 RG |
387 | if(typeid(*this) != typeid(rhs)) |
388 | return false; | |
389 | auto rrhs =dynamic_cast<const decltype(this)>(&rhs); | |
a820bc34 | 390 | return tie(d_tag, d_algorithm, d_digesttype, d_digest) == |
0b062478 | 391 | tie(rrhs->d_tag, rrhs->d_algorithm, rrhs->d_digesttype, rrhs->d_digest); |
a820bc34 | 392 | } |
393 | bool operator<(const DSRecordContent& rhs) const | |
394 | { | |
395 | return tie(d_tag, d_algorithm, d_digesttype, d_digest) < | |
396 | tie(rhs.d_tag, rhs.d_algorithm, rhs.d_digesttype, rhs.d_digest); | |
397 | } | |
398 | ||
8c1c9170 BH |
399 | includeboilerplate(DS) |
400 | ||
34c513f9 RG |
401 | uint16_t d_tag{0}; |
402 | uint8_t d_algorithm{0}, d_digesttype{0}; | |
8c1c9170 BH |
403 | string d_digest; |
404 | }; | |
405 | ||
882de365 PL |
406 | class CDSRecordContent : public DNSRecordContent |
407 | { | |
408 | public: | |
409 | CDSRecordContent(); | |
410 | includeboilerplate(CDS) | |
411 | ||
34c513f9 RG |
412 | uint16_t d_tag{0}; |
413 | uint8_t d_algorithm{0}, d_digesttype{0}; | |
882de365 PL |
414 | string d_digest; |
415 | }; | |
416 | ||
0b55f2f5 BH |
417 | class DLVRecordContent : public DNSRecordContent |
418 | { | |
419 | public: | |
420 | DLVRecordContent(); | |
421 | includeboilerplate(DLV) | |
422 | ||
34c513f9 RG |
423 | uint16_t d_tag{0}; |
424 | uint8_t d_algorithm{0}, d_digesttype{0}; | |
0b55f2f5 BH |
425 | string d_digest; |
426 | }; | |
427 | ||
428 | ||
a40a693b BH |
429 | class SSHFPRecordContent : public DNSRecordContent |
430 | { | |
431 | public: | |
432 | includeboilerplate(SSHFP) | |
433 | ||
434 | private: | |
435 | uint8_t d_algorithm, d_fptype; | |
436 | string d_fingerprint; | |
437 | }; | |
8c1c9170 | 438 | |
4b5762f1 BH |
439 | class KEYRecordContent : public DNSRecordContent |
440 | { | |
441 | public: | |
442 | includeboilerplate(KEY) | |
443 | ||
444 | private: | |
445 | uint16_t d_flags; | |
446 | uint8_t d_protocol, d_algorithm; | |
447 | string d_certificate; | |
448 | }; | |
449 | ||
37f47031 BH |
450 | class AFSDBRecordContent : public DNSRecordContent |
451 | { | |
452 | public: | |
453 | includeboilerplate(AFSDB) | |
454 | ||
455 | private: | |
456 | uint16_t d_subtype; | |
89735451 | 457 | DNSName d_hostname; |
37f47031 BH |
458 | }; |
459 | ||
460 | ||
2475a4fc BH |
461 | class CERTRecordContent : public DNSRecordContent |
462 | { | |
463 | public: | |
464 | includeboilerplate(CERT) | |
465 | ||
466 | private: | |
467 | uint16_t d_type, d_tag; | |
2475a4fc | 468 | string d_certificate; |
1e56bb82 | 469 | uint8_t d_algorithm; |
2475a4fc BH |
470 | }; |
471 | ||
07dbe87e BH |
472 | class TLSARecordContent : public DNSRecordContent |
473 | { | |
474 | public: | |
475 | includeboilerplate(TLSA) | |
476 | ||
477 | private: | |
f5a09796 | 478 | uint8_t d_certusage, d_selector, d_matchtype; |
07dbe87e BH |
479 | string d_cert; |
480 | }; | |
481 | ||
291935bb PL |
482 | class SMIMEARecordContent : public DNSRecordContent |
483 | { | |
484 | public: | |
485 | includeboilerplate(SMIMEA) | |
486 | ||
487 | private: | |
488 | uint8_t d_certusage, d_selector, d_matchtype; | |
489 | string d_cert; | |
490 | }; | |
491 | ||
68066337 JC |
492 | class OPENPGPKEYRecordContent : public DNSRecordContent |
493 | { | |
494 | public: | |
495 | includeboilerplate(OPENPGPKEY) | |
496 | ||
497 | private: | |
3fd06ce5 | 498 | string d_keyring; |
68066337 JC |
499 | }; |
500 | ||
07dbe87e | 501 | |
8c1c9170 BH |
502 | class RRSIGRecordContent : public DNSRecordContent |
503 | { | |
504 | public: | |
1c4d88c5 | 505 | RRSIGRecordContent(); |
8c1c9170 BH |
506 | includeboilerplate(RRSIG) |
507 | ||
34c513f9 RG |
508 | uint16_t d_type{0}; |
509 | uint16_t d_tag{0}; | |
89735451 PD |
510 | DNSName d_signer; |
511 | string d_signature; | |
34c513f9 RG |
512 | uint32_t d_originalttl{0}, d_sigexpire{0}, d_siginception{0}; |
513 | uint8_t d_algorithm{0}, d_labels{0}; | |
8c1c9170 BH |
514 | }; |
515 | ||
5ac6a3a3 | 516 | //namespace { |
2770fad0 BH |
517 | struct soatimes |
518 | { | |
519 | uint32_t serial; | |
520 | uint32_t refresh; | |
521 | uint32_t retry; | |
522 | uint32_t expire; | |
523 | uint32_t minimum; | |
524 | }; | |
5ac6a3a3 | 525 | //} |
2770fad0 | 526 | |
3150a49c | 527 | class RKEYRecordContent : public DNSRecordContent |
528 | { | |
529 | public: | |
530 | RKEYRecordContent(); | |
531 | includeboilerplate(RKEY) | |
34c513f9 RG |
532 | uint16_t d_flags{0}; |
533 | uint8_t d_protocol{0}, d_algorithm{0}; | |
3150a49c | 534 | string d_key; |
535 | }; | |
2770fad0 BH |
536 | |
537 | class SOARecordContent : public DNSRecordContent | |
538 | { | |
539 | public: | |
540 | includeboilerplate(SOA) | |
89735451 | 541 | SOARecordContent(const DNSName& mname, const DNSName& rname, const struct soatimes& st); |
2770fad0 | 542 | |
89735451 PD |
543 | DNSName d_mname; |
544 | DNSName d_rname; | |
1c21ab45 | 545 | struct soatimes d_st; |
2770fad0 | 546 | }; |
a0a276c2 | 547 | |
27d4a65b RG |
548 | class NSECBitmap |
549 | { | |
550 | public: | |
22a0ef16 RG |
551 | NSECBitmap(): d_bitset(nullptr) |
552 | { | |
553 | } | |
554 | NSECBitmap(const NSECBitmap& rhs): d_set(rhs.d_set) | |
555 | { | |
556 | if (rhs.d_bitset) { | |
557 | d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset))); | |
558 | } | |
559 | } | |
560 | NSECBitmap& operator=(const NSECBitmap& rhs) | |
561 | { | |
562 | d_set = rhs.d_set; | |
563 | ||
564 | if (rhs.d_bitset) { | |
565 | d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset))); | |
566 | } | |
567 | ||
568 | return *this; | |
569 | } | |
570 | NSECBitmap(NSECBitmap&& rhs): d_bitset(std::move(rhs.d_bitset)), d_set(std::move(rhs.d_set)) | |
571 | { | |
572 | } | |
27d4a65b RG |
573 | bool isSet(uint16_t type) const |
574 | { | |
575 | if (d_bitset) { | |
576 | return d_bitset->test(type); | |
577 | } | |
578 | return d_set.count(type); | |
579 | } | |
580 | void set(uint16_t type) | |
581 | { | |
582 | if (!d_bitset) { | |
583 | if (d_set.size() >= 200) { | |
584 | migrateToBitSet(); | |
585 | } | |
586 | } | |
587 | if (d_bitset) { | |
588 | d_bitset->set(type); | |
589 | } | |
590 | else { | |
591 | d_set.insert(type); | |
592 | } | |
593 | } | |
594 | size_t count() const | |
595 | { | |
596 | if (d_bitset) { | |
597 | return d_bitset->count(); | |
598 | } | |
599 | else { | |
600 | return d_set.size(); | |
601 | } | |
602 | } | |
603 | ||
604 | void fromPacket(PacketReader& pr); | |
605 | void toPacket(DNSPacketWriter& pw); | |
606 | std::string getZoneRepresentation() const; | |
607 | ||
9f607f21 RG |
608 | static constexpr size_t const nbTypes = 65536; |
609 | ||
27d4a65b | 610 | private: |
9f607f21 | 611 | |
27d4a65b RG |
612 | void migrateToBitSet() |
613 | { | |
9f607f21 | 614 | d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>()); |
27d4a65b RG |
615 | for (const auto& type : d_set) { |
616 | d_bitset->set(type); | |
617 | } | |
618 | d_set.clear(); | |
619 | } | |
620 | /* using a dynamic set is very efficient for a small number of | |
621 | types covered (~200), but uses a lot of memory (up to 3MB) | |
622 | when there are a lot of them. | |
623 | So we start with the set, but allocate and switch to a bitset | |
624 | if the number of covered types increases a lot */ | |
9f607f21 | 625 | std::unique_ptr<std::bitset<nbTypes>> d_bitset; |
27d4a65b RG |
626 | std::set<uint16_t> d_set; |
627 | }; | |
628 | ||
20133c59 BH |
629 | class NSECRecordContent : public DNSRecordContent |
630 | { | |
631 | public: | |
632 | static void report(void); | |
5a1f298f | 633 | NSECRecordContent() |
20133c59 | 634 | {} |
3343ad1f | 635 | NSECRecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone? |
20133c59 | 636 | |
32122aab RG |
637 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
638 | static std::shared_ptr<DNSRecordContent> make(const string& content); | |
f21fc0aa | 639 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 640 | void toPacket(DNSPacketWriter& pw) override; |
5a1f298f | 641 | uint16_t getType() const override |
642 | { | |
643 | return QType::NSEC; | |
644 | } | |
27d4a65b RG |
645 | bool isSet(uint16_t type) const |
646 | { | |
647 | return d_bitmap.isSet(type); | |
648 | } | |
649 | void set(uint16_t type) | |
650 | { | |
651 | d_bitmap.set(type); | |
652 | } | |
22a0ef16 RG |
653 | void set(const NSECBitmap& bitmap) |
654 | { | |
655 | d_bitmap = bitmap; | |
656 | } | |
27d4a65b RG |
657 | size_t numberOfTypesSet() const |
658 | { | |
659 | return d_bitmap.count(); | |
660 | } | |
661 | ||
89735451 | 662 | DNSName d_next; |
20133c59 | 663 | private: |
27d4a65b | 664 | NSECBitmap d_bitmap; |
20133c59 BH |
665 | }; |
666 | ||
1c4d88c5 BH |
667 | class NSEC3RecordContent : public DNSRecordContent |
668 | { | |
669 | public: | |
670 | static void report(void); | |
2cca142e | 671 | NSEC3RecordContent() |
1c4d88c5 | 672 | {} |
3343ad1f | 673 | NSEC3RecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone? |
1c4d88c5 | 674 | |
32122aab RG |
675 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
676 | static std::shared_ptr<DNSRecordContent> make(const string& content); | |
f21fc0aa | 677 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 678 | void toPacket(DNSPacketWriter& pw) override; |
1c4d88c5 | 679 | |
34c513f9 RG |
680 | uint8_t d_algorithm{0}, d_flags{0}; |
681 | uint16_t d_iterations{0}; | |
1c4d88c5 | 682 | string d_salt; |
1c4d88c5 | 683 | string d_nexthash; |
1c4d88c5 | 684 | |
5a1f298f | 685 | uint16_t getType() const override |
686 | { | |
687 | return QType::NSEC3; | |
688 | } | |
27d4a65b RG |
689 | bool isSet(uint16_t type) const |
690 | { | |
691 | return d_bitmap.isSet(type); | |
692 | } | |
693 | void set(uint16_t type) | |
694 | { | |
695 | d_bitmap.set(type); | |
696 | } | |
22a0ef16 RG |
697 | void set(const NSECBitmap& bitmap) |
698 | { | |
699 | d_bitmap = bitmap; | |
700 | } | |
27d4a65b RG |
701 | size_t numberOfTypesSet() const |
702 | { | |
703 | return d_bitmap.count(); | |
704 | } | |
5a1f298f | 705 | |
1c4d88c5 | 706 | private: |
27d4a65b | 707 | NSECBitmap d_bitmap; |
1c4d88c5 BH |
708 | }; |
709 | ||
710 | ||
711 | class NSEC3PARAMRecordContent : public DNSRecordContent | |
712 | { | |
713 | public: | |
827634f0 | 714 | static void report(void); |
5a1f298f | 715 | NSEC3PARAMRecordContent() |
827634f0 | 716 | {} |
3343ad1f | 717 | NSEC3PARAMRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone? |
827634f0 | 718 | |
32122aab RG |
719 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
720 | static std::shared_ptr<DNSRecordContent> make(const string& content); | |
f21fc0aa | 721 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 722 | void toPacket(DNSPacketWriter& pw) override; |
827634f0 | 723 | |
5a1f298f | 724 | uint16_t getType() const override |
725 | { | |
726 | return QType::NSEC3PARAM; | |
727 | } | |
728 | ||
1c4d88c5 | 729 | |
34c513f9 RG |
730 | uint8_t d_algorithm{0}, d_flags{0}; |
731 | uint16_t d_iterations{0}; | |
1c4d88c5 BH |
732 | string d_salt; |
733 | }; | |
734 | ||
735 | ||
c6a60874 BH |
736 | class LOCRecordContent : public DNSRecordContent |
737 | { | |
738 | public: | |
739 | static void report(void); | |
2cca142e | 740 | LOCRecordContent() |
c6a60874 BH |
741 | {} |
742 | LOCRecordContent(const string& content, const string& zone=""); | |
20133c59 | 743 | |
32122aab RG |
744 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
745 | static std::shared_ptr<DNSRecordContent> make(const string& content); | |
f21fc0aa | 746 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 747 | void toPacket(DNSPacketWriter& pw) override; |
c6a60874 | 748 | |
34c513f9 RG |
749 | uint8_t d_version{0}, d_size{0}, d_horizpre{0}, d_vertpre{0}; |
750 | uint32_t d_latitude{0}, d_longitude{0}, d_altitude{0}; | |
5a1f298f | 751 | uint16_t getType() const override |
752 | { | |
753 | return QType::LOC; | |
754 | } | |
755 | ||
c6a60874 BH |
756 | private: |
757 | }; | |
8c1c9170 | 758 | |
66a07c55 AT |
759 | class EUI48RecordContent : public DNSRecordContent |
760 | { | |
761 | public: | |
5a1f298f | 762 | EUI48RecordContent() {}; |
66a07c55 | 763 | static void report(void); |
32122aab RG |
764 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
765 | static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone? | |
f21fc0aa | 766 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 767 | void toPacket(DNSPacketWriter& pw) override; |
5a1f298f | 768 | uint16_t getType() const override { return QType::EUI48; } |
66a07c55 AT |
769 | private: |
770 | // storage for the bytes | |
771 | uint8_t d_eui48[6]; | |
772 | }; | |
773 | ||
774 | class EUI64RecordContent : public DNSRecordContent | |
775 | { | |
776 | public: | |
5a1f298f | 777 | EUI64RecordContent() {}; |
66a07c55 | 778 | static void report(void); |
32122aab RG |
779 | static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); |
780 | static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone? | |
f21fc0aa | 781 | string getZoneRepresentation(bool noDot=false) const override; |
2cca142e | 782 | void toPacket(DNSPacketWriter& pw) override; |
5a1f298f | 783 | uint16_t getType() const override { return QType::EUI64; } |
66a07c55 AT |
784 | private: |
785 | // storage for the bytes | |
786 | uint8_t d_eui64[8]; | |
787 | }; | |
d34d3e01 | 788 | |
b3ac6324 AT |
789 | class TKEYRecordContent : public DNSRecordContent |
790 | { | |
791 | public: | |
792 | TKEYRecordContent(); | |
793 | includeboilerplate(TKEY) | |
794 | ||
795 | // storage for the bytes | |
34c513f9 RG |
796 | uint16_t d_othersize{0}; |
797 | uint16_t d_mode{0}; | |
798 | uint32_t d_inception{0}; | |
799 | uint32_t d_expiration{0}; | |
adc18742 | 800 | |
0b6fa0eb | 801 | DNSName d_algo; |
b3ac6324 | 802 | string d_key; |
b3ac6324 | 803 | string d_other; |
adc18742 | 804 | |
34c513f9 RG |
805 | uint16_t d_error{0}; |
806 | uint16_t d_keysize{0}; | |
b3ac6324 AT |
807 | private: |
808 | }; | |
809 | ||
20966479 PL |
810 | class URIRecordContent : public DNSRecordContent { |
811 | public: | |
812 | includeboilerplate(URI) | |
813 | private: | |
fa38400f | 814 | uint16_t d_priority, d_weight; |
20966479 PL |
815 | string d_target; |
816 | }; | |
817 | ||
f75f6821 PL |
818 | class CAARecordContent : public DNSRecordContent { |
819 | public: | |
820 | includeboilerplate(CAA) | |
821 | private: | |
822 | uint8_t d_flags; | |
823 | string d_tag, d_value; | |
824 | }; | |
825 | ||
8c1c9170 | 826 | #define boilerplate(RNAME, RTYPE) \ |
32122aab | 827 | std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \ |
8c1c9170 | 828 | { \ |
32122aab | 829 | return std::make_shared<RNAME##RecordContent>(dr, pr); \ |
8c1c9170 BH |
830 | } \ |
831 | \ | |
5a1f298f | 832 | RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr) \ |
8c1c9170 BH |
833 | { \ |
834 | doRecordCheck(dr); \ | |
835 | xfrPacket(pr); \ | |
836 | } \ | |
837 | \ | |
32122aab | 838 | std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const string& zonedata) \ |
8c1c9170 | 839 | { \ |
32122aab | 840 | return std::make_shared<RNAME##RecordContent>(zonedata); \ |
8c1c9170 BH |
841 | } \ |
842 | \ | |
843 | void RNAME##RecordContent::toPacket(DNSPacketWriter& pw) \ | |
844 | { \ | |
845 | this->xfrPacket(pw); \ | |
846 | } \ | |
847 | \ | |
848 | void RNAME##RecordContent::report(void) \ | |
849 | { \ | |
250d1fd8 | 850 | regist(1, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \ |
d6f3feee | 851 | regist(254, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \ |
ee1ada80 BH |
852 | } \ |
853 | void RNAME##RecordContent::unreport(void) \ | |
854 | { \ | |
855 | unregist(1, RTYPE); \ | |
d6f3feee | 856 | unregist(254, RTYPE); \ |
8c1c9170 BH |
857 | } \ |
858 | \ | |
5a1f298f | 859 | RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) \ |
8c1c9170 | 860 | { \ |
aab4adb0 BH |
861 | try { \ |
862 | RecordTextReader rtr(zoneData); \ | |
863 | xfrPacket(rtr); \ | |
864 | } \ | |
81bb680e JS |
865 | catch(RecordTextException& rte) { \ |
866 | throw MOADNSException("Parsing record content (try 'pdnsutil check-zone'): "+string(rte.what())); \ | |
1649b6ef | 867 | } \ |
8c1c9170 BH |
868 | } \ |
869 | \ | |
f21fc0aa | 870 | string RNAME##RecordContent::getZoneRepresentation(bool noDot) const \ |
8c1c9170 BH |
871 | { \ |
872 | string ret; \ | |
f21fc0aa | 873 | RecordTextWriter rtw(ret, noDot); \ |
8c1c9170 BH |
874 | const_cast<RNAME##RecordContent*>(this)->xfrPacket(rtw); \ |
875 | return ret; \ | |
876 | } | |
877 | ||
878 | ||
879 | #define boilerplate_conv(RNAME, TYPE, CONV) \ | |
880 | boilerplate(RNAME, TYPE) \ | |
881 | template<class Convertor> \ | |
f21fc0aa | 882 | void RNAME##RecordContent::xfrPacket(Convertor& conv, bool noDot) \ |
8c1c9170 BH |
883 | { \ |
884 | CONV; \ | |
ddb79bca | 885 | if (conv.eof() == false) throw MOADNSException("When parsing " #RNAME " trailing data was not parsed: '" + conv.getRemaining() + "'"); \ |
8c1c9170 BH |
886 | } \ |
887 | ||
7f7b8d55 BH |
888 | struct EDNSOpts |
889 | { | |
5ca95d47 PL |
890 | enum zFlags { DNSSECOK=32768 }; |
891 | vector<pair<uint16_t, string> > d_options; | |
447e0cff | 892 | uint16_t d_packetsize{0}; |
d6c335ab | 893 | uint16_t d_extFlags{0}; |
5ca95d47 | 894 | uint8_t d_extRCode, d_version; |
7f7b8d55 BH |
895 | }; |
896 | //! Convenience function that fills out EDNS0 options, and returns true if there are any | |
897 | ||
898 | class MOADNSParser; | |
899 | bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo); | |
d6c335ab | 900 | DNSRecord makeOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t extFlags); |
ea634573 BH |
901 | void reportBasicTypes(); |
902 | void reportOtherTypes(); | |
903 | void reportAllTypes(); | |
f1ae49f7 | 904 | ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0); |
97c8ea81 | 905 | void checkHostnameCorrectness(const DNSResourceRecord& rr); |
a0a276c2 | 906 | #endif |