]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
DNSNameSet and QNameSetRule
authorAndrey Domas <andrey.domas@corp.mail.ru>
Fri, 1 Mar 2019 14:47:05 +0000 (17:47 +0300)
committerAndrey Domas <andrey.domas@corp.mail.ru>
Fri, 1 Mar 2019 14:47:05 +0000 (17:47 +0300)
pdns/dnsdist-console.cc
pdns/dnsdist-lua-bindings.cc
pdns/dnsdist-lua-rules.cc
pdns/dnsdistdist/dnsdist-rules.hh
pdns/dnsdistdist/docs/reference/dnsnameset.rst [new file with mode: 0644]
pdns/dnsdistdist/docs/rules-actions.rst
pdns/dnsname.hh

index 10f1e91918409e441642974c3757e3e8ab7809f0..6575cd4623d9380669424ca9bd292063a74ff797 100644 (file)
@@ -389,6 +389,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "newServer", true, "{address=\"ip:port\", qps=1000, order=1, weight=10, pool=\"abuse\", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName=\"a.root-servers.net.\", checkType=\"A\", maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source=\"address|interface name|address@interface\", sockets=1}", "instantiate a server" },
   { "newServerPolicy", true, "name, function", "create a policy object from a Lua function" },
   { "newSuffixMatchNode", true, "", "returns a new SuffixMatchNode" },
+  { "newDNSNameSet", true, "", "returns a new DNSNameSet" },
   { "NoRecurseAction", true, "", "strip RD bit from the question, let it go through" },
   { "PoolAction", true, "poolname", "set the packet into the specified pool" },
   { "printDNSCryptProviderFingerprint", true, "\"/path/to/providerPublic.key\"", "display the fingerprint of the provided resolver public key" },
index bec7c24bc9131cbd632031736cd1e96a34c661e3..ee966ab58885cd036c7685800d56b280d235a677 100644 (file)
@@ -175,6 +175,16 @@ void setupLuaBindings(bool client)
   g_lua.registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
   g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); });
   g_lua.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); });
+  g_lua.writeFunction("newDNSNameSet", []() { return DNSNameSet(); });
+
+  /* DNSNameSet */
+  g_lua.registerFunction<string(DNSNameSet::*)()>("toString", [](const DNSNameSet&dns ) { return dns.toString(); });
+  g_lua.registerFunction<void(DNSNameSet::*)(DNSName&)>("add", [](DNSNameSet& dns, DNSName& dn) { dns.insert(dn); });
+  g_lua.registerFunction<bool(DNSNameSet::*)(DNSName&)>("contains", [](DNSNameSet& dns, DNSName& dn) { return dns.find(dn) != dns.end(); });
+  g_lua.registerFunction("delete",(size_t (DNSNameSet::*)(const DNSName&)) &DNSNameSet::erase);
+  g_lua.registerFunction("size",(size_t (DNSNameSet::*)() const) &DNSNameSet::size);
+  g_lua.registerFunction("clear",(void (DNSNameSet::*)()) &DNSNameSet::clear);
+  g_lua.registerFunction("empty",(bool (DNSNameSet::*)()) &DNSNameSet::empty);
 
   /* SuffixMatchNode */
   g_lua.registerFunction("add",(void (SuffixMatchNode::*)(const DNSName&)) &SuffixMatchNode::add);
index c209d10a500822b1af30299a89b5b9df4ebc67ea..468c5d479aa79dc0f69e6f9ad46603ed9a83399b 100644 (file)
@@ -459,4 +459,8 @@ void setupLuaRules()
   g_lua.registerFunction<std::shared_ptr<DNSRule>(std::shared_ptr<TimedIPSetRule>::*)()>("slice", [](std::shared_ptr<TimedIPSetRule> tisr) {
       return std::dynamic_pointer_cast<DNSRule>(tisr);
     });
+
+  g_lua.writeFunction("QNameSetRule", [](const DNSNameSet& names) {
+      return std::shared_ptr<DNSRule>(new QNameSetRule(names));
+    });
 }
index f343f4f5db82b7356553aa5baf9a50a991184c8d..c29e48d65cd30bfc5598a2bed127f6077f93956f 100644 (file)
@@ -530,6 +530,7 @@ public:
   QNameRule(const DNSName& qname) : d_qname(qname)
   {
   }
