PageRenderTime 93ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/net/server_select.lua

https://bitbucket.org/jefferai/prosody
Lua | 935 lines | 781 code | 110 blank | 44 comment | 87 complexity | 7a52c2dd838a51e34d5b00f2f86f8391 MD5 | raw file
  1. --
  2. -- server.lua by blastbeat of the luadch project
  3. -- Re-used here under the MIT/X Consortium License
  4. --
  5. -- Modifications (C) 2008-2010 Matthew Wild, Waqas Hussain
  6. --
  7. -- // wrapping luadch stuff // --
  8. local use = function( what )
  9. return _G[ what ]
  10. end
  11. local clean = function( tbl )
  12. for i, k in pairs( tbl ) do
  13. tbl[ i ] = nil
  14. end
  15. end
  16. local log, table_concat = require ("util.logger").init("socket"), table.concat;
  17. local out_put = function (...) return log("debug", table_concat{...}); end
  18. local out_error = function (...) return log("warn", table_concat{...}); end
  19. local mem_free = collectgarbage
  20. ----------------------------------// DECLARATION //--
  21. --// constants //--
  22. local STAT_UNIT = 1 -- byte
  23. --// lua functions //--
  24. local type = use "type"
  25. local pairs = use "pairs"
  26. local ipairs = use "ipairs"
  27. local tostring = use "tostring"
  28. local collectgarbage = use "collectgarbage"
  29. --// lua libs //--
  30. local os = use "os"
  31. local table = use "table"
  32. local string = use "string"
  33. local coroutine = use "coroutine"
  34. --// lua lib methods //--
  35. local os_time = os.time
  36. local os_difftime = os.difftime
  37. local table_concat = table.concat
  38. local table_remove = table.remove
  39. local string_len = string.len
  40. local string_sub = string.sub
  41. local coroutine_wrap = coroutine.wrap
  42. local coroutine_yield = coroutine.yield
  43. --// extern libs //--
  44. local luasec = use "ssl"
  45. local luasocket = use "socket" or require "socket"
  46. --// extern lib methods //--
  47. local ssl_wrap = ( luasec and luasec.wrap )
  48. local socket_bind = luasocket.bind
  49. local socket_sleep = luasocket.sleep
  50. local socket_select = luasocket.select
  51. local ssl_newcontext = ( luasec and luasec.newcontext )
  52. --// functions //--
  53. local id
  54. local loop
  55. local stats
  56. local idfalse
  57. local addtimer
  58. local closeall
  59. local addserver
  60. local getserver
  61. local wrapserver
  62. local getsettings
  63. local closesocket
  64. local removesocket
  65. local removeserver
  66. local changetimeout
  67. local wrapconnection
  68. local changesettings
  69. --// tables //--
  70. local _server
  71. local _readlist
  72. local _timerlist
  73. local _sendlist
  74. local _socketlist
  75. local _closelist
  76. local _readtimes
  77. local _writetimes
  78. --// simple data types //--
  79. local _
  80. local _readlistlen
  81. local _sendlistlen
  82. local _timerlistlen
  83. local _sendtraffic
  84. local _readtraffic
  85. local _selecttimeout
  86. local _sleeptime
  87. local _starttime
  88. local _currenttime
  89. local _maxsendlen
  90. local _maxreadlen
  91. local _checkinterval
  92. local _sendtimeout
  93. local _readtimeout
  94. local _cleanqueue
  95. local _timer
  96. local _maxclientsperserver
  97. ----------------------------------// DEFINITION //--
  98. _server = { } -- key = port, value = table; list of listening servers
  99. _readlist = { } -- array with sockets to read from
  100. _sendlist = { } -- arrary with sockets to write to
  101. _timerlist = { } -- array of timer functions
  102. _socketlist = { } -- key = socket, value = wrapped socket (handlers)
  103. _readtimes = { } -- key = handler, value = timestamp of last data reading
  104. _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
  105. _closelist = { } -- handlers to close
  106. _readlistlen = 0 -- length of readlist
  107. _sendlistlen = 0 -- length of sendlist
  108. _timerlistlen = 0 -- lenght of timerlist
  109. _sendtraffic = 0 -- some stats
  110. _readtraffic = 0
  111. _selecttimeout = 1 -- timeout of socket.select
  112. _sleeptime = 0 -- time to wait at the end of every loop
  113. _maxsendlen = 51000 * 1024 -- max len of send buffer
  114. _maxreadlen = 25000 * 1024 -- max len of read buffer
  115. _checkinterval = 1200000 -- interval in secs to check idle clients
  116. _sendtimeout = 60000 -- allowed send idle time in secs
  117. _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
  118. _cleanqueue = false -- clean bufferqueue after using
  119. _maxclientsperserver = 1000
  120. _maxsslhandshake = 30 -- max handshake round-trips
  121. ----------------------------------// PRIVATE //--
  122. wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server
  123. maxconnections = maxconnections or _maxclientsperserver
  124. local connections = 0
  125. local dispatch, disconnect = listeners.onincoming, listeners.ondisconnect
  126. local accept = socket.accept
  127. --// public methods of the object //--
  128. local handler = { }
  129. handler.shutdown = function( ) end
  130. handler.ssl = function( )
  131. return sslctx ~= nil
  132. end
  133. handler.sslctx = function( )
  134. return sslctx
  135. end
  136. handler.remove = function( )
  137. connections = connections - 1
  138. end
  139. handler.close = function( )
  140. for _, handler in pairs( _socketlist ) do
  141. if handler.serverport == serverport then
  142. handler.disconnect( handler, "server closed" )
  143. handler:close( true )
  144. end
  145. end
  146. socket:close( )
  147. _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
  148. _readlistlen = removesocket( _readlist, socket, _readlistlen )
  149. _socketlist[ socket ] = nil
  150. handler = nil
  151. socket = nil
  152. --mem_free( )
  153. out_put "server.lua: closed server handler and removed sockets from list"
  154. end
  155. handler.ip = function( )
  156. return ip
  157. end
  158. handler.serverport = function( )
  159. return serverport
  160. end
  161. handler.socket = function( )
  162. return socket
  163. end
  164. handler.readbuffer = function( )
  165. if connections > maxconnections then
  166. out_put( "server.lua: refused new client connection: server full" )
  167. return false
  168. end
  169. local client, err = accept( socket ) -- try to accept
  170. if client then
  171. local ip, clientport = client:getpeername( )
  172. client:settimeout( 0 )
  173. local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
  174. if err then -- error while wrapping ssl socket
  175. return false
  176. end
  177. connections = connections + 1
  178. out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
  179. return dispatch( handler )
  180. elseif err then -- maybe timeout or something else
  181. out_put( "server.lua: error with new client connection: ", tostring(err) )
  182. return false
  183. end
  184. end
  185. return handler
  186. end
  187. wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object
  188. socket:settimeout( 0 )
  189. --// local import of socket methods //--
  190. local send
  191. local receive
  192. local shutdown
  193. --// private closures of the object //--
  194. local ssl
  195. local dispatch = listeners.onincoming
  196. local status = listeners.onstatus
  197. local disconnect = listeners.ondisconnect
  198. local drain = listeners.ondrain
  199. local bufferqueue = { } -- buffer array
  200. local bufferqueuelen = 0 -- end of buffer array
  201. local toclose
  202. local fatalerror
  203. local needtls
  204. local bufferlen = 0
  205. local noread = false
  206. local nosend = false
  207. local sendtraffic, readtraffic = 0, 0
  208. local maxsendlen = _maxsendlen
  209. local maxreadlen = _maxreadlen
  210. --// public methods of the object //--
  211. local handler = bufferqueue -- saves a table ^_^
  212. handler.dispatch = function( )
  213. return dispatch
  214. end
  215. handler.disconnect = function( )
  216. return disconnect
  217. end
  218. handler.setlistener = function( self, listeners )
  219. dispatch = listeners.onincoming
  220. disconnect = listeners.ondisconnect
  221. status = listeners.onstatus
  222. drain = listeners.ondrain
  223. end
  224. handler.getstats = function( )
  225. return readtraffic, sendtraffic
  226. end
  227. handler.ssl = function( )
  228. return ssl
  229. end
  230. handler.sslctx = function ( )
  231. return sslctx
  232. end
  233. handler.send = function( _, data, i, j )
  234. return send( socket, data, i, j )
  235. end
  236. handler.receive = function( pattern, prefix )
  237. return receive( socket, pattern, prefix )
  238. end
  239. handler.shutdown = function( pattern )
  240. return shutdown( socket, pattern )
  241. end
  242. handler.setoption = function (self, option, value)
  243. if socket.setoption then
  244. return socket:setoption(option, value);
  245. end
  246. return false, "setoption not implemented";
  247. end
  248. handler.close = function( self, forced )
  249. if not handler then return true; end
  250. _readlistlen = removesocket( _readlist, socket, _readlistlen )
  251. _readtimes[ handler ] = nil
  252. if bufferqueuelen ~= 0 then
  253. if not ( forced or fatalerror ) then
  254. handler.sendbuffer( )
  255. if bufferqueuelen ~= 0 then -- try again...
  256. if handler then
  257. handler.write = nil -- ... but no further writing allowed
  258. end
  259. toclose = true
  260. return false
  261. end
  262. else
  263. send( socket, table_concat( bufferqueue, "", 1, bufferqueuelen ), 1, bufferlen ) -- forced send
  264. end
  265. end
  266. if socket then
  267. _ = shutdown and shutdown( socket )
  268. socket:close( )
  269. _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
  270. _socketlist[ socket ] = nil
  271. socket = nil
  272. else
  273. out_put "server.lua: socket already closed"
  274. end
  275. if handler then
  276. _writetimes[ handler ] = nil
  277. _closelist[ handler ] = nil
  278. handler = nil
  279. end
  280. if server then
  281. server.remove( )
  282. end
  283. out_put "server.lua: closed client handler and removed socket from list"
  284. return true
  285. end
  286. handler.ip = function( )
  287. return ip
  288. end
  289. handler.serverport = function( )
  290. return serverport
  291. end
  292. handler.clientport = function( )
  293. return clientport
  294. end
  295. local write = function( self, data )
  296. bufferlen = bufferlen + string_len( data )
  297. if bufferlen > maxsendlen then
  298. _closelist[ handler ] = "send buffer exceeded" -- cannot close the client at the moment, have to wait to the end of the cycle
  299. handler.write = idfalse -- dont write anymore
  300. return false
  301. elseif socket and not _sendlist[ socket ] then
  302. _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
  303. end
  304. bufferqueuelen = bufferqueuelen + 1
  305. bufferqueue[ bufferqueuelen ] = data
  306. if handler then
  307. _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
  308. end
  309. return true
  310. end
  311. handler.write = write
  312. handler.bufferqueue = function( self )
  313. return bufferqueue
  314. end
  315. handler.socket = function( self )
  316. return socket
  317. end
  318. handler.set_mode = function( self, new )
  319. pattern = new or pattern
  320. return pattern
  321. end
  322. handler.set_send = function ( self, newsend )
  323. send = newsend or send
  324. return send
  325. end
  326. handler.bufferlen = function( self, readlen, sendlen )
  327. maxsendlen = sendlen or maxsendlen
  328. maxreadlen = readlen or maxreadlen
  329. return bufferlen, maxreadlen, maxsendlen
  330. end
  331. --TODO: Deprecate
  332. handler.lock_read = function (self, switch)
  333. if switch == true then
  334. local tmp = _readlistlen
  335. _readlistlen = removesocket( _readlist, socket, _readlistlen )
  336. _readtimes[ handler ] = nil
  337. if _readlistlen ~= tmp then
  338. noread = true
  339. end
  340. elseif switch == false then
  341. if noread then
  342. noread = false
  343. _readlistlen = addsocket(_readlist, socket, _readlistlen)
  344. _readtimes[ handler ] = _currenttime
  345. end
  346. end
  347. return noread
  348. end
  349. handler.pause = function (self)
  350. return self:lock_read(true);
  351. end
  352. handler.resume = function (self)
  353. return self:lock_read(false);
  354. end
  355. handler.lock = function( self, switch )
  356. handler.lock_read (switch)
  357. if switch == true then
  358. handler.write = idfalse
  359. local tmp = _sendlistlen
  360. _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
  361. _writetimes[ handler ] = nil
  362. if _sendlistlen ~= tmp then
  363. nosend = true
  364. end
  365. elseif switch == false then
  366. handler.write = write
  367. if nosend then
  368. nosend = false
  369. write( "" )
  370. end
  371. end
  372. return noread, nosend
  373. end
  374. local _readbuffer = function( ) -- this function reads data
  375. local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern"
  376. if not err or (err == "wantread" or err == "timeout") then -- received something
  377. local buffer = buffer or part or ""
  378. local len = string_len( buffer )
  379. if len > maxreadlen then
  380. disconnect( handler, "receive buffer exceeded" )
  381. handler:close( true )
  382. return false
  383. end
  384. local count = len * STAT_UNIT
  385. readtraffic = readtraffic + count
  386. _readtraffic = _readtraffic + count
  387. _readtimes[ handler ] = _currenttime
  388. --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
  389. return dispatch( handler, buffer, err )
  390. else -- connections was closed or fatal error
  391. out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
  392. fatalerror = true
  393. disconnect( handler, err )
  394. _ = handler and handler:close( )
  395. return false
  396. end
  397. end
  398. local _sendbuffer = function( ) -- this function sends data
  399. local succ, err, byte, buffer, count;
  400. local count;
  401. if socket then
  402. buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
  403. succ, err, byte = send( socket, buffer, 1, bufferlen )
  404. count = ( succ or byte or 0 ) * STAT_UNIT
  405. sendtraffic = sendtraffic + count
  406. _sendtraffic = _sendtraffic + count
  407. _ = _cleanqueue and clean( bufferqueue )
  408. --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
  409. else
  410. succ, err, count = false, "closed", 0;
  411. end
  412. if succ then -- sending succesful
  413. bufferqueuelen = 0
  414. bufferlen = 0
  415. _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
  416. _ = needtls and handler:starttls(nil, true)
  417. _writetimes[ handler ] = nil
  418. if drain then
  419. drain(handler)
  420. end
  421. _ = toclose and handler:close( )
  422. return true
  423. elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
  424. buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
  425. bufferqueue[ 1 ] = buffer -- insert new buffer in queue
  426. bufferqueuelen = 1
  427. bufferlen = bufferlen - byte
  428. _writetimes[ handler ] = _currenttime
  429. return true
  430. else -- connection was closed during sending or fatal error
  431. out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
  432. fatalerror = true
  433. disconnect( handler, err )
  434. _ = handler and handler:close( )
  435. return false
  436. end
  437. end
  438. -- Set the sslctx
  439. local handshake;
  440. function handler.set_sslctx(self, new_sslctx)
  441. ssl = true
  442. sslctx = new_sslctx;
  443. local wrote
  444. local read
  445. handshake = coroutine_wrap( function( client ) -- create handshake coroutine
  446. local err
  447. for i = 1, _maxsslhandshake do
  448. _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
  449. _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
  450. read, wrote = nil, nil
  451. _, err = client:dohandshake( )
  452. if not err then
  453. out_put( "server.lua: ssl handshake done" )
  454. handler.readbuffer = _readbuffer -- when handshake is done, replace the handshake function with regular functions
  455. handler.sendbuffer = _sendbuffer
  456. _ = status and status( handler, "ssl-handshake-complete" )
  457. _readlistlen = addsocket(_readlist, client, _readlistlen)
  458. return true
  459. else
  460. out_put( "server.lua: error during ssl handshake: ", tostring(err) )
  461. if err == "wantwrite" and not wrote then
  462. _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
  463. wrote = true
  464. elseif err == "wantread" and not read then
  465. _readlistlen = addsocket(_readlist, client, _readlistlen)
  466. read = true
  467. else
  468. break;
  469. end
  470. --coroutine_yield( handler, nil, err ) -- handshake not finished
  471. coroutine_yield( )
  472. end
  473. end
  474. disconnect( handler, "ssl handshake failed" )
  475. _ = handler and handler:close( true ) -- forced disconnect
  476. return false -- handshake failed
  477. end
  478. )
  479. end
  480. if luasec then
  481. if sslctx then -- ssl?
  482. handler:set_sslctx(sslctx);
  483. out_put("server.lua: ", "starting ssl handshake")
  484. local err
  485. socket, err = ssl_wrap( socket, sslctx ) -- wrap socket
  486. if err then
  487. out_put( "server.lua: ssl error: ", tostring(err) )
  488. --mem_free( )
  489. return nil, nil, err -- fatal error
  490. end
  491. socket:settimeout( 0 )
  492. handler.readbuffer = handshake
  493. handler.sendbuffer = handshake
  494. handshake( socket ) -- do handshake
  495. if not socket then
  496. return nil, nil, "ssl handshake failed";
  497. end
  498. else
  499. local sslctx;
  500. handler.starttls = function( self, _sslctx, now )
  501. if _sslctx then
  502. sslctx = _sslctx;
  503. handler:set_sslctx(sslctx);
  504. end
  505. if not now then
  506. out_put "server.lua: we need to do tls, but delaying until later"
  507. needtls = true
  508. return
  509. end
  510. out_put( "server.lua: attempting to start tls on " .. tostring( socket ) )
  511. local oldsocket, err = socket
  512. socket, err = ssl_wrap( socket, sslctx ) -- wrap socket
  513. --out_put( "server.lua: sslwrapped socket is " .. tostring( socket ) )
  514. if err then
  515. out_put( "server.lua: error while starting tls on client: ", tostring(err) )
  516. return nil, err -- fatal error
  517. end
  518. socket:settimeout( 0 )
  519. -- add the new socket to our system
  520. send = socket.send
  521. receive = socket.receive
  522. shutdown = id
  523. _socketlist[ socket ] = handler
  524. _readlistlen = addsocket(_readlist, socket, _readlistlen)
  525. -- remove traces of the old socket
  526. _readlistlen = removesocket( _readlist, oldsocket, _readlistlen )
  527. _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen )
  528. _socketlist[ oldsocket ] = nil
  529. handler.starttls = nil
  530. needtls = nil
  531. -- Secure now
  532. ssl = true
  533. handler.readbuffer = handshake
  534. handler.sendbuffer = handshake
  535. handshake( socket ) -- do handshake
  536. end
  537. handler.readbuffer = _readbuffer
  538. handler.sendbuffer = _sendbuffer
  539. end
  540. else
  541. handler.readbuffer = _readbuffer
  542. handler.sendbuffer = _sendbuffer
  543. end
  544. send = socket.send
  545. receive = socket.receive
  546. shutdown = ( ssl and id ) or socket.shutdown
  547. _socketlist[ socket ] = handler
  548. _readlistlen = addsocket(_readlist, socket, _readlistlen)
  549. if listeners.onconnect then
  550. _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
  551. handler.sendbuffer = function ()
  552. listeners.onconnect(handler);
  553. handler.sendbuffer = _sendbuffer;
  554. if bufferqueuelen > 0 then
  555. return _sendbuffer();
  556. end
  557. end
  558. end
  559. return handler, socket
  560. end
  561. id = function( )
  562. end
  563. idfalse = function( )
  564. return false
  565. end
  566. addsocket = function( list, socket, len )
  567. if not list[ socket ] then
  568. len = len + 1
  569. list[ len ] = socket
  570. list[ socket ] = len
  571. end
  572. return len;
  573. end
  574. removesocket = function( list, socket, len ) -- this function removes sockets from a list ( copied from copas )
  575. local pos = list[ socket ]
  576. if pos then
  577. list[ socket ] = nil
  578. local last = list[ len ]
  579. list[ len ] = nil
  580. if last ~= socket then
  581. list[ last ] = pos
  582. list[ pos ] = last
  583. end
  584. return len - 1
  585. end
  586. return len
  587. end
  588. closesocket = function( socket )
  589. _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
  590. _readlistlen = removesocket( _readlist, socket, _readlistlen )
  591. _socketlist[ socket ] = nil
  592. socket:close( )
  593. --mem_free( )
  594. end
  595. local function link(sender, receiver, buffersize)
  596. sender:set_mode(buffersize);
  597. local sender_locked;
  598. local _sendbuffer = receiver.sendbuffer;
  599. function receiver.sendbuffer()
  600. _sendbuffer();
  601. if sender_locked and receiver.bufferlen() < buffersize then
  602. sender:lock_read(false); -- Unlock now
  603. sender_locked = nil;
  604. end
  605. end
  606. local _readbuffer = sender.readbuffer;
  607. function sender.readbuffer()
  608. _readbuffer();
  609. if not sender_locked and receiver.bufferlen() >= buffersize then
  610. sender_locked = true;
  611. sender:lock_read(true);
  612. end
  613. end
  614. end
  615. ----------------------------------// PUBLIC //--
  616. addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
  617. local err
  618. if type( listeners ) ~= "table" then
  619. err = "invalid listener table"
  620. end
  621. if type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
  622. err = "invalid port"
  623. elseif _server[ port ] then
  624. err = "listeners on port '" .. port .. "' already exist"
  625. elseif sslctx and not luasec then
  626. err = "luasec not found"
  627. end
  628. if err then
  629. out_error( "server.lua, port ", port, ": ", err )
  630. return nil, err
  631. end
  632. addr = addr or "*"
  633. local server, err = socket_bind( addr, port )
  634. if err then
  635. out_error( "server.lua, port ", port, ": ", err )
  636. return nil, err
  637. end
  638. local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket
  639. if not handler then
  640. server:close( )
  641. return nil, err
  642. end
  643. server:settimeout( 0 )
  644. _readlistlen = addsocket(_readlist, server, _readlistlen)
  645. _server[ port ] = handler
  646. _socketlist[ server ] = handler
  647. out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '", addr, ":", port, "'" )
  648. return handler
  649. end
  650. getserver = function ( port )
  651. return _server[ port ];
  652. end
  653. removeserver = function( port )
  654. local handler = _server[ port ]
  655. if not handler then
  656. return nil, "no server found on port '" .. tostring( port ) .. "'"
  657. end
  658. handler:close( )
  659. _server[ port ] = nil
  660. return true
  661. end
  662. closeall = function( )
  663. for _, handler in pairs( _socketlist ) do
  664. handler:close( )
  665. _socketlist[ _ ] = nil
  666. end
  667. _readlistlen = 0
  668. _sendlistlen = 0
  669. _timerlistlen = 0
  670. _server = { }
  671. _readlist = { }
  672. _sendlist = { }
  673. _timerlist = { }
  674. _socketlist = { }
  675. --mem_free( )
  676. end
  677. getsettings = function( )
  678. return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxclientsperserver, _maxsslhandshake
  679. end
  680. changesettings = function( new )
  681. if type( new ) ~= "table" then
  682. return nil, "invalid settings table"
  683. end
  684. _selecttimeout = tonumber( new.timeout ) or _selecttimeout
  685. _sleeptime = tonumber( new.sleeptime ) or _sleeptime
  686. _maxsendlen = tonumber( new.maxsendlen ) or _maxsendlen
  687. _maxreadlen = tonumber( new.maxreadlen ) or _maxreadlen
  688. _checkinterval = tonumber( new.checkinterval ) or _checkinterval
  689. _sendtimeout = tonumber( new.sendtimeout ) or _sendtimeout
  690. _readtimeout = tonumber( new.readtimeout ) or _readtimeout
  691. _cleanqueue = new.cleanqueue
  692. _maxclientsperserver = new._maxclientsperserver or _maxclientsperserver
  693. _maxsslhandshake = new._maxsslhandshake or _maxsslhandshake
  694. return true
  695. end
  696. addtimer = function( listener )
  697. if type( listener ) ~= "function" then
  698. return nil, "invalid listener function"
  699. end
  700. _timerlistlen = _timerlistlen + 1
  701. _timerlist[ _timerlistlen ] = listener
  702. return true
  703. end
  704. stats = function( )
  705. return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
  706. end
  707. local dontstop = true; -- thinking about tomorrow, ...
  708. setquitting = function (quit)
  709. dontstop = not quit;
  710. return;
  711. end
  712. loop = function( ) -- this is the main loop of the program
  713. while dontstop do
  714. local read, write, err = socket_select( _readlist, _sendlist, _selecttimeout )
  715. for i, socket in ipairs( write ) do -- send data waiting in writequeues
  716. local handler = _socketlist[ socket ]
  717. if handler then
  718. handler.sendbuffer( )
  719. else
  720. closesocket( socket )
  721. out_put "server.lua: found no handler and closed socket (writelist)" -- this should not happen
  722. end
  723. end
  724. for i, socket in ipairs( read ) do -- receive data
  725. local handler = _socketlist[ socket ]
  726. if handler then
  727. handler.readbuffer( )
  728. else
  729. closesocket( socket )
  730. out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
  731. end
  732. end
  733. for handler, err in pairs( _closelist ) do
  734. handler.disconnect( )( handler, err )
  735. handler:close( true ) -- forced disconnect
  736. end
  737. clean( _closelist )
  738. _currenttime = os_time( )
  739. if os_difftime( _currenttime - _timer ) >= 1 then
  740. for i = 1, _timerlistlen do
  741. _timerlist[ i ]( _currenttime ) -- fire timers
  742. end
  743. _timer = _currenttime
  744. end
  745. socket_sleep( _sleeptime ) -- wait some time
  746. --collectgarbage( )
  747. end
  748. return "quitting"
  749. end
  750. local function get_backend()
  751. return "select";
  752. end
  753. --// EXPERIMENTAL //--
  754. local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
  755. local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
  756. _socketlist[ socket ] = handler
  757. _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
  758. return handler, socket
  759. end
  760. local addclient = function( address, port, listeners, pattern, sslctx )
  761. local client, err = luasocket.tcp( )
  762. if err then
  763. return nil, err
  764. end
  765. client:settimeout( 0 )
  766. _, err = client:connect( address, port )
  767. if err then -- try again
  768. local handler = wrapclient( client, address, port, listeners )
  769. else
  770. wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx )
  771. end
  772. end
  773. --// EXPERIMENTAL //--
  774. ----------------------------------// BEGIN //--
  775. use "setmetatable" ( _socketlist, { __mode = "k" } )
  776. use "setmetatable" ( _readtimes, { __mode = "k" } )
  777. use "setmetatable" ( _writetimes, { __mode = "k" } )
  778. _timer = os_time( )
  779. _starttime = os_time( )
  780. addtimer( function( )
  781. local difftime = os_difftime( _currenttime - _starttime )
  782. if difftime > _checkinterval then
  783. _starttime = _currenttime
  784. for handler, timestamp in pairs( _writetimes ) do
  785. if os_difftime( _currenttime - timestamp ) > _sendtimeout then
  786. --_writetimes[ handler ] = nil
  787. handler.disconnect( )( handler, "send timeout" )
  788. handler:close( true ) -- forced disconnect
  789. end
  790. end
  791. for handler, timestamp in pairs( _readtimes ) do
  792. if os_difftime( _currenttime - timestamp ) > _readtimeout then
  793. --_readtimes[ handler ] = nil
  794. handler.disconnect( )( handler, "read timeout" )
  795. handler:close( ) -- forced disconnect?
  796. end
  797. end
  798. end
  799. end
  800. )
  801. local function setlogger(new_logger)
  802. local old_logger = log;
  803. if new_logger then
  804. log = new_logger;
  805. end
  806. return old_logger;
  807. end
  808. ----------------------------------// PUBLIC INTERFACE //--
  809. return {
  810. addclient = addclient,
  811. wrapclient = wrapclient,
  812. loop = loop,
  813. link = link,
  814. stats = stats,
  815. closeall = closeall,
  816. addtimer = addtimer,
  817. addserver = addserver,
  818. getserver = getserver,
  819. setlogger = setlogger,
  820. getsettings = getsettings,
  821. setquitting = setquitting,
  822. removeserver = removeserver,
  823. get_backend = get_backend,
  824. changesettings = changesettings,
  825. }