From: Remi Gacogne Date: Mon, 31 Oct 2016 10:49:47 +0000 (+0100) Subject: dnsdist: Add `getStatisticsCounters()` to access counters from Lua X-Git-Tag: dnsdist-1.1.0-beta2~59^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F4653%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Add `getStatisticsCounters()` to access counters from Lua --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 9334932781..65fa6a8f68 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -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 diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 7afe7c0f87..0c3362e4b1 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -1012,4 +1012,14 @@ void moreLua(bool client) }); #endif /* HAVE_EBPF */ + + g_lua.writeFunction()>("getStatisticsCounters", []() { + setLuaNoSideEffect(); + std::unordered_map res; + for(const auto& entry : g_stats.entries) { + if(const auto& val = boost::get(&entry.second)) + res[entry.first] = (*val)->load(); + } + return res; + }); } diff --git a/regression-tests.dnsdist/test_Spoofing.py b/regression-tests.dnsdist/test_Spoofing.py index cc817462d4..7c271a0692 100644 --- a/regression-tests.dnsdist/test_Spoofing.py +++ b/regression-tests.dnsdist/test_Spoofing.py @@ -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)