Comparison

mod_throttle_unsolicited/mod_throttle_unsolicited.lua @ 2082:163d55777ad5

mod_throttle_unsolicited: Limit rate of unsolicited messages sent to non-contacts
author Kim Alvefur <zash@zash.se>
date Mon, 14 Mar 2016 13:36:50 +0100
child 2120:f6dcfe263b85
comparison
equal deleted inserted replaced
2081:73096d8d924c 2082:163d55777ad5
1 local st = require"util.stanza";
2 local jid_split = require "util.jid".split;
3 local jid_bare = require "util.jid".bare;
4 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
5 local throttle = require "util.throttle";
6
7 local sessions = prosody.full_sessions;
8
9 local max = module:get_option_number("unsolicited_messages_per_minute", 10);
10 local multiplier = module:get_option_number("throttle_unsolicited_burst", 1);
11
12 function check_subscribed(event)
13 local stanza, origin = event.stanza, event.origin;
14 local log = origin.log or module._log;
15 log("debug", "check_subscribed(%s)", stanza:top_tag());
16 if stanza.attr.type == "error" then return end
17
18 -- Check if it's a message to a joined room
19 local to_bare = jid_bare(stanza.attr.to);
20 local rooms = origin.rooms_joined;
21 if rooms and rooms[to_bare] then
22 log("debug", "Message to joined room, no limit");
23 return
24 end
25
26 -- Retrieve or create throttle object
27 local lim = origin.throttle_unsolicited;
28 if not lim then
29 log("debug", "New throttle");
30 lim = throttle.create(max * multiplier, 60 * multiplier);
31 origin.throttle_unsolicited = lim;
32 end
33
34 local to_user, to_host = jid_split(stanza.attr.to);
35 local from_jid = jid_bare(stanza.attr.from);
36 if to_user and not is_contact_subscribed(to_user, to_host, from_jid) then
37 log("debug", "%s is not subscribed to %s@%s", from_jid, to_user, to_host);
38 if not lim:poll(1) then
39 log("warn", "Sent too many messages to non-contacts, bouncing message");
40 event.origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
41 return true;
42 end
43 end
44 end
45
46 module:hook("pre-message/bare", check_subscribed, 200);
47 module:hook("pre-message/full", check_subscribed, 200);
48
49 module:depends("track_muc_joins");