an unordered_set as well.
return record;
}
+ [[nodiscard]] string wireFormatContent(const DNSName& qname, bool canonic = false, bool lowerCase = false) const
+ {
+ vector<uint8_t> packet;
+ DNSPacketWriter packetWriter(packet, g_rootdnsname, QType::A);
+
+ if (canonic) {
+ packetWriter.setCanonic(true);
+ }
+ if (lowerCase) {
+ packetWriter.setLowercase(true);
+ }
+
+ packetWriter.startRecord(qname, getType());
+ toPacket(packetWriter);
+
+ string record;
+ packetWriter.getContentWireFormat(record); // needs to be called before commit()
+ return record;
+ }
+
virtual bool operator==(const DNSRecordContent& rhs) const
{
return typeid(*this)==typeid(rhs) && this->getZoneRepresentation() == rhs.getZoneRepresentation();
records.assign(d_content.begin() + d_sor, d_content.end());
}
+// call __before commit__
+template <typename Container> void GenericDNSPacketWriter<Container>::getContentWireFormat(string& records)
+{
+ records.assign(d_content.begin() + d_rollbackmarker, d_content.end());
+}
+
template <typename Container> uint32_t GenericDNSPacketWriter<Container>::size() const
{
return d_content.size();
dnsheader* getHeader();
void getRecordPayload(string& records); // call __before commit__
+ void getContentWireFormat(string& records); // call __before commit__
void setCanonic(bool val)
{
BOOST_CHECK_EQUAL(dups, 1U);
BOOST_CHECK_EQUAL(list.size(), 2U);
addRecordToList(list, DNSName("Foo"), QType::A, "1.2.3.4");
+ addRecordToList(list, DNSName("FoO"), QType::A, "1.2.3.4", DNSResourceRecord::ADDITIONAL, 999);
dups = pdns::dedup(list);
- BOOST_CHECK_EQUAL(dups, 1U);
+ BOOST_CHECK_EQUAL(dups, 2U);
BOOST_CHECK_EQUAL(list.size(), 2U);
BOOST_CHECK_EQUAL(address, &list);
}
unsigned int pdns::dedup(vector<DNSRecord>& rrs)
{
- // This functino tries to avoid unneccesary work
+ // This function tries to avoid unneccesary work
// First a vector with zero or one element does not need dedupping
if (rrs.size() <= 1) {
return 0;
// If we have a larger vector, first check if we actually have duplicates.
// We assume the most common case is: no
- std::set<std::tuple<DNSName, QType, std::string>> seen;
+ std::unordered_set<std::string> seen;
std::vector<bool> dups(rrs.size(), false);
unsigned int counter = 0;
unsigned int numDups = 0;
for (const auto& rec : rrs) {
+ const auto key = rec.getContent()->wireFormatContent(rec.d_name, true, true);
// This ignores class, ttl and place by using constants for those
- if (!seen.emplace(rec.d_name.makeLowerCase(), rec.d_type, rec.getContent()->serialize(rec.d_name, true, false)).second) {
+ if (!seen.emplace(key).second) {
dups[counter] = true;
numDups++;
}