Comparison

net/server_select.lua @ 4980:2e35cfe11835

net.server_select: Never call ondisconnect() directly, go via handler:close() or handler:force_close() - fixes cases where ondisconnect() could be called multiple times for the same connection, leading to issues with s2sout retry logic.
author Matthew Wild <mwild1@gmail.com>
date Sun, 22 Jul 2012 22:12:17 +0100
parent 4962:1d8fb12a9b2d
child 4982:07f478b1f7c0
comparison
equal deleted inserted replaced
4979:5614bbc163e0 4980:2e35cfe11835
312 if socket.setoption then 312 if socket.setoption then
313 return socket:setoption(option, value); 313 return socket:setoption(option, value);
314 end 314 end
315 return false, "setoption not implemented"; 315 return false, "setoption not implemented";
316 end 316 end
317 handler.force_close = function ( self ) 317 handler.force_close = function ( self, err )
318 if bufferqueuelen ~= 0 then 318 if bufferqueuelen ~= 0 then
319 out_put("discarding unwritten data for ", tostring(ip), ":", tostring(clientport)) 319 out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
320 for i = bufferqueuelen, 1, -1 do 320 for i = bufferqueuelen, 1, -1 do
321 bufferqueue[i] = nil; 321 bufferqueue[i] = nil;
322 end 322 end
323 bufferqueuelen = 0; 323 bufferqueuelen = 0;
324 end 324 end
325 return self:close(); 325 return self:close(err);
326 end 326 end
327 handler.close = function( self ) 327 handler.close = function( self, err )
328 if not handler then return true; end 328 if not handler then return true; end
329 _readlistlen = removesocket( _readlist, socket, _readlistlen ) 329 _readlistlen = removesocket( _readlist, socket, _readlistlen )
330 _readtimes[ handler ] = nil 330 _readtimes[ handler ] = nil
331 if bufferqueuelen ~= 0 then 331 if bufferqueuelen ~= 0 then
332 handler.sendbuffer() -- Try now to send any outstanding data 332 handler.sendbuffer() -- Try now to send any outstanding data
351 _writetimes[ handler ] = nil 351 _writetimes[ handler ] = nil
352 _closelist[ handler ] = nil 352 _closelist[ handler ] = nil
353 local _handler = handler; 353 local _handler = handler;
354 handler = nil 354 handler = nil
355 if disconnect then 355 if disconnect then
356 disconnect(_handler, false); 356 disconnect(_handler, err or false);
357 disconnect = nil
357 end 358 end
358 end 359 end
359 if server then 360 if server then
360 server.remove( ) 361 server.remove( )
361 end 362 end
454 local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern" 455 local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern"
455 if not err or (err == "wantread" or err == "timeout") then -- received something 456 if not err or (err == "wantread" or err == "timeout") then -- received something
456 local buffer = buffer or part or "" 457 local buffer = buffer or part or ""
457 local len = string_len( buffer ) 458 local len = string_len( buffer )
458 if len > maxreadlen then 459 if len > maxreadlen then
459 disconnect( handler, "receive buffer exceeded" ) 460 handler:close( "receive buffer exceeded" )
460 handler:close( true )
461 return false 461 return false
462 end 462 end
463 local count = len * STAT_UNIT 463 local count = len * STAT_UNIT
464 readtraffic = readtraffic + count 464 readtraffic = readtraffic + count
465 _readtraffic = _readtraffic + count 465 _readtraffic = _readtraffic + count
467 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err ) 467 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
468 return dispatch( handler, buffer, err ) 468 return dispatch( handler, buffer, err )
469 else -- connections was closed or fatal error 469 else -- connections was closed or fatal error
470 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) 470 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
471 fatalerror = true 471 fatalerror = true
472 disconnect( handler, err ) 472 _ = handler and handler:force_close( err )
473 _ = handler and handler:close( )
474 return false 473 return false
475 end 474 end
476 end 475 end
477 local _sendbuffer = function( ) -- this function sends data 476 local _sendbuffer = function( ) -- this function sends data
478 local succ, err, byte, buffer, count; 477 local succ, err, byte, buffer, count;
507 _writetimes[ handler ] = _currenttime 506 _writetimes[ handler ] = _currenttime
508 return true 507 return true
509 else -- connection was closed during sending or fatal error 508 else -- connection was closed during sending or fatal error
510 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) ) 509 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
511 fatalerror = true 510 fatalerror = true
512 disconnect( handler, err ) 511 _ = handler and handler:force_close( err )
513 _ = handler and handler:force_close( )
514 return false 512 return false
515 end 513 end
516 end 514 end
517 515
518 -- Set the sslctx 516 -- Set the sslctx
550 err = nil; 548 err = nil;
551 coroutine_yield( ) -- handshake not finished 549 coroutine_yield( ) -- handshake not finished
552 end 550 end
553 end 551 end
554 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") ) 552 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
555 disconnect( handler, "ssl handshake failed" ) 553 _ = handler and handler:force_close("ssl handshake failed")
556 _ = handler and handler:force_close() 554 return false, err -- handshake failed
557 return false, err -- handshake failed
558 end 555 end
559 ) 556 )
560 end 557 end
561 if luasec then 558 if luasec then
562 handler.starttls = function( self, _sslctx) 559 handler.starttls = function( self, _sslctx)