Mercurial > prosody-modules
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 |
parents | |
children | 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"); |