Software / code / prosody
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) |