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 });