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