Software /
code /
prosody
Comparison
net/server_select.lua @ 5024:d25e1b9332cc
Merge with Florob
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 28 Jul 2012 01:14:31 +0100 |
parent | 4983:4fd6a020d0d8 |
child | 5197:beffe931b3b6 |
comparison
equal
deleted
inserted
replaced
5023:dcc8e789df36 | 5024:d25e1b9332cc |
---|---|
17 end | 17 end |
18 | 18 |
19 local log, table_concat = require ("util.logger").init("socket"), table.concat; | 19 local log, table_concat = require ("util.logger").init("socket"), table.concat; |
20 local out_put = function (...) return log("debug", table_concat{...}); end | 20 local out_put = function (...) return log("debug", table_concat{...}); end |
21 local out_error = function (...) return log("warn", table_concat{...}); end | 21 local out_error = function (...) return log("warn", table_concat{...}); end |
22 local mem_free = collectgarbage | |
23 | 22 |
24 ----------------------------------// DECLARATION //-- | 23 ----------------------------------// DECLARATION //-- |
25 | 24 |
26 --// constants //-- | 25 --// constants //-- |
27 | 26 |
32 local type = use "type" | 31 local type = use "type" |
33 local pairs = use "pairs" | 32 local pairs = use "pairs" |
34 local ipairs = use "ipairs" | 33 local ipairs = use "ipairs" |
35 local tonumber = use "tonumber" | 34 local tonumber = use "tonumber" |
36 local tostring = use "tostring" | 35 local tostring = use "tostring" |
37 local collectgarbage = use "collectgarbage" | |
38 | 36 |
39 --// lua libs //-- | 37 --// lua libs //-- |
40 | 38 |
41 local os = use "os" | 39 local os = use "os" |
42 local table = use "table" | 40 local table = use "table" |
47 | 45 |
48 local os_difftime = os.difftime | 46 local os_difftime = os.difftime |
49 local math_min = math.min | 47 local math_min = math.min |
50 local math_huge = math.huge | 48 local math_huge = math.huge |
51 local table_concat = table.concat | 49 local table_concat = table.concat |
52 local table_remove = table.remove | |
53 local string_len = string.len | 50 local string_len = string.len |
54 local string_sub = string.sub | 51 local string_sub = string.sub |
55 local coroutine_wrap = coroutine.wrap | 52 local coroutine_wrap = coroutine.wrap |
56 local coroutine_yield = coroutine.yield | 53 local coroutine_yield = coroutine.yield |
57 | 54 |
65 | 62 |
66 local ssl_wrap = ( luasec and luasec.wrap ) | 63 local ssl_wrap = ( luasec and luasec.wrap ) |
67 local socket_bind = luasocket.bind | 64 local socket_bind = luasocket.bind |
68 local socket_sleep = luasocket.sleep | 65 local socket_sleep = luasocket.sleep |
69 local socket_select = luasocket.select | 66 local socket_select = luasocket.select |
70 local ssl_newcontext = ( luasec and luasec.newcontext ) | |
71 | 67 |
72 --// functions //-- | 68 --// functions //-- |
73 | 69 |
74 local id | 70 local id |
75 local loop | 71 local loop |
82 local wrapserver | 78 local wrapserver |
83 local getsettings | 79 local getsettings |
84 local closesocket | 80 local closesocket |
85 local removesocket | 81 local removesocket |
86 local removeserver | 82 local removeserver |
87 local changetimeout | |
88 local wrapconnection | 83 local wrapconnection |
89 local changesettings | 84 local changesettings |
90 | 85 |
91 --// tables //-- | 86 --// tables //-- |
92 | 87 |
312 if socket.setoption then | 307 if socket.setoption then |
313 return socket:setoption(option, value); | 308 return socket:setoption(option, value); |
314 end | 309 end |
315 return false, "setoption not implemented"; | 310 return false, "setoption not implemented"; |
316 end | 311 end |
317 handler.close = function( self, forced ) | 312 handler.force_close = function ( self, err ) |
313 if bufferqueuelen ~= 0 then | |
314 out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport)) | |
315 for i = bufferqueuelen, 1, -1 do | |
316 bufferqueue[i] = nil; | |
317 end | |
318 bufferqueuelen = 0; | |
319 end | |
320 return self:close(err); | |
321 end | |
322 handler.close = function( self, err ) | |
318 if not handler then return true; end | 323 if not handler then return true; end |
319 _readlistlen = removesocket( _readlist, socket, _readlistlen ) | 324 _readlistlen = removesocket( _readlist, socket, _readlistlen ) |
320 _readtimes[ handler ] = nil | 325 _readtimes[ handler ] = nil |
321 if bufferqueuelen ~= 0 then | 326 if bufferqueuelen ~= 0 then |
322 if not ( forced or fatalerror ) then | 327 handler.sendbuffer() -- Try now to send any outstanding data |
323 handler.sendbuffer( ) | 328 if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later |
324 if bufferqueuelen ~= 0 then -- try again... | 329 if handler then |
325 if handler then | 330 handler.write = nil -- ... but no further writing allowed |
326 handler.write = nil -- ... but no further writing allowed | |
327 end | |
328 toclose = true | |
329 return false | |
330 end | 331 end |
331 else | 332 toclose = true |
332 send( socket, table_concat( bufferqueue, "", 1, bufferqueuelen ), 1, bufferlen ) -- forced send | 333 return false |
333 end | 334 end |
334 end | 335 end |
335 if socket then | 336 if socket then |
336 _ = shutdown and shutdown( socket ) | 337 _ = shutdown and shutdown( socket ) |
337 socket:close( ) | 338 socket:close( ) |
345 _writetimes[ handler ] = nil | 346 _writetimes[ handler ] = nil |
346 _closelist[ handler ] = nil | 347 _closelist[ handler ] = nil |
347 local _handler = handler; | 348 local _handler = handler; |
348 handler = nil | 349 handler = nil |
349 if disconnect then | 350 if disconnect then |
350 disconnect(_handler, "closed"); | 351 disconnect(_handler, err or false); |
352 disconnect = nil | |
351 end | 353 end |
352 end | 354 end |
353 if server then | 355 if server then |
354 server.remove( ) | 356 server.remove( ) |
355 end | 357 end |
448 local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern" | 450 local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern" |
449 if not err or (err == "wantread" or err == "timeout") then -- received something | 451 if not err or (err == "wantread" or err == "timeout") then -- received something |
450 local buffer = buffer or part or "" | 452 local buffer = buffer or part or "" |
451 local len = string_len( buffer ) | 453 local len = string_len( buffer ) |
452 if len > maxreadlen then | 454 if len > maxreadlen then |
453 disconnect( handler, "receive buffer exceeded" ) | 455 handler:close( "receive buffer exceeded" ) |
454 handler:close( true ) | |
455 return false | 456 return false |
456 end | 457 end |
457 local count = len * STAT_UNIT | 458 local count = len * STAT_UNIT |
458 readtraffic = readtraffic + count | 459 readtraffic = readtraffic + count |
459 _readtraffic = _readtraffic + count | 460 _readtraffic = _readtraffic + count |
461 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err ) | 462 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err ) |
462 return dispatch( handler, buffer, err ) | 463 return dispatch( handler, buffer, err ) |
463 else -- connections was closed or fatal error | 464 else -- connections was closed or fatal error |
464 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) | 465 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) |
465 fatalerror = true | 466 fatalerror = true |
466 disconnect( handler, err ) | 467 _ = handler and handler:force_close( err ) |
467 _ = handler and handler:close( ) | |
468 return false | 468 return false |
469 end | 469 end |
470 end | 470 end |
471 local _sendbuffer = function( ) -- this function sends data | 471 local _sendbuffer = function( ) -- this function sends data |
472 local succ, err, byte, buffer, count; | 472 local succ, err, byte, buffer, count; |
473 local count; | |
474 if socket then | 473 if socket then |
475 buffer = table_concat( bufferqueue, "", 1, bufferqueuelen ) | 474 buffer = table_concat( bufferqueue, "", 1, bufferqueuelen ) |
476 succ, err, byte = send( socket, buffer, 1, bufferlen ) | 475 succ, err, byte = send( socket, buffer, 1, bufferlen ) |
477 count = ( succ or byte or 0 ) * STAT_UNIT | 476 count = ( succ or byte or 0 ) * STAT_UNIT |
478 sendtraffic = sendtraffic + count | 477 sendtraffic = sendtraffic + count |
479 _sendtraffic = _sendtraffic + count | 478 _sendtraffic = _sendtraffic + count |
480 _ = _cleanqueue and clean( bufferqueue ) | 479 _ = _cleanqueue and clean( bufferqueue ) |
481 --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) ) | 480 --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) ) |
482 else | 481 else |
483 succ, err, count = false, "closed", 0; | 482 succ, err, count = false, "unexpected close", 0; |
484 end | 483 end |
485 if succ then -- sending succesful | 484 if succ then -- sending succesful |
486 bufferqueuelen = 0 | 485 bufferqueuelen = 0 |
487 bufferlen = 0 | 486 bufferlen = 0 |
488 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist | 487 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist |
489 _writetimes[ handler ] = nil | 488 _writetimes[ handler ] = nil |
490 if drain then | 489 if drain then |
491 drain(handler) | 490 drain(handler) |
492 end | 491 end |
493 _ = needtls and handler:starttls(nil) | 492 _ = needtls and handler:starttls(nil) |
494 _ = toclose and handler:close( ) | 493 _ = toclose and handler:force_close( ) |
495 return true | 494 return true |
496 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write | 495 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write |
497 buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer | 496 buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer |
498 bufferqueue[ 1 ] = buffer -- insert new buffer in queue | 497 bufferqueue[ 1 ] = buffer -- insert new buffer in queue |
499 bufferqueuelen = 1 | 498 bufferqueuelen = 1 |
501 _writetimes[ handler ] = _currenttime | 500 _writetimes[ handler ] = _currenttime |
502 return true | 501 return true |
503 else -- connection was closed during sending or fatal error | 502 else -- connection was closed during sending or fatal error |
504 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) ) | 503 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) ) |
505 fatalerror = true | 504 fatalerror = true |
506 disconnect( handler, err ) | 505 _ = handler and handler:force_close( err ) |
507 _ = handler and handler:close( ) | |
508 return false | 506 return false |
509 end | 507 end |
510 end | 508 end |
511 | 509 |
512 -- Set the sslctx | 510 -- Set the sslctx |
544 err = nil; | 542 err = nil; |
545 coroutine_yield( ) -- handshake not finished | 543 coroutine_yield( ) -- handshake not finished |
546 end | 544 end |
547 end | 545 end |
548 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") ) | 546 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") ) |
549 disconnect( handler, "ssl handshake failed" ) | 547 _ = handler and handler:force_close("ssl handshake failed") |
550 _ = handler and handler:close( true ) -- forced disconnect | 548 return false, err -- handshake failed |
551 return false, err -- handshake failed | |
552 end | 549 end |
553 ) | 550 ) |
554 end | 551 end |
555 if luasec then | 552 if luasec then |
556 handler.starttls = function( self, _sslctx) | 553 handler.starttls = function( self, _sslctx) |
808 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen | 805 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen |
809 end | 806 end |
810 end | 807 end |
811 for handler, err in pairs( _closelist ) do | 808 for handler, err in pairs( _closelist ) do |
812 handler.disconnect( )( handler, err ) | 809 handler.disconnect( )( handler, err ) |
813 handler:close( true ) -- forced disconnect | 810 handler:force_close() -- forced disconnect |
814 end | 811 end |
815 clean( _closelist ) | 812 clean( _closelist ) |
816 _currenttime = luasocket_gettime( ) | 813 _currenttime = luasocket_gettime( ) |
817 if _currenttime - _timer >= math_min(next_timer_time, 1) then | 814 if _currenttime - _timer >= math_min(next_timer_time, 1) then |
818 next_timer_time = math_huge; | 815 next_timer_time = math_huge; |
894 _starttime = _currenttime | 891 _starttime = _currenttime |
895 for handler, timestamp in pairs( _writetimes ) do | 892 for handler, timestamp in pairs( _writetimes ) do |
896 if os_difftime( _currenttime - timestamp ) > _sendtimeout then | 893 if os_difftime( _currenttime - timestamp ) > _sendtimeout then |
897 --_writetimes[ handler ] = nil | 894 --_writetimes[ handler ] = nil |
898 handler.disconnect( )( handler, "send timeout" ) | 895 handler.disconnect( )( handler, "send timeout" ) |
899 handler:close( true ) -- forced disconnect | 896 handler:force_close() -- forced disconnect |
900 end | 897 end |
901 end | 898 end |
902 for handler, timestamp in pairs( _readtimes ) do | 899 for handler, timestamp in pairs( _readtimes ) do |
903 if os_difftime( _currenttime - timestamp ) > _readtimeout then | 900 if os_difftime( _currenttime - timestamp ) > _readtimeout then |
904 --_readtimes[ handler ] = nil | 901 --_readtimes[ handler ] = nil |