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         sender:set_mode("*a");
713 end
714
715 ----------------------------------// PUBLIC //--
716
717 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
718         local err
719         if type( listeners ) ~= "table" then
720                 err = "invalid listener table"
721         end
722         if 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 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         addr = addr or "*"
734         local server, err = socket_bind( addr, port, _tcpbacklog )
735         if err then
736                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
737                 return nil, err
738         end
739         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
740         if not handler then
741                 server:close( )
742                 return nil, err
743         end
744         server:settimeout( 0 )
745         _readlistlen = addsocket(_readlist, server, _readlistlen)
746         _server[ addr..":"..port ] = handler
747         _socketlist[ server ] = handler
748         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
749         return handler
750 end
751
752 getserver = function ( addr, port )
753         return _server[ addr..":"..port ];
754 end
755
756 removeserver = function( addr, port )
757         local handler = _server[ addr..":"..port ]
758         if not handler then
759                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
760         end
761         handler:close( )
762         _server[ addr..":"..port ] = nil
763         return true
764 end
765
766 closeall = function( )
767         for _, handler in pairs( _socketlist ) do
768                 handler:close( )
769                 _socketlist[ _ ] = nil
770         end
771         _readlistlen = 0
772         _sendlistlen = 0
773         _timerlistlen = 0
774         _server = { }
775         _readlist = { }
776         _sendlist = { }
777         _timerlist = { }
778         _socketlist = { }
779         --mem_free( )
780 end
781
782 getsettings = function( )
783         return {
784                 select_timeout = _selecttimeout;
785                 select_sleep_time = _sleeptime;
786                 tcp_backlog = _tcpbacklog;
787                 max_send_buffer_size = _maxsendlen;
788                 max_receive_buffer_size = _maxreadlen;
789                 select_idle_check_interval = _checkinterval;
790                 send_timeout = _sendtimeout;
791                 read_timeout = _readtimeout;
792                 max_connections = _maxselectlen;
793                 max_ssl_handshake_roundtrips = _maxsslhandshake;
794                 highest_allowed_fd = _maxfd;
795         }
796 end
797
798 changesettings = function( new )
799         if type( new ) ~= "table" then
800                 return nil, "invalid settings table"
801         end
802         _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout
803         _sleeptime = tonumber( new.select_sleep_time ) or _sleeptime
804         _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
805         _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
806         _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
807         _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
808         _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
809         _readtimeout = tonumber( new.read_timeout ) or _readtimeout
810         _maxselectlen = new.max_connections or _maxselectlen
811         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
812         _maxfd = new.highest_allowed_fd or _maxfd
813         return true
814 end
815
816 addtimer = function( listener )
817         if type( listener ) ~= "function" then
818                 return nil, "invalid listener function"
819         end
820         _timerlistlen = _timerlistlen + 1
821         _timerlist[ _timerlistlen ] = listener
822         return true
823 end
824
825 stats = function( )
826         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
827 end
828
829 local quitting;
830
831 local function setquitting(quit)
832         quitting = not not quit;
833 end
834
835 loop = function(once) -- this is the main loop of the program
836         if quitting then return "quitting"; end
837         if once then quitting = "once"; end
838         local next_timer_time = math_huge;
839         repeat
840                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
841                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
842                         local handler = _socketlist[ socket ]
843                         if handler then
844                                 handler.sendbuffer( )
845                         else
846                                 closesocket( socket )
847                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
848                         end
849                 end
850                 for i, socket in ipairs( read ) do -- receive data
851                         local handler = _socketlist[ socket ]
852                         if handler then
853                                 handler.readbuffer( )
854                         else
855                                 closesocket( socket )
856                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
857                         end
858                 end
859                 for handler, err in pairs( _closelist ) do
860                         handler.disconnect( )( handler, err )
861                         handler:force_close()    -- forced disconnect
862                         _closelist[ handler ] = nil;
863                 end
864                 _currenttime = luasocket_gettime( )
865
866                 -- Check for socket timeouts
867                 local difftime = os_difftime( _currenttime - _starttime )
868                 if difftime > _checkinterval then
869                         _starttime = _currenttime
870                         for handler, timestamp in pairs( _writetimes ) do
871                                 if os_difftime( _currenttime - timestamp ) > _sendtimeout then
872                                         handler.disconnect( )( handler, "send timeout" )
873                                         handler:force_close()    -- forced disconnect
874                                 end
875                         end
876                         for handler, timestamp in pairs( _readtimes ) do
877                                 if os_difftime( _currenttime - timestamp ) > _readtimeout then
878                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
879                                                 handler.disconnect( )( handler, "read timeout" )
880                                                 handler:close( )        -- forced disconnect?
881                                         end
882                                 end
883                         end
884                 end
885
886                 -- Fire timers
887                 if _currenttime - _timer >= math_min(next_timer_time, 1) then
888                         next_timer_time = math_huge;
889                         for i = 1, _timerlistlen do
890                                 local t = _timerlist[ i ]( _currenttime ) -- fire timers
891                                 if t then next_timer_time = math_min(next_timer_time, t); end
892                         end
893                         _timer = _currenttime
894                 else
895                         next_timer_time = next_timer_time - (_currenttime - _timer);
896                 end
897
898                 -- wait some time (0 by default)
899                 socket_sleep( _sleeptime )
900         until quitting;
901         if once and quitting == "once" then quitting = nil; return; end
902         return "quitting"
903 end
904
905 local function step()
906         return loop(true);
907 end
908
909 local function get_backend()
910         return "select";
911 end
912
913 --// EXPERIMENTAL //--
914
915 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
916         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
917         if not handler then return nil, err end
918         _socketlist[ socket ] = handler
919         if not sslctx then
920                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
921                 if listeners.onconnect then
922                         -- When socket is writeable, call onconnect
923                         local _sendbuffer = handler.sendbuffer;
924                         handler.sendbuffer = function ()
925                                 handler.sendbuffer = _sendbuffer;
926                                 listeners.onconnect(handler);
927                                 return _sendbuffer(); -- Send any queued outgoing data
928                         end
929                 end
930         end
931         return handler, socket
932 end
933
934 local addclient = function( address, port, listeners, pattern, sslctx )
935         local client, err = luasocket.tcp( )
936         if err then
937                 return nil, err
938         end
939         client:settimeout( 0 )
940         _, err = client:connect( address, port )
941         if err then -- try again
942                 return wrapclient( client, address, port, listeners, pattern, sslctx )
943         else
944                 return wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx )
945         end
946 end
947
948 --// EXPERIMENTAL //--
949
950 ----------------------------------// BEGIN //--
951
952 use "setmetatable" ( _socketlist, { __mode = "k" } )
953 use "setmetatable" ( _readtimes, { __mode = "k" } )
954 use "setmetatable" ( _writetimes, { __mode = "k" } )
955
956 _timer = luasocket_gettime( )
957 _starttime = luasocket_gettime( )
958
959 local function setlogger(new_logger)
960         local old_logger = log;
961         if new_logger then
962                 log = new_logger;
963         end
964         return old_logger;
965 end
966
967 ----------------------------------// PUBLIC INTERFACE //--
968
969 return {
970         _addtimer = addtimer,
971
972         addclient = addclient,
973         wrapclient = wrapclient,
974
975         loop = loop,
976         link = link,
977         step = step,
978         stats = stats,
979         closeall = closeall,
980         addserver = addserver,
981         getserver = getserver,
982         setlogger = setlogger,
983         getsettings = getsettings,
984         setquitting = setquitting,
985         removeserver = removeserver,
986         get_backend = get_backend,
987         changesettings = changesettings,
988 }