aboutsummaryrefslogtreecommitdiffstats
path: root/net/server_event.lua
diff options
context:
space:
mode:
Diffstat (limited to 'net/server_event.lua')
-rw-r--r--net/server_event.lua69
1 files changed, 39 insertions, 30 deletions
diff --git a/net/server_event.lua b/net/server_event.lua
index 375ab47e..b467a84d 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -52,6 +52,7 @@ local log = require ("util.logger").init("socket")
local function debug(...)
return log("debug", ("%s "):rep(select('#', ...)), ...)
end
+local vdebug = debug;
local bitor = ( function( ) -- thx Rici Lake
local hasbit = function( x, p )
@@ -139,14 +140,14 @@ do
self.fatalerror = "connection timeout"
self.listener.ontimeout( self ) -- call timeout listener
self:_close()
- debug( "new connection failed. id:", self, "error:", self.fatalerror )
+ debug( "new connection failed. id:", self.id, "error:", self.fatalerror )
else
if plainssl then -- start ssl session
self:_start_ssl( self.listener.onconnect )
else -- normal connection
self:_start_session( self.listener.onconnect )
end
- debug( "new connection established. id:", self )
+ debug( "new connection established. id:", self.id )
end
self.eventconnect = nil
return -1
@@ -158,28 +159,28 @@ do
if self.type == "client" then
local callback = function( )
self:_lock( false, false, false )
- --vdebug( "start listening on client socket with id:", self )
+ --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
- onconnect( self )
+ self:onconnect()
self.eventsession = nil
return -1
end
self.eventsession = addevent( base, nil, EV_TIMEOUT, callback, 0 )
else
self:_lock( false )
- --vdebug( "start listening on server socket with id:", self )
+ --vdebug( "start listening on server socket with id:", self.id )
self.eventread = addevent( base, self.conn, EV_READ, self.readcallback ) -- register callback
end
return true
end
function interface_mt:_start_ssl(arg) -- old socket will be destroyed, therefore we have to close read/write events first
- --vdebug( "starting ssl session with client id:", self )
+ --vdebug( "starting ssl session with client id:", self.id )
local _
_ = self.eventread and self.eventread:close( ) -- close events; this must be called outside of the event callbacks!
_ = self.eventwrite and self.eventwrite:close( )
self.eventread, self.eventwrite = nil, nil
local err
- self.conn, err = ssl.wrap( self.conn, self.sslctx )
+ self.conn, err = ssl.wrap( self.conn, self._sslctx )
if err then
self.fatalerror = err
self.conn = nil -- cannot be used anymore
@@ -198,7 +199,7 @@ do
local maxattempt = cfg.MAX_HANDSHAKE_ATTEMPS
while attempt < 1000 do -- no endless loop
attempt = attempt + 1
- debug( "ssl handshake of client with id:", self, "attemp:", attempt )
+ debug( "ssl handshake of client with id:"..tostring(self).."attemp:"..attempt )
if attempt > maxattempt then
self.fatalerror = "max handshake attemps exceeded"
elseif EV_TIMEOUT == event then
@@ -211,16 +212,16 @@ do
self.receive = self.conn.receive
local onsomething
if "onconnect" == arg then -- trigger listener
- onsomething = self.listener.onconnect
+ onsomething = self.onconnect
else
- onsomething = self.listener.onsslconnection
+ onsomething = self.onsslconnection
end
self:_start_session( onsomething )
debug( "ssl handshake done" )
self.eventhandshake = nil
return -1
end
- debug( "error during ssl handshake:", err )
+ debug( "error during ssl handshake:", err )
if err == "wantwrite" then
event = EV_WRITE
elseif err == "wantread" then
@@ -248,7 +249,7 @@ do
return true
end
function interface_mt:_destroy() -- close this interface + events and call last listener
- debug( "closing client with id:", self )
+ debug( "closing client with id:", self.id )
self:_lock( true, true, true ) -- first of all, lock the interface to avoid further actions
local _
_ = self.eventread and self.eventread:close( ) -- close events; this must be called outside of the event callbacks!
@@ -274,6 +275,7 @@ do
interfacelist( "delete", self )
return true
end
+
function interface_mt:_lock(nointerface, noreading, nowriting) -- lock or unlock this interface or events
self.nointerface, self.noreading, self.nowriting = nointerface, noreading, nowriting
return nointerface, noreading, nowriting
@@ -288,7 +290,8 @@ do
-- Public methods
function interface_mt:write(data)
- --vdebug( "try to send data to client, id/data:", self, data )
+ if self.nowriting then return nil, "locked" end
+ --vdebug( "try to send data to client, id/data:", self.id, data )
data = tostring( data )
local len = string_len( data )
local total = len + self.writebufferlen
@@ -306,7 +309,8 @@ do
return true
end
function interface_mt:close(now)
- debug( "try to close client connection with id:", self )
+ if self.nointerface then return nil, "locked"; end
+ debug( "try to close client connection with id:", self.id )
if self.type == "client" then
self.fatalerror = "client to close"
if ( not self.eventwrite ) or now then -- try to close immediately
@@ -319,7 +323,7 @@ do
return nil, "writebuffer not empty, waiting"
end
else
- debug( "try to close server with id:", self, "args:", now )
+ debug( "try to close server with id:", self.id, "args:", now )
self.fatalerror = "server to close"
self:_lock( true )
local count = 0
@@ -353,7 +357,7 @@ do
end
function interface_mt:ssl()
- return self.usingssl
+ return self._usingssl
end
function interface_mt:type()
@@ -368,22 +372,25 @@ do
return self.addr
end
-
+ function interface_mt:set_sslctx(sslctx)
+ self._sslctx = sslctx;
+ end
function interface_mt:starttls()
- debug( "try to start ssl at client id:", self )
+ debug( "try to start ssl at client id:", self.id )
local err
- if not self.sslctx then -- no ssl available
+ if not self._sslctx then -- no ssl available
err = "no ssl context available"
- elseif self.usingssl then -- startssl was already called
+ elseif self._usingssl then -- startssl was already called
err = "ssl already active"
end
if err then
debug( "error:", err )
return nil, err
end
- self.usingssl = true
+ self._usingssl = true
self.startsslcallback = function( ) -- we have to start the handshake outside of a read/write event
+ self.startsslcallback = nil
self:_start_ssl();
self.eventstarthandshake = nil
return -1
@@ -443,6 +450,7 @@ do
_sslctx = sslctx; -- parameters
_usingssl = false; -- client is using ssl;
}
+ interface.id = tostring(interface):match("%x+$");
interface.writecallback = function( event ) -- called on write events
--vdebug( "new client write event, id/ip/port:", interface, ip, port )
if interface.nowriting or ( interface.fatalerror and ( "client to close" ~= interface.fatalerror ) ) then -- leave this event
@@ -457,7 +465,7 @@ do
interface.eventwrite = false
return -1
else -- can write :)
- if interface.usingssl then -- handle luasec
+ if interface._usingssl then -- handle luasec
if interface.eventreadtimeout then -- we have to read first
local ret = interface.readcallback( ) -- call readcallback
--vdebug( "tried to read in writecallback, result:", ret )
@@ -467,7 +475,7 @@ do
interface.eventwritetimeout = false
end
end
- local succ, err, byte = interface.send( interface.conn, interface.writebuffer, 1, interface.writebufferlen )
+ local succ, err, byte = interface.conn:send( interface.writebuffer, 1, interface.writebufferlen )
--vdebug( "write data:", interface.writebuffer, "error:", err, "part:", byte )
if succ then -- writing succesful
interface.writebuffer = ""
@@ -508,7 +516,7 @@ do
end
end
end
- local usingssl, receive = interface._usingssl, interface.receive;
+
interface.readcallback = function( event ) -- called on read events
--vdebug( "new client read event, id/ip/port:", interface, ip, port )
if interface.noreading or interface.fatalerror then -- leave this event
@@ -523,7 +531,7 @@ do
interface.eventread = nil
return -1
else -- can read
- if usingssl then -- handle luasec
+ if interface._usingssl then -- handle luasec
if interface.eventwritetimeout then -- ok, in the past writecallback was regged
local ret = interface.writecallback( ) -- call it
--vdebug( "tried to write in readcallback, result:", ret )
@@ -533,8 +541,8 @@ do
interface.eventreadtimeout = nil
end
end
- local buffer, err, part = receive( client, pattern ) -- receive buffer with "pattern"
- --vdebug( "read data:", buffer, "error:", err, "part:", part )
+ local buffer, err, part = interface.conn:receive( 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 )
if len > cfg.MAX_READ_LENGTH then -- check buffer length
@@ -544,7 +552,7 @@ do
interface.eventread = nil
return -1
end
- if err and ( "timeout" ~= err ) then
+ if err and ( err ~= "timeout" and err ~= "wantread" ) then
if "wantwrite" == err then -- need to read on write event
if not interface.eventwrite then -- register new write event if needed
interface.eventwrite = addevent( base, interface.conn, EV_WRITE, interface.writecallback, cfg.WRITE_TIMEOUT )
@@ -591,6 +599,7 @@ do
fatalerror = false; -- error message
nointerface = true; -- lock/unlock parameter
}
+ interface.id = tostring(interface):match("%x+$");
interface.readcallback = function( event ) -- server handler, called on incoming connections
--vdebug( "server can accept, id/addr/port:", interface, addr, port )
if interface.fatalerror then
@@ -639,9 +648,9 @@ do
end
local addserver = ( function( )
- return function( addr, port, listener, pattern, backlog, sslcfg, startssl ) -- TODO: check arguments
+ return function( addr, port, listener, pattern, sslcfg, startssl ) -- TODO: check arguments
--vdebug( "creating new tcp server with following parameters:", addr or "nil", port or "nil", sslcfg or "nil", startssl or "nil")
- local server, err = socket.bind( addr, port, backlog ) -- create server socket
+ local server, err = socket.bind( addr, port, cfg.ACCEPT_QUEUE ) -- create server socket
if not server then
debug( "creating server socket failed because:", err )
return nil, err