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