aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/http.lua3
-rw-r--r--net/server_epoll.lua40
-rw-r--r--net/server_event.lua17
-rw-r--r--net/tls_luasec.lua5
4 files changed, 63 insertions, 2 deletions
diff --git a/net/http.lua b/net/http.lua
index bea1e905..35a92d57 100644
--- a/net/http.lua
+++ b/net/http.lua
@@ -317,6 +317,9 @@ local function request(self, u, ex, callback)
if ex and ex.use_dane ~= nil then
use_dane = ex.use_dane;
end
+ if not sslctx then
+ error("Attempt to make HTTPS request but no 'sslctx' provided in options");
+ end
end
if self.pool then
diff --git a/net/server_epoll.lua b/net/server_epoll.lua
index c946a751..6c110241 100644
--- a/net/server_epoll.lua
+++ b/net/server_epoll.lua
@@ -35,6 +35,38 @@ local poller = require "prosody.util.poll"
local EEXIST = poller.EEXIST;
local ENOENT = poller.ENOENT;
+-- systemd socket activation
+local SD_LISTEN_FDS_START = 3;
+local SD_LISTEN_FDS = tonumber(os.getenv("LISTEN_FDS")) or 0;
+
+local inherited_sockets = setmetatable({}, {
+ __index = function(t, k)
+ local serv_mt = debug.getregistry()["tcp{server}"];
+ for i = 1, SD_LISTEN_FDS do
+ local serv = socket.tcp();
+ if serv:getfd() ~= _SOCKETINVALID then
+ -- If LuaSocket allocated a FD for then we can't really close it and it would leak.
+ log("error", "LuaSocket not compatible with socket activation. Upgrade LuaSocket or disable socket activation.");
+ setmetatable(t, nil);
+ break
+ end
+ serv:setfd(SD_LISTEN_FDS_START + i - 1);
+ debug.setmetatable(serv, serv_mt);
+ serv:settimeout(0);
+ local ip, port = serv:getsockname();
+ t[ip .. ":" .. port] = serv;
+ if ip == "0.0.0.0" then
+ -- LuaSocket treats '*' as an alias for '0.0.0.0'
+ t["*:" .. port] = serv;
+ end
+ end
+
+ -- Disable lazy-loading mechanism once performed
+ setmetatable(t, nil);
+ return t[k];
+ end;
+});
+
local poll = assert(poller.new());
local _ENV = nil;
@@ -944,6 +976,14 @@ local function wrapserver(conn, addr, port, listeners, config)
end
local function listen(addr, port, listeners, config)
+ local inherited = inherited_sockets[addr .. ":" .. port];
+ if inherited then
+ local conn = wrapserver(inherited, addr, port, listeners, config);
+ -- sockets created by systemd must not be :close() since we may not have
+ -- privileges to create them
+ conn.destroy = interface.del;
+ return conn;
+ end
local conn, err = socket.bind(addr, port, cfg.tcp_backlog);
if not conn then return conn, err; end
conn:settimeout(0);
diff --git a/net/server_event.lua b/net/server_event.lua
index 3bad3474..44222aa3 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -735,7 +735,10 @@ local function handleserver( server, addr, port, pattern, listener, sslctx, star
debug( "maximal connections reached, refuse client connection; accept delay:", delay )
return EV_TIMEOUT, delay -- delay for next accept attempt
end
- local client_ip, client_port = client:getpeername( )
+ local client_ip, client_port = addr, port;
+ if client.getpeername then -- Only IP sockets have this method, UNIX sockets don't
+ client_ip, client_port = client:getpeername( )
+ end
interface._connections = interface._connections + 1 -- increase connection count
local clientinterface = handleclient( client, client_ip, client_port, interface, pattern, listener, sslctx )
--vdebug( "client id:", clientinterface, "startssl:", startssl )
@@ -758,6 +761,17 @@ local function handleserver( server, addr, port, pattern, listener, sslctx, star
return interface
end
+local function wrapserver(conn, addr, port, listeners, config)
+ config = config or {}
+ if config.sslctx and not has_luasec then
+ debug "fatal error: luasec not found"
+ return nil, "luasec not found"
+ end
+ local interface = handleserver( conn, addr, port, config.read_size, listeners, config.tls_ctx, config.tls_direct) -- new server handler
+ debug( "new server created with id:", tostring(interface))
+ return interface
+end
+
local function listen(addr, port, listener, config)
config = config or {}
if config.sslctx and not has_luasec then
@@ -947,6 +961,7 @@ return {
listen = listen,
addclient = addclient,
wrapclient = wrapclient,
+ wrapserver = wrapserver,
setquitting = setquitting,
closeall = closeallservers,
get_backend = get_backend,
diff --git a/net/tls_luasec.lua b/net/tls_luasec.lua
index 3af2fc6b..4e4e92ed 100644
--- a/net/tls_luasec.lua
+++ b/net/tls_luasec.lua
@@ -54,7 +54,10 @@ local function new_context(cfg, builder)
-- LuaSec expects dhparam to be a callback that takes two arguments.
-- We ignore those because it is mostly used for having a separate
-- set of params for EXPORT ciphers, which we don't have by default.
- if type(cfg.dhparam) == "string" then
+ if type(cfg.dhparam) == "string" and cfg.dhparam:sub(1, 10) == "-----BEGIN" then
+ local dhparam = cfg.dhparam;
+ cfg.dhparam = function() return dhparam; end
+ elseif type(cfg.dhparam) == "string" then
local f, err = io_open(cfg.dhparam);
if not f then return nil, "Could not open DH parameters: "..err end
local dhparam = f:read("*a");