]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
support multiple addresses in daf src/dst filter
authorAnbang Wen <anbang@cloudflare.com>
Tue, 14 Aug 2018 23:10:10 +0000 (16:10 -0700)
committerMarek Vavruša <mvavrusa@cloudflare.com>
Fri, 7 Sep 2018 17:45:21 +0000 (10:45 -0700)
This enables using syntax like "src { CIDR-a CIDR-b } deny" to specify
multiple addresses to filter. All the conditions are ORed together
like qname/ns.

modules/daf/daf.lua
modules/daf/daf.test.lua

index 349100387056ca4aebf2f24607bc974f0ffe1f62..41651fb629f576f52753dfc3a4916910e60fa308 100644 (file)
@@ -190,13 +190,37 @@ M.filters = {
        end,
        -- Filter on source address
        src = function (op, arg)
-               if op ~= '=' or #arg ~= 1 then error('address supports only "=" operator with single argument') end
-               return view.rule_src(true, arg[1])
+               if op ~= '=' or #arg == 0 then
+                       error('address supports only "=" operator with one or more arguments')
+               end
+
+               local f
+               for _, v in ipairs(arg) do
+                       local fa, fb = f, view.rule_src(true, v)
+                       if f == nil then
+                               f = fb
+                       else
+                               f = function (req, qry) return fa(req, qry) or fb(req, qry) end
+                       end
+               end
+               return f
        end,
        -- Filter on destination address
        dst = function (op, arg)
-               if op ~= '=' or #arg ~= 1 then error('address supports only "=" operator with single argument') end
-               return view.rule_dst(true, arg[1])
+               if op ~= '=' or #arg == 0 then
+                       error('address supports only "=" operator with one or more arguments')
+               end
+
+               local f
+               for _, v in ipairs(arg) do
+                       local fa, fb = f, view.rule_dst(true, v)
+                       if f == nil then
+                               f = fb
+                       else
+                               f = function (req, qry) return fa(req, qry) or fb(req, qry) end
+                       end
+               end
+               return f
        end,
 }
 
index 8aeb045b55ae9dad5bafe75dda1ef4d5e88b4444..06dc90883e75d7396bbe6de6f073494786780f6e 100644 (file)
@@ -104,6 +104,11 @@ local function test_parser()
        nok(daf.compile('qname ~ {A AAAA} deny'), 'rejects "qname ~ {A AAAA} deny"')
        nok(daf.compile('qname and'), 'rejects "qname and"')
        nok(daf.compile('qname A or'), 'rejects "qname A or"')
+       nok(daf.compile('src ~ 192.0.2.0'), 'src only support =')
+
+       -- valid rules
+       ok(daf.compile('src = 192.0.2.0/24 deny'), 'filter on CIDR')
+       ok(daf.compile('dst { 192.0.2.0/32 192.0.2.1 } deny'), 'filter on multiple addresses')
 
        local filters = {
                -- test catch all
@@ -192,4 +197,4 @@ local tests = {
        test_features,
 }
 
-return tests
\ No newline at end of file
+return tests