Mercurial > prosody-modules
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; |