diff options
author | Kim Alvefur <zash@zash.se> | 2019-11-29 23:27:51 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2019-11-29 23:27:51 +0100 |
commit | 0fdb85997abd2be59252595b1fec9e46389da586 (patch) | |
tree | 69d0f584473e7af9d56eba8aa56dd07be64a0954 | |
parent | e354f1abd8ca2fb0fc2c25c1c61c1866cc41d5eb (diff) | |
download | prosody-0fdb85997abd2be59252595b1fec9e46389da586.tar.gz prosody-0fdb85997abd2be59252595b1fec9e46389da586.zip |
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.
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | doc/doap.xml | 1 | ||||
-rw-r--r-- | plugins/mod_c2s.lua | 1 | ||||
-rw-r--r-- | plugins/mod_http.lua | 1 | ||||
-rw-r--r-- | plugins/mod_net_multiplex.lua | 40 | ||||
-rw-r--r-- | plugins/mod_s2s/mod_s2s.lua | 1 |
6 files changed, 42 insertions, 3 deletions
@@ -13,6 +13,7 @@ TRUNK - 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 ====== diff --git a/doc/doap.xml b/doc/doap.xml index 673e0c23..1633e2f3 100644 --- a/doc/doap.xml +++ b/doc/doap.xml @@ -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/"/> diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index aec0370d..aecf2210 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -374,6 +374,7 @@ module:provides("net", { default_port = 5222; encryption = "starttls"; multiplex = { + protocol = "xmpp-client"; pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:client%1.*>"; }; }); diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index e6ef89f5..c3e19bb3 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -242,6 +242,7 @@ module:provides("net", { default_port = 5281; encryption = "ssl"; multiplex = { + protocol = "http/1.1"; pattern = "^[A-Z]"; }; }); 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; }); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 7cd90a84..7f6546e9 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -796,6 +796,7 @@ module:provides("net", { verify = { "peer", "client_once", }; }; multiplex = { + protocol = "xmpp-server"; pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:server%1.*>"; }; }); |