diff options
author | Kim Alvefur <zash@zash.se> | 2013-02-12 03:24:41 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2013-02-12 03:24:41 +0100 |
commit | a003acb3851806e0e1682333f5d572eb566208a0 (patch) | |
tree | a1751bd7428f316b4d2830dc15c3e729e67d5b3c /net/server_select.lua | |
parent | 4f6cb9d1c644fdd8d7254e4ae38e7dc96f971ba3 (diff) | |
download | prosody-a003acb3851806e0e1682333f5d572eb566208a0.tar.gz prosody-a003acb3851806e0e1682333f5d572eb566208a0.zip |
net.server_select: Limit global number of sockets passed to select.
Diffstat (limited to 'net/server_select.lua')
-rw-r--r-- | net/server_select.lua | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/net/server_select.lua b/net/server_select.lua index 36cb1265..250438c3 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -122,7 +122,8 @@ local _cleanqueue local _timer -local _maxclientsperserver +local _maxselectlen +local _maxfd local _maxsslhandshake @@ -156,15 +157,20 @@ _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs _cleanqueue = false -- clean bufferqueue after using -_maxclientsperserver = 1000 +_maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something. +_maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows _maxsslhandshake = 30 -- max handshake round-trips ----------------------------------// PRIVATE //-- -wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server +wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd - maxconnections = maxconnections or _maxclientsperserver + if socket:getfd() >= _maxfd then + out_error("server.lua: Disallowed FD number: "..socket:getfd()) + socket:close() + return nil, "fd-too-large" + end local connections = 0 @@ -233,7 +239,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxco return socket end handler.readbuffer = function( ) - if connections > maxconnections then + if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then handler.pause( ) out_put( "server.lua: refused new client connection: server full" ) return false @@ -261,6 +267,12 @@ end wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object + if socket:getfd() >= _maxfd then + out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent + socket:close( ) -- Should we send some kind of error here? + server.pause( ) + return nil, nil, "fd-too-large" + end socket:settimeout( 0 ) --// local import of socket methods //-- @@ -724,7 +736,7 @@ addserver = function( addr, port, listeners, pattern, sslctx ) -- this function out_error( "server.lua, [", addr, "]:", port, ": ", err ) return nil, err end - local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket + local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket if not handler then server:close( ) return nil, err @@ -768,7 +780,7 @@ closeall = function( ) end getsettings = function( ) - return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxclientsperserver, _maxsslhandshake + return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxselectlen, _maxsslhandshake, _maxfd end changesettings = function( new ) @@ -783,8 +795,9 @@ changesettings = function( new ) _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout _readtimeout = tonumber( new.read_timeout ) or _readtimeout _cleanqueue = new.select_clean_queue - _maxclientsperserver = new.max_connections or _maxclientsperserver + _maxselectlen = new.max_connections or _maxselectlen _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake + _maxfd = new.highest_allowed_fd or _maxfd return true end @@ -865,7 +878,8 @@ end --// EXPERIMENTAL //-- local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) - local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) + local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) + if not handler then return nil, err end _socketlist[ socket ] = handler if not sslctx then _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) |