+
   bool matches(const DNSQuestion* dq) const override
   {
     return d_qname==*dq->qname;
@@ -542,6 +543,22 @@ private:
   DNSName d_qname;
 };
 
+class QNameSetRule : public DNSRule {
+public:
+    QNameSetRule(const DNSNameSet names) : qname_idx(names) {}
+
+    bool matches(const DNSQuestion* dq) const override {
+        return qname_idx.find(*dq->qname) != qname_idx.end();
+    }
+
+    string toString() const override {
+        std::stringstream ss;
+        ss << "qname in DNSNameSet(" << qname_idx.size() << " FQDNs)";
+        return ss.str();
+    }
+private:
+    DNSNameSet qname_idx;
+};
 
 class QTypeRule : public DNSRule
 {
diff --git a/pdns/dnsdistdist/docs/reference/dnsnameset.rst b/pdns/dnsdistdist/docs/reference/dnsnameset.rst
new file mode 100644 (file)
index 0000000..49b2860
--- /dev/null
@@ -0,0 +1,60 @@
+.. _DNSNameSet:
+
+DNSNameSet objects
+==================
+
+A :class:`DNSNameSet` object is a set of :class:`DNSName` objects. 
+Based on std::set (usually implemented as red-black trees).
+Creating a ``DNSName`` is done with the :func:`newDNSNameSet`::
+
+  myset = newDNSNameSet()
+
+The set can be filled by func:`DNSNameSet:add`::
+
+  myset.add(newDNSName("domain1.tld"))
+  myset.add(newDNSName("domain2.tld"))
+
+Functions and methods of a ``DNSNameSet``
+-----------------------------------------
+
+.. function:: newDNSNameSet(name) -> DNSNameSet
+
+  Returns the :class:`DNSNameSet`.
+
+.. class:: DNSNameSet
+
+  A ``DNSNameSet`` object is a set of :class:`DNSName` objects.
+
+  .. method:: DNSNameSet:add(name)
+
+    Adds the name to the set.
+
+    :param DNSName name The name to add.
+
+  .. method:: DNSNameSet:empty() -> bool
+
+    Returns true is the DNSNameSet is empty.
+
+  .. method:: DNSNameSet:clear()
+
+    Clean up the set.
+
+  .. method:: DNSNameSet:toString() -> string
+
+    Returns a human-readable form of the DNSName.
+
+  .. method:: DNSNameSet:size() -> int
+
+    Returns the number of names in the set.
+
+  .. method:: DNSNameSet:delete(name) -> int
+
+    Removes the name from the set. Returns the number of deleted elements.
+
+   :param DNSName name The name to remove.
+
+  .. method:: DNSNameSet:contains(name) -> bool
+
+    Returns true if the set contains the name.
+
+   :param DNSname name The name.
index 7838f6dd4e8929af14afc1232641671a70a0937e..b6f2d980e408b7d0bccaa11c94705f8ca28b2adf 100644 (file)
@@ -610,6 +610,11 @@ These ``DNSRule``\ s be one of the following items:
 
    :param string qname: Qname to match
 
+.. function:: QNameSetRule(set)
+   Matches if the set contains qname.
+
+  :param DNSNameSet set: Set with qnames.
+
 .. function:: QNameLabelsCountRule(min, max)
 
   Matches if the qname has less than ``min`` or more than ``max`` labels.
index f2d9eee21c196b3ff12a42d86fa6d0176a924bf9..0f64376f6eb81dd11835927196225e3edbcb9c11 100644 (file)
@@ -26,6 +26,8 @@
 #include <deque>
 #include <strings.h>
 #include <stdexcept>
+#include <sstream>
+#include <iterator>
 
 #include <boost/version.hpp>
 
@@ -376,3 +378,11 @@ bool DNSName::operator==(const DNSName& rhs) const
 }
 
 extern const DNSName g_rootdnsname, g_wildcarddnsname;
+
+struct DNSNameSet: public std::set<DNSName> {
+    std::string toString() const {
+        std::ostringstream oss;
+        std::copy(begin(), end(), std::ostream_iterator<DNSName>(oss, "\n"));
+        return oss.str();
+    }
+};