From 4c6992a00e582dc2c9c6a7ad721cd7e831202a1e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 1 Jun 2020 15:42:19 +0100 Subject: mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality --- plugins/mod_admin_socket.lua | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 plugins/mod_admin_socket.lua (limited to 'plugins/mod_admin_socket.lua') diff --git a/plugins/mod_admin_socket.lua b/plugins/mod_admin_socket.lua new file mode 100644 index 00000000..c094aad2 --- /dev/null +++ b/plugins/mod_admin_socket.lua @@ -0,0 +1,69 @@ +module:set_global(); + +local have_unix, unix = pcall(require, "socket.unix"); + +if not have_unix or type(unix) ~= "table" then + module:log_status("error", "LuaSocket unix socket support not available or incompatible, ensure it is up to date"); + return; +end + +local server = require "net.server"; + +local adminstream = require "util.adminstream"; + +local socket_path = module:get_option_string("admin_socket", prosody.paths.data.."/prosody.sock"); + +local sessions = module:shared("sessions"); + +local function fire_admin_event(session, stanza) + local event_data = { + origin = session, stanza = stanza; + }; + local event_name; + if stanza.attr.xmlns then + event_name = "admin/"..stanza.attr.xmlns..":"..stanza.name; + else + event_name = "admin/"..stanza.name; + end + module:log("debug", "Firing %s", event_name); + return module:fire_event(event_name, event_data); +end + +module:hook("server-stopping", function () + for _, session in pairs(sessions) do + session:close("system-shutdown"); + end + os.remove(socket_path); +end); + +--- Unix domain socket management + +local conn, sock; + +local listeners = adminstream.server(sessions, fire_admin_event).listeners; + +local function accept_connection() + module:log("debug", "accepting..."); + local client = sock:accept(); + if not client then return; end + server.wrapclient(client, "unix", 0, listeners, "*a"); +end + +function module.load() + sock = unix.stream(); + sock:settimeout(0); + os.remove(socket_path); + assert(sock:bind(socket_path)); + assert(sock:listen()); + conn = server.watchfd(sock:getfd(), accept_connection); +end + +function module.unload() + if conn then + conn:close(); + end + if sock then + sock:close(); + end + os.remove(socket_path); +end -- cgit v1.2.3