Merge 0.9->0.10
[prosody.git] / net / server_select.lua
1 --
2 -- server.lua by blastbeat of the luadch project
3 -- Re-used here under the MIT/X Consortium License
4 --
5 -- Modifications (C) 2008-2010 Matthew Wild, Waqas Hussain
6 --
7
8 -- // wrapping luadch stuff // --
9
10 local use = function( what )
11         return _G[ what ]
12 end
13
14 local log, table_concat = require ("util.logger").init("socket"), table.concat;
15 local out_put = function (...) return log("debug", table_concat{...}); end
16 local out_error = function (...) return log("warn", table_concat{...}); end
17
18 ----------------------------------// DECLARATION //--
19
20 --// constants //--
21
22 local STAT_UNIT = 1 -- byte
23
24 --// lua functions //--
25
26 local type = use "type"
27 local pairs = use "pairs"
28 local ipairs = use "ipairs"
29 local tonumber = use "tonumber"
30 local tostring = use "tostring"
31
32 --// lua libs //--
33
34 local os = use "os"
35 local table = use "table"
36 local string = use "string"
37 local coroutine = use "coroutine"
38
39 --// lua lib methods //--
40
41 local os_difftime = os.difftime
42 local math_min = math.min
43 local math_huge = math.huge
44 local table_concat = table.concat
45 local string_sub = string.sub
46 local coroutine_wrap = coroutine.wrap
47 local coroutine_yield = coroutine.yield
48
49 --// extern libs //--
50
51 local luasec = use "ssl"
52 local luasocket = use "socket" or require "socket"
53 local luasocket_gettime = luasocket.gettime
54
55 --// extern lib methods //--
56
57 local ssl_wrap = ( luasec and luasec.wrap )
58 local socket_bind = luasocket.bind
59 local socket_sleep = luasocket.sleep
60 local socket_select = luasocket.select
61
62 --// functions //--
63
64 local id
65 local loop
66 local stats
67 local idfalse
68 local closeall
69 local addsocket
70 local addserver
71 local addtimer
72 local getserver
73 local wrapserver
74 local getsettings
75 local closesocket
76 local removesocket
77 local removeserver
78 local wrapconnection
79 local changesettings
80
81 --// tables //--
82
83 local _server
84 local _readlist
85 local _timerlist
86 local _sendlist
87 local _socketlist
88 local _closelist
89 local _readtimes
90 local _writetimes
91
92 --// simple data types //--
93
94 local _
95 local _readlistlen
96 local _sendlistlen
97 local _timerlistlen
98
99 local _sendtraffic
100 local _readtraffic
101
102 local _selecttimeout
103 local _sleeptime
104 local _tcpbacklog
105
106 local _starttime
107 local _currenttime
108
109 local _maxsendlen
110 local _maxreadlen
111
112 local _checkinterval
113 local _sendtimeout
114 local _readtimeout
115
116 local _timer
117
118 local _maxselectlen
119 local _maxfd
120
121 local _maxsslhandshake
122
123 ----------------------------------// DEFINITION //--
124
125 _server = { } -- key = port, value = table; list of listening servers
126 _readlist = { } -- array with sockets to read from
127 _sendlist = { } -- arrary with sockets to write to
128 _timerlist = { } -- array of timer functions
129 _socketlist = { } -- key = socket, value = wrapped socket (handlers)
130 _readtimes = { } -- key = handler, value = timestamp of last data reading
131 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
132 _closelist = { } -- handlers to close
133
134 _readlistlen = 0 -- length of readlist
135 _sendlistlen = 0 -- length of sendlist
136 _timerlistlen = 0 -- lenght of timerlist
137
138 _sendtraffic = 0 -- some stats
139 _readtraffic = 0
140
141 _selecttimeout = 1 -- timeout of socket.select
142 _sleeptime = 0 -- time to wait at the end of every loop
143 _tcpbacklog = 128 -- some kind of hint to the OS
144
145 _maxsendlen = 51000 * 1024 -- max len of send buffer
146 _maxreadlen = 25000 * 1024 -- max len of read buffer
147
148 _checkinterval = 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 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 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         local err
717         if type( listeners ) ~= "table" then
718                 err = "invalid listener table"
719         end
720         if type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
721                 err = "invalid port"
722         elseif _server[ addr..":"..port ] then
723                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
724         elseif sslctx and not luasec then
725                 err = "luasec not found"
726         end
727         if err then
728                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
729                 return nil, err
730         end
731         addr = addr or "*"
732         local server, err = socket_bind( addr, port, _tcpbacklog )
733         if err then
734                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
735                 return nil, err
736         end
737         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
738         if not handler then
739                 server:close( )
740                 return nil, err
741         end
742         server:settimeout( 0 )
743         _readlistlen = addsocket(_readlist, server, _readlistlen)
744         _server[ addr..":"..port ] = handler
745         _socketlist[ server ] = handler
746         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
747         return handler
748 end
749
750 getserver = function ( addr, port )
751         return _server[ addr..":"..port ];
752 end
753
754 removeserver = function( addr, port )
755         local handler = _server[ addr..":"..port ]
756         if not handler then
757                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
758         end
759         handler:close( )
760         _server[ addr..":"..port ] = nil
761         return true
762 end
763
764 closeall = function( )
765         for _, handler in pairs( _socketlist ) do
766                 handler:close( )
767                 _socketlist[ _ ] = nil
768         end
769         _readlistlen = 0
770         _sendlistlen = 0
771         _timerlistlen = 0
772         _server = { }
773         _readlist = { }
774         _sendlist = { }
775         _timerlist = { }
776         _socketlist = { }
777         --mem_free( )
778 end
779
780 getsettings = function( )
781         return {
782                 select_timeout = _selecttimeout;
783                 select_sleep_time = _sleeptime;
784                 tcp_backlog = _tcpbacklog;
785                 max_send_buffer_size = _maxsendlen;
786                 max_receive_buffer_size = _maxreadlen;
787                 select_idle_check_interval = _checkinterval;
788                 send_timeout = _sendtimeout;
789                 read_timeout = _readtimeout;
790                 max_connections = _maxselectlen;
791                 max_ssl_handshake_roundtrips = _maxsslhandshake;
792                 highest_allowed_fd = _maxfd;
793         }
794 end
795
796 changesettings = function( new )
797         if type( new ) ~= "table" then
798                 return nil, "invalid settings table"
799         end
800         _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout
801         _sleeptime = tonumber( new.select_sleep_time ) or _sleeptime
802         _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
803         _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
804         _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
805         _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
806         _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
807         _readtimeout = tonumber( new.read_timeout ) or _readtimeout
808         _maxselectlen = new.max_connections or _maxselectlen
809         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
810         _maxfd = new.highest_allowed_fd or _maxfd
811         return true
812 end
813
814 addtimer = function( listener )
815         if type( listener ) ~= "function" then
816                 return nil, "invalid listener function"
817         end
818         _timerlistlen = _timerlistlen + 1
819         _timerlist[ _timerlistlen ] = listener
820         return true
821 end
822
823 stats = function( )
824         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
825 end
826
827 local quitting;
828
829 local function setquitting(quit)
830         quitting = not not quit;
831 end
832
833 loop = function(once) -- this is the main loop of the program
834         if quitting then return "quitting"; end
835         if once then quitting = "once"; end
836         local next_timer_time = math_huge;
837         repeat
838                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
839                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
840                         local handler = _socketlist[ socket ]
841                         if handler then
842                                 handler.sendbuffer( )
843                         else
844                                 closesocket( socket )
845                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
846                         end
847                 end
848                 for i, socket in ipairs( read ) do -- receive data
849                         local handler = _socketlist[ socket ]
850                         if handler then
851                                 handler.readbuffer( )
852                         else
853                                 closesocket( socket )
854                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
855                         end
856                 end
857                 for handler, err in pairs( _closelist ) do
858                         handler.disconnect( )( handler, err )
859                         handler:force_close()    -- forced disconnect
860                         _closelist[ handler ] = nil;
861                 end
862                 _currenttime = luasocket_gettime( )
863
864                 -- Check for socket timeouts
865                 local difftime = os_difftime( _currenttime - _starttime )
866                 if difftime > _checkinterval then
867                         _starttime = _currenttime
868                         for handler, timestamp in pairs( _writetimes ) do
869                                 if os_difftime( _currenttime - timestamp ) > _sendtimeout then
870                                         handler.disconnect( )( handler, "send timeout" )
871                                         handler:force_close()    -- forced disconnect
872                                 end
873                         end
874                         for handler, timestamp in pairs( _readtimes ) do
875                                 if os_difftime( _currenttime - timestamp ) > _readtimeout then
876                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
877                                                 handler.disconnect( )( handler, "read timeout" )
878                                                 handler:close( )        -- forced disconnect?
879                                         end
880                                 end
881                         end
882                 end
883
884                 -- Fire timers
885                 if _currenttime - _timer >= math_min(next_timer_time, 1) then
886                         next_timer_time = math_huge;
887                         for i = 1, _timerlistlen do
888                                 local t = _timerlist[ i ]( _currenttime ) -- fire timers
889                                 if t then next_timer_time = math_min(next_timer_time, t); end
890                         end
891                         _timer = _currenttime
892                 else
893                         next_timer_time = next_timer_time - (_currenttime - _timer);
894                 end
895
896                 -- wait some time (0 by default)
897                 socket_sleep( _sleeptime )
898         until quitting;
899         if once and quitting == "once" then quitting = nil; return; end
900         return "quitting"
901 end
902
903 local function step()
904         return loop(true);
905 end
906
907 local function get_backend()
908         return "select";
909 end
910
911 --// EXPERIMENTAL //--
912
913 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
914         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
915         if not handler then return nil, err end
916         _socketlist[ socket ] = handler
917         if not sslctx then
918                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
919                 if listeners.onconnect then
920                         -- When socket is writeable, call onconnect
921                         local _sendbuffer = handler.sendbuffer;
922                         handler.sendbuffer = function ()
923                                 handler.sendbuffer = _sendbuffer;
924                                 listeners.onconnect(handler);
925                                 return _sendbuffer(); -- Send any queued outgoing data
926                         end
927                 end
928         end
929         return handler, socket
930 end
931
932 local addclient = function( address, port, listeners, pattern, sslctx )
933         local client, err = luasocket.tcp( )
934         if err then
935                 return nil, err
936         end
937         client:settimeout( 0 )
938         _, err = client:connect( address, port )
939         if err then -- try again
940                 return wrapclient( client, address, port, listeners, pattern, sslctx )
941         else
942                 return wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx )
943         end
944 end
945
946 --// EXPERIMENTAL //--
947
948 ----------------------------------// BEGIN //--
949
950 use "setmetatable" ( _socketlist, { __mode = "k" } )
951 use "setmetatable" ( _readtimes, { __mode = "k" } )
952 use "setmetatable" ( _writetimes, { __mode = "k" } )
953
954 _timer = luasocket_gettime( )
955 _starttime = luasocket_gettime( )
956
957 local function setlogger(new_logger)
958         local old_logger = log;
959         if new_logger then
960                 log = new_logger;
961         end
962         return old_logger;
963 end
964
965 ----------------------------------// PUBLIC INTERFACE //--
966
967 return {
968         _addtimer = addtimer,
969
970         addclient = addclient,
971         wrapclient = wrapclient,
972
973         loop = loop,
974         link = link,
975         step = step,
976         stats = stats,
977         closeall = closeall,
978         addserver = addserver,
979         getserver = getserver,
980         setlogger = setlogger,
981         getsettings = getsettings,
982         setquitting = setquitting,
983         removeserver = removeserver,
984         get_backend = get_backend,
985         changesettings = changesettings,
986 }