mod_s2s_keepalive/mod_s2s_keepalive.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 24 Sep 2022 09:25:46 +0100
changeset 5062 39c2824c2880
parent 4633 0e60ce83205c
permissions -rw-r--r--
mod_cloud_notify: README overhaul
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local st = require "util.stanza";
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
     2
local watchdog = require "util.watchdog";
4207
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
     3
local dt = require "util.datetime";
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local keepalive_servers = module:get_option_set("keepalive_servers");
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local keepalive_interval = module:get_option_number("keepalive_interval", 60);
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
     7
local keepalive_timeout = module:get_option_number("keepalive_timeout", 593);
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local host = module.host;
3768
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    10
local s2sout = prosody.hosts[host].s2sout;
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local function send_pings()
3768
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    13
	local ping_hosts = {};
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    14
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    15
	for remote_domain, session in pairs(s2sout) do
3775
98e1e3ce307d mod_s2s_keepalive: Invert check to work with bidi connections
Kim Alvefur <zash@zash.se>
parents: 3774
diff changeset
    16
		if session.type ~= "s2sout_unauthed"
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
		and (not(keepalive_servers) or keepalive_servers:contains(remote_domain)) then
4208
a5930a185806 mod_s2s_keepalive: Fix name of timestamp function
Kim Alvefur <zash@zash.se>
parents: 4207
diff changeset
    18
			session.sends2s(st.iq({ to = remote_domain, type = "get", from = host, id = "keepalive:"..dt.datetime()})
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
				:tag("ping", { xmlns = "urn:xmpp:ping" })
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
			);
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
		end
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
	end
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
	for session in pairs(prosody.incoming_s2s) do
3775
98e1e3ce307d mod_s2s_keepalive: Invert check to work with bidi connections
Kim Alvefur <zash@zash.se>
parents: 3774
diff changeset
    25
		if session.type ~= "s2sin_unauthed"
4297
edde5905744a mod_s2s_keepalive: Don't send whitespace keepalives before s2sin stream is open
Kim Alvefur <zash@zash.se>
parents: 4217
diff changeset
    26
		and not session.notopen
3776
22f02716819f mod_s2s_keepalive: Isolate source host of pings
Kim Alvefur <zash@zash.se>
parents: 3775
diff changeset
    27
		and session.to_host == host
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
		and (not(keepalive_servers) or keepalive_servers:contains(session.from_host)) then
3768
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    29
			if not s2sout[session.from_host] then ping_hosts[session.from_host] = true; end
1264
2db2c03dfb95 mod_s2s_keepalive: Don't send directly on the connection, use sends2s
Kim Alvefur <zash@zash.se>
parents: 1110
diff changeset
    30
			session.sends2s " ";
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
			-- If the connection is dead, this should make it time out.
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
		end
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	end
3768
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    34
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    35
	-- ping remotes we only have s2sin from
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    36
	for remote_domain in pairs(ping_hosts) do
4208
a5930a185806 mod_s2s_keepalive: Fix name of timestamp function
Kim Alvefur <zash@zash.se>
parents: 4207
diff changeset
    37
		module:send(st.iq({ to = remote_domain, type = "get", from = host, id = "keepalive:"..dt.datetime() })
3768
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    38
			:tag("ping", { xmlns = "urn:xmpp:ping" })
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    39
		);
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    40
	end
07a1faa24261 mod_s2s_keepalive: Ping remotes we only have s2sin established from
Kim Alvefur <zash@zash.se>
parents: 3727
diff changeset
    41
