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; |
