]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/dnsrecords.hh
Merge pull request #7734 from franklouwers/docs2
[thirdparty/pdns.git] / pdns / dnsrecords.hh
index 80d320e8afec509548e31ea50e41950fb4e963d4..d9f5a18ec4740107e7865e93903d19cc8fee8c47 100644 (file)
@@ -38,8 +38,8 @@
   RNAME##RecordContent(const string& zoneData);                                                  \
   static void report(void);                                                                      \
   static void unreport(void);                                                                    \
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);                          \
-  static DNSRecordContent* make(const string& zonedata);                                         \
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);          \
+  static std::shared_ptr<DNSRecordContent> make(const string& zonedata);                         \
   string getZoneRepresentation(bool noDot=false) const override;                                 \
   void toPacket(DNSPacketWriter& pw) override;                                                   \
   uint16_t getType() const override { return QType::RNAME; }                                   \
@@ -195,7 +195,7 @@ class LUARecordContent : public DNSRecordContent
 {
 public:
   includeboilerplate(LUA)
-  string getCode();
+  string getCode() const;
   uint16_t d_type;
   string d_code;
 };
@@ -211,6 +211,10 @@ class SPFRecordContent : public DNSRecordContent
 {
 public:
   includeboilerplate(SPF)
+  const std::string& getText() const
+  {
+    return d_text;
+  }
 
 private:
   string d_text;
@@ -240,6 +244,7 @@ class PTRRecordContent : public DNSRecordContent
 public:
   includeboilerplate(PTR)
   explicit PTRRecordContent(const DNSName& content) : d_content(content){}
+  const DNSName& getContent() const { return d_content; }
 private:
   DNSName d_content;
 };
@@ -537,6 +542,87 @@ public:
   struct soatimes d_st;
 };
 
+class NSECBitmap
+{
+public:
+  NSECBitmap(): d_bitset(nullptr)
+  {
+  }
+  NSECBitmap(const NSECBitmap& rhs): d_set(rhs.d_set)
+  {
+    if (rhs.d_bitset) {
+      d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
+    }
+  }
+  NSECBitmap& operator=(const NSECBitmap& rhs)
+  {
+    d_set = rhs.d_set;
+
+    if (rhs.d_bitset) {
+      d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>(*(rhs.d_bitset)));
+    }
+
+    return *this;
+  }
+  NSECBitmap(NSECBitmap&& rhs): d_bitset(std::move(rhs.d_bitset)), d_set(std::move(rhs.d_set))
+  {
+  }
+  bool isSet(uint16_t type) const
+  {
+    if (d_bitset) {
+      return d_bitset->test(type);
+    }
+    return d_set.count(type);
+  }
+  void set(uint16_t type)
+  {
+    if (!d_bitset) {
+      if (d_set.size() >= 200) {
+        migrateToBitSet();
+      }
+    }
+    if (d_bitset) {
+      d_bitset->set(type);
+    }
+    else {
+      d_set.insert(type);
+    }
+  }
+  size_t count() const
+  {
+    if (d_bitset) {
+      return d_bitset->count();
+    }
+    else {
+      return d_set.size();
+    }
+  }
+
+  void fromPacket(PacketReader& pr);
+  void toPacket(DNSPacketWriter& pw);
+  std::string getZoneRepresentation() const;
+
+  static constexpr size_t const nbTypes = 65536;
+
+private:
+
+  void migrateToBitSet()
+  {
+    d_bitset = std::unique_ptr<std::bitset<nbTypes>>(new std::bitset<nbTypes>());
+    for (const auto& type : d_set) {
+      d_bitset->set(type);
+    }
+    d_set.clear();
+  }
+  /* using a dynamic set is very efficient for a small number of
+     types covered (~200), but uses a lot of memory (up to 3MB)
+     when there are a lot of them.
+     So we start with the set, but allocate and switch to a bitset
+     if the number of covered types increases a lot */
+  std::unique_ptr<std::bitset<nbTypes>> d_bitset;
+  std::set<uint16_t> d_set;
+};
+
 class NSECRecordContent : public DNSRecordContent
 {
 public:
@@ -545,17 +631,34 @@ public:
   {}
   NSECRecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
 
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& content);
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& content);
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
   uint16_t getType() const override
   {
     return QType::NSEC;
   }
