Merge 0.10->trunk
[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 table = use "table"
35 local string = use "string"
36 local coroutine = use "coroutine"
37
38 --// lua lib methods //--
39
40 local math_min = math.min
41 local math_huge = math.huge
42 local table_concat = table.concat
43 local table_insert = table.insert
44 local string_sub = string.sub
45 local coroutine_wrap = coroutine.wrap
46 local coroutine_yield = coroutine.yield
47
48 --// extern libs //--
49
50 local has_luasec, luasec = pcall ( require , "ssl" )
51 local luasocket = use "socket" or require "socket"
52 local luasocket_gettime = luasocket.gettime
53 local getaddrinfo = luasocket.dns.getaddrinfo
54
55 --// extern lib methods //--
56
57 local ssl_wrap = ( has_luasec and luasec.wrap )
58 local socket_bind = luasocket.bind
59 local socket_select = luasocket.select
60
61 --// functions //--
62
63 local id
64 local loop
65 local stats
66 local idfalse
67 local closeall
68 local addsocket
69 local addserver
70 local addtimer
71 local getserver
72 local wrapserver
73 local getsettings
74 local closesocket
75 local removesocket
76 local removeserver
77 local wrapconnection
78 local changesettings
79
80 --// tables //--
81
82 local _server
83 local _readlist
84 local _timerlist
85 local _sendlist
86 local _socketlist
87 local _closelist
88 local _readtimes
89 local _writetimes
90
91 --// simple data types //--
92
93 local _
94 local _readlistlen
95 local _sendlistlen
96 local _timerlistlen
97
98 local _sendtraffic
99 local _readtraffic
100
101 local _selecttimeout
102 local _tcpbacklog
103
104 local _starttime
105 local _currenttime
106
107 local _maxsendlen
108 local _maxreadlen
109
110 local _checkinterval
111 local _sendtimeout
112 local _readtimeout
113
114 local _maxselectlen
115 local _maxfd
116
117 local _maxsslhandshake
118
119 ----------------------------------// DEFINITION //--
120
121 _server = { } -- key = port, value = table; list of listening servers
122 _readlist = { } -- array with sockets to read from
123 _sendlist = { } -- arrary with sockets to write to
124 _timerlist = { } -- array of timer functions
125 _socketlist = { } -- key = socket, value = wrapped socket (handlers)
126 _readtimes = { } -- key = handler, value = timestamp of last data reading
127 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
128 _closelist = { } -- handlers to close
129
130 _readlistlen = 0 -- length of readlist
131 _sendlistlen = 0 -- length of sendlist
132 _timerlistlen = 0 -- lenght of timerlist
133
134 _sendtraffic = 0 -- some stats
135 _readtraffic = 0
136
137 _selecttimeout = 1 -- timeout of socket.select
138 _tcpbacklog = 128 -- some kind of hint to the OS
139
140 _maxsendlen = 51000 * 1024 -- max len of send buffer
141 _maxreadlen = 25000 * 1024 -- max len of read buffer
142
143 _checkinterval = 30 -- interval in secs to check idle clients
144 _sendtimeout = 60000 -- allowed send idle time in secs
145 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
146
147 local is_windows = package.config:sub(1,1) == "\\" -- check the directory separator, to detemine whether this is Windows
148 _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
149 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows
150
151 _maxsslhandshake = 30 -- max handshake round-trips
152
153 ----------------------------------// PRIVATE //--
154
155 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd
156
157         if socket:getfd() >= _maxfd then
158                 out_error("server.lua: Disallowed FD number: "..socket:getfd())
159                 socket:close()
160                 return nil, "fd-too-large"
161         end
162
163         local connections = 0
164
165         local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect
166
167         local accept = socket.accept
168
169         --// public methods of the object //--
170
171         local handler = { }
172
173         handler.shutdown = function( ) end
174
175         handler.ssl = function( )
176                 return sslctx ~= nil
177         end
178         handler.sslctx = function( )
179                 return sslctx
180         end
181         handler.remove = function( )
182                 connections = connections - 1
183                 if handler then
184                         handler.resume( )
185                 end
186         end
187         handler.close = function()
188                 socket:close( )
189                 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
190                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
191                 _server[ip..":"..serverport] = nil;
192                 _socketlist[ socket ] = nil
193                 handler = nil
194                 socket = nil
195                 --mem_free( )
196                 out_put "server.lua: closed server handler and removed sockets from list"
197         end
198         handler.pause = function( hard )
199                 if not handler.paused then
200                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
201                         if hard then
202                                 _socketlist[ socket ] = nil
203                                 socket:close( )
204                                 socket = nil;
205                         end
206                         handler.paused = true;
207                 end
208         end
209         handler.resume = function( )
210                 if handler.paused then
211                         if not socket then
212                                 socket = socket_bind( ip, serverport, _tcpbacklog );
213                                 socket:settimeout( 0 )
214                         end
215                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
216                         _socketlist[ socket ] = handler
217                         handler.paused = false;
218                 end
219         end
220         handler.ip = function( )
221                 return ip
222         end
223         handler.serverport = function( )
224                 return serverport
225         end
226         handler.socket = function( )
227                 return socket
228         end
229         handler.readbuffer = function( )
230                 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
231                         handler.pause( )
232                         out_put( "server.lua: refused new client connection: server full" )
233                         return false
234                 end
235                 local client, err = accept( socket )    -- try to accept
236                 if client then
237                         local ip, clientport = client:getpeername( )
238                         local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
239                         if err then -- error while wrapping ssl socket
240                                 return false
241                         end
242                         connections = connections + 1
243                         out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
244                         if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes
245                                 return dispatch( handler );
246                         end
247                         return;
248                 elseif err then -- maybe timeout or something else
249                         out_put( "server.lua: error with new client connection: ", tostring(err) )
250                         return false
251                 end
252         end
253         return handler
254 end
255
256 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object
257
258         if socket:getfd() >= _maxfd then
259                 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
260                 socket:close( ) -- Should we send some kind of error here?
261                 if server then
262                         server.pause( )
263                 end
264                 return nil, nil, "fd-too-large"
265         end
266         socket:settimeout( 0 )
267
268         --// local import of socket methods //--
269
270         local send
271         local receive
272         local shutdown
273
274         --// private closures of the object //--
275
276         local ssl
277
278         local dispatch = listeners.onincoming
279         local status = listeners.onstatus
280         local disconnect = listeners.ondisconnect
281         local drain = listeners.ondrain
282         local onreadtimeout = listeners.onreadtimeout;
283         local detach = listeners.ondetach
284
285         local bufferqueue = { } -- buffer array
286         local bufferqueuelen = 0        -- end of buffer array
287
288         local toclose
289         local needtls
290
291         local bufferlen = 0
292
293         local noread = false
294         local nosend = false
295
296         local sendtraffic, readtraffic = 0, 0
297
298         local maxsendlen = _maxsendlen
299         local maxreadlen = _maxreadlen
300
301         --// public methods of the object //--
302
303         local handler = bufferqueue -- saves a table ^_^
304
305         handler.dispatch = function( )
306                 return dispatch
307         end
308         handler.disconnect = function( )
309                 return disconnect
310         end
311         handler.onreadtimeout = onreadtimeout;
312
313         handler.setlistener = function( self, listeners )
314                 if detach then
315                         detach(self) -- Notify listener that it is no longer responsible for this connection
316                 end
317                 dispatch = listeners.onincoming
318                 disconnect = listeners.ondisconnect
319                 status = listeners.onstatus
320                 drain = listeners.ondrain
321                 handler.onreadtimeout = listeners.onreadtimeout
322                 detach = listeners.ondetach
323         end
324         handler.getstats = function( )
325                 return readtraffic, sendtraffic
326         end
327         handler.ssl = function( )
328                 return ssl
329         end
330         handler.sslctx = function ( )
331                 return sslctx
332         end
333         handler.send = function( _, data, i, j )
334                 return send( socket, data, i, j )
335         end
336         handler.receive = function( pattern, prefix )
337                 return receive( socket, pattern, prefix )
338         end
339         handler.shutdown = function( pattern )
340                 return shutdown( socket, pattern )
341         end
342         handler.setoption = function (self, option, value)
343                 if socket.setoption then
344                         return socket:setoption(option, value);
345                 end
346                 return false, "setoption not implemented";
347         end
348         handler.force_close = function ( self, err )
349                 if bufferqueuelen ~= 0 then
350                         out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
351                         bufferqueuelen = 0;
352                 end
353                 return self:close(err);
354         end
355         handler.close = function( self, err )
356                 if not handler then return true; end
357                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
358                 _readtimes[ handler ] = nil
359                 if bufferqueuelen ~= 0 then
360                         handler.sendbuffer() -- Try now to send any outstanding data
361                         if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later
362                                 if handler then
363                                         handler.write = nil -- ... but no further writing allowed
364                                 end
365                                 toclose = true
366                                 return false
367                         end
368                 end
369                 if socket then
370                         _ = shutdown and shutdown( socket )
371                         socket:close( )
372                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
373                         _socketlist[ socket ] = nil
374                         socket = nil
375                 else
376                         out_put "server.lua: socket already closed"
377                 end
378                 if handler then
379                         _writetimes[ handler ] = nil
380                         _closelist[ handler ] = nil
381                         local _handler = handler;
382                         handler = nil
383                         if disconnect then
384                                 disconnect(_handler, err or false);
385                                 disconnect = nil
386                         end
387                 end
388                 if server then
389                         server.remove( )
390                 end
391                 out_put "server.lua: closed client handler and removed socket from list"
392                 return true
393         end
394         handler.server = function ( )
395                 return server
396         end
397         handler.ip = function( )
398                 return ip
399         end
400         handler.serverport = function( )
401                 return serverport
402         end
403         handler.clientport = function( )
404                 return clientport
405         end
406         handler.port = handler.clientport -- COMPAT server_event
407         local write = function( self, data )
408                 bufferlen = bufferlen + #data
409                 if bufferlen > maxsendlen then
410                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
411                         handler.write = idfalse -- dont write anymore
412                         return false
413                 elseif socket and not _sendlist[ socket ] then
414                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
415                 end
416                 bufferqueuelen = bufferqueuelen + 1
417                 bufferqueue[ bufferqueuelen ] = data
418                 if handler then
419                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
420                 end
421                 return true
422         end
423         handler.write = write
424         handler.bufferqueue = function( self )
425                 return bufferqueue
426         end
427         handler.socket = function( self )
428                 return socket
429         end
430         handler.set_mode = function( self, new )
431                 pattern = new or pattern
432                 return pattern
433         end
434         handler.set_send = function ( self, newsend )
435                 send = newsend or send
436                 return send
437         end
438         handler.bufferlen = function( self, readlen, sendlen )
439                 maxsendlen = sendlen or maxsendlen
440                 maxreadlen = readlen or maxreadlen
441                 return bufferlen, maxreadlen, maxsendlen
442         end
443         --TODO: Deprecate
444         handler.lock_read = function (self, switch)
445                 if switch == true then
446                         local tmp = _readlistlen
447                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
448                         _readtimes[ handler ] = nil
449                         if _readlistlen ~= tmp then
450                                 noread = true
451                         end
452                 elseif switch == false then
453                         if noread then
454                                 noread = false
455                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
456                                 _readtimes[ handler ] = _currenttime
457                         end
458                 end
459                 return noread
460         end
461         handler.pause = function (self)
462                 return self:lock_read(true);
463         end
464         handler.resume = function (self)
465                 return self:lock_read(false);
466         end
467         handler.lock = function( self, switch )
468                 handler.lock_read (switch)
469                 if switch == true then
470                         handler.write = idfalse
471                         local tmp = _sendlistlen
472                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
473                         _writetimes[ handler ] = nil
474                         if _sendlistlen ~= tmp then
475                                 nosend = true
476                         end
477                 elseif switch == false then
478                         handler.write = write
479                         if nosend then
480                                 nosend = false
481                                 write( "" )
482                         end
483                 end
484                 return noread, nosend
485         end
486         local _readbuffer = function( ) -- this function reads data
487                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
488                 if not err or (err == "wantread" or err == "timeout") then -- received something
489                         local buffer = buffer or part or ""
490                         local len = #buffer
491                         if len > maxreadlen then
492                                 handler:close( "receive buffer exceeded" )
493                                 return false
494                         end
495                         local count = len * STAT_UNIT
496                         readtraffic = readtraffic + count
497                         _readtraffic = _readtraffic + count
498                         _readtimes[ handler ] = _currenttime
499                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
500                         return dispatch( handler, buffer, err )
501                 else    -- connections was closed or fatal error
502                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
503                         _ = handler and handler:force_close( err )
504                         return false
505                 end
506         end
507         local _sendbuffer = function( ) -- this function sends data
508                 local succ, err, byte, buffer, count;
509                 if socket then
510                         buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
511                         succ, err, byte = send( socket, buffer, 1, bufferlen )
512                         count = ( succ or byte or 0 ) * STAT_UNIT
513                         sendtraffic = sendtraffic + count
514                         _sendtraffic = _sendtraffic + count
515                         for i = bufferqueuelen,1,-1 do
516                                 bufferqueue[ i ] = nil
517                         end
518                         --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
519                 else
520                         succ, err, count = false, "unexpected close", 0;
521                 end
522                 if succ then    -- sending succesful
523                         bufferqueuelen = 0
524                         bufferlen = 0
525                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
526                         _writetimes[ handler ] = nil
527                         if drain then
528                                 drain(handler)
529                         end
530                         _ = needtls and handler:starttls(nil)
531                         _ = toclose and handler:force_close( )
532                         return true
533                 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
534                         buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
535                         bufferqueue[ 1 ] = buffer        -- insert new buffer in queue
536                         bufferqueuelen = 1
537                         bufferlen = bufferlen - byte
538                         _writetimes[ handler ] = _currenttime
539                         return true
540                 else    -- connection was closed during sending or fatal error
541                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
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                                                         if bufferqueuelen ~= 0 then
567                                                                 _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
568                                                         end
569                                                 end
570                                                 _readlistlen = addsocket(_readlist, client, _readlistlen)
571                                                 return true
572                                         else
573                                                 if err == "wantwrite" then
574                                                         _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
575                                                         wrote = true
576                                                 elseif err == "wantread" then
577                                                         _readlistlen = addsocket(_readlist, client, _readlistlen)
578                                                         read = true
579                                                 else
580                                                         break;
581                                                 end
582                                                 err = nil;
583                                                 coroutine_yield( ) -- handshake not finished
584                                         end
585                                 end
586                                 err = "ssl handshake error: " .. ( err or "handshake too long" );
587                                 out_put( "server.lua: ", err );
588                                 _ = handler and handler:force_close(err)
589                                 return false, err -- handshake failed
590                         end
591                 )
592         end
593         if has_luasec then
594                 handler.starttls = function( self, _sslctx)
595                         if _sslctx then
596                                 handler:set_sslctx(_sslctx);
597                         end
598                         if bufferqueuelen > 0 then
599                                 out_put "server.lua: we need to do tls, but delaying until send buffer empty"
600                                 needtls = true
601                                 return
602                         end
603                         out_put( "server.lua: attempting to start tls on " .. tostring( socket ) )
604                         local oldsocket, err = socket
605                         socket, err = ssl_wrap( socket, sslctx )        -- wrap socket
606                         if not socket then
607                                 out_put( "server.lua: error while starting tls on client: ", tostring(err or "unknown error") )
608                                 return nil, err -- fatal error
609                         end
610
611                         socket:settimeout( 0 )
612
613                         -- add the new socket to our system
614                         send = socket.send
615                         receive = socket.receive
616                         shutdown = id
617                         _socketlist[ socket ] = handler
618                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
619
620                         -- remove traces of the old socket
621                         _readlistlen = removesocket( _readlist, oldsocket, _readlistlen )
622                         _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen )
623                         _socketlist[ oldsocket ] = nil
624
625                         handler.starttls = nil
626                         needtls = nil
627
628                         -- Secure now (if handshake fails connection will close)
629                         ssl = true
630
631                         handler.readbuffer = handshake
632                         handler.sendbuffer = handshake
633                         return handshake( socket ) -- do handshake
634                 end
635         end
636
637         handler.readbuffer = _readbuffer
638         handler.sendbuffer = _sendbuffer
639         send = socket.send
640         receive = socket.receive
641         shutdown = ( ssl and id ) or socket.shutdown
642
643         _socketlist[ socket ] = handler
644         _readlistlen = addsocket(_readlist, socket, _readlistlen)
645
646         if sslctx and has_luasec then
647                 out_put "server.lua: auto-starting ssl negotiation..."
648                 handler.autostart_ssl = true;
649                 local ok, err = handler:starttls(sslctx);
650                 if ok == false then
651                         return nil, nil, err
652                 end
653         end
654
655         return handler, socket
656 end
657
658 id = function( )
659 end
660
661 idfalse = function( )
662         return false
663 end
664
665 addsocket = function( list, socket, len )
666         if not list[ socket ] then
667                 len = len + 1
668                 list[ len ] = socket
669                 list[ socket ] = len
670         end
671         return len;
672 end
673
674 removesocket = function( list, socket, len )    -- this function removes sockets from a list ( copied from copas )
675         local pos = list[ socket ]
676         if pos then
677                 list[ socket ] = nil
678                 local last = list[ len ]
679                 list[ len ] = nil
680                 if last ~= socket then
681                         list[ last ] = pos
682                         list[ pos ] = last
683                 end
684                 return len - 1
685         end
686         return len
687 end
688
689 closesocket = function( socket )
690         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
691         _readlistlen = removesocket( _readlist, socket, _readlistlen )
692         _socketlist[ socket ] = nil
693         socket:close( )
694         --mem_free( )
695 end
696
697 local function link(sender, receiver, buffersize)
698         local sender_locked;
699         local _sendbuffer = receiver.sendbuffer;
700         function receiver.sendbuffer()
701                 _sendbuffer();
702                 if sender_locked and receiver.bufferlen() < buffersize then
703                         sender:lock_read(false); -- Unlock now
704                         sender_locked = nil;
705                 end
706         end
707
708         local _readbuffer = sender.readbuffer;
709         function sender.readbuffer()
710                 _readbuffer();
711                 if not sender_locked and receiver.bufferlen() >= buffersize then
712                         sender_locked = true;
713                         sender:lock_read(true);
714                 end
715         end
716         sender:set_mode("*a");
717 end
718
719 ----------------------------------// PUBLIC //--
720
721 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
722         addr = addr or "*"
723         local err
724         if type( listeners ) ~= "table" then
725                 err = "invalid listener table"
726         elseif type ( addr ) ~= "string" then
727                 err = "invalid address"
728         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
729                 err = "invalid port"
730         elseif _server[ addr..":"..port ] then
731                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
732         elseif sslctx and not has_luasec then
733                 err = "luasec not found"
734         end
735         if err then
736                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
737                 return nil, err
738         end
739         local server, err = socket_bind( addr, port, _tcpbacklog )
740         if err then
741                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
742                 return nil, err
743         end
744         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
745         if not handler then
746                 server:close( )
747                 return nil, err
748         end
749         server:settimeout( 0 )
750         _readlistlen = addsocket(_readlist, server, _readlistlen)
751         _server[ addr..":"..port ] = handler
752         _socketlist[ server ] = handler
753         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
754         return handler
755 end
756
757 getserver = function ( addr, port )
758         return _server[ addr..":"..port ];
759 end
760
761 removeserver = function( addr, port )
762         local handler = _server[ addr..":"..port ]
763         if not handler then
764                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
765         end
766         handler:close( )
767         _server[ addr..":"..port ] = nil
768         return true
769 end
770
771 closeall = function( )
772         for _, handler in pairs( _socketlist ) do
773                 handler:close( )
774                 _socketlist[ _ ] = nil
775         end
776         _readlistlen = 0
777         _sendlistlen = 0
778         _timerlistlen = 0
779         _server = { }
780         _readlist = { }
781         _sendlist = { }
782         _timerlist = { }
783         _socketlist = { }
784         --mem_free( )
785 end
786
787 getsettings = function( )
788         return {
789                 select_timeout = _selecttimeout;
790                 tcp_backlog = _tcpbacklog;
791                 max_send_buffer_size = _maxsendlen;
792                 max_receive_buffer_size = _maxreadlen;
793                 select_idle_check_interval = _checkinterval;
794                 send_timeout = _sendtimeout;
795                 read_timeout = _readtimeout;
796                 max_connections = _maxselectlen;
797                 max_ssl_handshake_roundtrips = _maxsslhandshake;
798                 highest_allowed_fd = _maxfd;
799         }
800 end
801
802 changesettings = function( new )
803         if type( new ) ~= "table" then
804                 return nil, "invalid settings table"
805         end
806         _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout
807         _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
808         _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
809         _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
810         _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
811         _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
812         _readtimeout = tonumber( new.read_timeout ) or _readtimeout
813         _maxselectlen = new.max_connections or _maxselectlen
814         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
815         _maxfd = new.highest_allowed_fd or _maxfd
816         return true
817 end
818
819 addtimer = function( listener )
820         if type( listener ) ~= "function" then
821                 return nil, "invalid listener function"
822         end
823         _timerlistlen = _timerlistlen + 1
824         _timerlist[ _timerlistlen ] = listener
825         return true
826 end
827
828 local add_task do
829         local data = {};
830         local new_data = {};
831
832         function add_task(delay, callback)
833                 local current_time = luasocket_gettime();
834                 delay = delay + current_time;
835                 if delay >= current_time then
836                         table_insert(new_data, {delay, callback});
837                 else
838                         local r = callback(current_time);
839                         if r and type(r) == "number" then
840                                 return add_task(r, callback);
841                         end
842                 end
843         end
844
845         addtimer(function(current_time)
846                 if #new_data > 0 then
847                         for _, d in pairs(new_data) do
848                                 table_insert(data, d);
849                         end
850                         new_data = {};
851                 end
852
853                 local next_time = math_huge;
854                 for i, d in pairs(data) do
855                         local t, callback = d[1], d[2];
856                         if t <= current_time then
857                                 data[i] = nil;
858                                 local r = callback(current_time);
859                                 if type(r) == "number" then
860                                         add_task(r, callback);
861                                         next_time = math_min(next_time, r);
862                                 end
863                         else
864                                 next_time = math_min(next_time, t - current_time);
865                         end
866                 end
867                 return next_time;
868         end);
869 end
870
871 stats = function( )
872         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
873 end
874
875 local quitting;
876
877 local function setquitting(quit)
878         quitting = not not quit;
879 end
880
881 loop = function(once) -- this is the main loop of the program
882         if quitting then return "quitting"; end
883         if once then quitting = "once"; end
884         _currenttime = luasocket_gettime( )
885         repeat
886                 -- Fire timers
887                 local 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
893                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
894                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
895                         local handler = _socketlist[ socket ]
896                         if handler then
897                                 handler.sendbuffer( )
898                         else
899                                 closesocket( socket )
900                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
901                         end
902                 end
903                 for i, socket in ipairs( read ) do -- receive data
904                         local handler = _socketlist[ socket ]
905                         if handler then
906                                 handler.readbuffer( )
907                         else
908                                 closesocket( socket )
909                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
910                         end
911                 end
912                 for handler, err in pairs( _closelist ) do
913                         handler.disconnect( )( handler, err )
914                         handler:force_close()    -- forced disconnect
915                         _closelist[ handler ] = nil;
916                 end
917                 _currenttime = luasocket_gettime( )
918
919                 -- Check for socket timeouts
920                 if _currenttime - _starttime > _checkinterval then
921                         _starttime = _currenttime
922                         for handler, timestamp in pairs( _writetimes ) do
923                                 if _currenttime - timestamp > _sendtimeout then
924                                         handler.disconnect( )( handler, "send timeout" )
925                                         handler:force_close()    -- forced disconnect
926                                 end
927                         end
928                         for handler, timestamp in pairs( _readtimes ) do
929                                 if _currenttime - timestamp > _readtimeout then
930                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
931                                                 handler.disconnect( )( handler, "read timeout" )
932                                                 handler:close( )        -- forced disconnect?
933                                         else
934                                                 _readtimes[ handler ] = _currenttime -- reset timer
935                                         end
936                                 end
937                         end
938                 end
939         until quitting;
940         if once and quitting == "once" then quitting = nil; return; end
941         closeall();
942         return "quitting"
943 end
944
945 local function step()
946         return loop(true);
947 end
948
949 local function get_backend()
950         return "select";
951 end
952
953 --// EXPERIMENTAL //--
954
955 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
956         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
957         if not handler then return nil, err end
958         _socketlist[ socket ] = handler
959         if not sslctx then
960                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
961                 if listeners.onconnect then
962                         -- When socket is writeable, call onconnect
963                         local _sendbuffer = handler.sendbuffer;
964                         handler.sendbuffer = function ()
965                                 handler.sendbuffer = _sendbuffer;
966                                 listeners.onconnect(handler);
967                                 return _sendbuffer(); -- Send any queued outgoing data
968                         end
969                 end
970         end
971         return handler, socket
972 end
973
974 local addclient = function( address, port, listeners, pattern, sslctx, typ )
975         local err
976         if type( listeners ) ~= "table" then
977                 err = "invalid listener table"
978         elseif type ( address ) ~= "string" then
979                 err = "invalid address"
980         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
981                 err = "invalid port"
982         elseif sslctx and not has_luasec then
983                 err = "luasec not found"
984         end
985         if getaddrinfo and not typ then
986                 local addrinfo, err = getaddrinfo(address)
987                 if not addrinfo then return nil, err end
988                 if addrinfo[1] and addrinfo[1].family == "inet6" then
989                         typ = "tcp6"
990                 end
991         end
992         local create = luasocket[typ or "tcp"]
993         if type( create ) ~= "function"  then
994                 err = "invalid socket type"
995         end
996
997         if err then
998                 out_error( "server.lua, addclient: ", err )
999                 return nil, err
1000         end
1001
1002         local client, err = create( )
1003         if err then
1004                 return nil, err
1005         end
1006         client:settimeout( 0 )
1007         local ok, err = client:connect( address, port )
1008         if ok or err == "timeout" or err == "Operation already in progress" then
1009                 return wrapclient( client, address, port, listeners, pattern, sslctx )
1010         else
1011                 return nil, err
1012         end
1013 end
1014
1015 ----------------------------------// BEGIN //--
1016
1017 use "setmetatable" ( _socketlist, { __mode = "k" } )
1018 use "setmetatable" ( _readtimes, { __mode = "k" } )
1019 use "setmetatable" ( _writetimes, { __mode = "k" } )
1020
1021 _starttime = luasocket_gettime( )
1022
1023 local function setlogger(new_logger)
1024         local old_logger = log;
1025         if new_logger then
1026                 log = new_logger;
1027         end
1028         return old_logger;
1029 end
1030
1031 ----------------------------------// PUBLIC INTERFACE //--
1032
1033 return {
1034         _addtimer = addtimer,
1035         add_task = add_task;
1036
1037         addclient = addclient,
1038         wrapclient = wrapclient,
1039
1040         loop = loop,
1041         link = link,
1042         step = step,
1043         stats = stats,
1044         closeall = closeall,
1045         addserver = addserver,
1046         getserver = getserver,
1047         setlogger = setlogger,
1048         getsettings = getsettings,
1049         setquitting = setquitting,
1050         removeserver = removeserver,
1051         get_backend = get_backend,
1052         changesettings = changesettings,
1053 }