configmanager: nameprep VirtualHost and Component names
[prosody.git] / net / server_select.lua
index 28f1dc6da1f47db2589e026edb9a36efec0521fb..e896451830d3c85c06d8721d8954528bf20f8112 100644 (file)
@@ -101,6 +101,7 @@ local _readtraffic
 
 local _selecttimeout
 local _sleeptime
+local _tcpbacklog
 
 local _starttime
 local _currenttime
@@ -139,6 +140,7 @@ _readtraffic = 0
 
 _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
@@ -147,7 +149,8 @@ _checkinterval = 1200000 -- interval in secs to check idle clients
 _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
@@ -211,7 +214,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
        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)
@@ -260,7 +263,9 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
        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 )
@@ -392,6 +397,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
        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
@@ -699,6 +705,7 @@ local function link(sender, receiver, buffersize)
                        sender:lock_read(true);
                end
        end
+       sender:set_mode("*a");
 end
 
 ----------------------------------// PUBLIC //--
@@ -720,7 +727,7 @@ addserver = function( addr, port, listeners, pattern, sslctx ) -- this function
                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
@@ -772,6 +779,7 @@ getsettings = function( )
        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;
@@ -792,6 +800,7 @@ changesettings = function( new )
        _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
@@ -909,13 +918,9 @@ local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx
                        -- 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