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