From e191475653c77bf21b680c47359ab1cfc018147b Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Fri, 20 Jan 2017 10:59:26 +0100 Subject: [PATCH] TT#9402 refresh modules from upstream * migrate from files to dirs as upstream * refresh debian/control list of modules * refresh mod_auth_sql.patch * update_plugins.sh for automate the process * keep the list of prosody modules at prosody-modules.list file * keep the upstream mercurial revision at prosody-modules.revision file Change-Id: Id4a0a2c4e88dae64641270ee79c6ee206f5bb695 --- debian/control | 15 +- debian/ngcp-prosody-modules.docs | 1 + debian/patches/mod_auth_sql.path | 4 +- debian/rules | 14 ++ plugins/mod_auth_sql/README.markdown | 40 ++++++ plugins/{ => mod_auth_sql}/mod_auth_sql.lua | 0 plugins/mod_blocking/README.markdown | 54 ++++++++ plugins/{ => mod_blocking}/mod_blocking.lua | 0 plugins/mod_carbons/README.markdown | 49 +++++++ plugins/{ => mod_carbons}/mod_carbons.lua | 16 +-- .../mod_carbons_adhoc.lua | 0 .../mod_carbons_copies.lua | 0 plugins/mod_csi/README.markdown | 32 +++++ plugins/{ => mod_csi}/mod_csi.lua | 0 plugins/mod_filter_chatstates/README.markdown | 26 ++++ .../mod_filter_chatstates.lua | 0 plugins/mod_limit_auth/README.markdown | 35 +++++ .../{ => mod_limit_auth}/mod_limit_auth.lua | 0 plugins/mod_log_auth/README.markdown | 49 +++++++ plugins/{ => mod_log_auth}/mod_log_auth.lua | 2 +- plugins/mod_mam/README.markdown | 128 ++++++++++++++++++ plugins/mod_smacks/README.markdown | 76 +++++++++++ plugins/{ => mod_smacks}/mod_smacks.lua | 56 ++++++-- plugins/mod_throttle_presence/README.markdown | 31 +++++ .../mod_throttle_presence.lua | 0 prosody-modules.list | 13 ++ prosody-modules.revision | 1 + update_plugins.sh | 44 ++++++ 28 files changed, 663 insertions(+), 23 deletions(-) create mode 100644 debian/ngcp-prosody-modules.docs create mode 100644 plugins/mod_auth_sql/README.markdown rename plugins/{ => mod_auth_sql}/mod_auth_sql.lua (100%) create mode 100644 plugins/mod_blocking/README.markdown rename plugins/{ => mod_blocking}/mod_blocking.lua (100%) create mode 100644 plugins/mod_carbons/README.markdown rename plugins/{ => mod_carbons}/mod_carbons.lua (88%) rename plugins/{ => mod_carbons_adhoc}/mod_carbons_adhoc.lua (100%) rename plugins/{ => mod_carbons_copies}/mod_carbons_copies.lua (100%) create mode 100644 plugins/mod_csi/README.markdown rename plugins/{ => mod_csi}/mod_csi.lua (100%) create mode 100644 plugins/mod_filter_chatstates/README.markdown rename plugins/{ => mod_filter_chatstates}/mod_filter_chatstates.lua (100%) create mode 100644 plugins/mod_limit_auth/README.markdown rename plugins/{ => mod_limit_auth}/mod_limit_auth.lua (100%) create mode 100644 plugins/mod_log_auth/README.markdown rename plugins/{ => mod_log_auth}/mod_log_auth.lua (76%) create mode 100644 plugins/mod_mam/README.markdown create mode 100644 plugins/mod_smacks/README.markdown rename plugins/{ => mod_smacks}/mod_smacks.lua (87%) create mode 100644 plugins/mod_throttle_presence/README.markdown rename plugins/{ => mod_throttle_presence}/mod_throttle_presence.lua (100%) create mode 100644 prosody-modules.list create mode 100644 prosody-modules.revision create mode 100755 update_plugins.sh diff --git a/debian/control b/debian/control index de4fd0c..b4302be 100644 --- a/debian/control +++ b/debian/control @@ -43,12 +43,19 @@ Description: ngcp modules for the prosody Jabber/XMPP server The following modules are from prosody-modules: . * mod_auth_sql.lua: simple SQL Authentication module + * mod_blocking: allows the client to manage a simple + list of blocked JIDs * mod_carbons: XEP-0280: Message Carbons + * mod_carbons_adhoc + * mod_carbons_copies + * mod_csi: XEP-0352: Client State Indication + * mod_filter_chatstates: will filter Chat State Notifications out + while the session is considered inactive + * mod_limit_auth: lets you put a per-IP limit on the number of + failed authentication attempts * mod_log_auth: logs IP address in a failed authentication attempt - * mod_websocket.lua: XMPP over websocket * mod_man: XEP-0313: Message Archive Management - * mod_csi: XEP-0352: Client State Indication + * mod_smacks: XEP-0198: Stream Management * mod_throttle_presence: cuts down on presence traffic when clients indicate they are inactive - * mod_filter_chatstates: will filter Chat State Notifications out - while the session is considered inactive + * mod_websocket.lua: XMPP over websocket diff --git a/debian/ngcp-prosody-modules.docs b/debian/ngcp-prosody-modules.docs new file mode 100644 index 0000000..547bb7b --- /dev/null +++ b/debian/ngcp-prosody-modules.docs @@ -0,0 +1 @@ +debian/README_mod* diff --git a/debian/patches/mod_auth_sql.path b/debian/patches/mod_auth_sql.path index 0eefd9d..ee57cfd 100644 --- a/debian/patches/mod_auth_sql.path +++ b/debian/patches/mod_auth_sql.path @@ -2,8 +2,8 @@ From: Andreas Granig Date: Wed Aug 7 22:34:34 2013 +0200 Subject: sipwise custom auth --- ---- a/plugins/mod_auth_sql.lua -+++ b/plugins/mod_auth_sql.lua +--- a/plugins/mod_auth_sql/mod_auth_sql.lua ++++ b/plugins/mod_auth_sql/mod_auth_sql.lua @@ -71,7 +71,7 @@ local function getsql(sql, ...) end diff --git a/debian/rules b/debian/rules index bc7f149..9ffdfea 100755 --- a/debian/rules +++ b/debian/rules @@ -4,3 +4,17 @@ %: dh $@ --with quilt + +override_dh_auto_configure: + while read module ; do \ + if [ -f plugins/$$module/README.markdown ] ; then \ + cp plugins/$$module/README.markdown debian/README_$$module.markdown; \ + fi; \ + done < prosody-modules.list; \ + +override_dh_install: + dh_install + find debian/ngcp-prosody-modules/ -name README.\* -delete + +override_dh_auto_clean: + rm -f debian/README_mod_*.* diff --git a/plugins/mod_auth_sql/README.markdown b/plugins/mod_auth_sql/README.markdown new file mode 100644 index 0000000..31485d1 --- /dev/null +++ b/plugins/mod_auth_sql/README.markdown @@ -0,0 +1,40 @@ +--- +labels: +- 'Type-Auth' +- 'Stage-Stable' +summary: SQL Database authentication module +... + +Introduction +============ + +Allow client authentication to be handled by an SQL database query. + +Unlike mod\_storage\_sql (which is supplied with Prosody) this module +allows for custom schemas (though currently it is required to edit the +source). + +Configuration +============= + +As with all auth modules, there is no need to add this to +modules\_enabled. Simply add in the global section, or for the relevant +hosts: + + authentication = "sql" + +This module reuses the database configuration of +[mod\_storage\_sql](http://prosody.im/doc/modules/mod_storage_sql) (the +'sql' option), which you can set even if you are not using SQL as +Prosody's primary storage backend. + +The query is currently hardcoded in the module, so you will need to edit +the module to change it. The default query is compatible with jabberd2 +DB schema. + +Compatibility +============= + + ----- ------- + 0.8 Works + ----- ------- diff --git a/plugins/mod_auth_sql.lua b/plugins/mod_auth_sql/mod_auth_sql.lua similarity index 100% rename from plugins/mod_auth_sql.lua rename to plugins/mod_auth_sql/mod_auth_sql.lua diff --git a/plugins/mod_blocking/README.markdown b/plugins/mod_blocking/README.markdown new file mode 100644 index 0000000..21b2a26 --- /dev/null +++ b/plugins/mod_blocking/README.markdown @@ -0,0 +1,54 @@ +--- +labels: +- 'Stage-Alpha' +summary: 'XEP-0191: Simple Communications Blocking support' +... + +Introduction +============ + +Privacy lists are a widely implemented protocol for instructing your +server on blocking communications with selected users and services. + +However experience has shown that the power and flexibility of the +rule-based system that privacy lists allow is very often much more +complex than the user needs, and that in most cases a simple block on +all communications to or from a list of specified JIDs would suffice. + +Such a protocol would also allow much simpler user interface design than +the current attempts at full privacy list interfaces. + +Details +======= + +Simple Communications Blocking was developed to solve the above issues, +and allows the client to manage a simple list of blocked JIDs. This +plugin implements support for that protocol in Prosody, however the +actual blocking is still managed by mod\_privacy, so it is **required** +for that plugin to be loaded (this may change in future). + +An XEP-0191 implementation without dependency on mod\_privacy is +available in Prosody 0.10 as [mod\_blocklist][doc:modules:mod_blocklist]. + +Configuration +============= + +Simply ensure that mod\_privacy (or [mod\_privacy\_lists] in 0.10+) and +mod\_blocking are loaded in your modules\_enabled list: + + modules_enabled = { + -- ... + "privacy", -- or privacy_lists in Prosody 0.10+ + "blocking", + -- ... + +Compatibility +============= + + ------ --------------------------------------------- + 0.10 Works but will conflict with mod\_blocklist + 0.9 Works + 0.8 Works + 0.7 Works + 0.6 Doesn't work + ------ --------------------------------------------- diff --git a/plugins/mod_blocking.lua b/plugins/mod_blocking/mod_blocking.lua similarity index 100% rename from plugins/mod_blocking.lua rename to plugins/mod_blocking/mod_blocking.lua diff --git a/plugins/mod_carbons/README.markdown b/plugins/mod_carbons/README.markdown new file mode 100644 index 0000000..1778134 --- /dev/null +++ b/plugins/mod_carbons/README.markdown @@ -0,0 +1,49 @@ +--- +labels: +- 'Stage-Beta' +summary: Message Carbons +... + +Introduction +============ + +This module implements [XEP-0280: Message +Carbons](http://xmpp.org/extensions/xep-0280.html), allowing users to +maintain a shared and synchronized view of all conversations across all +their online clients and devices. + +Configuration +============= + +As with all modules, you enable it by adding it to the modules\_enabled +list. + + modules_enabled = { + ... + "carbons"; + ... + } + +The module has no further configuration. + +Clients +======= + +Clients that support XEP-0280: + +- [Gajim](http://gajim.org/) (Desktop) +- [Adium (1.6)](http://adium.im/) (Desktop - OS X) +- [Yaxim](http://yaxim.org/) (Mobile - Android) +- [Conversations](https://play.google.com/store/apps/details?id=eu.siacs.conversations) + (Mobile - Android) +- [poezio](http://poezio.eu/en/) (Console) + +Compatibility +============= + + ------- ----------------------- + 0.8 Works + 0.9 Works + 0.10 Included with prosody + trunk Included with prosody + ------- ----------------------- diff --git a/plugins/mod_carbons.lua b/plugins/mod_carbons/mod_carbons.lua similarity index 88% rename from plugins/mod_carbons.lua rename to plugins/mod_carbons/mod_carbons.lua index 2fa1914..5bf2e14 100644 --- a/plugins/mod_carbons.lua +++ b/plugins/mod_carbons/mod_carbons.lua @@ -1,5 +1,5 @@ -- XEP-0280: Message Carbons implementation for Prosody --- Copyright (C) 2011 Kim Alvefur +-- Copyright (C) 2011-2016 Kim Alvefur -- -- This file is MIT/X11 licensed. @@ -33,7 +33,7 @@ local function message_handler(event, c2s) local orig_from = stanza.attr.from; local orig_to = stanza.attr.to; - if not(orig_type == "chat" or orig_type == "normal" and stanza:get_child("body")) then + if not(orig_type == "chat" or (orig_type == "normal" and stanza:get_child("body"))) then return -- Only chat type messages end @@ -74,7 +74,7 @@ local function message_handler(event, c2s) elseif stanza:get_child("no-copy", "urn:xmpp:hints") then module:log("debug", "Message has no-copy hint, ignoring"); return - elseif stanza:get_child("x", "http://jabber.org/protocol/muc#user") then + elseif not c2s and bare_jid == orig_from and stanza:get_child("x", "http://jabber.org/protocol/muc#user") then module:log("debug", "MUC PM, ignoring"); return end @@ -122,12 +122,12 @@ local function c2s_message_handler(event) end -- Stanzas sent by local clients -module:hook("pre-message/host", c2s_message_handler, 1); -module:hook("pre-message/bare", c2s_message_handler, 1); -module:hook("pre-message/full", c2s_message_handler, 1); +module:hook("pre-message/host", c2s_message_handler, 0.05); -- priority between mod_message (0 in 0.9) and mod_firewall (0.1) +module:hook("pre-message/bare", c2s_message_handler, 0.05); +module:hook("pre-message/full", c2s_message_handler, 0.05); -- Stanzas to local clients -module:hook("message/bare", message_handler, 1); -module:hook("message/full", message_handler, 1); +module:hook("message/bare", message_handler, 0.05); +module:hook("message/full", message_handler, 0.05); module:add_feature(xmlns_carbons); module:add_feature(xmlns_carbons_old); diff --git a/plugins/mod_carbons_adhoc.lua b/plugins/mod_carbons_adhoc/mod_carbons_adhoc.lua similarity index 100% rename from plugins/mod_carbons_adhoc.lua rename to plugins/mod_carbons_adhoc/mod_carbons_adhoc.lua diff --git a/plugins/mod_carbons_copies.lua b/plugins/mod_carbons_copies/mod_carbons_copies.lua similarity index 100% rename from plugins/mod_carbons_copies.lua rename to plugins/mod_carbons_copies/mod_carbons_copies.lua diff --git a/plugins/mod_csi/README.markdown b/plugins/mod_csi/README.markdown new file mode 100644 index 0000000..bc748eb --- /dev/null +++ b/plugins/mod_csi/README.markdown @@ -0,0 +1,32 @@ +--- +summary: Client State Indication support +... + +Introduction +============ + +This module implements [Client State +Indication](http://xmpp.org/extensions/xep-0352.html), a way for mobile +clients to tell the server that they are sitting in someones pocket and +would rather not get some less urgent things pushed to it. + +However this module does not do anything by itself. Deciding what things +are considered "less urgent" is left to other modules. + +- [mod\_throttle\_presence](/mod_throttle_presence.html) supresses + presence updates +- [mod\_filter\_chatstates](/mod_filter_chatstates.html) removes chat + states (*Someone is typing...*) + +Configuration +============= + +There is no configuration for this module, just add it to +modules\_enabled as normal. + +Compatibility +============= + + ----- ------- + 0.9 Works + ----- ------- diff --git a/plugins/mod_csi.lua b/plugins/mod_csi/mod_csi.lua similarity index 100% rename from plugins/mod_csi.lua rename to plugins/mod_csi/mod_csi.lua diff --git a/plugins/mod_filter_chatstates/README.markdown b/plugins/mod_filter_chatstates/README.markdown new file mode 100644 index 0000000..66d8898 --- /dev/null +++ b/plugins/mod_filter_chatstates/README.markdown @@ -0,0 +1,26 @@ +--- +summary: Drop chat states from messages to inactive sessions +... + +Introduction +============ + +Some mobile XMPP client developers consider [Chat State +Notifications](http://xmpp.org/extensions/xep-0085.html) to be a waste +of power and bandwidth, especially when the user is not actively looking +at their device. This module will filter them out while the session is +considered inactive. It depends on [mod\_csi](/mod_csi.html) for +deciding when to begin and end filtering. + +Configuration +============= + +There is no configuration for this module, just add it to +modules\_enabled as normal. + +Compatibility +============= + + ----- ------- + 0.9 Works + ----- ------- diff --git a/plugins/mod_filter_chatstates.lua b/plugins/mod_filter_chatstates/mod_filter_chatstates.lua similarity index 100% rename from plugins/mod_filter_chatstates.lua rename to plugins/mod_filter_chatstates/mod_filter_chatstates.lua diff --git a/plugins/mod_limit_auth/README.markdown b/plugins/mod_limit_auth/README.markdown new file mode 100644 index 0000000..4cf3143 --- /dev/null +++ b/plugins/mod_limit_auth/README.markdown @@ -0,0 +1,35 @@ +--- +summary: Throttle authentication attempts with optional tarpit +... + +Introduction +============ + +This module lets you put a per-IP limit on the number of failed +authentication attempts. + +It features an optioanal +[tarpit](https://en.wikipedia.org/wiki/Tarpit_%28networking%29), i.e. +waiting some time before returning an "authentication failed" response. + +Configuration +============= + +``` {.lua} +modules_enabled = { + -- your other modules + "limit_auth"; +} + +limit_auth_period = 30 -- over 30 seconds + +limit_auth_max = 5 -- tolerate no more than 5 failed attempts + + -- Will only work with Prosody trunk: +limit_auth_tarpit_delay = 10 -- delay answer this long +``` + +Compatibility +============= + +Requires 0.9 or later. The tarpit feature requires Prosody trunk. diff --git a/plugins/mod_limit_auth.lua b/plugins/mod_limit_auth/mod_limit_auth.lua similarity index 100% rename from plugins/mod_limit_auth.lua rename to plugins/mod_limit_auth/mod_limit_auth.lua diff --git a/plugins/mod_log_auth/README.markdown b/plugins/mod_log_auth/README.markdown new file mode 100644 index 0000000..6e74d01 --- /dev/null +++ b/plugins/mod_log_auth/README.markdown @@ -0,0 +1,49 @@ +--- +labels: +- 'Stage-Stable' +summary: Log failed authentication attempts with their IP address +... + +Introduction +============ + +Prosody doesn't write IP addresses to its log file by default for +privacy reasons (unless debug logging is enabled). + +This module enables logging of the IP address in a failed authentication +attempt so that those trying to break into accounts for example can be +blocked. + +fail2ban configuration +====================== + +fail2ban is a utility for monitoring log files and automatically +blocking "bad" IP addresses at the firewall level. + +With this module enabled in Prosody you can use the following example +configuration for fail2ban: + + # /etc/fail2ban/filter.d/prosody-auth.conf + # Fail2Ban configuration file for prosody authentication + [Definition] + failregex = Failed authentication attempt \(not-authorized\) for user .* from IP: + ignoreregex = + +And at the appropriate place (usually the bottom) of +/etc/fail2ban/jail.conf add these lines: + + [prosody] + enabled = true + port = 5222 + filter = prosody-auth + logpath = /var/log/prosody/prosody*.log + maxretry = 6 + +Compatibility +------------- + + ------- -------------- + trunk Works + 0.9 Works + 0.8 Doesn't work + ------- -------------- diff --git a/plugins/mod_log_auth.lua b/plugins/mod_log_auth/mod_log_auth.lua similarity index 76% rename from plugins/mod_log_auth.lua rename to plugins/mod_log_auth/mod_log_auth.lua index ddea907..0dd607c 100644 --- a/plugins/mod_log_auth.lua +++ b/plugins/mod_log_auth/mod_log_auth.lua @@ -3,7 +3,7 @@ assert(({ all = true, failure = true, success = true })[mode], "Unknown log mode if mode == "failure" or mode == "all" then module:hook("authentication-failure", function (event) - module:log("info", "Failed authentication attempt (%s) from IP: %s", event.condition or "unknown-condition", event.session.ip or "?"); + module:log("info", "Failed authentication attempt (%s) for user %s from IP: %s", event.condition or "unknown-condition", event.session.username or "?", event.session.ip or "?"); end); end diff --git a/plugins/mod_mam/README.markdown b/plugins/mod_mam/README.markdown new file mode 100644 index 0000000..38a0591 --- /dev/null +++ b/plugins/mod_mam/README.markdown @@ -0,0 +1,128 @@ +--- +labels: +- 'Stage-Beta' +summary: 'XEP-0313: Message Archive Management' +... + +Introduction +============ + +Implementation of [XEP-0313: Message Archive Management]. + +Details +======= + +This module will archive all messages that match the simple rules setup +by the user, and allow the user to access this archive. + +Usage +===== + +First copy the module to the prosody plugins directory. + +Then add "mam" to your modules\_enabled list: + +``` {.lua} +modules_enabled = { + -- ... + "mam", + -- ... +} +``` + +Configuration +============= + +Option summary +-------------- + + option type default + ------------------------------ ----------------------- ----------- + max\_archive\_query\_results number `50` + default\_archive\_policy boolean or `"roster"` `true` + archive\_expires\_after string `"1w"` + archive\_cleanup\_interval number `4*60*60` + + +Storage backend +--------------- + +mod\_mam uses the store "archive2"[^1]. See [Prosodys data storage +documentation][doc:storage] for information on how to configure storage. + +For example, to use mod\_storage\_sql (requires Prosody 0.10 or later): + +``` {.lua} +storage = { + archive2 = "sql"; +} +``` + +If no archive-capable storage backend can be opened then an in-memory +one will be used as fallback. + +Query size limits +----------------- + + max_archive_query_results = 20; + +This is the largest number of messages that are allowed to be retrieved +in one request *page*. A query that does not fit in one page will +include a reference to the next page, letting clients page through the +result set. Setting large number is not recomended, as Prosody will be +blocked while processing the request and will not be able to do anything +else. + +Archive expiry +-------------- + +Messages in the archive will expire after some time, by default one +week. This can be changed by setting `archive_expires_after`: + +``` {.lua} +archive_expires_after = "1d" -- one day + +archive_expires_after = "1w" -- one week, the default + +archive_expires_after = "2m" -- two months + +archive_expires_after = "1y" -- one year + +archive_expires_after = 60 * 60 -- one hour + +archive_expires_after = "never" -- forever +``` + +The format is an integer number of seconds or a multiple of a period +given by a suffix that can be one of `d` (day), `w` (week), `m` (month) +or `y` (year). No multiplier means seconds. + +Message matching policy +----------------------- + +The MAM protocol includes a way for clients to control what messages +should be stored. This allows users to enable or disable archiving by +default or for specific contacts. + +``` {.lua} +default_archive_policy = true +``` + + `default_archive_policy =` Meaning + ---------------------------- ------------------------------------------------------ + `false` Store no messages. + `"roster"` Store messages to/from contacts in the users roster. + `true` Store all messages. This is the default. + +Compatibility +============= + + ------- --------------- + trunk Works + 0.10 Works + 0.9 Works + 0.8 Does not work + ------- --------------- + +[^1]: Might be changed to "mam" at some point + diff --git a/plugins/mod_smacks/README.markdown b/plugins/mod_smacks/README.markdown new file mode 100644 index 0000000..ea8c9fe --- /dev/null +++ b/plugins/mod_smacks/README.markdown @@ -0,0 +1,76 @@ +--- +labels: +- 'Stage-Alpha' +summary: 'XEP-0198: Reliability and fast reconnects for XMPP' +... + +Introduction +============ + +By default XMPP is as reliable as your network is. Unfortunately in some +cases that is not very reliable - in some network conditions disconnects +can be frequent and message loss can occur. + +To overcome this, XMPP has an optional extension (XEP-0198: Stream +Management) which, when supported by both the client and server, can +allow a client to resume a disconnected session, and prevent message +loss. + +Details +======= + +When using XEP-0198 both the client and the server keep a queue of the +most recently sent stanzas - this is cleared when the other end +acknowledges they have received the stanzas. If the client disconnects, +instead of marking the user offline the server pretends the client is +still online for a short (configurable) period of time. If the client +reconnects within this period, any stanzas in the queue that the client +did not receive are re-sent. + +If the client fails to reconnect before the timeout then it is marked +offline as normal, and any stanzas in the queue are returned to the +sender as a "recipient-unavailable" error. + +If you don't want this behaviour on timeout you can use [mod_smacks_offline] +or [mod_smacks_noerror] to customize the behaviour further. + +This module also provides some events used by [mod_cloud_notify]. +These events are: "smacks-ack-delayed", "smacks-hibernation-start" and +"smacks-hibernation-end". See [mod_cloud_notify] for details on how this +events are used there. + +Configuration +============= + + Option Default Description + ------------------------------ ----------------- ----------------------------------------------------------------------------------------- + `smacks_hibernation_time` 300 (5 minutes) The number of seconds a disconnected session should stay alive for (to allow reconnect) + `smacks_enabled_s2s` false Enable Stream Management on server connections? *Experimental* + `smacks_max_unacked_stanzas` 0 How many stanzas to send before requesting acknowledgement + `smacks_max_ack_delay` 60 (1 minute) The number of seconds an ack must be unanswered to trigger an "smacks-ack-delayed" event + +Compatibility +============= + + ----- ----------------------------------- + 0.10 Works + 0.9 Works + 0.8 Works, use version [7693724881b3] + ----- ----------------------------------- + + +Clients +======= + +Clients that support XEP-0198: + +- Gajim +- Swift (but not resumption, as of version 2.0 and alphas of 3.0) +- Psi (in an unreleased branch) +- Conversations +- Yaxim + +[7693724881b3]: //hg.prosody.im/prosody-modules/raw-file/7693724881b3/mod_smacks/mod_smacks.lua +[mod_smacks_offline]: //modules.prosody.im/mod_smacks_offline +[mod_smacks_noerror]: //modules.prosody.im/mod_smacks_noerror +[mod_cloud_notify]: //modules.prosody.im/mod_cloud_notify diff --git a/plugins/mod_smacks.lua b/plugins/mod_smacks/mod_smacks.lua similarity index 87% rename from plugins/mod_smacks.lua rename to plugins/mod_smacks/mod_smacks.lua index c80aa46..e32f19f 100644 --- a/plugins/mod_smacks.lua +++ b/plugins/mod_smacks/mod_smacks.lua @@ -5,6 +5,7 @@ -- Copyright (C) 2012-2015 Kim Alvefur -- Copyright (C) 2012 Thijs Alkemade -- Copyright (C) 2014 Florian Zeitz +-- Copyright (C) 2016 Thilo Molitor -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. @@ -33,17 +34,26 @@ local resume_timeout = module:get_option_number("smacks_hibernation_time", 300); local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", false); local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false); local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0); +local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 60); local core_process_stanza = prosody.core_process_stanza; local sessionmanager = require"core.sessionmanager"; local c2s_sessions = module:shared("/*/c2s/sessions"); local session_registry = {}; +local function delayed_ack_function(session) + -- fire event only when configured to do so + if delayed_ack_timeout > 0 and session.awaiting_ack and not session.outgoing_stanza_queue == nil then + session.log("debug", "Firing event 'smacks-ack-delayed', queue = %d", #session.outgoing_stanza_queue); + module:fire_event("smacks-ack-delayed", {origin = session, queue = session.outgoing_stanza_queue}); + end +end + local function can_do_smacks(session, advertise_only) if session.smacks then return false, "unexpected-request", "Stream management is already enabled"; end local session_type = session.type; - if session_type == "c2s" then + if session.username then if not(advertise_only) and not(session.resource) then -- Fail unless we're only advertising sm return false, "unexpected-request", "Client must bind a resource before enabling stream management"; end @@ -85,11 +95,22 @@ local function outgoing_stanza_filter(stanza, session) session.log("debug", "#queue = %d", #queue); if session.hibernating then session.log("debug", "hibernating, stanza queued"); - return ""; -- Hack to make session.send() not return nil + return nil; end - if #queue > max_unacked_stanzas and not session.awaiting_ack then - session.awaiting_ack = true; - return tostring(stanza)..tostring(st.stanza("r", { xmlns = session.smacks })); + if #queue > max_unacked_stanzas and session.awaiting_ack == nil then + session.log("debug", "Queuing (in a moment)"); + session.awaiting_ack = false; + session.awaiting_ack_timer = module:add_timer(1e-06, function () + if not session.awaiting_ack then + session.log("debug", "Sending (before send)"); + (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks })) + session.log("debug", "Sending (after send)"); + session.awaiting_ack = true; + session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function() + delayed_ack_function(session); + end); + end + end); end end return stanza; @@ -109,7 +130,7 @@ local function wrap_session_out(session, resume) session.last_acknowledged_stanza = 0; end - add_filter(session, "stanzas/out", outgoing_stanza_filter, -1000); + add_filter(session, "stanzas/out", outgoing_stanza_filter, -999); local session_close = session.close; function session.close(...) @@ -126,7 +147,7 @@ local function wrap_session_in(session, resume) if not resume then session.handled_stanza_count = 0; end - add_filter(session, "stanzas/in", count_incoming_stanzas, 1000); + add_filter(session, "stanzas/in", count_incoming_stanzas, 999); return session; end @@ -165,7 +186,7 @@ module:hook_stanza(xmlns_sm3, "enable", function (session, stanza) return handle module:hook_stanza("http://etherx.jabber.org/streams", "features", function (session, stanza) - module:add_timer(0, function () + module:add_timer(1e-6, function () if can_do_smacks(session) then if stanza:get_child("sm", xmlns_sm3) then session.sends2s(st.stanza("enable", sm3_attr)); @@ -210,6 +231,12 @@ module:hook_stanza(xmlns_sm3, "r", function (origin, stanza) return handle_r(ori function handle_a(origin, stanza) if not origin.smacks then return; end origin.awaiting_ack = nil; + if origin.awaiting_ack_timer then + origin.awaiting_ack_timer:stop(); + end + if origin.delayed_ack_timer then + origin.delayed_ack_timer:stop(); + end -- Remove handled stanzas from outgoing_stanza_queue --log("debug", "ACK: h=%s, last=%s", stanza.attr.h or "", origin.last_acknowledged_stanza or ""); local h = tonumber(stanza.attr.h); @@ -272,6 +299,7 @@ module:hook("pre-resource-unbind", function (event) local hibernate_time = os_time(); -- Track the time we went into hibernation session.hibernating = hibernate_time; local resumption_token = session.resumption_token; + module:fire_event("smacks-hibernation-start", {origin = session, queue = session.outgoing_stanza_queue}); timer.add_task(resume_timeout, function () session.log("debug", "mod_smacks hibernation timeout reached..."); -- We need to check the current resumption token for this resource @@ -369,6 +397,7 @@ function handle_resume(session, stanza, xmlns_sm) -- Ok, we need to re-send any stanzas that the client didn't see -- ...they are what is now left in the outgoing stanza queue local queue = original_session.outgoing_stanza_queue; + module:fire_event("smacks-hibernation-end", {origin = session, queue = queue}); session.log("debug", "#queue = %d", #queue); for i=1,#queue do session.send(queue[i]); @@ -390,10 +419,21 @@ local function handle_read_timeout(event) local session = event.session; if session.smacks then if session.awaiting_ack then + if session.awaiting_ack_timer then + session.awaiting_ack_timer:stop(); + end + if session.delayed_ack_timer then + session.delayed_ack_timer:stop(); + end return false; -- Kick the session end + session.log("debug", "Sending (read timeout)"); + session.awaiting_ack = false; (session.sends2s or session.send)(st.stanza("r", { xmlns = session.smacks })); session.awaiting_ack = true; + session.delayed_ack_timer = module:add_timer(delayed_ack_timeout, function() + delayed_ack_function(session); + end); return true; end end diff --git a/plugins/mod_throttle_presence/README.markdown b/plugins/mod_throttle_presence/README.markdown new file mode 100644 index 0000000..c953ad6 --- /dev/null +++ b/plugins/mod_throttle_presence/README.markdown @@ -0,0 +1,31 @@ +--- +labels: +- 'Stage-Beta' +summary: Limit presence stanzas to save traffic +... + +Introduction +============ + +For most people 'presence' (status changes) of contacts make up most of +the traffic received by their client. However much of the time it is not +essential to have highly accurate presence information. + +This module automatically cuts down on presence traffic when clients +indicate they are inactive (using the [CSI protocol](mod_csi.html)). + +This is extremely valuable for mobile clients that wish to save battery +power while in the background. + +Configuration +============= + +Just load the module (e.g. in modules\_enabled). There are no +configuration options. + +Compatibility +============= + + ----- ------- + 0.9 Works + ----- ------- diff --git a/plugins/mod_throttle_presence.lua b/plugins/mod_throttle_presence/mod_throttle_presence.lua similarity index 100% rename from plugins/mod_throttle_presence.lua rename to plugins/mod_throttle_presence/mod_throttle_presence.lua diff --git a/prosody-modules.list b/prosody-modules.list new file mode 100644 index 0000000..d2d1a51 --- /dev/null +++ b/prosody-modules.list @@ -0,0 +1,13 @@ +mod_auth_sql +mod_blocking +mod_carbons +mod_carbons_adhoc +mod_carbons_copies +mod_csi +mod_filter_chatstates +mod_limit_auth +mod_log_auth +mod_mam +mod_smacks +mod_throttle_presence +mod_websocket diff --git a/prosody-modules.revision b/prosody-modules.revision new file mode 100644 index 0000000..56be96e --- /dev/null +++ b/prosody-modules.revision @@ -0,0 +1 @@ +51cf82d36a8a diff --git a/update_plugins.sh b/update_plugins.sh new file mode 100755 index 0000000..8b5b6b8 --- /dev/null +++ b/update_plugins.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +set -e + +MOD_SRC=$1 + +usage() { + echo "$0 modules_src_dir" + printf "\tmodules_src_dir:\tpath to prosody-modules mercurial source\n" +} + +refresh_sources() { + echo "refresh sources at $MOD_SRC" + ( cd "$MOD_SRC" && hg pull && hg update ) +} + +copy_modules() { + while read -r dir ; do + if [ -d "$MOD_SRC/$dir" ] ; then + cp -vr "$MOD_SRC/$dir" plugins + else + echo "$MOD_SRC/$dir no longer there" + fi + done < prosody-modules.list +} + +get_revision_id() { + (cd "$MOD_SRC/$dir" && hg id -i) > 'prosody-modules.revision' +} + +if [ $# -ne 1 ] ; then + echo "wrong number of parameters" >&2 + usage + exit 1 +fi + +if ! [ -d "$MOD_SRC" ] ; then + printf "modules_src_dir[%s] not found\n" "$MOD_SRC" +fi + +refresh_sources +copy_modules +get_revision_id +exit 0