comparison mod_firewall/definitions.lib.lua @ 2128:21bc4d7cddae

mod_firewall: Add support for throttling based on user-defined properties (experimental)
author Matthew Wild <mwild1@gmail.com>
date Fri, 18 Mar 2016 09:47:52 +0000
parents edec9de0220a
children 9239893a2400
comparison
equal deleted inserted replaced
2127:59023dffbdd4 2128:21bc4d7cddae
4 4
5 local definition_handlers = {}; 5 local definition_handlers = {};
6 6
7 local set = require"util.set"; 7 local set = require"util.set";
8 local new_throttle = require "util.throttle".create; 8 local new_throttle = require "util.throttle".create;
9 local new_cache = require "util.cache".new;
10
11 local multirate_cache_size = module:get_option_number("firewall_multirate_cache_limit", 1000);
9 12
10 function definition_handlers.ZONE(zone_name, zone_members) 13 function definition_handlers.ZONE(zone_name, zone_members)
11 local zone_member_list = {}; 14 local zone_member_list = {};
12 for member in zone_members:gmatch("[^, ]+") do 15 for member in zone_members:gmatch("[^, ]+") do
13 zone_member_list[#zone_member_list+1] = member; 16 zone_member_list[#zone_member_list+1] = member;
14 end 17 end
15 return set.new(zone_member_list)._items; 18 return set.new(zone_member_list)._items;
16 end 19 end
17 20
21 -- Helper function used by RATE handler
22 local function evict_only_unthrottled(name, throttle)
23 throttle:update();
24 -- Check whether the throttle is at max balance (i.e. totally safe to forget about it)
25 if throttle.balance < throttle.max then
26 -- Not safe to forget
27 return false;
28 end
29 end
30
18 function definition_handlers.RATE(name, line) 31 function definition_handlers.RATE(name, line)
19 local rate = assert(tonumber(line:match("([%d.]+)")), "Unable to parse rate"); 32 local rate = assert(tonumber(line:match("([%d.]+)")), "Unable to parse rate");
20 local burst = tonumber(line:match("%(%s*burst%s+([%d.]+)%s*%)")) or 1; 33 local burst = tonumber(line:match("%(%s*burst%s+([%d.]+)%s*%)")) or 1;
21 return new_throttle(rate*burst, burst); 34 local max_throttles = tonumber(line:match("%(%s*entries%s+([%d]+)%s*%)")) or multirate_cache_size;
35
36 local cache = new_cache(max_throttles, evict_only_unthrottled);
37
38 return {
39 single = function ()
40 return new_throttle(rate*burst, burst);
41 end;
42
43 multi = function ()
44 return {
45 poll_on = function (_, key, amount)
46 assert(key, "no key");
47 local throttle = cache:get(key);
48 if not throttle then
49 throttle = new_throttle(rate*burst, burst);
50 if not cache:set(key, throttle) then
51 module:log("warn", "Multirate '%s' has hit its maximum number of active throttles (%d), denying new events", name, max_throttles);
52 return false;
53 end
54 end
55 return throttle:poll(amount);
56 end;
57 }
58 end;
59 };
22 end 60 end
23 61
24 return definition_handlers; 62 return definition_handlers;