aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_net_multiplex.lua
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-04-29 02:10:55 +0100
committerMatthew Wild <mwild1@gmail.com>2012-04-29 02:10:55 +0100
commitfe228888c0d51612e8b32adc3f9db91b7c6e8ded (patch)
treee78baabff21e9b6fefaeef4a709098ca30b35922 /plugins/mod_net_multiplex.lua
parent9d04baca862bcad5b49ac4ab0b9c3432321150d3 (diff)
parent1ee9f6e09228b268bf3f5dc985d4ba9026a72666 (diff)
downloadprosody-fe228888c0d51612e8b32adc3f9db91b7c6e8ded.tar.gz
prosody-fe228888c0d51612e8b32adc3f9db91b7c6e8ded.zip
Merge 0.9->trunk
Diffstat (limited to 'plugins/mod_net_multiplex.lua')
-rw-r--r--plugins/mod_net_multiplex.lua70
1 files changed, 70 insertions, 0 deletions
diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua
new file mode 100644
index 00000000..44e1c1ee
--- /dev/null
+++ b/plugins/mod_net_multiplex.lua
@@ -0,0 +1,70 @@
+module:set_global();
+
+local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024);
+
+local portmanager = require "core.portmanager";
+
+local available_services = {};
+
+local function add_service(service)
+ local multiplex_pattern = service.multiplex and service.multiplex.pattern;
+ if multiplex_pattern then
+ module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern);
+ available_services[service] = multiplex_pattern;
+ else
+ module:log("debug", "Service %q is not multiplex-capable", service.name);
+ end
+end
+module:hook("service-added", function (event) add_service(event.service); end);
+module:hook("service-removed", function (event) available_services[event.service] = nil; end);
+
+for service_name, services in pairs(portmanager.get_registered_services()) do
+ for i, service in ipairs(services) do
+ add_service(service);
+ end
+end
+
+local buffers = {};
+
+local listener = { default_mode = "*a" };
+
+function listener.onconnect()
+end
+
+function listener.onincoming(conn, data)
+ if not data then return; end
+ local buf = buffers[conn];
+ buffers[conn] = nil;
+ buf = buf and buf..data or data;
+ for service, multiplex_pattern in pairs(available_services) do
+ if buf:match(multiplex_pattern) then
+ module:log("debug", "Routing incoming connection to %s", service.name);
+ local listener = service.listener;
+ conn:setlistener(listener);
+ local onconnect = listener.onconnect;
+ if onconnect then onconnect(conn) end
+ return listener.onincoming(conn, buf);
+ end
+ end
+ if #buf > max_buffer_len then -- Give up
+ conn:close();
+ else
+ buffers[conn] = buf;
+ end
+end
+
+function listener.ondisconnect(conn, err)
+ buffers[conn] = nil; -- warn if no buffer?
+end
+
+module:add_item("net-provider", {
+ name = "multiplex";
+ config_prefix = "";
+ listener = listener;
+});
+
+module:provides("net", {
+ name = "multiplex_ssl";
+ config_prefix = "ssl";
+ listener = listener;
+});