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         handler.port = handler.clientport -- COMPAT server_event
405         local write = function( self, data )
406                 bufferlen = bufferlen + #data
407                 if bufferlen > maxsendlen then
408                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
409                         handler.write = idfalse -- dont write anymore
410                         return false
411                 elseif socket and not _sendlist[ socket ] then
412                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
413                 end
414                 bufferqueuelen = bufferqueuelen + 1
415                 bufferqueue[ bufferqueuelen ] = data
416                 if handler then
417                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
418                 end
419                 return true
420         end
421         handler.write = write
422         handler.bufferqueue = function( self )
423                 return bufferqueue
424         end
425         handler.socket = function( self )
426                 return socket
427         end
428         handler.set_mode = function( self, new )
429                 pattern = new or pattern
430                 return pattern
431         end
432         handler.set_send = function ( self, newsend )
433                 send = newsend or send
434                 return send
435         end
436         handler.bufferlen = function( self, readlen, sendlen )
437                 maxsendlen = sendlen or maxsendlen
438                 maxreadlen = readlen or maxreadlen
439                 return bufferlen, maxreadlen, maxsendlen
440         end
441         --TODO: Deprecate
442         handler.lock_read = function (self, switch)
443                 if switch == true then
444                         local tmp = _readlistlen
445                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
446                         _readtimes[ handler ] = nil
447                         if _readlistlen ~= tmp then
448                                 noread = true
449                         end
450                 elseif switch == false then
451                         if noread then
452                                 noread = false
453                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
454                                 _readtimes[ handler ] = _currenttime
455                         end
456                 end
457                 return noread
458         end
459         handler.pause = function (self)
460                 return self:lock_read(true);
461         end
462         handler.resume = function (self)
463                 return self:lock_read(false);
464         end
465         handler.lock = function( self, switch )
466                 handler.lock_read (switch)
467                 if switch == true then
468                         handler.write = idfalse
469                         local tmp = _sendlistlen
470                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
471                         _writetimes[ handler ] = nil
472                         if _sendlistlen ~= tmp then
473                                 nosend = true
474                         end
475                 elseif switch == false then
476                         handler.write = write
477                         if nosend then
478                                 nosend = false
479                                 write( "" )
480                         end
481                 end
482                 return noread, nosend
483         end
484         local _readbuffer = function( ) -- this function reads data
485                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
486                 if not err or (err == "wantread" or err == "timeout") then -- received something
487                         local buffer = buffer or part or ""
488                         local len = #buffer
489                         if len > maxreadlen then
490                                 handler:close( "receive buffer exceeded" )
491                                 return false
492                         end
493                         local count = len * STAT_UNIT
494                         readtraffic = readtraffic + count
495                         _readtraffic = _readtraffic + count
496                         _readtimes[ handler ] = _currenttime
497                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
498                         return dispatch( handler, buffer, err )
499                 else    -- connections was closed or fatal error
500                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
501                         fatalerror = true
502                         _ = handler and handler:force_close( err )
503                         return false
504                 end
505         end
506         local _sendbuffer = function( ) -- this function sends data
507                 local succ, err, byte, buffer, count;
508                 if socket then
509                         buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
510                         succ, err, byte = send( socket, buffer, 1, bufferlen )
511                         count = ( succ or byte or 0 ) * STAT_UNIT
512                         sendtraffic = sendtraffic + count
513                         _sendtraffic = _sendtraffic + count
514                         for i = bufferqueuelen,1,-1 do
515                                 bufferqueue[ i ] = nil
516                         end
517                         --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
518                 else
519                         succ, err, count = false, "unexpected close", 0;
520                 end
521                 if succ then    -- sending succesful
522                         bufferqueuelen = 0
523                         bufferlen = 0
524                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
525                         _writetimes[ handler ] = nil
526                         if drain then
527                                 drain(handler)
528                         end
529                         _ = needtls and handler:starttls(nil)
530                         _ = toclose and handler:force_close( )
531                         return true
532                 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
533                         buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
534                         bufferqueue[ 1 ] = buffer        -- insert new buffer in queue
535                         bufferqueuelen = 1
536                         bufferlen = bufferlen - byte
537                         _writetimes[ handler ] = _currenttime
538                         return true
539                 else    -- connection was closed during sending or fatal error
540                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
541                         fatalerror = true
542                         _ = handler and handler:force_close( err )
543                         return false
544                 end
545         end
546
547         -- Set the sslctx
548         local handshake;
549         function handler.set_sslctx(self, new_sslctx)
550                 sslctx = new_sslctx;
551                 local read, wrote
552                 handshake = coroutine_wrap( function( client ) -- create handshake coroutine
553                                 local err
554                                 for i = 1, _maxsslhandshake do
555                                         _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
556                                         _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
557                                         read, wrote = nil, nil
558                                         _, err = client:dohandshake( )
559                                         if not err then
560                                                 out_put( "server.lua: ssl handshake done" )
561                                                 handler.readbuffer = _readbuffer        -- when handshake is done, replace the handshake function with regular functions
562                                                 handler.sendbuffer = _sendbuffer
563                                                 _ = status and status( handler, "ssl-handshake-complete" )
564                                                 if self.autostart_ssl and listeners.onconnect then
565                                                         listeners.onconnect(self);
566                                                 end
567                                                 _readlistlen = addsocket(_readlist, client, _readlistlen)
568                                                 return true
569                                         else
570                                                 if err == "wantwrite" then
571                                                         _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
572                                                         wrote = true
573                                                 elseif err == "wantread" then
574                                                         _readlistlen = addsocket(_readlist, client, _readlistlen)
575                                                         read = true
576                                                 else
577                                                         break;
578                                                 end
579                                                 err = nil;
580                                                 coroutine_yield( ) -- handshake not finished
581                                         end
582                                 end
583                                 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
584                                 _ = handler and handler:force_close("ssl handshake failed")
585                                 return false, err -- handshake failed
586                         end
587                 )
588         end
589         if luasec then
590                 handler.starttls = function( self, _sslctx)
591                         if _sslctx then
592                                 handler:set_sslctx(_sslctx);
593                         end
594                         if bufferqueuelen > 0 then
595                                 out_put "server.lua: we need to do tls, but delaying until send buffer empty"
596                                 needtls = true
597                                 return
598                         end
599                         out_put( "server.lua: attempting to start tls on " .. tostring( socket ) )
600                         local oldsocket, err = socket
601                         socket, err = ssl_wrap( socket, sslctx )        -- wrap socket
602                         if not socket then
603                                 out_put( "server.lua: error while starting tls on client: ", tostring(err or "unknown error") )
604                                 return nil, err -- fatal error
605                         end
606
607                         socket:settimeout( 0 )
608
609                         -- add the new socket to our system
610                         send = socket.send
611                         receive = socket.receive
612                         shutdown = id
613                         _socketlist[ socket ] = handler
614                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
615
616                         -- remove traces of the old socket
617                         _readlistlen = removesocket( _readlist, oldsocket, _readlistlen )
618                         _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen )
619                         _socketlist[ oldsocket ] = nil
620
621                         handler.starttls = nil
622                         needtls = nil
623
624                         -- Secure now (if handshake fails connection will close)
625                         ssl = true
626
627                         handler.readbuffer = handshake
628                         handler.sendbuffer = handshake
629                         return handshake( socket ) -- do handshake
630                 end
631         end
632
633         handler.readbuffer = _readbuffer
634         handler.sendbuffer = _sendbuffer
635         send = socket.send
636         receive = socket.receive
637         shutdown = ( ssl and id ) or socket.shutdown
638
639         _socketlist[ socket ] = handler
640         _readlistlen = addsocket(_readlist, socket, _readlistlen)
641
642         if sslctx and luasec then
643                 out_put "server.lua: auto-starting ssl negotiation..."
644                 handler.autostart_ssl = true;
645                 local ok, err = handler:starttls(sslctx);
646                 if ok == false then
647                         return nil, nil, err
648                 end
649         end
650
651         return handler, socket
652 end
653
654 id = function( )
655 end
656
657 idfalse = function( )
658         return false
659 end
660
661 addsocket = function( list, socket, len )
662         if not list[ socket ] then
663                 len = len + 1
664                 list[ len ] = socket
665                 list[ socket ] = len
666         end
667         return len;
668 end
669
670 removesocket = function( list, socket, len )    -- this function removes sockets from a list ( copied from copas )
671         local pos = list[ socket ]
672         if pos then
673                 list[ socket ] = nil
674                 local last = list[ len ]
675                 list[ len ] = nil
676                 if last ~= socket then
677                         list[ last ] = pos
678                         list[ pos ] = last
679                 end
680                 return len - 1
681         end
682         return len
683 end
684
685 closesocket = function( socket )
686         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
687         _readlistlen = removesocket( _readlist, socket, _readlistlen )
688         _socketlist[ socket ] = nil
689         socket:close( )
690         --mem_free( )
691 end
692
693 local function link(sender, receiver, buffersize)
694         local sender_locked;
695         local _sendbuffer = receiver.sendbuffer;
696         function receiver.sendbuffer()
697                 _sendbuffer();
698                 if sender_locked and receiver.bufferlen() < buffersize then
699                         sender:lock_read(false); -- Unlock now
700                         sender_locked = nil;
701                 end
702         end
703
704         local _readbuffer = sender.readbuffer;
705         function sender.readbuffer()
706                 _readbuffer();
707                 if not sender_locked and receiver.bufferlen() >= buffersize then
708                         sender_locked = true;
709                         sender:lock_read(true);
710                 end
711         end
712 end
713
714 ----------------------------------// PUBLIC //--
715
716 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
717         local err
718         if type( listeners ) ~= "table" then
719                 err = "invalid listener table"
720         end
721         if type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
722                 err = "invalid port"
723         elseif _server[ addr..":"..port ] then
724                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
725         elseif sslctx and not luasec then
726                 err = "luasec not found"
727         end
728         if err then
729                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
730                 return nil, err
731         end
732         addr = addr or "*"
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 client, err = luasocket.tcp( )
935         if err then
936                 return nil, err
937         end
938         client:settimeout( 0 )
939         _, err = client:connect( address, port )
940         if err then -- try again
941                 return wrapclient( client, address, port, listeners, pattern, sslctx )
942         else
943                 return wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx )
944         end
945 end
946
947 --// EXPERIMENTAL //--
948
949 ----------------------------------// BEGIN //--
950
951 use "setmetatable" ( _socketlist, { __mode = "k" } )
952 use "setmetatable" ( _readtimes, { __mode = "k" } )
953 use "setmetatable" ( _writetimes, { __mode = "k" } )
954
955 _timer = luasocket_gettime( )
956 _starttime = luasocket_gettime( )
957
958 local function setlogger(new_logger)
959         local old_logger = log;
960         if new_logger then
961                 log = new_logger;
962         end
963         return old_logger;
964 end
965
966 ----------------------------------// PUBLIC INTERFACE //--
967
968 return {
969         _addtimer = addtimer,
970
971         addclient = addclient,
972         wrapclient = wrapclient,
973
974         loop = loop,
975         link = link,
976         step = step,
977         stats = stats,
978         closeall = closeall,
979         addserver = addserver,
980         getserver = getserver,
981         setlogger = setlogger,
982         getsettings = getsettings,
983         setquitting = setquitting,
984         removeserver = removeserver,
985         get_backend = get_backend,
986         changesettings = changesettings,
987 }