]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add `getStatisticsCounters()` to access counters from Lua 4653/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 31 Oct 2016 10:49:47 +0000 (11:49 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 31 Oct 2016 10:54:12 +0000 (11:54 +0100)
pdns/README-dnsdist.md
pdns/dnsdist-lua2.cc
regression-tests.dnsdist/test_Spoofing.py

index 9334932781f72285a37926e2f1b14046a1606ca3..65fa6a8f688cbb7c5b72e54c557358a4189ae4cc 100644 (file)
@@ -1245,6 +1245,7 @@ Here are all functions:
     * `controlSocket(addr)`: open a control socket on this address / connect to this address in client mode
  * Diagnostics and statistics
     * `dumpStats()`: print all statistics we gather
+    * `getStatisticsCounters()`: return the statistics counters as a Lua table
     * `grepq(Netmask|DNS Name|100ms [, n])`: shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms
     * `grepq({"::1", "powerdns.com", "100ms"} [, n])`: shows the last n queries and responses matching the specified client address AND range (Netmask) AND the specified DNS Name AND slower than 100ms
     * `topQueries(n[, labels])`: show top 'n' queries, as grouped when optionally cut down to 'labels' labels
index 7afe7c0f87c337c040a466f0f4f6c4f9a931f441..0c3362e4b158fa5498f554f3b2bdd92295c210b4 100644 (file)
@@ -1012,4 +1012,14 @@ void moreLua(bool client)
       });
 
 #endif /* HAVE_EBPF */
+
+    g_lua.writeFunction<std::unordered_map<string,uint64_t>()>("getStatisticsCounters", []() {
+        setLuaNoSideEffect();
+        std::unordered_map<string,uint64_t> res;
+        for(const auto& entry : g_stats.entries) {
+          if(const auto& val = boost::get<DNSDistStats::stat_t*>(&entry.second))
+            res[entry.first] = (*val)->load();
+        }
+        return res;
+      });
 }
index cc817462d4fe7cce3a1d87eaff148f64a1b896ab..7c271a069236dcd020f4e6caef98f4f65042366b 100644 (file)
@@ -393,3 +393,67 @@ class TestSpoofingLuaSpoof(DNSDistTest):
         (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
         self.assertTrue(receivedResponse)
         self.assertEquals(expectedResponse, receivedResponse)
+
+class TestSpoofingLuaWithStatistics(DNSDistTest):
+
+    _config_template = """
+    function spoof1rule(dq)
+        queriesCount = getStatisticsCounters()['queries']
+        if(queriesCount == 1) then
+                return DNSAction.Spoof, "192.0.2.1"
+        elseif(queriesCount == 2) then
+                return DNSAction.Spoof, "192.0.2.2"
+        else
+                return DNSAction.Spoof, "192.0.2.0"
+        end
+    end
+    addLuaAction("luaspoofwithstats.spoofing.tests.powerdns.com.", spoof1rule)
+    newServer{address="127.0.0.1:%s"}
+    """
+
+    def testLuaSpoofBasedOnStatistics(self):
+        """
+        Spoofing: Spoofing an A via Lua based on statistics counters
+
+        """
+        name = 'luaspoofwithstats.spoofing.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN')
+        # dnsdist set RA = RD for spoofed responses
+        query.flags &= ~dns.flags.RD
+        expectedResponse1 = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    60,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '192.0.2.1')
+        expectedResponse1.answer.append(rrset)
+        expectedResponse2 = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    60,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '192.0.2.2')
+        expectedResponse2.answer.append(rrset)
+        expectedResponseAfterwards = dns.message.make_response(query)
+        rrset = dns.rrset.from_text(name,
+                                    60,
+                                    dns.rdataclass.IN,
+                                    dns.rdatatype.A,
+                                    '192.0.2.0')
+        expectedResponseAfterwards.answer.append(rrset)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertTrue(receivedResponse)
+        self.assertEquals(expectedResponse1, receivedResponse)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertTrue(receivedResponse)
+        self.assertEquals(expectedResponse2, receivedResponse)
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertTrue(receivedResponse)
+        self.assertEquals(expectedResponseAfterwards, receivedResponse)
+
+        (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
+        self.assertTrue(receivedResponse)
+        self.assertEquals(expectedResponseAfterwards, receivedResponse)