local _selecttimeout
local _sleeptime
+local _tcpbacklog
local _starttime
local _currenttime
_selecttimeout = 1 -- timeout of socket.select
_sleeptime = 0 -- time to wait at the end of every loop
+_tcpbacklog = 128 -- some kind of hint to the OS
_maxsendlen = 51000 * 1024 -- max len of send buffer
_maxreadlen = 25000 * 1024 -- max len of read buffer
_sendtimeout = 60000 -- allowed send idle time in secs
_readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
-_maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something.
+local is_windows = package.config:sub(1,1) == "\\" -- check the directory separator, to detemine whether this is Windows
+_maxfd = (is_windows and math.huge) or luasocket._SETSIZE or 1024 -- max fd number, limit to 1024 by default to prevent glibc buffer overflow, but not on Windows
_maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows
_maxsslhandshake = 30 -- max handshake round-trips
handler.resume = function( )
if handler.paused then
if not socket then
- socket = socket_bind( ip, serverport );
+ socket = socket_bind( ip, serverport, _tcpbacklog );
socket:settimeout( 0 )
end
_readlistlen = addsocket(_readlist, socket, _readlistlen)
end
connections = connections + 1
out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
- if dispatch then
+ if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes
return dispatch( handler );
end
return;
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( )
+ if server then
+ server.pause( )
+ end
return nil, nil, "fd-too-large"
end
socket:settimeout( 0 )
local status = listeners.onstatus
local disconnect = listeners.ondisconnect
local drain = listeners.ondrain
+ local detach = listeners.ondetach
local bufferqueue = { } -- buffer array
local bufferqueuelen = 0 -- end of buffer array
return disconnect
end
handler.setlistener = function( self, listeners )
+ if detach then
+ detach(self) -- Notify listener that it is no longer responsible for this connection
+ end
dispatch = listeners.onincoming
disconnect = listeners.ondisconnect
status = listeners.onstatus
drain = listeners.ondrain
+ detach = listeners.ondetach
end
handler.getstats = function( )
return readtraffic, sendtraffic
handler.clientport = function( )
return clientport
end
+ handler.port = handler.clientport -- COMPAT server_event
local write = function( self, data )
bufferlen = bufferlen + #data
if bufferlen > maxsendlen then
sender:lock_read(true);
end
end
+ sender:set_mode("*a");
end
----------------------------------// PUBLIC //--
return nil, err
end
addr = addr or "*"
- local server, err = socket_bind( addr, port )
+ local server, err = socket_bind( addr, port, _tcpbacklog )
if err then
out_error( "server.lua, [", addr, "]:", port, ": ", err )
return nil, err
return {
select_timeout = _selecttimeout;
select_sleep_time = _sleeptime;
+ tcp_backlog = _tcpbacklog;
max_send_buffer_size = _maxsendlen;
max_receive_buffer_size = _maxreadlen;
select_idle_check_interval = _checkinterval;
_maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
_maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
_checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
+ _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
_sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
_readtimeout = tonumber( new.read_timeout ) or _readtimeout
_maxselectlen = new.max_connections or _maxselectlen
-- When socket is writeable, call onconnect
local _sendbuffer = handler.sendbuffer;
handler.sendbuffer = function ()
- _sendlistlen = removesocket( _sendlist, socket, _sendlistlen );
handler.sendbuffer = _sendbuffer;
listeners.onconnect(handler);
- -- If there was data with the incoming packet, handle it now.
- if #handler:bufferqueue() > 0 then
- return _sendbuffer();
- end
+ return _sendbuffer(); -- Send any queued outgoing data
end
end
end