From: Remi Gacogne Date: Wed, 30 Mar 2016 21:48:25 +0000 (+0200) Subject: dnsdist: Under threshold, QPS action should return None, not Allow X-Git-Tag: dnsdist-1.0.0-beta1~49^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=856c35e3fa6e75b501a41d5abe0de6239ddf858d;p=pdns dnsdist: Under threshold, QPS action should return None, not Allow Closes #3638. --- diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 6f15664bb..ec0864d34 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -365,7 +365,7 @@ public: DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override { if(d_qps.check()) - return Action::Allow; + return Action::None; else return Action::Drop; } diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 24e66d254..a4b31356d 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -1,6 +1,7 @@ #!/usr/bin/env python from datetime import datetime, timedelta import os +import time import dns from dnsdisttests import DNSDistTest @@ -873,3 +874,78 @@ class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest): (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) self.assertTrue(receivedResponse) self.assertEquals(response, receivedResponse) + +class TestAdvancedQPS(DNSDistTest): + + _config_template = """ + addQPSLimit("qps.advanced.tests.powerdns.com", 10) + newServer{address="127.0.0.1:%s"} + """ + + def testAdvancedQPSLimit(self): + """ + Advanced: QPS Limit + + Send queries to "qps.advanced.tests.powerdns.com." + check that dnsdist drops queries when the max QPS has been reached. + """ + maxQPS = 10 + name = 'qps.advanced.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + for _ in range(maxQPS): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEquals(query, receivedQuery) + self.assertEquals(response, receivedResponse) + + # we should now be dropped + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEquals(receivedResponse, None) + + time.sleep(1) + + # again, over TCP this time + for _ in range(maxQPS): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEquals(query, receivedQuery) + self.assertEquals(response, receivedResponse) + + + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEquals(receivedResponse, None) + +class TestAdvancedQPSNone(DNSDistTest): + + _config_template = """ + addQPSLimit("qpsnone.advanced.tests.powerdns.com", 100) + addAction(AllRule(), RCodeAction(5)) + newServer{address="127.0.0.1:%s"} + """ + + def testAdvancedQPSNone(self): + """ + Advanced: Not matching QPS returns None, not Allow + + Send queries to "qps.advanced.tests.powerdns.com." + check that the rule returns None when the QPS has not been + reached, not Allow. + """ + name = 'qpsnone.advanced.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(dns.rcode.REFUSED) + + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEquals(receivedResponse, expectedResponse) + + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEquals(receivedResponse, expectedResponse)