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