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