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