net/server_select: addclient: Check arguments
[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 has_luasec, luasec = pcall ( require , "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 = ( has_luasec and luasec.wrap )
58 local socket_bind = luasocket.bind
59 local socket_sleep = luasocket.sleep
60 local socket_select = luasocket.select
61
62 --// functions //--
63
64 local id
65 local loop
66 local stats
67 local idfalse
68 local closeall
69 local addsocket
70 local addserver
71 local addtimer
72 local getserver
73 local wrapserver
74 local getsettings
75 local closesocket
76 local removesocket
77 local removeserver
78 local wrapconnection
79 local changesettings
80
81 --// tables //--
82
83 local _server
84 local _readlist
85 local _timerlist
86 local _sendlist
87 local _socketlist
88 local _closelist
89 local _readtimes
90 local _writetimes
91
92 --// simple data types //--
93
94 local _
95 local _readlistlen
96 local _sendlistlen
97 local _timerlistlen
98
99 local _sendtraffic
100 local _readtraffic
101
102 local _selecttimeout
103 local _sleeptime
104 local _tcpbacklog
105
106 local _starttime
107 local _currenttime
108
109 local _maxsendlen
110 local _maxreadlen
111
112 local _checkinterval
113 local _sendtimeout
114 local _readtimeout
115
116 local _timer
117
118 local _maxselectlen
119 local _maxfd
120
121 local _maxsslhandshake
122
123 ----------------------------------// DEFINITION //--
124
125 _server = { } -- key = port, value = table; list of listening servers
126 _readlist = { } -- array with sockets to read from
127 _sendlist = { } -- arrary with sockets to write to
128 _timerlist = { } -- array of timer functions
129 _socketlist = { } -- key = socket, value = wrapped socket (handlers)
130 _readtimes = { } -- key = handler, value = timestamp of last data reading
131 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
132 _closelist = { } -- handlers to close
133
134 _readlistlen = 0 -- length of readlist
135 _sendlistlen = 0 -- length of sendlist
136 _timerlistlen = 0 -- lenght of timerlist
137
138 _sendtraffic = 0 -- some stats
139 _readtraffic = 0
140
141 _selecttimeout = 1 -- timeout of socket.select
142 _sleeptime = 0 -- time to wait at the end of every loop
143 _tcpbacklog = 128 -- some kind of hint to the OS
144
145 _maxsendlen = 51000 * 1024 -- max len of send buffer
146 _maxreadlen = 25000 * 1024 -- max len of read buffer
147
148 _checkinterval = 30 -- interval in secs to check idle clients
149 _sendtimeout = 60000 -- allowed send idle time in secs
150 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
151
152 local is_windows = package.config:sub(1,1) == "\\" -- check the directory separator, to detemine whether this is Windows
153 _maxfd = (is_windows and math.huge) or luasocket._SETSIZE or 1024 -- max fd number, limit to 1024 by default to prevent glibc buffer overflow, but not on Windows
154 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows
155
156 _maxsslhandshake = 30 -- max handshake round-trips
157
158 ----------------------------------// PRIVATE //--
159
160 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd
161
162         if socket:getfd() >= _maxfd then
163                 out_error("server.lua: Disallowed FD number: "..socket:getfd())
164                 socket:close()
165                 return nil, "fd-too-large"
166         end
167
168         local connections = 0
169
170         local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect
171
172         local accept = socket.accept
173
174         --// public methods of the object //--
175
176         local handler = { }
177
178         handler.shutdown = function( ) end
179
180         handler.ssl = function( )
181                 return sslctx ~= nil
182         end
183         handler.sslctx = function( )
184                 return sslctx
185         end
186         handler.remove = function( )
187                 connections = connections - 1
188                 if handler then
189                         handler.resume( )
190                 end
191         end
192         handler.close = function()
193                 socket:close( )
194                 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
195                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
196                 _server[ip..":"..serverport] = nil;
197                 _socketlist[ socket ] = nil
198                 handler = nil
199                 socket = nil
200                 --mem_free( )
201                 out_put "server.lua: closed server handler and removed sockets from list"
202         end
203         handler.pause = function( hard )
204                 if not handler.paused then
205                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
206                         if hard then
207                                 _socketlist[ socket ] = nil
208                                 socket:close( )
209                                 socket = nil;
210                         end
211                         handler.paused = true;
212                 end
213         end
214         handler.resume = function( )
215                 if handler.paused then
216                         if not socket then
217                                 socket = socket_bind( ip, serverport, _tcpbacklog );
218                                 socket:settimeout( 0 )
219                         end
220                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
221                         _socketlist[ socket ] = handler
222                         handler.paused = false;
223                 end
224         end
225         handler.ip = function( )
226                 return ip
227         end
228         handler.serverport = function( )
229                 return serverport
230         end
231         handler.socket = function( )
232                 return socket
233         end
234         handler.readbuffer = function( )
235                 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
236                         handler.pause( )
237                         out_put( "server.lua: refused new client connection: server full" )
238                         return false
239                 end
240                 local client, err = accept( socket )    -- try to accept
241                 if client then
242                         local ip, clientport = client:getpeername( )
243                         local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
244                         if err then -- error while wrapping ssl socket
245                                 return false
246                         end
247                         connections = connections + 1
248                         out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
249                         if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes
250                                 return dispatch( handler );
251                         end
252                         return;
253                 elseif err then -- maybe timeout or something else
254                         out_put( "server.lua: error with new client connection: ", tostring(err) )
255                         return false
256                 end
257         end
258         return handler
259 end
260
261 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object
262
263         if socket:getfd() >= _maxfd then
264                 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
265                 socket:close( ) -- Should we send some kind of error here?
266                 if server then
267                         server.pause( )
268                 end
269                 return nil, nil, "fd-too-large"
270         end
271         socket:settimeout( 0 )
272
273         --// local import of socket methods //--
274
275         local send
276         local receive
277         local shutdown
278
279         --// private closures of the object //--
280
281         local ssl
282
283         local dispatch = listeners.onincoming
284         local status = listeners.onstatus
285         local disconnect = listeners.ondisconnect
286         local drain = listeners.ondrain
287         local onreadtimeout = listeners.onreadtimeout;
288         local detach = listeners.ondetach
289
290         local bufferqueue = { } -- buffer array
291         local bufferqueuelen = 0        -- end of buffer array
292
293         local toclose
294         local fatalerror
295         local needtls
296
297         local bufferlen = 0
298
299         local noread = false
300         local nosend = false
301
302         local sendtraffic, readtraffic = 0, 0
303
304         local maxsendlen = _maxsendlen
305         local maxreadlen = _maxreadlen
306
307         --// public methods of the object //--
308
309         local handler = bufferqueue -- saves a table ^_^
310
311         handler.dispatch = function( )
312                 return dispatch
313         end
314         handler.disconnect = function( )
315                 return disconnect
316         end
317         handler.onreadtimeout = onreadtimeout;
318
319         handler.setlistener = function( self, listeners )
320                 if detach then
321                         detach(self) -- Notify listener that it is no longer responsible for this connection
322                 end
323                 dispatch = listeners.onincoming
324                 disconnect = listeners.ondisconnect
325                 status = listeners.onstatus
326                 drain = listeners.ondrain
327                 handler.onreadtimeout = listeners.onreadtimeout
328                 detach = listeners.ondetach
329         end
330         handler.getstats = function( )
331                 return readtraffic, sendtraffic
332         end
333         handler.ssl = function( )
334                 return ssl
335         end
336         handler.sslctx = function ( )
337                 return sslctx
338         end
339         handler.send = function( _, data, i, j )
340                 return send( socket, data, i, j )
341         end
342         handler.receive = function( pattern, prefix )
343                 return receive( socket, pattern, prefix )
344         end
345         handler.shutdown = function( pattern )
346                 return shutdown( socket, pattern )
347         end
348         handler.setoption = function (self, option, value)
349                 if socket.setoption then
350                         return socket:setoption(option, value);
351                 end
352                 return false, "setoption not implemented";
353         end
354         handler.force_close = function ( self, err )
355                 if bufferqueuelen ~= 0 then
356                         out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
357                         bufferqueuelen = 0;
358                 end
359                 return self:close(err);
360         end
361         handler.close = function( self, err )
362                 if not handler then return true; end
363                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
364                 _readtimes[ handler ] = nil
365                 if bufferqueuelen ~= 0 then
366                         handler.sendbuffer() -- Try now to send any outstanding data
367                         if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later
368                                 if handler then
369                                         handler.write = nil -- ... but no further writing allowed
370                                 end
371                                 toclose = true
372                                 return false
373                         end
374                 end
375                 if socket then
376                         _ = shutdown and shutdown( socket )
377                         socket:close( )
378                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
379                         _socketlist[ socket ] = nil
380                         socket = nil
381                 else
382                         out_put "server.lua: socket already closed"
383                 end
384                 if handler then
385                         _writetimes[ handler ] = nil
386                         _closelist[ handler ] = nil
387                         local _handler = handler;
388                         handler = nil
389                         if disconnect then
390                                 disconnect(_handler, err or false);
391                                 disconnect = nil
392                         end
393                 end
394                 if server then
395                         server.remove( )
396                 end
397                 out_put "server.lua: closed client handler and removed socket from list"
398                 return true
399         end
400         handler.ip = function( )
401                 return ip
402         end
403         handler.serverport = function( )
404                 return serverport
405         end
406         handler.clientport = function( )
407                 return clientport
408         end
409         handler.port = handler.clientport -- COMPAT server_event
410         local write = function( self, data )
411                 bufferlen = bufferlen + #data
412                 if bufferlen > maxsendlen then
413                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
414                         handler.write = idfalse -- dont write anymore
415                         return false
416                 elseif socket and not _sendlist[ socket ] then
417                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
418                 end
419                 bufferqueuelen = bufferqueuelen + 1
420                 bufferqueue[ bufferqueuelen ] = data
421                 if handler then
422                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
423                 end
424                 return true
425         end
426         handler.write = write
427         handler.bufferqueue = function( self )
428                 return bufferqueue
429         end
430         handler.socket = function( self )
431                 return socket
432         end
433         handler.set_mode = function( self, new )
434                 pattern = new or pattern
435                 return pattern
436         end
437         handler.set_send = function ( self, newsend )
438                 send = newsend or send
439                 return send
440         end
441         handler.bufferlen = function( self, readlen, sendlen )
442                 maxsendlen = sendlen or maxsendlen
443                 maxreadlen = readlen or maxreadlen
444                 return bufferlen, maxreadlen, maxsendlen
445         end
446         --TODO: Deprecate
447         handler.lock_read = function (self, switch)
448                 if switch == true then
449                         local tmp = _readlistlen
450                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
451                         _readtimes[ handler ] = nil
452                         if _readlistlen ~= tmp then
453                                 noread = true
454                         end
455                 elseif switch == false then
456                         if noread then
457                                 noread = false
458                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
459                                 _readtimes[ handler ] = _currenttime
460                         end
461                 end
462                 return noread
463         end
464         handler.pause = function (self)
465                 return self:lock_read(true);
466         end
467         handler.resume = function (self)
468                 return self:lock_read(false);
469         end
470         handler.lock = function( self, switch )
471                 handler.lock_read (switch)
472                 if switch == true then
473                         handler.write = idfalse
474                         local tmp = _sendlistlen
475                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
476                         _writetimes[ handler ] = nil
477                         if _sendlistlen ~= tmp then
478                                 nosend = true
479                         end
480                 elseif switch == false then
481                         handler.write = write
482                         if nosend then
483                                 nosend = false
484                                 write( "" )
485                         end
486                 end
487                 return noread, nosend
488         end
489         local _readbuffer = function( ) -- this function reads data
490                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
491                 if not err or (err == "wantread" or err == "timeout") then -- received something
492                         local buffer = buffer or part or ""
493                         local len = #buffer
494                         if len > maxreadlen then
495                                 handler:close( "receive buffer exceeded" )
496                                 return false
497                         end
498                         local count = len * STAT_UNIT
499                         readtraffic = readtraffic + count
500                         _readtraffic = _readtraffic + count
501                         _readtimes[ handler ] = _currenttime
502                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
503                         return dispatch( handler, buffer, err )
504                 else    -- connections was closed or fatal error
505                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
506                         fatalerror = true
507                         _ = handler and handler:force_close( err )
508                         return false
509                 end
510         end
511         local _sendbuffer = function( ) -- this function sends data
512                 local succ, err, byte, buffer, count;
513                 if socket then
514                         buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
515                         succ, err, byte = send( socket, buffer, 1, bufferlen )
516                         count = ( succ or byte or 0 ) * STAT_UNIT
517                         sendtraffic = sendtraffic + count
518                         _sendtraffic = _sendtraffic + count
519                         for i = bufferqueuelen,1,-1 do
520                                 bufferqueue[ i ] = nil
521                         end
522                         --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
523                 else
524                         succ, err, count = false, "unexpected close", 0;
525                 end
526                 if succ then    -- sending succesful
527                         bufferqueuelen = 0
528                         bufferlen = 0
529                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
530                         _writetimes[ handler ] = nil
531                         if drain then
532                                 drain(handler)
533                         end
534                         _ = needtls and handler:starttls(nil)
535                         _ = toclose and handler:force_close( )
536                         return true
537                 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
538                         buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
539                         bufferqueue[ 1 ] = buffer        -- insert new buffer in queue
540                         bufferqueuelen = 1
541                         bufferlen = bufferlen - byte
542                         _writetimes[ handler ] = _currenttime
543                         return true
544                 else    -- connection was closed during sending or fatal error
545                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
546                         fatalerror = true
547                         _ = handler and handler:force_close( err )
548                         return false
549                 end
550         end
551
552         -- Set the sslctx
553         local handshake;
554         function handler.set_sslctx(self, new_sslctx)
555                 sslctx = new_sslctx;
556                 local read, wrote
557                 handshake = coroutine_wrap( function( client ) -- create handshake coroutine
558                                 local err
559                                 for i = 1, _maxsslhandshake do
560                                         _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
561                                         _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
562                                         read, wrote = nil, nil
563                                         _, err = client:dohandshake( )
564                                         if not err then
565                                                 out_put( "server.lua: ssl handshake done" )
566                                                 handler.readbuffer = _readbuffer        -- when handshake is done, replace the handshake function with regular functions
567                                                 handler.sendbuffer = _sendbuffer
568                                                 _ = status and status( handler, "ssl-handshake-complete" )
569                                                 if self.autostart_ssl and listeners.onconnect then
570                                                         listeners.onconnect(self);
571                                                         if bufferqueuelen ~= 0 then
572                                                                 _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
573                                                         end
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 has_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 has_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         addr = addr or "*"
727         local err
728         if type( listeners ) ~= "table" then
729                 err = "invalid listener table"
730         elseif type ( addr ) ~= "string" then
731                 err = "invalid address"
732         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
733                 err = "invalid port"
734         elseif _server[ addr..":"..port ] then
735                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
736         elseif sslctx and not has_luasec then
737                 err = "luasec not found"
738         end
739         if err then
740                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
741                 return nil, err
742         end
743         local server, err = socket_bind( addr, port, _tcpbacklog )
744         if err then
745                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
746                 return nil, err
747         end
748         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
749         if not handler then
750                 server:close( )
751                 return nil, err
752         end
753         server:settimeout( 0 )
754         _readlistlen = addsocket(_readlist, server, _readlistlen)
755         _server[ addr..":"..port ] = handler
756         _socketlist[ server ] = handler
757         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
758         return handler
759 end
760
761 getserver = function ( addr, port )
762         return _server[ addr..":"..port ];
763 end
764
765 removeserver = function( addr, port )
766         local handler = _server[ addr..":"..port ]
767         if not handler then
768                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
769         end
770         handler:close( )
771         _server[ addr..":"..port ] = nil
772         return true
773 end
774
775 closeall = function( )
776         for _, handler in pairs( _socketlist ) do
777                 handler:close( )
778                 _socketlist[ _ ] = nil
779         end
780         _readlistlen = 0
781         _sendlistlen = 0
782         _timerlistlen = 0
783         _server = { }
784         _readlist = { }
785         _sendlist = { }
786         _timerlist = { }
787         _socketlist = { }
788         --mem_free( )
789 end
790
791 getsettings = function( )
792         return {
793                 select_timeout = _selecttimeout;
794                 select_sleep_time = _sleeptime;
795                 tcp_backlog = _tcpbacklog;
796                 max_send_buffer_size = _maxsendlen;
797                 max_receive_buffer_size = _maxreadlen;
798                 select_idle_check_interval = _checkinterval;
799                 send_timeout = _sendtimeout;
800                 read_timeout = _readtimeout;
801                 max_connections = _maxselectlen;
802                 max_ssl_handshake_roundtrips = _maxsslhandshake;
803                 highest_allowed_fd = _maxfd;
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         _maxselectlen = new.max_connections or _maxselectlen
820         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
821         _maxfd = new.highest_allowed_fd or _maxfd
822         return true
823 end
824
825 addtimer = function( listener )
826         if type( listener ) ~= "function" then
827                 return nil, "invalid listener function"
828         end
829         _timerlistlen = _timerlistlen + 1
830         _timerlist[ _timerlistlen ] = listener
831         return true
832 end
833
834 stats = function( )
835         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
836 end
837
838 local quitting;
839
840 local function setquitting(quit)
841         quitting = not not quit;
842 end
843
844 loop = function(once) -- this is the main loop of the program
845         if quitting then return "quitting"; end
846         if once then quitting = "once"; end
847         local next_timer_time = math_huge;
848         repeat
849                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
850                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
851                         local handler = _socketlist[ socket ]
852                         if handler then
853                                 handler.sendbuffer( )
854                         else
855                                 closesocket( socket )
856                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
857                         end
858                 end
859                 for i, socket in ipairs( read ) do -- receive data
860                         local handler = _socketlist[ socket ]
861                         if handler then
862                                 handler.readbuffer( )
863                         else
864                                 closesocket( socket )
865                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
866                         end
867                 end
868                 for handler, err in pairs( _closelist ) do
869                         handler.disconnect( )( handler, err )
870                         handler:force_close()    -- forced disconnect
871                         _closelist[ handler ] = nil;
872                 end
873                 _currenttime = luasocket_gettime( )
874
875                 -- Check for socket timeouts
876                 local difftime = os_difftime( _currenttime - _starttime )
877                 if difftime > _checkinterval then
878                         _starttime = _currenttime
879                         for handler, timestamp in pairs( _writetimes ) do
880                                 if os_difftime( _currenttime - timestamp ) > _sendtimeout then
881                                         handler.disconnect( )( handler, "send timeout" )
882                                         handler:force_close()    -- forced disconnect
883                                 end
884                         end
885                         for handler, timestamp in pairs( _readtimes ) do
886                                 if os_difftime( _currenttime - timestamp ) > _readtimeout then
887                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
888                                                 handler.disconnect( )( handler, "read timeout" )
889                                                 handler:close( )        -- forced disconnect?
890                                         else
891                                                 _readtimes[ handler ] = _currenttime -- reset timer
892                                         end
893                                 end
894                         end
895                 end
896
897                 -- Fire timers
898                 if _currenttime - _timer >= math_min(next_timer_time, 1) then
899                         next_timer_time = math_huge;
900                         for i = 1, _timerlistlen do
901                                 local t = _timerlist[ i ]( _currenttime ) -- fire timers
902                                 if t then next_timer_time = math_min(next_timer_time, t); end
903                         end
904                         _timer = _currenttime
905                 else
906                         next_timer_time = next_timer_time - (_currenttime - _timer);
907                 end
908
909                 -- wait some time (0 by default)
910                 socket_sleep( _sleeptime )
911         until quitting;
912         if once and quitting == "once" then quitting = nil; return; end
913         return "quitting"
914 end
915
916 local function step()
917         return loop(true);
918 end
919
920 local function get_backend()
921         return "select";
922 end
923
924 --// EXPERIMENTAL //--
925
926 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
927         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
928         if not handler then return nil, err end
929         _socketlist[ socket ] = handler
930         if not sslctx then
931                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
932                 if listeners.onconnect then
933                         -- When socket is writeable, call onconnect
934                         local _sendbuffer = handler.sendbuffer;
935                         handler.sendbuffer = function ()
936                                 handler.sendbuffer = _sendbuffer;
937                                 listeners.onconnect(handler);
938                                 return _sendbuffer(); -- Send any queued outgoing data
939                         end
940                 end
941         end
942         return handler, socket
943 end
944
945 local addclient = function( address, port, listeners, pattern, sslctx )
946         local err
947         if type( listeners ) ~= "table" then
948                 err = "invalid listener table"
949         elseif type ( addr ) ~= "string" then
950                 err = "invalid address"
951         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
952                 err = "invalid port"
953         elseif sslctx and not has_luasec then
954                 err = "luasec not found"
955         end
956         if err then
957                 out_error( "server.lua, addclient: ", err )
958                 return nil, err
959         end
960
961         local client, err = luasocket.tcp( )
962         if err then
963                 return nil, err
964         end
965         client:settimeout( 0 )
966         local ok, err = client:connect( address, port )
967         if ok or err == "timeout" then
968                 return wrapclient( client, address, port, listeners, pattern, sslctx )
969         else
970                 return nil, err
971         end
972 end
973
974 --// EXPERIMENTAL //--
975
976 ----------------------------------// BEGIN //--
977
978 use "setmetatable" ( _socketlist, { __mode = "k" } )
979 use "setmetatable" ( _readtimes, { __mode = "k" } )
980 use "setmetatable" ( _writetimes, { __mode = "k" } )
981
982 _timer = luasocket_gettime( )
983 _starttime = luasocket_gettime( )
984
985 local function setlogger(new_logger)
986         local old_logger = log;
987         if new_logger then
988                 log = new_logger;
989         end
990         return old_logger;
991 end
992
993 ----------------------------------// PUBLIC INTERFACE //--
994
995 return {
996         _addtimer = addtimer,
997
998         addclient = addclient,
999         wrapclient = wrapclient,
1000
1001         loop = loop,
1002         link = link,
1003         step = step,
1004         stats = stats,
1005         closeall = closeall,
1006         addserver = addserver,
1007         getserver = getserver,
1008         setlogger = setlogger,
1009         getsettings = getsettings,
1010         setquitting = setquitting,
1011         removeserver = removeserver,
1012         get_backend = get_backend,
1013         changesettings = changesettings,
1014 }