Software /
code /
prosody
Changeset
10465:09697a673015
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.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 29 Nov 2019 23:27:51 +0100 |
parents | 10464:8d3acf16c404 |
children | 10466:276f62d14437 |
files | CHANGES doc/doap.xml plugins/mod_c2s.lua plugins/mod_http.lua plugins/mod_net_multiplex.lua plugins/mod_s2s/mod_s2s.lua |
diffstat | 6 files changed, 42 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES Fri Nov 29 23:25:59 2019 +0100 +++ b/CHANGES Fri Nov 29 23:27:51 2019 +0100 @@ -13,6 +13,7 @@ - Bi-directional server-to-server (XEP-0288) - Built-in HTTP server now handles HEAD requests - MUC presence broadcast controls +- ALPN support in mod\_net\_multiplex 0.11.0 ======
--- a/doc/doap.xml Fri Nov 29 23:25:59 2019 +0100 +++ b/doc/doap.xml Fri Nov 29 23:27:51 2019 +0100 @@ -51,6 +51,7 @@ <implements rdf:resource="https://www.rfc-editor.org/info/rfc6121"/> <implements rdf:resource="https://www.rfc-editor.org/info/rfc6122"/> <implements rdf:resource="https://www.rfc-editor.org/info/rfc6455"/> + <implements rdf:resource="https://www.rfc-editor.org/info/rfc7301"/> <implements rdf:resource="https://www.rfc-editor.org/info/rfc7395"/> <!-- Added in hg:0bbbc9042361 released in 0.6.0 --> <implements rdf:resource="https://datatracker.ietf.org/doc/draft-cridland-xmpp-session/"/>
--- a/plugins/mod_c2s.lua Fri Nov 29 23:25:59 2019 +0100 +++ b/plugins/mod_c2s.lua Fri Nov 29 23:27:51 2019 +0100 @@ -374,6 +374,7 @@ default_port = 5222; encryption = "starttls"; multiplex = { + protocol = "xmpp-client"; pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:client%1.*>"; }; });
--- a/plugins/mod_http.lua Fri Nov 29 23:25:59 2019 +0100 +++ b/plugins/mod_http.lua Fri Nov 29 23:27:51 2019 +0100 @@ -242,6 +242,7 @@ default_port = 5281; encryption = "ssl"; multiplex = { + protocol = "http/1.1"; pattern = "^[A-Z]"; }; });
--- a/plugins/mod_net_multiplex.lua Fri Nov 29 23:25:59 2019 +0100 +++ b/plugins/mod_net_multiplex.lua Fri Nov 29 23:27:51 2019 +0100 @@ -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 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 @@ name = "multiplex_ssl"; config_prefix = "ssl"; encryption = "ssl"; + ssl_config = { + alpn = function () + return available_protocols; + end; + }; listener = listener; });
--- a/plugins/mod_s2s/mod_s2s.lua Fri Nov 29 23:25:59 2019 +0100 +++ b/plugins/mod_s2s/mod_s2s.lua Fri Nov 29 23:27:51 2019 +0100 @@ -796,6 +796,7 @@ verify = { "peer", "client_once", }; }; multiplex = { + protocol = "xmpp-server"; pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:server%1.*>"; }; });