+  bool isSet(uint16_t type) const
+  {
+    return d_bitmap.isSet(type);
+  }
+  void set(uint16_t type)
+  {
+    d_bitmap.set(type);
+  }
+  void set(const NSECBitmap& bitmap)
+  {
+    d_bitmap = bitmap;
+  }
+  size_t numberOfTypesSet() const
+  {
+    return d_bitmap.count();
+  }
+
   DNSName d_next;
-  std::set<uint16_t> d_set;
 private:
+  NSECBitmap d_bitmap;
 };
 
 class NSEC3RecordContent : public DNSRecordContent
@@ -566,8 +669,8 @@ public:
   {}
   NSEC3RecordContent(const string& content, const string& zone=""); //FIXME400: DNSName& zone?
 
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& content);
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& content);
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
 
@@ -575,15 +678,30 @@ public:
   uint16_t d_iterations{0};
   string d_salt;
   string d_nexthash;
-  std::set<uint16_t> d_set;
 
   uint16_t getType() const override
   {
     return QType::NSEC3;
   }
-
+  bool isSet(uint16_t type) const
+  {
+    return d_bitmap.isSet(type);
+  }
+  void set(uint16_t type)
+  {
+    d_bitmap.set(type);
+  }
+  void set(const NSECBitmap& bitmap)
+  {
+    d_bitmap = bitmap;
+  }
+  size_t numberOfTypesSet() const
+  {
+    return d_bitmap.count();
+  }
 
 private:
+  NSECBitmap d_bitmap;
 };
 
 
@@ -595,8 +713,8 @@ public:
   {}
   NSEC3PARAMRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone?
 
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& content);
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& content);
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
 
@@ -620,8 +738,8 @@ public:
   {}
   LOCRecordContent(const string& content, const string& zone="");
 
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& content);
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& content);
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
 
@@ -635,32 +753,13 @@ public:
 private:
 };
 
-
-class WKSRecordContent : public DNSRecordContent
-{
-public:
-  static void report(void);
-  WKSRecordContent() 
-  {}
-  WKSRecordContent(const string& content, const string& zone=""); // FIXME400: DNSName& zone?
-
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& content);
-  string getZoneRepresentation(bool noDot=false) const override;
-  void toPacket(DNSPacketWriter& pw) override;
-
-  uint32_t d_ip{0};
-  std::bitset<65535> d_services;
-private:
-};
-
 class EUI48RecordContent : public DNSRecordContent 
 {
 public:
   EUI48RecordContent() {};
   static void report(void);
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone?
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
   uint16_t getType() const override { return QType::EUI48; }
@@ -674,8 +773,8 @@ class EUI64RecordContent : public DNSRecordContent
 public:
   EUI64RecordContent() {};
   static void report(void);
-  static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
-  static DNSRecordContent* make(const string& zone); // FIXME400: DNSName& zone?
+  static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
+  static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
   string getZoneRepresentation(bool noDot=false) const override;
   void toPacket(DNSPacketWriter& pw) override;
   uint16_t getType() const override { return QType::EUI64; }
@@ -722,9 +821,9 @@ class CAARecordContent : public DNSRecordContent {
 };
 
 #define boilerplate(RNAME, RTYPE)                                                                         \
-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
+std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
 {                                                                                                  \
-  return new RNAME##RecordContent(dr, pr);                                                         \
+  return std::make_shared<RNAME##RecordContent>(dr, pr);                                           \
 }                                                                                                  \
                                                                                                    \
 RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr)                  \
@@ -733,9 +832,9 @@ RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr
   xfrPacket(pr);                                                                                   \
 }                                                                                                  \
                                                                                                    \
-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const string& zonedata)         \
+std::shared_ptr<RNAME##RecordContent::DNSRecordContent> RNAME##RecordContent::make(const string& zonedata)         \
 {                                                                                                  \
-  return new RNAME##RecordContent(zonedata);                                                       \
+  return std::make_shared<RNAME##RecordContent>(zonedata);                                         \
 }                                                                                                  \
                                                                                                    \
 void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)                                           \
@@ -800,4 +899,5 @@ void reportBasicTypes();
 void reportOtherTypes();
 void reportAllTypes();
 ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0);
+void checkHostnameCorrectness(const DNSResourceRecord& rr);
 #endif