Mercurial > prosody-hg
comparison plugins/mod_net_multiplex.lua @ 11200:bf8f2da84007
Merge 0.11->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 05 Nov 2020 22:31:25 +0100 |
| parents | 1c7602c70d1f |
| children | 74b9e05af71e |
comparison
equal
deleted
inserted
replaced
| 11199:6c7c50a4de32 | 11200:bf8f2da84007 |
|---|---|
| 1 module:set_global(); | 1 module:set_global(); |
| 2 | 2 |
| 3 local array = require "util.array"; | |
| 3 local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024); | 4 local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024); |
| 5 local default_mode = module:get_option_number("network_default_read_size", 4096); | |
| 4 | 6 |
| 5 local portmanager = require "core.portmanager"; | 7 local portmanager = require "core.portmanager"; |
| 6 | 8 |
| 7 local available_services = {}; | 9 local available_services = {}; |
| 10 local service_by_protocol = {}; | |
| 11 local available_protocols = array(); | |
| 8 | 12 |
| 9 local function add_service(service) | 13 local function add_service(service) |
| 10 local multiplex_pattern = service.multiplex and service.multiplex.pattern; | 14 local multiplex_pattern = service.multiplex and service.multiplex.pattern; |
| 15 local protocol_name = service.multiplex and service.multiplex.protocol; | |
| 16 if protocol_name then | |
| 17 module:log("debug", "Adding multiplex service %q with protocol %q", service.name, protocol_name); | |
| 18 service_by_protocol[protocol_name] = service; | |
| 19 available_protocols:push(protocol_name); | |
| 20 end | |
| 11 if multiplex_pattern then | 21 if multiplex_pattern then |
| 12 module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern); | 22 module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern); |
| 13 available_services[service] = multiplex_pattern; | 23 available_services[service] = multiplex_pattern; |
| 14 else | 24 elseif not protocol_name then |
| 15 module:log("debug", "Service %q is not multiplex-capable", service.name); | 25 module:log("debug", "Service %q is not multiplex-capable", service.name); |
| 16 end | 26 end |
| 17 end | 27 end |
| 18 module:hook("service-added", function (event) add_service(event.service); end); | 28 module:hook("service-added", function (event) add_service(event.service); end); |
| 19 module:hook("service-removed", function (event) available_services[event.service] = nil; end); | 29 module:hook("service-removed", function (event) |
| 30 available_services[event.service] = nil; | |
| 31 if event.service.multiplex and event.service.multiplex.protocol then | |
| 32 available_protocols:filter(function (p) return p ~= event.service.multiplex.protocol end); | |
| 33 service_by_protocol[event.service.multiplex.protocol] = nil; | |
| 34 end | |
| 35 end); | |
| 20 | 36 |
| 21 for _, services in pairs(portmanager.get_registered_services()) do | 37 for _, services in pairs(portmanager.get_registered_services()) do |
| 22 for _, service in ipairs(services) do | 38 for _, service in ipairs(services) do |
| 23 add_service(service); | 39 add_service(service); |
| 24 end | 40 end |
| 25 end | 41 end |
| 26 | 42 |
| 27 local buffers = {}; | 43 local buffers = {}; |
| 28 | 44 |
| 29 local listener = { default_mode = "*a" }; | 45 local listener = { default_mode = max_buffer_len }; |
| 30 | 46 |
| 31 function listener.onconnect() | 47 function listener.onconnect(conn) |
| 48 local sock = conn:socket(); | |
| 49 if sock.getalpn then | |
| 50 local selected_proto = sock:getalpn(); | |
| 51 local service = service_by_protocol[selected_proto]; | |
| 52 if service then | |
| 53 module:log("debug", "Routing incoming connection to %s based on ALPN %q", service.name, selected_proto); | |
| 54 local next_listener = service.listener; | |
| 55 conn:setlistener(next_listener); | |
| 56 conn:set_mode(next_listener.default_mode or default_mode); | |
| 57 local onconnect = next_listener.onconnect; | |
| 58 if onconnect then return onconnect(conn) end | |
| 59 end | |
| 60 end | |
| 32 end | 61 end |
| 33 | 62 |
| 34 function listener.onincoming(conn, data) | 63 function listener.onincoming(conn, data) |
| 35 if not data then return; end | 64 if not data then return; end |
| 36 local buf = buffers[conn]; | 65 local buf = buffers[conn]; |
| 38 for service, multiplex_pattern in pairs(available_services) do | 67 for service, multiplex_pattern in pairs(available_services) do |
| 39 if buf:match(multiplex_pattern) then | 68 if buf:match(multiplex_pattern) then |
| 40 module:log("debug", "Routing incoming connection to %s", service.name); | 69 module:log("debug", "Routing incoming connection to %s", service.name); |
| 41 local next_listener = service.listener; | 70 local next_listener = service.listener; |
| 42 conn:setlistener(next_listener); | 71 conn:setlistener(next_listener); |
| 72 conn:set_mode(next_listener.default_mode or default_mode); | |
| 43 local onconnect = next_listener.onconnect; | 73 local onconnect = next_listener.onconnect; |
| 44 if onconnect then onconnect(conn) end | 74 if onconnect then onconnect(conn) end |
| 45 return next_listener.onincoming(conn, buf); | 75 return next_listener.onincoming(conn, buf); |
| 46 end | 76 end |
| 47 end | 77 end |
| 66 | 96 |
| 67 module:provides("net", { | 97 module:provides("net", { |
| 68 name = "multiplex_ssl"; | 98 name = "multiplex_ssl"; |
| 69 config_prefix = "ssl"; | 99 config_prefix = "ssl"; |
| 70 encryption = "ssl"; | 100 encryption = "ssl"; |
| 101 ssl_config = { | |
| 102 alpn = function () | |
| 103 return available_protocols; | |
| 104 end; | |
| 105 }; | |
| 71 listener = listener; | 106 listener = listener; |
| 72 }); | 107 }); |
