Mercurial > prosody-hg
comparison core/portmanager.lua @ 10411:db2a06b9ff98
Merge 0.11->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 16 Nov 2019 16:52:31 +0100 |
| parents | 1dbabbebb53c |
| children | 9af6ab2623b0 |
comparison
equal
deleted
inserted
replaced
| 10410:659b577f280c | 10411:db2a06b9ff98 |
|---|---|
| 7 local multitable = require "util.multitable"; | 7 local multitable = require "util.multitable"; |
| 8 local set = require "util.set"; | 8 local set = require "util.set"; |
| 9 | 9 |
| 10 local table = table; | 10 local table = table; |
| 11 local setmetatable, rawset, rawget = setmetatable, rawset, rawget; | 11 local setmetatable, rawset, rawget = setmetatable, rawset, rawget; |
| 12 local type, tonumber, tostring, ipairs = type, tonumber, tostring, ipairs; | 12 local type, tonumber, ipairs = type, tonumber, ipairs; |
| 13 local pairs = pairs; | |
| 13 | 14 |
| 14 local prosody = prosody; | 15 local prosody = prosody; |
| 15 local fire_event = prosody.events.fire_event; | 16 local fire_event = prosody.events.fire_event; |
| 16 | 17 |
| 17 local _ENV = nil; | 18 local _ENV = nil; |
| 93 or {service_info.default_port | 94 or {service_info.default_port |
| 94 or listener.default_port -- COMPAT w/pre-0.9 | 95 or listener.default_port -- COMPAT w/pre-0.9 |
| 95 } | 96 } |
| 96 bind_ports = set.new(type(bind_ports) ~= "table" and { bind_ports } or bind_ports ); | 97 bind_ports = set.new(type(bind_ports) ~= "table" and { bind_ports } or bind_ports ); |
| 97 | 98 |
| 98 local mode, ssl = listener.default_mode or default_mode; | 99 local mode = listener.default_mode or default_mode; |
| 99 local hooked_ports = {}; | 100 local hooked_ports = {}; |
| 100 | 101 |
| 101 for interface in bind_interfaces do | 102 for interface in bind_interfaces do |
| 102 for port in bind_ports do | 103 for port in bind_ports do |
| 103 local port_number = tonumber(port); | 104 local port_number = tonumber(port); |
| 104 if not port_number then | 105 if not port_number then |
| 105 log("error", "Invalid port number specified for service '%s': %s", service_info.name, tostring(port)); | 106 log("error", "Invalid port number specified for service '%s': %s", service_info.name, port); |
| 106 elseif #active_services:search(nil, interface, port_number) > 0 then | 107 elseif #active_services:search(nil, interface, port_number) > 0 then |
| 107 log("error", "Multiple services configured to listen on the same port ([%s]:%d): %s, %s", interface, port, | 108 log("error", "Multiple services configured to listen on the same port ([%s]:%d): %s, %s", interface, port, |
| 108 active_services:search(nil, interface, port)[1][1].service.name or "<unnamed>", service_name or "<unnamed>"); | 109 active_services:search(nil, interface, port)[1][1].service.name or "<unnamed>", service_name or "<unnamed>"); |
| 109 else | 110 else |
| 110 local err; | 111 local ssl, cfg, err; |
| 111 -- Create SSL context for this service/port | 112 -- Create SSL context for this service/port |
| 112 if service_info.encryption == "ssl" then | 113 if service_info.encryption == "ssl" then |
| 113 local global_ssl_config = config.get("*", "ssl") or {}; | 114 local global_ssl_config = config.get("*", "ssl") or {}; |
| 114 local prefix_ssl_config = config.get("*", config_prefix.."ssl") or global_ssl_config; | 115 local prefix_ssl_config = config.get("*", config_prefix.."ssl") or global_ssl_config; |
| 115 log("debug", "Creating context for direct TLS service %s on port %d", service_info.name, port); | 116 log("debug", "Creating context for direct TLS service %s on port %d", service_info.name, port); |
| 116 ssl, err = certmanager.create_context(service_info.name.." port "..port, "server", | 117 ssl, err, cfg = certmanager.create_context(service_info.name.." port "..port, "server", |
| 117 prefix_ssl_config[interface], | 118 prefix_ssl_config[interface], |
| 118 prefix_ssl_config[port], | 119 prefix_ssl_config[port], |
| 119 prefix_ssl_config, | 120 prefix_ssl_config, |
| 120 service_info.ssl_config or {}, | 121 service_info.ssl_config or {}, |
| 121 global_ssl_config[interface], | 122 global_ssl_config[interface], |
| 125 error_to_friendly_message(service_name, port_number, err) or "unknown error"); | 126 error_to_friendly_message(service_name, port_number, err) or "unknown error"); |
| 126 end | 127 end |
| 127 end | 128 end |
| 128 if not err then | 129 if not err then |
| 129 -- Start listening on interface+port | 130 -- Start listening on interface+port |
| 130 local handler, err = server.addserver(interface, port_number, listener, mode, ssl); | 131 local handler, err = server.listen(interface, port_number, listener, { |
| 132 read_size = mode, | |
| 133 tls_ctx = ssl, | |
| 134 tls_direct = service_info.encryption == "ssl"; | |
| 135 sni_hosts = {}, | |
| 136 }); | |
| 131 if not handler then | 137 if not handler then |
| 132 log("error", "Failed to open server port %d on %s, %s", port_number, interface, | 138 log("error", "Failed to open server port %d on %s, %s", port_number, interface, |
| 133 error_to_friendly_message(service_name, port_number, err)); | 139 error_to_friendly_message(service_name, port_number, err)); |
| 134 else | 140 else |
| 135 table.insert(hooked_ports, "["..interface.."]:"..port_number); | 141 table.insert(hooked_ports, "["..interface.."]:"..port_number); |
| 136 log("debug", "Added listening service %s to [%s]:%d", service_name, interface, port_number); | 142 log("debug", "Added listening service %s to [%s]:%d", service_name, interface, port_number); |
| 137 active_services:add(service_name, interface, port_number, { | 143 active_services:add(service_name, interface, port_number, { |
| 138 server = handler; | 144 server = handler; |
| 139 service = service_info; | 145 service = service_info; |
| 146 tls_cfg = cfg; | |
| 140 }); | 147 }); |
| 141 end | 148 end |
| 142 end | 149 end |
| 143 end | 150 end |
| 144 end | 151 end |
| 220 return services; | 227 return services; |
| 221 end | 228 end |
| 222 | 229 |
| 223 -- Event handlers | 230 -- Event handlers |
| 224 | 231 |
| 232 local function add_sni_host(host, service) | |
| 233 -- local global_ssl_config = config.get(host, "ssl") or {}; | |
| 234 for name, interface, port, n, active_service --luacheck: ignore 213 | |
| 235 in active_services:iter(service, nil, nil, nil) do | |
| 236 if active_service.server.hosts and active_service.tls_cfg then | |
| 237 -- local config_prefix = (active_service.config_prefix or name).."_"; | |
| 238 -- if config_prefix == "_" then | |
| 239 -- config_prefix = ""; | |
| 240 -- end | |
| 241 -- local prefix_ssl_config = config.get(host, config_prefix.."ssl") or global_ssl_config; | |
| 242 -- FIXME only global 'ssl' settings are mixed in here | |
| 243 -- TODO per host and per service settings should be merged in, | |
| 244 -- without overriding the per-host certificate | |
| 245 local ssl, err, cfg = certmanager.create_context(host, "server"); | |
| 246 if ssl then | |
| 247 active_service.server.hosts[host] = ssl; | |
| 248 if not active_service.tls_cfg.certificate then | |
| 249 active_service.server.tls_ctx = ssl; | |
| 250 active_service.tls_cfg = cfg; | |
| 251 end | |
| 252 else | |
| 253 log("error", "err = %q", err); | |
| 254 end | |
| 255 end | |
| 256 end | |
| 257 end | |
| 225 prosody.events.add_handler("item-added/net-provider", function (event) | 258 prosody.events.add_handler("item-added/net-provider", function (event) |
| 226 local item = event.item; | 259 local item = event.item; |
| 227 register_service(item.name, item); | 260 register_service(item.name, item); |
| 261 for host in pairs(prosody.hosts) do | |
| 262 add_sni_host(host, item.name); | |
| 263 end | |
| 228 end); | 264 end); |
| 229 prosody.events.add_handler("item-removed/net-provider", function (event) | 265 prosody.events.add_handler("item-removed/net-provider", function (event) |
| 230 local item = event.item; | 266 local item = event.item; |
| 231 unregister_service(item.name, item); | 267 unregister_service(item.name, item); |
| 268 end); | |
| 269 | |
| 270 prosody.events.add_handler("host-activated", add_sni_host); | |
| 271 prosody.events.add_handler("host-deactivated", function (host) | |
| 272 for name, interface, port, n, active_service --luacheck: ignore 213 | |
| 273 in active_services:iter(nil, nil, nil, nil) do | |
| 274 if active_service.tls_cfg then | |
| 275 active_service.server.hosts[host] = nil; | |
| 276 end | |
| 277 end | |
| 232 end); | 278 end); |
| 233 | 279 |
| 234 return { | 280 return { |
| 235 activate = activate; | 281 activate = activate; |
| 236 deactivate = deactivate; | 282 deactivate = deactivate; |
