plugins/mod_net_multiplex.lua
author Kim Alvefur <zash@zash.se>
Fri, 29 Nov 2019 23:41:41 +0100
changeset 10470 276f62d14437
parent 10469 09697a673015
child 10479 fa0cad7c89e3
permissions -rw-r--r--
mod_net_multiplex: Tweak debug logging for ALPN case
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
     3
local array = require "util.array";
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024);
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local portmanager = require "core.portmanager";
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local available_services = {};
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
     9
local service_by_protocol = {};
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    10
local available_protocols = array();
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local function add_service(service)
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	local multiplex_pattern = service.multiplex and service.multiplex.pattern;
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    14
	local protocol_name = service.multiplex and service.multiplex.protocol;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    15
	if protocol_name then
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    16
		module:log("debug", "Adding multiplex service %q with protocol %q", service.name, protocol_name);
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    17
		service_by_protocol[protocol_name] = service;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    18
		available_protocols:push(protocol_name);
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    19
	end
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	if multiplex_pattern then
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
		module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern);
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
		available_services[service] = multiplex_pattern;
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    23
	elseif not protocol_name then
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
		module:log("debug", "Service %q is not multiplex-capable", service.name);
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
	end
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    26
	module:log("info", "available_protocols = %q", available_protocols);
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
module:hook("service-added", function (event) add_service(event.service); end);
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    29
module:hook("service-removed", function (event)
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    30
	available_services[event.service] = nil;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    31
	if event.service.multiplex and event.service.multiplex.protocol then
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    32
		available_protocols:filter(function (p) return p ~= event.service.multiplex.protocol end);
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    33
		service_by_protocol[event.service.multiplex.protocol] = nil;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    34
	end
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    35
end);
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
9468
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    37
for _, services in pairs(portmanager.get_registered_services()) do
7505
021d2b844c51 mod_net_multiplex: remove unused one-letter loop variable [luacheck]
Anton Shestakov <av6@dwimlabs.net>
parents: 6380
diff changeset
    38
	for _, service in ipairs(services) do
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
		add_service(service);
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
local buffers = {};
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
local listener = { default_mode = "*a" };
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    47
function listener.onconnect(conn)
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    48
	local sock = conn:socket();
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    49
	if sock.getalpn then
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    50
		local selected_proto = sock:getalpn();
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    51
		local service = service_by_protocol[selected_proto];
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    52
		if service then
10470
276f62d14437 mod_net_multiplex: Tweak debug logging for ALPN case
Kim Alvefur <zash@zash.se>
parents: 10469
diff changeset
    53
			module:log("debug", "Routing incoming connection to %s based on ALPN %q", service.name, selected_proto);
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    54
			local next_listener = service.listener;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    55
			conn:setlistener(next_listener);
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    56
			local onconnect = next_listener.onconnect;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    57
			if onconnect then return onconnect(conn) end
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    58
		end
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    59
	end
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
function listener.onincoming(conn, data)
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
	if not data then return; end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	local buf = buffers[conn];
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
	buf = buf and buf..data or data;
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	for service, multiplex_pattern in pairs(available_services) do
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
		if buf:match(multiplex_pattern) then
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
			module:log("debug", "Routing incoming connection to %s", service.name);
9468
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    69
			local next_listener = service.listener;
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    70
			conn:setlistener(next_listener);
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    71
			local onconnect = next_listener.onconnect;
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
			if onconnect then onconnect(conn) end
9468
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    73
			return next_listener.onincoming(conn, buf);
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
		end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
	end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
	if #buf > max_buffer_len then -- Give up
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
		conn:close();
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
	else
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
		buffers[conn] = buf;
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
	end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
9468
876171084ea3 mod_net_multiplex: Silence luacheck warnings
Kim Alvefur <zash@zash.se>
parents: 7810
diff changeset
    83
function listener.ondisconnect(conn)
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
	buffers[conn] = nil; -- warn if no buffer?
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
end
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
6380
4220ffb87b22 net.http, net.http.server, mod_c2s, mod_s2s, mod_component, mod_admin_telnet, mod_net_multiplex: Add ondetach to release connection from 'sessions' table (or equivalent)
Matthew Wild <mwild1@gmail.com>
parents: 5120
diff changeset
    87
listener.ondetach = listener.ondisconnect;
4220ffb87b22 net.http, net.http.server, mod_c2s, mod_s2s, mod_component, mod_admin_telnet, mod_net_multiplex: Add ondetach to release connection from 'sessions' table (or equivalent)
Matthew Wild <mwild1@gmail.com>
parents: 5120
diff changeset
    88
5120
bcabea740c00 mod_{admin_telnet,c2s,component,http,net_multiplex,s2s}: Use module:provides() instead of module:add_item().
Waqas Hussain <waqas20@gmail.com>
parents: 4619
diff changeset
    89
module:provides("net", {
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	name = "multiplex";
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
	config_prefix = "";
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	listener = listener;
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
});
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
module:provides("net", {
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
	name = "multiplex_ssl";
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	config_prefix = "ssl";
7809
00bca79ae778 mod_net_multiplex: Enable SSL on the SSL port (fixes #803)
Kim Alvefur <zash@zash.se>
parents: 6380
diff changeset
    98
	encryption = "ssl";
10469
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
    99
	ssl_config = {
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
   100
		alpn = function ()
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
   101
			return available_protocols;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
   102
		end;
09697a673015 mod_net_multiplex: Add support for using ALPN
Kim Alvefur <zash@zash.se>
parents: 9468
diff changeset
   103
	};
4619
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
	listener = listener;
d5739b8b7161 mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
});