Software / code / prosody-modules
Comparison
mod_s2s_keepalive/mod_s2s_keepalive.lua @ 3765:11878130f266
mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 21 Dec 2019 17:52:32 +0100 |
| parent | 3764:07a1faa24261 |
| child | 3766:f547eafb5a6d |
comparison
equal
deleted
inserted
replaced
| 3764:07a1faa24261 | 3765:11878130f266 |
|---|---|
| 1 local st = require "util.stanza"; | 1 local st = require "util.stanza"; |
| 2 local watchdog = require "util.watchdog"; | |
| 2 | 3 |
| 3 local keepalive_servers = module:get_option_set("keepalive_servers"); | 4 local keepalive_servers = module:get_option_set("keepalive_servers"); |
| 4 local keepalive_interval = module:get_option_number("keepalive_interval", 60); | 5 local keepalive_interval = module:get_option_number("keepalive_interval", 60); |
| 6 local keepalive_timeout = module:get_option_number("keepalive_timeout", 593); | |
| 5 | 7 |
| 6 local host = module.host; | 8 local host = module.host; |
| 7 local s2sout = prosody.hosts[host].s2sout; | 9 local s2sout = prosody.hosts[host].s2sout; |
| 8 | 10 |
| 9 local function send_pings() | 11 local function send_pings() |
| 13 if session.type == "s2sout" -- as opposed to _unauthed | 15 if session.type == "s2sout" -- as opposed to _unauthed |
| 14 and (not(keepalive_servers) or keepalive_servers:contains(remote_domain)) then | 16 and (not(keepalive_servers) or keepalive_servers:contains(remote_domain)) then |
| 15 session.sends2s(st.iq({ to = remote_domain, type = "get", from = host, id = "keepalive" }) | 17 session.sends2s(st.iq({ to = remote_domain, type = "get", from = host, id = "keepalive" }) |
| 16 :tag("ping", { xmlns = "urn:xmpp:ping" }) | 18 :tag("ping", { xmlns = "urn:xmpp:ping" }) |
| 17 ); | 19 ); |
| 18 -- Note: We don't actually check if this comes back. | |
| 19 end | 20 end |
| 20 end | 21 end |
| 21 | 22 |
| 22 for session in pairs(prosody.incoming_s2s) do | 23 for session in pairs(prosody.incoming_s2s) do |
| 23 if session.type == "s2sin" -- as opposed to _unauthed | 24 if session.type == "s2sin" -- as opposed to _unauthed |
| 36 end | 37 end |
| 37 | 38 |
| 38 return keepalive_interval; | 39 return keepalive_interval; |
| 39 end | 40 end |
| 40 | 41 |
| 42 module:hook("s2sin-established", function (event) | |
| 43 local session = event.session; | |
| 44 if session.watchdog_keepalive then return end -- in case mod_bidi fires this twice | |
| 45 session.watchdog_keepalive = watchdog.new(keepalive_timeout, function () | |
| 46 session.log("info", "Keepalive ping timed out, closing connection"); | |
| 47 session:close("connection-timeout"); | |
| 48 end); | |
| 49 end); | |
| 50 | |
| 51 module:hook("s2sout-established", function (event) | |
| 52 local session = event.session; | |
| 53 if session.watchdog_keepalive then return end -- in case mod_bidi fires this twice | |
| 54 session.watchdog_keepalive = watchdog.new(keepalive_timeout, function () | |
| 55 session.log("info", "Keepalive ping timed out, closing connection"); | |
| 56 session:close("connection-timeout"); | |
| 57 end); | |
| 58 end); | |
| 59 | |
| 60 module:hook("iq-result/host/keepalive", function (event) | |
| 61 local origin = event.origin; | |
| 62 if origin.watchdog_keepalive then | |
| 63 origin.watchdog_keepalive:reset(); | |
| 64 end | |
| 65 if s2sout[origin.from_host] then | |
| 66 s2sout[origin.from_host]:reset(); | |
| 67 end | |
| 68 end); | |
| 69 | |
| 70 module:hook("iq-error/host/keepalive", function (event) | |
| 71 local origin = event.origin; | |
| 72 if origin.dummy then return end -- Probably a sendq bounce | |
| 73 | |
| 74 if origin.type == "s2sin" or origin.type == "s2sout" then | |
| 75 -- An error from the remote means connectivity is ok, | |
| 76 -- so treat it the same as a result | |
| 77 return module:fire_event("iq-result/host/keepalive"); | |
| 78 end | |
| 79 end); | |
| 80 | |
| 41 module:add_timer(keepalive_interval, send_pings); | 81 module:add_timer(keepalive_interval, send_pings); |