]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/dnsname.hh
dnsdist: Add SetNegativeAndSOAAction() and its Lua binding
[thirdparty/pdns.git] / pdns / dnsname.hh
index e5f6b11dbbaa639f51910068aa47ee3dca260c84..5028273070ba99ad9fa2dc3b1240beb6e57eef53 100644 (file)
@@ -64,7 +64,7 @@ public:
   DNSName()  {}          //!< Constructs an *empty* DNSName, NOT the root!
   explicit DNSName(const char* p);      //!< Constructs from a human formatted, escaped presentation
   explicit DNSName(const std::string& str) : DNSName(str.c_str()) {}; //!< Constructs from a human formatted, escaped presentation
-  DNSName(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=0, uint16_t* qclass=0, unsigned int* consumed=0, uint16_t minOffset=0); //!< Construct from a DNS Packet, taking the first question if offset=12
+  DNSName(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=nullptr, uint16_t* qclass=nullptr, unsigned int* consumed=nullptr, uint16_t minOffset=0); //!< Construct from a DNS Packet, taking the first question if offset=12. If supplied, consumed is set to the number of bytes consumed from the packet, which will not be equal to the wire length of the resulting name in case of compression.
   
   bool isPartOf(const DNSName& rhs) const;   //!< Are we part of the rhs name?
   inline bool operator==(const DNSName& rhs) const; //!< DNS-native comparison (case insensitive) - empty compares to empty
@@ -150,7 +150,7 @@ private:
   string_t d_storage;
 
   void packetParser(const char* p, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed, int depth, uint16_t minOffset);
-  static std::string escapeLabel(const std::string& orig);
+  static void appendEscapedLabel(std::string& appendTo, const char* orig, size_t len);
   static std::string unescapeLabel(const std::string& orig);
 };
 
@@ -242,6 +242,17 @@ struct SuffixMatchTree
       d_value = rhs.d_value;
     }
   }
+  SuffixMatchTree & operator=(const SuffixMatchTree &rhs)
+  {
+    d_name = rhs.d_name;
+    children = rhs.children;
+    endNode = rhs.endNode;
+    if (endNode) {
+      d_value = rhs.d_value;
+    }
+    return *this;
+  }
+  
   std::string d_name;
   mutable std::set<SuffixMatchTree> children;
   mutable bool endNode;
@@ -299,6 +310,11 @@ struct SuffixMatchTree
    */
   void remove(std::vector<std::string> labels) const
   {
+    if (labels.empty()) { // this allows removal of the root
+      endNode = false;
+      return;
+    }
+
     SuffixMatchTree smt(*labels.rbegin());
     auto child = children.find(smt);
     if (child == children.end()) {
@@ -328,8 +344,9 @@ struct SuffixMatchTree
     if(children.empty()) { // speed up empty set
       if(endNode)
         return &d_value;
-      return 0;
+      return nullptr;
     }
+
     return lookup(name.getRawLabels());
   }
 
@@ -338,7 +355,7 @@ struct SuffixMatchTree
     if(labels.empty()) { // optimization
       if(endNode)
         return &d_value;
-      return 0;
+      return nullptr;
     }
 
     SuffixMatchTree smn(*labels.rbegin());
@@ -346,10 +363,14 @@ struct SuffixMatchTree
     if(child == children.end()) {
       if(endNode)
         return &d_value;
-      return 0;
+      return nullptr;
     }
     labels.pop_back();
-    return child->lookup(labels);
+    auto result = child->lookup(labels);
+    if (result) {
+      return result;
+    }
+    return endNode ? &d_value : nullptr;
   }
 
   // Returns all end-nodes, fully qualified (not as separate labels)
@@ -383,6 +404,11 @@ struct SuffixMatchNode
       d_nodes.insert(dnsname);
     }
 
+    void add(const std::string& name)
+    {
+      add(DNSName(name));
+    }
+
     void add(std::vector<std::string> labels)
     {
       d_tree.add(labels, true);