plugins/mod_admin_socket.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 11 Oct 2022 11:37:55 +0100
changeset 12767 d26eefe98d09
parent 12422 dd47adf74e93
child 12856 c35afa353f8f
child 12891 68df46926c26
permissions -rw-r--r--
util.dbuffer: Add efficient shortcuts for discard() in certain cases If the buffer is already empty, nothing to do. If we're throwing away the whole buffer, we can just empty it and avoid read_chunk() (which in turn may collapse()). These shortcuts are much more efficient.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local have_unix, unix = pcall(require, "socket.unix");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
12396
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
     5
if have_unix and type(unix) == "function" then
12397
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     6
	-- COMPAT #1717
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     7
	-- Before the introduction of datagram support, only the stream socket
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     8
	-- constructor was exported instead of a module table. Due to the lack of a
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     9
	-- proper release of LuaSocket, distros have settled on shipping either the
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
    10
	-- last RC tag or some commit since then.
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
    11
	-- Here we accomodate both variants.
12396
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
    12
	unix = { stream = unix };
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
    13
end
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
if not have_unix or type(unix) ~= "table" then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
	module:log_status("error", "LuaSocket unix socket support not available or incompatible, ensure it is up to date");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	return;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
local server = require "net.server";
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
local adminstream = require "util.adminstream";
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
10870
5265f7fe11dd mod_admin_socket: Use module API meant for file paths
Kim Alvefur <zash@zash.se>
parents: 10866
diff changeset
    23
local socket_path = module:get_option_path("admin_socket", "prosody.sock", "data");
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
local sessions = module:shared("sessions");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
local function fire_admin_event(session, stanza)
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	local event_data = {
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
		origin = session, stanza = stanza;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
	};
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	local event_name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	if stanza.attr.xmlns then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
		event_name = "admin/"..stanza.attr.xmlns..":"..stanza.name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	else
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
		event_name = "admin/"..stanza.name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	module:log("debug", "Firing %s", event_name);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	return module:fire_event(event_name, event_data);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
module:hook("server-stopping", function ()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	for _, session in pairs(sessions) do
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
		session:close("system-shutdown");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
	os.remove(socket_path);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
end);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
--- Unix domain socket management
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
local conn, sock;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
local listeners = adminstream.server(sessions, fire_admin_event).listeners;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
local function accept_connection()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	module:log("debug", "accepting...");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
	local client = sock:accept();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
	if not client then return; end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
	server.wrapclient(client, "unix", 0, listeners, "*a");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
function module.load()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	sock = unix.stream();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
	sock:settimeout(0);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	os.remove(socket_path);
12422
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    65
	local ok, err = sock:bind(socket_path);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    66
	if not ok then
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    67
		module:log_status("error", "Unable to bind admin socket %s: %s", socket_path, err);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    68
		return;
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    69
	end
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    70
	local ok, err = sock:listen();
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    71
	if not ok then
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    72
		module:log_status("error", "Unable to listen on admin socket %s: %s", socket_path, err);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    73
		return;
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    74
	end
10866
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    75
	if server.wrapserver then
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    76
		conn = server.wrapserver(sock, socket_path, 0, listeners);
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    77
	else
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    78
		conn = server.watchfd(sock:getfd(), accept_connection);
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    79
	end
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
function module.unload()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
	if conn then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
		conn:close();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
	if sock then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
		sock:close();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
	os.remove(socket_path);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
end