]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix insertion issues in SuffixMatchTree 4541/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 6 Oct 2016 12:35:09 +0000 (14:35 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 6 Oct 2016 12:35:09 +0000 (14:35 +0200)
pdns/dnsname.hh
pdns/test-dnsname_cc.cc

index f951dfaf1506fe06369d2fdf8ac231ee10c0210c..492def3dd7b92801afaed3d932b8a44ba333d3d4 100644 (file)
@@ -301,13 +301,11 @@ struct SuffixMatchTree
   SuffixMatchTree(const SuffixMatchTree& rhs)
   {
     name = rhs.name;
-    d_human = rhs.d_human;
     children = rhs.children;
     endNode = rhs.endNode;
     d_value = rhs.d_value;
   }
   std::string name;
-  std::string d_human;
   mutable std::set<SuffixMatchTree> children;
   mutable bool endNode;
   mutable T d_value;
@@ -338,16 +336,19 @@ struct SuffixMatchTree
     }
     else if(labels.size()==1) {
       SuffixMatchTree newChild(*labels.begin(), true);
-      newChild.d_value=value;
-      children.insert(newChild);
+      auto res=children.insert(newChild);
+      if(!res.second) {
+        // we might already have had the node as an
+        // intermediary one, but it's now an end node
+        if(!res.first->endNode) {
+          res.first->endNode = true;
+        }
+      }
+      res.first->d_value = value;
     }
     else {
       SuffixMatchTree newnode(*labels.rbegin(), false);
       auto res=children.insert(newnode);
-      if(!res.second) {
-        children.erase(newnode);
-        res=children.insert(newnode);
-      }
       labels.pop_back();
       res.first->add(labels, value);
     }
index 4995ee45e87f3342719f32d1135c0eb4a04c450b..ea76cae70c2a7e008b8c8e98a94323b4053287af 100644 (file)
@@ -493,6 +493,57 @@ BOOST_AUTO_TEST_CASE(test_suffixmatch) {
   BOOST_CHECK(smn.check(DNSName("a.root-servers.net.")));
 }
 
+BOOST_AUTO_TEST_CASE(test_suffixmatch_tree) {
+  SuffixMatchTree<DNSName> smt;
+  DNSName ezdns("ezdns.it.");
+  smt.add(ezdns, ezdns);
+
+  smt.add(DNSName("org.").getRawLabels(), DNSName("org."));
+
+  DNSName wwwpowerdnscom("www.powerdns.com.");
+  DNSName wwwezdnsit("www.ezdns.it.");
+  BOOST_REQUIRE(smt.lookup(wwwezdnsit));
+  BOOST_CHECK_EQUAL(*smt.lookup(wwwezdnsit), ezdns);
+  BOOST_CHECK(smt.lookup(wwwpowerdnscom) == nullptr);
+
+  BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.org.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.org.")), DNSName("org."));
+  BOOST_REQUIRE(smt.lookup(DNSName("www.powerdns.oRG.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.powerdns.oRG.")), DNSName("org."));
+
+  smt.add(DNSName("news.bbc.co.uk."), DNSName("news.bbc.co.uk."));
+  BOOST_REQUIRE(smt.lookup(DNSName("news.bbc.co.uk.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
+  BOOST_REQUIRE(smt.lookup(DNSName("www.news.bbc.co.uk.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
+  BOOST_REQUIRE(smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("www.www.www.www.www.news.bbc.co.uk.")), DNSName("news.bbc.co.uk."));
+  BOOST_CHECK(smt.lookup(DNSName("images.bbc.co.uk.")) == nullptr);
+  BOOST_CHECK(smt.lookup(DNSName("www.news.gov.uk.")) == nullptr);
+
+  smt.add(g_rootdnsname, g_rootdnsname); // block the root
+  BOOST_REQUIRE(smt.lookup(DNSName("a.root-servers.net.")));
+  BOOST_CHECK_EQUAL(*smt.lookup(DNSName("a.root-servers.net.")), g_rootdnsname);
+
+  DNSName apowerdnscom("a.powerdns.com.");
+  DNSName bpowerdnscom("b.powerdns.com.");
+  smt.add(apowerdnscom, apowerdnscom);
+  smt.add(bpowerdnscom, bpowerdnscom);
+  BOOST_REQUIRE(smt.lookup(apowerdnscom));
+  BOOST_CHECK_EQUAL(*smt.lookup(apowerdnscom), apowerdnscom);
+  BOOST_REQUIRE(smt.lookup(bpowerdnscom));
+  BOOST_CHECK_EQUAL(*smt.lookup(bpowerdnscom), bpowerdnscom);
+
+  DNSName examplenet("example.net.");
+  DNSName net("net.");
+  smt.add(examplenet, examplenet);
+  smt.add(net, net);
+  BOOST_REQUIRE(smt.lookup(examplenet));
+  BOOST_CHECK_EQUAL(*smt.lookup(examplenet), examplenet);
+  BOOST_REQUIRE(smt.lookup(net));
+  BOOST_CHECK_EQUAL(*smt.lookup(net), net);
+}
+
 
 BOOST_AUTO_TEST_CASE(test_concat) {
   DNSName first("www."), second("powerdns.com.");