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