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