1110
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	return keepalive_interval;
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
end
97e238ce37ce mod_s2s_keepalive: Initial commit, poke s2s connections with pings and whitespace
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    45
module:hook("s2sin-established", function (event)
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    46
	local session = event.session;
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    47
	if session.watchdog_keepalive then return end -- in case mod_bidi fires this twice
3837
580862decd77 mod_s2s_keepalive: Respect keepalive_servers when creating watchdogs
Kim Alvefur <zash@zash.se>
parents: 3776
diff changeset
    48
	if keepalive_servers and not keepalive_servers:contains(session.from_host) then return end
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    49
	session.watchdog_keepalive = watchdog.new(keepalive_timeout, function ()
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    50
		session.log("info", "Keepalive ping timed out, closing connection");
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    51
		session:close("connection-timeout");
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    52
	end);
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    53
end);
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    54
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    55
module:hook("s2sout-established", function (event)
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    56
	local session = event.session;
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    57
	if session.watchdog_keepalive then return end -- in case mod_bidi fires this twice
3837
580862decd77 mod_s2s_keepalive: Respect keepalive_servers when creating watchdogs
Kim Alvefur <zash@zash.se>
parents: 3776
diff changeset
    58
	if keepalive_servers and not keepalive_servers:contains(session.from_host) then return end
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    59
	session.watchdog_keepalive = watchdog.new(keepalive_timeout, function ()
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    60
		session.log("info", "Keepalive ping timed out, closing connection");
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    61
		session:close("connection-timeout");
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    62
	end);
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    63
end);
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    64
4216
593fd9e0a435 mod_s2s_keepalive: Fix response handler (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4208
diff changeset
    65
module:hook("iq/host", function (event)
4207
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
    66
	local stanza = event.stanza;
4632
15c4eabdcea0 mod_s2s_keepalive: Fix identification of replies (error-replies included)
Kim Alvefur <zash@zash.se>
parents: 4297
diff changeset
    67
	if stanza.attr.type ~= "result" and stanza.attr.type ~= "error" then
4216
593fd9e0a435 mod_s2s_keepalive: Fix response handler (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4208
diff changeset
    68
		return -- not a reply iq stanza
593fd9e0a435 mod_s2s_keepalive: Fix response handler (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4208
diff changeset
    69
	end
4207
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
    70
	if not (stanza.attr.id and stanza.attr.id:sub(1, #"keepalive:") == "keepalive:") then
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
    71
		return -- not a reply to this module
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
    72
	end
4633
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    73
	if stanza.attr.type == "error" then
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    74
		local err = stanza:get_child("error");
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    75
		local err_by = err and err.attr.by;
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    76
		if err_by and prosody.hosts[err_by] then
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    77
			return -- error produced by the local host
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    78
		end
0e60ce83205c mod_s2s_keepalive: Ignore errors from the local server
Kim Alvefur <zash@zash.se>
parents: 4632
diff changeset
    79
	end
4207
c4002aae4ad3 mod_s2s_keepalive: Use timestamp as iq @id
Kim Alvefur <zash@zash.se>
parents: 3837
diff changeset
    80
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    81
	local origin = event.origin;
4216
593fd9e0a435 mod_s2s_keepalive: Fix response handler (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4208
diff changeset
    82
	if origin.dummy then return end -- Probably a sendq bounce
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    83
	if origin.watchdog_keepalive then
4216
593fd9e0a435 mod_s2s_keepalive: Fix response handler (thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4208
diff changeset
    84
		origin.log("debug", "Resetting keepalive watchdog")
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    85
		origin.watchdog_keepalive:reset();
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    86
	end
3770
f547eafb5a6d mod_s2s_keepalive: Fix s2sout watchdog reset
Kim Alvefur <zash@zash.se>
parents: 3769
diff changeset
    87
	if s2sout[origin.from_host] and s2sout[origin.from_host].watchdog_keepalive then
f547eafb5a6d mod_s2s_keepalive: Fix s2sout watchdog reset
Kim Alvefur <zash@zash.se>
parents: 3769
diff changeset
    88
		s2sout[origin.from_host].watchdog_keepalive:reset();
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    89
	end
3774
ae34ee0867f0 mod_s2s_keepalive: Mark ping response event as handled
Kim Alvefur <zash@zash.se>
parents: 3773
diff changeset
    90
	return true;
3769
11878130f266 mod_s2s_keepalive: Use a watchdog to close unresponsive sessions (fixes #1457)
Kim Alvefur <zash@zash.se>
parents: 3768
diff changeset
    91
end);
4217
93a980ac1816 mod_s2s_keepalive: Restore timer start (Thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4216
diff changeset
    92
93a980ac1816 mod_s2s_keepalive: Restore timer start (Thanks Ge0rG)
Kim Alvefur <zash@zash.se>
parents: 4216
diff changeset
    93
module:add_timer(keepalive_interval, send_pings);