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