File

plugins/mod_net_multiplex.lua @ 10390:82705ec87253 0.11

util.startup: Ensure prosody.paths are absolute (see #1430) Normally these paths are injected into the installed 'prosody' executable as absolute paths, but it is possible to override at least the config path via environment variable or command line argument. This makes sure a path relative to pwd stays relative to that instead of the data directory.
author Kim Alvefur <zash@zash.se>
date Mon, 04 Nov 2019 00:29:49 +0100
parent 9465:876171084ea3
child 10465:09697a673015
line wrap: on
line source

module:set_global();

local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024);

local portmanager = require "core.portmanager";

local available_services = {};

local function add_service(service)
	local multiplex_pattern = service.multiplex and service.multiplex.pattern;
	if multiplex_pattern then
		module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern);
		available_services[service] = multiplex_pattern;
	else
		module:log("debug", "Service %q is not multiplex-capable", service.name);
	end
end
module:hook("service-added", function (event) add_service(event.service); end);
module:hook("service-removed", function (event)	available_services[event.service] = nil; end);

for _, services in pairs(portmanager.get_registered_services()) do
	for _, service in ipairs(services) do
		add_service(service);
	end
end

local buffers = {};

local listener = { default_mode = "*a" };

function listener.onconnect()
end

function listener.onincoming(conn, data)
	if not data then return; end
	local buf = buffers[conn];
	buf = buf and buf..data or data;
	for service, multiplex_pattern in pairs(available_services) do
		if buf:match(multiplex_pattern) then
			module:log("debug", "Routing incoming connection to %s", service.name);
			local next_listener = service.listener;
			conn:setlistener(next_listener);
			local onconnect = next_listener.onconnect;
			if onconnect then onconnect(conn) end
			return next_listener.onincoming(conn, buf);
		end
	end
	if #buf > max_buffer_len then -- Give up
		conn:close();
	else
		buffers[conn] = buf;
	end
end

function listener.ondisconnect(conn)
	buffers[conn] = nil; -- warn if no buffer?
end

listener.ondetach = listener.ondisconnect;

module:provides("net", {
	name = "multiplex";
	config_prefix = "";
	listener = listener;
});

module:provides("net", {
	name = "multiplex_ssl";
	config_prefix = "ssl";
	encryption = "ssl";
	listener = listener;
});