diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index 9ba8ba7fbb74..ccf8eb004de6 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -179,6 +179,13 @@ public: return d_storage; } + [[nodiscard]] size_t sizeEstimate() const + { + return d_storage.size(); // knowingly overestimating small strings as most string + // implementations have internal capacity and we always include + // sizeof(*this) + } + bool has8bitBytes() const; /* returns true if at least one byte of the labels forming the name is not included in [A-Za-z0-9_*./@ \\:-] */ class RawLabelsVisitor diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 762358fddadb..412dafb6c8f0 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -293,6 +293,8 @@ public: d_locked.store(true); } + [[nodiscard]] virtual size_t sizeEstimate() const = 0; + protected: typedef std::map, makerfunc_t* > typemap_t; typedef std::map, zmakerfunc_t* > zmakermap_t; @@ -433,6 +435,11 @@ public: return *d_content == *rhs.d_content; } + + [[nodiscard]] size_t sizeEstimate() const + { + return sizeof(*this) + d_name.sizeEstimate() + (d_content ? d_content->sizeEstimate() : 0U); + } }; struct DNSZoneRecord @@ -469,6 +476,11 @@ public: return d_record; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_dr.sizeEstimate() + d_record.size(); + } + private: DNSRecord d_dr; vector d_record; diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index 8e3c46aacd07..b5239b68fadf 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -36,16 +36,19 @@ struct ReportIsOnlyCallableByReportAllTypes; -#define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \ - RNAME##RecordContent(const string& zoneData); \ - static void report(const ReportIsOnlyCallableByReportAllTypes& guard); \ - static std::shared_ptr make(const DNSRecord &dr, PacketReader& pr); \ - static std::shared_ptr make(const string& zonedata); \ - string getZoneRepresentation(bool noDot=false) const override; \ - void toPacket(DNSPacketWriter& pw) const override; \ - uint16_t getType() const override { return QType::RNAME; } \ - template void xfrPacket(Convertor& conv, bool noDot=false) const; \ - template void xfrPacket(Convertor& conv, bool noDot=false); +#define includeboilerplate(RNAME) \ + RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \ + RNAME##RecordContent(const string& zoneData); \ + static void report(const ReportIsOnlyCallableByReportAllTypes& guard); \ + static std::shared_ptr make(const DNSRecord& dr, PacketReader& pr); \ + static std::shared_ptr make(const string& zonedata); \ + string getZoneRepresentation(bool noDot = false) const override; \ + void toPacket(DNSPacketWriter& pw) const override; \ + uint16_t getType() const override { return QType::RNAME; } \ + template \ + void xfrPacket(Convertor& conv, bool noDot = false) const; \ + template \ + void xfrPacket(Convertor& conv, bool noDot = false); class NAPTRRecordContent : public DNSRecordContent { @@ -62,6 +65,10 @@ public: { return d_replacement; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_replacement.sizeEstimate() + d_flags.size() + d_services.size() + d_regexp.size(); + } private: uint16_t d_order, d_preference; string d_flags, d_services, d_regexp; @@ -83,6 +90,10 @@ public: return false; return d_ip == dynamic_cast(rhs).d_ip; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: uint32_t d_ip; }; @@ -100,6 +111,10 @@ public: return false; return d_ip6 == dynamic_cast(&rhs)->d_ip6; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_ip6.size(); + } private: string d_ip6; // why?? }; @@ -121,7 +136,10 @@ public: auto rrhs =dynamic_cast(&rhs); return std::tie(d_preference, d_mxname) == std::tie(rrhs->d_preference, rrhs->d_mxname); } - + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_mxname.sizeEstimate(); + } }; class KXRecordContent : public DNSRecordContent @@ -131,6 +149,10 @@ public: includeboilerplate(KX) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_exchanger.sizeEstimate(); + } private: uint16_t d_preference; DNSName d_exchanger; @@ -143,6 +165,10 @@ public: includeboilerplate(IPSECKEY) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_gateway.sizeEstimate() + d_publickey.size() + d_ip6.size(); + } private: uint32_t d_ip4; DNSName d_gateway; @@ -155,6 +181,10 @@ class DHCIDRecordContent : public DNSRecordContent { public: includeboilerplate(DHCID) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.size(); + } private: string d_content; @@ -167,6 +197,10 @@ public: SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, DNSName target); includeboilerplate(SRV) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_target.sizeEstimate(); + } uint16_t d_weight, d_port; DNSName d_target; @@ -178,6 +212,10 @@ class TSIGRecordContent : public DNSRecordContent public: includeboilerplate(TSIG) TSIGRecordContent() = default; + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_algoName.sizeEstimate() + d_mac.size() + d_otherData.size(); + } uint16_t d_origID{0}; uint16_t d_fudge{0}; @@ -197,6 +235,11 @@ class TXTRecordContent : public DNSRecordContent public: includeboilerplate(TXT) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_text.size(); + } + string d_text; }; @@ -205,6 +248,10 @@ class LUARecordContent : public DNSRecordContent { public: includeboilerplate(LUA) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + getCode().size(); + } string getCode() const; uint16_t d_type; string d_code; @@ -215,6 +262,10 @@ class ENTRecordContent : public DNSRecordContent { public: includeboilerplate(ENT) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } }; class SPFRecordContent : public DNSRecordContent @@ -225,6 +276,10 @@ public: { return d_text; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_text.size(); + } private: string d_text; @@ -244,7 +299,10 @@ public: auto rrhs =dynamic_cast(&rhs); return d_content == rrhs->d_content; } - + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.sizeEstimate(); + } private: DNSName d_content; }; @@ -255,6 +313,10 @@ public: includeboilerplate(PTR) explicit PTRRecordContent(const DNSName& content) : d_content(content){} const DNSName& getContent() const { return d_content; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.sizeEstimate(); + } private: DNSName d_content; }; @@ -265,6 +327,10 @@ public: includeboilerplate(CNAME) CNAMERecordContent(const DNSName& content) : d_content(content){} DNSName getTarget() const { return d_content; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.sizeEstimate(); + } private: DNSName d_content; }; @@ -279,6 +345,10 @@ public: { return d_content; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.sizeEstimate(); + } private: DNSName d_content; }; @@ -290,6 +360,10 @@ public: includeboilerplate(DNAME) DNAMERecordContent(const DNSName& content) : d_content(content){} const DNSName& getTarget() const { return d_content; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_content.sizeEstimate(); + } private: DNSName d_content; }; @@ -299,6 +373,10 @@ class MBRecordContent : public DNSRecordContent { public: includeboilerplate(MB) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_madname.sizeEstimate(); + } private: DNSName d_madname; @@ -308,6 +386,10 @@ class MGRecordContent : public DNSRecordContent { public: includeboilerplate(MG) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_mgmname.sizeEstimate(); + } private: DNSName d_mgmname; @@ -317,6 +399,10 @@ class MRRecordContent : public DNSRecordContent { public: includeboilerplate(MR) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_alias.sizeEstimate(); + } private: DNSName d_alias; @@ -326,6 +412,10 @@ class MINFORecordContent : public DNSRecordContent { public: includeboilerplate(MINFO) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_rmailbx.sizeEstimate() + d_emailbx.sizeEstimate(); + } private: DNSName d_rmailbx; @@ -338,6 +428,10 @@ public: OPTRecordContent() = default; includeboilerplate(OPT) void getData(vector > &opts) const; + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_data.size(); + } private: string d_data; }; @@ -347,6 +441,10 @@ class HINFORecordContent : public DNSRecordContent { public: includeboilerplate(HINFO) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_cpu.size() + d_host.size(); + } private: string d_cpu, d_host; @@ -356,7 +454,10 @@ class RPRecordContent : public DNSRecordContent { public: includeboilerplate(RP) - + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_mbox.sizeEstimate() + d_info.sizeEstimate(); + } private: DNSName d_mbox, d_info; }; @@ -378,6 +479,10 @@ public: return std::tie(d_flags, d_protocol, d_algorithm, d_key) < std::tie(rhs.d_flags, rhs.d_protocol, rhs.d_algorithm, rhs.d_key); } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_key.size(); + } }; class CDNSKEYRecordContent : public DNSRecordContent @@ -386,6 +491,10 @@ public: CDNSKEYRecordContent(); includeboilerplate(CDNSKEY) uint16_t getTag(); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_key.size(); + } uint16_t d_flags{0}; uint8_t d_protocol{0}; @@ -412,6 +521,10 @@ public: } includeboilerplate(DS) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_digest.size(); + } uint16_t d_tag{0}; uint8_t d_algorithm{0}, d_digesttype{0}; @@ -423,6 +536,10 @@ class CDSRecordContent : public DNSRecordContent public: CDSRecordContent(); includeboilerplate(CDS) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_digest.size(); + } uint16_t d_tag{0}; uint8_t d_algorithm{0}, d_digesttype{0}; @@ -434,6 +551,10 @@ class DLVRecordContent : public DNSRecordContent public: DLVRecordContent(); includeboilerplate(DLV) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_digest.size(); + } uint16_t d_tag{0}; uint8_t d_algorithm{0}, d_digesttype{0}; @@ -445,6 +566,10 @@ class SSHFPRecordContent : public DNSRecordContent { public: includeboilerplate(SSHFP) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_fingerprint.size(); + } private: uint8_t d_algorithm, d_fptype; @@ -455,6 +580,10 @@ class KEYRecordContent : public DNSRecordContent { public: includeboilerplate(KEY) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_certificate.size(); + } private: uint16_t d_flags; @@ -466,6 +595,10 @@ class AFSDBRecordContent : public DNSRecordContent { public: includeboilerplate(AFSDB) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_hostname.sizeEstimate(); + } private: uint16_t d_subtype; @@ -481,6 +614,10 @@ class CERTRecordContent : public DNSRecordContent { public: includeboilerplate(CERT) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_certificate.size(); + } private: uint16_t d_type, d_tag; @@ -492,6 +629,10 @@ class TLSARecordContent : public DNSRecordContent { public: includeboilerplate(TLSA) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_cert.size(); + } private: uint8_t d_certusage, d_selector, d_matchtype; @@ -502,6 +643,10 @@ class SMIMEARecordContent : public DNSRecordContent { public: includeboilerplate(SMIMEA) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_cert.size(); + } private: uint8_t d_certusage, d_selector, d_matchtype; @@ -512,6 +657,10 @@ class OPENPGPKEYRecordContent : public DNSRecordContent { public: includeboilerplate(OPENPGPKEY) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_keyring.size(); + } private: string d_keyring; @@ -536,6 +685,11 @@ class SVCBBaseRecordContent : public DNSRecordContent SvcParam getParam(const SvcParam::SvcParamKey &key) const; virtual std::shared_ptr clone() const = 0; + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_params.size() * sizeof(SvcParam) + d_target.sizeEstimate(); + } + protected: std::set d_params; DNSName d_target; @@ -565,6 +719,10 @@ public: RRSIGRecordContent(); includeboilerplate(RRSIG) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_signer.sizeEstimate() + d_signature.size(); + } uint16_t d_type{0}; uint16_t d_tag{0}; DNSName d_signer; @@ -589,6 +747,10 @@ class RKEYRecordContent : public DNSRecordContent public: RKEYRecordContent(); includeboilerplate(RKEY) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_key.size(); + } uint16_t d_flags{0}; uint8_t d_protocol{0}, d_algorithm{0}; string d_key; @@ -600,6 +762,10 @@ public: includeboilerplate(SOA) SOARecordContent(DNSName mname, DNSName rname, const struct soatimes& st); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_mname.sizeEstimate() + d_rname.sizeEstimate(); + } DNSName d_mname; DNSName d_rname; struct soatimes d_st; @@ -611,6 +777,10 @@ public: includeboilerplate(ZONEMD) //ZONEMDRecordContent(uint32_t serial, uint8_t scheme, uint8_t hashalgo, string digest); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_digest.size(); + } uint32_t d_serial; uint8_t d_scheme; uint8_t d_hashalgo; @@ -680,6 +850,11 @@ public: static constexpr size_t const nbTypes = 65536; + [[nodiscard]] size_t sizeEstimate() const + { + return d_bitset ? nbTypes / 8 : d_set.size() * (2U + sizeof(std::set)); // XXX + } + private: void migrateToBitSet() @@ -731,6 +906,10 @@ public: return d_bitmap.count(); } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_next.sizeEstimate() + d_bitmap.sizeEstimate(); + } DNSName d_next; private: NSECBitmap d_bitmap; @@ -778,6 +957,10 @@ public: return d_flags & 1; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_salt.size() + d_nexthash.size() + d_bitmap.sizeEstimate(); + } private: NSECBitmap d_bitmap; }; @@ -804,6 +987,11 @@ public: d_bitmap.set(type); } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_bitmap.sizeEstimate(); + } + private: uint32_t d_serial{0}; uint16_t d_flags{0}; @@ -827,6 +1015,10 @@ public: return QType::NSEC3PARAM; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_salt.size(); + } uint8_t d_algorithm{0}, d_flags{0}; uint16_t d_iterations{0}; @@ -853,6 +1045,10 @@ public: return QType::LOC; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: }; @@ -861,6 +1057,10 @@ class NIDRecordContent : public DNSRecordContent { public: includeboilerplate(NID); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: uint16_t d_preference; @@ -871,6 +1071,10 @@ class L32RecordContent : public DNSRecordContent { public: includeboilerplate(L32); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: uint16_t d_preference; @@ -881,6 +1085,10 @@ class L64RecordContent : public DNSRecordContent { public: includeboilerplate(L64); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: uint16_t d_preference; @@ -891,6 +1099,10 @@ class LPRecordContent : public DNSRecordContent { public: includeboilerplate(LP); + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_fqdn.sizeEstimate(); + } private: uint16_t d_preference; @@ -907,6 +1119,10 @@ public: string getZoneRepresentation(bool noDot=false) const override; void toPacket(DNSPacketWriter& pw) const override; uint16_t getType() const override { return QType::EUI48; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: // storage for the bytes uint8_t d_eui48[6]; @@ -922,6 +1138,10 @@ public: string getZoneRepresentation(bool noDot=false) const override; void toPacket(DNSPacketWriter& pw) const override; uint16_t getType() const override { return QType::EUI64; } + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this); + } private: // storage for the bytes uint8_t d_eui64[8]; @@ -944,6 +1164,10 @@ class APLRecordContent : public DNSRecordContent public: APLRecordContent() = default; includeboilerplate(APL) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + aplrdata.size() * sizeof(APLRDataElement); + } private: std::vector aplrdata; APLRDataElement parseAPLElement(const string &element); @@ -955,6 +1179,10 @@ class TKEYRecordContent : public DNSRecordContent public: TKEYRecordContent(); includeboilerplate(TKEY) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_algo.sizeEstimate() + d_key.size() + d_other.size(); + } // storage for the bytes uint16_t d_othersize{0}; @@ -974,15 +1202,23 @@ private: class URIRecordContent : public DNSRecordContent { public: includeboilerplate(URI) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_target.size(); + } private: uint16_t d_priority, d_weight; string d_target; }; class CAARecordContent : public DNSRecordContent { - public: - includeboilerplate(CAA) - private: +public: + includeboilerplate(CAA) + [[nodiscard]] size_t sizeEstimate() const override + { + return sizeof(*this) + d_tag.size() + d_value.size(); + } +private: uint8_t d_flags; string d_tag, d_value; }; diff --git a/pdns/recursordist/metrics_table.py b/pdns/recursordist/metrics_table.py index 8ed450dfa624..93e6e3ba9ae6 100644 --- a/pdns/recursordist/metrics_table.py +++ b/pdns/recursordist/metrics_table.py @@ -85,7 +85,7 @@ 'lambda': 'doGetCacheBytes', 'ptype': 'gauge', 'desc': 'Size of the cache in bytes', - 'longdesc': '''Disabled by default, see :ref:`setting-stats-rec-control-disabled-list`. This metric is currently broken, it always is 0.''', + 'longdesc': '''Since version 5.3.0 this metric computes a rough estimate of the number of bytes allocated by the record cache. Older versions return a number that cannot be relied upon. Disabled by default, as computing this number is CPU intensive, see :ref:`setting-stats-rec-control-disabled-list`.''', 'snmp': 7, }, { diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index fd9d6e12c417..df29606e46b3 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -126,6 +126,41 @@ size_t MemRecursorCache::ecsIndexSize() return count; } +size_t MemRecursorCache::CacheEntry::authRecsSizeEstimate() const +{ + size_t ret = 0; + if (d_authorityRecs) { + for (const auto& record : *d_authorityRecs) { + ret += record.sizeEstimate(); + } + } + return ret; +} + +size_t MemRecursorCache::CacheEntry::sigRecsSizeEstimate() const +{ + size_t ret = 0; + if (d_signatures) { + for (const auto& record : *d_signatures) { + ret += record->sizeEstimate(); + } + } + return ret; +} + +size_t MemRecursorCache::CacheEntry::sizeEstimate() const +{ + auto ret = sizeof(struct CacheEntry); + ret += d_qname.sizeEstimate(); + ret += d_authZone.sizeEstimate(); + for (const auto& record : d_records) { + ret += record->sizeEstimate(); + } + ret += authRecsSizeEstimate(); + ret += sigRecsSizeEstimate(); + return ret; +} + // this function is too slow to poll! size_t MemRecursorCache::bytes() { @@ -133,11 +168,7 @@ size_t MemRecursorCache::bytes() for (auto& shard : d_maps) { auto lockedShard = shard.lock(); for (const auto& entry : lockedShard->d_map) { - ret += sizeof(struct CacheEntry); - ret += entry.d_qname.toString().length(); - for (const auto& record : entry.d_records) { - ret += sizeof(record); // XXX WRONG we don't know the stored size! - } + ret += entry.sizeEstimate(); } } return ret; @@ -881,7 +912,11 @@ uint64_t MemRecursorCache::doDump(int fileDesc, size_t maxCacheEntries) for (auto& shard : d_maps) { auto lockedShard = shard.lock(); const auto shardSize = lockedShard->d_map.size(); - fprintf(filePtr.get(), "; record cache shard %zu; size %zu\n", shardNumber, shardSize); + size_t bytes = 0; + for (const auto& entry : lockedShard->d_map) { + bytes += entry.sizeEstimate(); + } + fprintf(filePtr.get(), "; record cache shard %zu; size %zu bytes %zu\n", shardNumber, shardSize, bytes); min = std::min(min, shardSize); max = std::max(max, shardSize); shardNumber++; diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index beaf44a9799d..004b0c196530 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -156,6 +156,10 @@ private: bool shouldReplace(time_t now, bool auth, vState state, bool refresh); + [[nodiscard]] size_t sizeEstimate() const; + [[nodiscard]] size_t authRecsSizeEstimate() const; + [[nodiscard]] size_t sigRecsSizeEstimate() const; + records_t d_records; SigRecs d_signatures; AuthRecs d_authorityRecs; diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index ddcd04271a24..fb83a86bbc31 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -716,4 +716,27 @@ BOOST_AUTO_TEST_CASE(test_nsec3_records_types) { } } +BOOST_AUTO_TEST_CASE(test_size_estimate) +{ + auto anA = DNSRecordContent::make(QType::A, QClass::IN, "1.2.3.4"); + auto anAAAA = DNSRecordContent::make(QType::AAAA, QClass::IN, "1234:4578:89ab::"); + auto aTXT = DNSRecordContent::make(QType::TXT, QClass::IN, "\"a somewhat long text\""); + BOOST_CHECK(anAAAA->sizeEstimate() < aTXT->sizeEstimate()); + + auto rrsigA = DNSRecordContent::make(QType::RRSIG, QClass::IN, "SOA 8 3 300 20130523000000 20130509000000 54216 rec.test. ecWKD/OsdAiXpbM/sgPT82KVD/WiQnnqcxoJgiH3ixHa+LOAcYU7FG7V4BRRJxLriY1e0rB2gAs3kCel9D4bzfK6wAqG4Di/eHUgHptRlaR2ycELJ4t1pjzrnuGiIzA1wM2izRmeE+Xoy1367Qu0pOz5DLzTfQITWFsB2iUzN4Y="); + auto rrsigB = DNSRecordContent::make(QType::RRSIG, QClass::IN, "SOA 8 3 300 20130523000000 20130509000000 54216 rec.test. fcWKD/OsdAiXpbM/sgPT82KVD/WiQnnqcxoJgiH3ixHa+LOAcYU7FG7V4BRRJxLriY1e0rB2gAs3kCel9D4bzfK6wAqG4Di/eHUgHptRlaR2ycELJ4t1pjzrnuGiIzA1wM2izRmeE+Xoy1367Qu0pOz5DLzTfQITWFsB2iUzN4YAAAA="); + BOOST_CHECK(rrsigA->sizeEstimate() < rrsigB->sizeEstimate()); + BOOST_CHECK(rrsigA->sizeEstimate() > aTXT->sizeEstimate()); + + auto nsecA = DNSRecordContent::make(QType::NSEC, QClass::IN, "host.example.com. A MX RRSIG NSEC TYPE1234"); + auto nsecB = DNSRecordContent::make(QType::NSEC, QClass::IN, "host1.example.com. A MX RRSIG NSEC TYPE1234"); + BOOST_CHECK(nsecA->sizeEstimate() < nsecB->sizeEstimate()); + BOOST_CHECK(nsecA->sizeEstimate() > aTXT->sizeEstimate()); + + auto nsec3A = DNSRecordContent::make(QType::NSEC3, QClass::IN, "1 1 12 aabbccdd 2vptu5timamqttgl4luu9kg21e0aor3s a mx rrsig nsec3 type1234 type65535"); + auto nsec3B = DNSRecordContent::make(QType::NSEC3, QClass::IN, "1 1 0 - 2vptu5timamqttgl4luu9kg21e0aor3s"); + BOOST_CHECK(nsec3A->sizeEstimate() > nsec3B->sizeEstimate()); + BOOST_CHECK(nsec3B->sizeEstimate() > aTXT->sizeEstimate()); +} + BOOST_AUTO_TEST_SUITE_END()