X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=net%2Fserver_event.lua;h=0331e793a7fa447ef339e073ffc2e9645cf79d94;hb=d67b44d083d688733b9e4f8fe66e0b4c6995dccb;hp=b767cb20f62e1ce76fbec47648a5b10b460f96b0;hpb=98564da6e8f851f99e3c981833dc686991026a94;p=prosody.git diff --git a/net/server_event.lua b/net/server_event.lua index b767cb20..0331e793 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -20,14 +20,14 @@ local LAST_MODIFIED = "2009/11/20" local cfg = { MAX_CONNECTIONS = 100000, -- max per server connections (use "ulimit -n" on *nix) - MAX_HANDSHAKE_ATTEMPS = 1000, -- attemps to finish ssl handshake - HANDSHAKE_TIMEOUT = 30, -- timout in seconds per handshake attemp + MAX_HANDSHAKE_ATTEMPTS= 1000, -- attempts to finish ssl handshake + HANDSHAKE_TIMEOUT = 60, -- timeout in seconds per handshake attempt MAX_READ_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes allowed to read from sockets MAX_SEND_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes size of write buffer (for writing on sockets) - ACCEPT_DELAY = 10, -- seconds to wait until the next attemp of a full server to accept - READ_TIMEOUT = 60 * 30, -- timeout in seconds for read data from socket - WRITE_TIMEOUT = 30, -- timeout in seconds for write data on socket - CONNECT_TIMEOUT = 20, -- timeout in seconds for connection attemps + ACCEPT_DELAY = 10, -- seconds to wait until the next attempt of a full server to accept + READ_TIMEOUT = 60 * 60 * 6, -- timeout in seconds for read data from socket + WRITE_TIMEOUT = 180, -- timeout in seconds for write data on socket + CONNECT_TIMEOUT = 20, -- timeout in seconds for connection attempts CLEAR_DELAY = 5, -- seconds to wait for clearing interface list (and calling ondisconnect listeners) DEBUG = true, -- show debug messages } @@ -136,7 +136,7 @@ do function interface_mt:_start_connection(plainssl) -- should be called from addclient local callback = function( event ) - if EV_TIMEOUT == event then -- timout during connection + if EV_TIMEOUT == event then -- timeout during connection self.fatalerror = "connection timeout" self:ontimeout() -- call timeout listener self:_close() @@ -160,8 +160,8 @@ do local callback = function( ) self:_lock( false, false, false ) --vdebug( "start listening on client socket with id:", self.id ) - self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ) -- register callback - self:onincoming() + self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback + self:onconnect() self.eventsession = nil return -1 end @@ -196,12 +196,12 @@ do function( event ) local _, err local attempt = 0 - local maxattempt = cfg.MAX_HANDSHAKE_ATTEMPS + local maxattempt = cfg.MAX_HANDSHAKE_ATTEMPTS while attempt < maxattempt do -- no endless loop attempt = attempt + 1 - debug( "ssl handshake of client with id:"..tostring(self).."attemp:"..attempt ) + debug( "ssl handshake of client with id:"..tostring(self)..", attempt:"..attempt ) if attempt > maxattempt then - self.fatalerror = "max handshake attemps exceeded" + self.fatalerror = "max handshake attempts exceeded" elseif EV_TIMEOUT == event then self.fatalerror = "timeout during handshake" else @@ -282,8 +282,21 @@ do return nointerface, noreading, nowriting end + --TODO: Deprecate function interface_mt:lock_read(switch) - return self:_lock(self.nointerface, switch, self.nowriting); + if switch then + return self:pause(); + else + return self:resume(); + end + end + + function interface_mt:pause() + return self:_lock(self.nointerface, true, self.nowriting); + end + + function interface_mt:resume() + return self:_lock(self.nointerface, false, self.nowriting); end function interface_mt:counter(c) @@ -389,6 +402,13 @@ do self.starttls = false; -- prevent starttls() end end + + function interface_mt:set_mode(pattern) + if pattern then + self._pattern = pattern; + end + return self._pattern; + end function interface_mt:set_send(new_send) -- No-op, we always use the underlying connection's send @@ -437,6 +457,7 @@ do -- Stub handlers function interface_mt:onconnect() + return self:onincoming(nil); end function interface_mt:onincoming() end @@ -444,6 +465,8 @@ do end function interface_mt:ontimeout() end + function interface_mt:ondrain() + end function interface_mt:onstatus() debug("server.lua: Dummy onstatus()") end @@ -524,6 +547,7 @@ do if succ then -- writing succesful interface.writebuffer = "" interface.writebufferlen = 0 + interface:ondrain(); if interface.fatalerror then debug "closing client after writing" interface:_close() -- close interface if needed @@ -535,7 +559,7 @@ do end interface.eventwrite = nil return -1 - elseif byte then -- want write again + elseif byte and (err == "timeout" or err == "wantwrite") then -- want write again --vdebug( "writebuffer is not empty:", err ) interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer interface.writebufferlen = interface.writebufferlen - byte @@ -546,7 +570,7 @@ do return -1; end interface.eventwritetimeout = addevent( base, nil, EV_TIMEOUT, callback, cfg.WRITE_TIMEOUT ) -- reg a new timeout event - debug( "wantread during write attemp, reg it in readcallback but dont know what really happens next..." ) + debug( "wantread during write attempt, reg it in readcallback but dont know what really happens next..." ) -- hopefully this works with luasec; its simply not possible to use 2 different write events on a socket in luaevent return -1 end @@ -585,7 +609,7 @@ do interface.eventreadtimeout = nil end end - local buffer, err, part = interface.conn:receive( pattern ) -- receive buffer with "pattern" + local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern" --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) buffer = buffer or part or "" local len = string_len( buffer ) @@ -607,7 +631,7 @@ do interface:_close() end, cfg.READ_TIMEOUT ) - debug( "wantwrite during read attemp, reg it in writecallback but dont know what really happens next..." ) + debug( "wantwrite during read attempt, reg it in writecallback but dont know what really happens next..." ) -- to be honest i dont know what happens next, if it is allowed to first read, the write etc... else -- connection was closed or fatal error interface.fatalerror = err @@ -669,7 +693,7 @@ do if interface._connections >= cfg.MAX_CONNECTIONS then client:close( ) -- refuse connection debug( "maximal connections reached, refuse client connection; accept delay:", delay ) - return EV_TIMEOUT, delay -- delay for next accept attemp + return EV_TIMEOUT, delay -- delay for next accept attempt end local client_ip, client_port = client:getpeername( ) interface._connections = interface._connections + 1 -- increase connection count @@ -726,7 +750,7 @@ do function wrapclient( client, ip, port, listeners, pattern, sslctx, startssl ) local interface = handleclient( client, ip, port, nil, pattern, listeners, sslctx ) interface:_start_session() - return interface + return interface, client --function handleclient( client, ip, port, server, pattern, listener, _, sslctx ) -- creates an client interface end @@ -821,11 +845,32 @@ function hook_signal(signal_num, handler) return signal_events[signal_num]; end +local function link(sender, receiver, buffersize) + sender:set_mode(buffersize); + local sender_locked; + + function receiver:ondrain() + if sender_locked then + sender:resume(); + sender_locked = nil; + end + end + + function sender:onincoming(data) + receiver:write(data); + if receiver.writebufferlen >= buffersize then + sender_locked = true; + sender:pause(); + end + end +end + return { cfg = cfg, base = base, loop = loop, + link = link, event = event, event_base = base, addevent = newevent,