From 0fdb85997abd2be59252595b1fec9e46389da586 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 29 Nov 2019 23:27:51 +0100 Subject: mod_net_multiplex: Add support for using ALPN Potentially a bit more efficient since it can jump to the selected protocol on connect instead of waiting for some data to look at. Adds a 'protocol' field to net providers for this purpose. --- plugins/mod_net_multiplex.lua | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'plugins/mod_net_multiplex.lua') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 8ef77883..2bf1f88d 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -1,22 +1,38 @@ module:set_global(); +local array = require "util.array"; local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024); local portmanager = require "core.portmanager"; local available_services = {}; +local service_by_protocol = {}; +local available_protocols = array(); local function add_service(service) local multiplex_pattern = service.multiplex and service.multiplex.pattern; + local protocol_name = service.multiplex and service.multiplex.protocol; + if protocol_name then + module:log("debug", "Adding multiplex service %q with protocol %q", service.name, protocol_name); + service_by_protocol[protocol_name] = service; + available_protocols:push(protocol_name); + end if multiplex_pattern then module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern); available_services[service] = multiplex_pattern; - else + elseif not protocol_name then module:log("debug", "Service %q is not multiplex-capable", service.name); end + module:log("info", "available_protocols = %q", available_protocols); end module:hook("service-added", function (event) add_service(event.service); end); -module:hook("service-removed", function (event) available_services[event.service] = nil; end); +module:hook("service-removed", function (event) + available_services[event.service] = nil; + if event.service.multiplex and event.service.multiplex.protocol then + available_protocols:filter(function (p) return p ~= event.service.multiplex.protocol end); + service_by_protocol[event.service.multiplex.protocol] = nil; + end +end); for _, services in pairs(portmanager.get_registered_services()) do for _, service in ipairs(services) do @@ -28,7 +44,20 @@ local buffers = {}; local listener = { default_mode = "*a" }; -function listener.onconnect() +function listener.onconnect(conn) + local sock = conn:socket(); + if sock.getalpn then + local selected_proto = sock:getalpn(); + module:log("debug", "ALPN selected is %s", selected_proto); + local service = service_by_protocol[selected_proto]; + if service 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 return onconnect(conn) end + end + end end function listener.onincoming(conn, data) @@ -68,5 +97,10 @@ module:provides("net", { name = "multiplex_ssl"; config_prefix = "ssl"; encryption = "ssl"; + ssl_config = { + alpn = function () + return available_protocols; + end; + }; listener = listener; }); -- cgit v1.2.3 From a95af210d143f3c16c6512a53c154a80baa4f98d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 29 Nov 2019 23:41:41 +0100 Subject: mod_net_multiplex: Tweak debug logging for ALPN case --- plugins/mod_net_multiplex.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'plugins/mod_net_multiplex.lua') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 2bf1f88d..3de81ddc 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -48,10 +48,9 @@ function listener.onconnect(conn) local sock = conn:socket(); if sock.getalpn then local selected_proto = sock:getalpn(); - module:log("debug", "ALPN selected is %s", selected_proto); local service = service_by_protocol[selected_proto]; if service then - module:log("debug", "Routing incoming connection to %s", service.name); + module:log("debug", "Routing incoming connection to %s based on ALPN %q", service.name, selected_proto); local next_listener = service.listener; conn:setlistener(next_listener); local onconnect = next_listener.onconnect; -- cgit v1.2.3 From 62b9a7f53fcbce310f19f224edc45418885ee5c0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 1 Dec 2019 02:04:24 +0100 Subject: mod_net_multiplex: Remove debug message This was something I added during development and set to info level for visibility. --- plugins/mod_net_multiplex.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/mod_net_multiplex.lua') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 3de81ddc..849b22ee 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -23,7 +23,6 @@ local function add_service(service) elseif not protocol_name then module:log("debug", "Service %q is not multiplex-capable", service.name); end - module:log("info", "available_protocols = %q", available_protocols); end module:hook("service-added", function (event) add_service(event.service); end); module:hook("service-removed", function (event) -- cgit v1.2.3 From 8fae7acf319d7ff48a12f62e208ddd62665c81ba Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 2 Aug 2020 00:22:57 +0200 Subject: mod_net_multiplex: Read no more than the max buffer size setting Otherwise the '*a' read mode applies, which under certain circumstances can read infinite amounts of data into memory. --- plugins/mod_net_multiplex.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/mod_net_multiplex.lua') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 849b22ee..42a41709 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -41,7 +41,7 @@ end local buffers = {}; -local listener = { default_mode = "*a" }; +local listener = { default_mode = max_buffer_len }; function listener.onconnect(conn) local sock = conn:socket(); -- cgit v1.2.3 From 7acd3092ecba0fde91d7e56770c47d7bf98dfc30 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 2 Aug 2020 00:24:54 +0200 Subject: mod_net_multiplex: Set read size/mode to that of the target listener Otherwise it would use the configured buffer size, or previously '*a'. Using the read size set by the listener seems more sensible. --- plugins/mod_net_multiplex.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins/mod_net_multiplex.lua') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 42a41709..ddd58463 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -2,6 +2,7 @@ module:set_global(); local array = require "util.array"; local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024); +local default_mode = module:get_option_number("network_default_read_size", 4096); local portmanager = require "core.portmanager"; @@ -52,6 +53,7 @@ function listener.onconnect(conn) module:log("debug", "Routing incoming connection to %s based on ALPN %q", service.name, selected_proto); local next_listener = service.listener; conn:setlistener(next_listener); + conn:set_mode(next_listener.default_mode or default_mode); local onconnect = next_listener.onconnect; if onconnect then return onconnect(conn) end end @@ -67,6 +69,7 @@ function listener.onincoming(conn, data) module:log("debug", "Routing incoming connection to %s", service.name); local next_listener = service.listener; conn:setlistener(next_listener); + conn:set_mode(next_listener.default_mode or default_mode); local onconnect = next_listener.onconnect; if onconnect then onconnect(conn) end return next_listener.onincoming(conn, buf); -- cgit v1.2.3