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.ip = function( )
395                 return ip
396         end
397         handler.serverport = function( )
398                 return serverport
399         end
400         handler.clientport = function( )
401                 return clientport
402         end
403         handler.port = handler.clientport -- COMPAT server_event
404         local write = function( self, data )
405                 bufferlen = bufferlen + #data
406                 if bufferlen > maxsendlen then
407                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
408                         handler.write = idfalse -- dont write anymore
409                         return false
410                 elseif socket and not _sendlist[ socket ] then
411                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
412                 end
413                 bufferqueuelen = bufferqueuelen + 1
414                 bufferqueue[ bufferqueuelen ] = data
415                 if handler then
416                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
417                 end
418                 return true
419         end
420         handler.write = write
421         handler.bufferqueue = function( self )
422                 return bufferqueue
423         end
424         handler.socket = function( self )
425                 return socket
426         end
427         handler.set_mode = function( self, new )
428                 pattern = new or pattern
429                 return pattern
430         end
431         handler.set_send = function ( self, newsend )
432                 send = newsend or send
433                 return send
434         end
435         handler.bufferlen = function( self, readlen, sendlen )
436                 maxsendlen = sendlen or maxsendlen
437                 maxreadlen = readlen or maxreadlen
438                 return bufferlen, maxreadlen, maxsendlen
439         end
440         --TODO: Deprecate
441         handler.lock_read = function (self, switch)
442                 if switch == true then
443                         local tmp = _readlistlen
444                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
445                         _readtimes[ handler ] = nil
446                         if _readlistlen ~= tmp then
447                                 noread = true
448                         end
449                 elseif switch == false then
450                         if noread then
451                                 noread = false
452                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
453                                 _readtimes[ handler ] = _currenttime
454                         end
455                 end
456                 return noread
457         end
458         handler.pause = function (self)
459                 return self:lock_read(true);
460         end
461         handler.resume = function (self)
462                 return self:lock_read(false);
463         end
464         handler.lock = function( self, switch )
465                 handler.lock_read (switch)
466                 if switch == true then
467                         handler.write = idfalse
468                         local tmp = _sendlistlen
469                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
470                         _writetimes[ handler ] = nil
471                         if _sendlistlen ~= tmp then
472                                 nosend = true
473                         end
474                 elseif switch == false then
475                         handler.write = write
476                         if nosend then
477                                 nosend = false
478                                 write( "" )
479                         end
480                 end
481                 return noread, nosend
482         end
483         local _readbuffer = function( ) -- this function reads data
484                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
485                 if not err or (err == "wantread" or err == "timeout") then -- received something
486                         local buffer = buffer or part or ""
487                         local len = #buffer
488                         if len > maxreadlen then
489                                 handler:close( "receive buffer exceeded" )
490                                 return false
491                         end
492                         local count = len * STAT_UNIT
493                         readtraffic = readtraffic + count
494                         _readtraffic = _readtraffic + count
495                         _readtimes[ handler ] = _currenttime
496                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
497                         return dispatch( handler, buffer, err )
498                 else    -- connections was closed or fatal error
499                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
500                         _ = handler and handler:force_close( err )
501                         return false
502                 end
503         end
504         local _sendbuffer = function( ) -- this function sends data
505                 local succ, err, byte, buffer, count;
506                 if socket then
507                         buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
508                         succ, err, byte = send( socket, buffer, 1, bufferlen )
509                         count = ( succ or byte or 0 ) * STAT_UNIT
510                         sendtraffic = sendtraffic + count
511                         _sendtraffic = _sendtraffic + count
512                         for i = bufferqueuelen,1,-1 do
513                                 bufferqueue[ i ] = nil
514                         end
515                         --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
516                 else
517                         succ, err, count = false, "unexpected close", 0;
518                 end
519                 if succ then    -- sending succesful
520                         bufferqueuelen = 0
521                         bufferlen = 0
522                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
523                         _writetimes[ handler ] = nil
524                         if drain then
525                                 drain(handler)
526                         end
527                         _ = needtls and handler:starttls(nil)
528                         _ = toclose and handler:force_close( )
529                         return true
530                 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
531                         buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
532                         bufferqueue[ 1 ] = buffer        -- insert new buffer in queue
533                         bufferqueuelen = 1
534                         bufferlen = bufferlen - byte
535                         _writetimes[ handler ] = _currenttime
536                         return true
537                 else    -- connection was closed during sending or fatal error
538                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
539                         _ = handler and handler:force_close( err )
540                         return false
541                 end
542         end
543
544         -- Set the sslctx
545         local handshake;
546         function handler.set_sslctx(self, new_sslctx)
547                 sslctx = new_sslctx;
548                 local read, wrote
549                 handshake = coroutine_wrap( function( client ) -- create handshake coroutine
550                                 local err
551                                 for i = 1, _maxsslhandshake do
552                                         _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
553                                         _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
554                                         read, wrote = nil, nil
555                                         _, err = client:dohandshake( )
556                                         if not err then
557                                                 out_put( "server.lua: ssl handshake done" )
558                                                 handler.readbuffer = _readbuffer        -- when handshake is done, replace the handshake function with regular functions
559                                                 handler.sendbuffer = _sendbuffer
560                                                 _ = status and status( handler, "ssl-handshake-complete" )
561                                                 if self.autostart_ssl and listeners.onconnect then
562                                                         listeners.onconnect(self);
563                                                         if bufferqueuelen ~= 0 then
564                                                                 _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
565                                                         end
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 has_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 has_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         addr = addr or "*"
719         local err
720         if type( listeners ) ~= "table" then
721                 err = "invalid listener table"
722         elseif type ( addr ) ~= "string" then
723                 err = "invalid address"
724         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
725                 err = "invalid port"
726         elseif _server[ addr..":"..port ] then
727                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
728         elseif sslctx and not has_luasec then
729                 err = "luasec not found"
730         end
731         if err then
732                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
733                 return nil, err
734         end
735         local server, err = socket_bind( addr, port, _tcpbacklog )
736         if err then
737                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
738                 return nil, err
739         end
740         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
741         if not handler then
742                 server:close( )
743                 return nil, err
744         end
745         server:settimeout( 0 )
746         _readlistlen = addsocket(_readlist, server, _readlistlen)
747         _server[ addr..":"..port ] = handler
748         _socketlist[ server ] = handler
749         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
750         return handler
751 end
752
753 getserver = function ( addr, port )
754         return _server[ addr..":"..port ];
755 end
756
757 removeserver = function( addr, port )
758         local handler = _server[ addr..":"..port ]
759         if not handler then
760                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
761         end
762         handler:close( )
763         _server[ addr..":"..port ] = nil
764         return true
765 end
766
767 closeall = function( )
768         for _, handler in pairs( _socketlist ) do
769                 handler:close( )
770                 _socketlist[ _ ] = nil
771         end
772         _readlistlen = 0
773         _sendlistlen = 0
774         _timerlistlen = 0
775         _server = { }
776         _readlist = { }
777         _sendlist = { }
778         _timerlist = { }
779         _socketlist = { }
780         --mem_free( )
781 end
782
783 getsettings = function( )
784         return {
785                 select_timeout = _selecttimeout;
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         _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 local add_task do
825         local data = {};
826         local new_data = {};
827
828         function add_task(delay, callback)
829                 local current_time = luasocket_gettime();
830                 delay = delay + current_time;
831                 if delay >= current_time then
832                         table_insert(new_data, {delay, callback});
833                 else
834                         local r = callback(current_time);
835                         if r and type(r) == "number" then
836                                 return add_task(r, callback);
837                         end
838                 end
839         end
840
841         addtimer(function(current_time)
842                 if #new_data > 0 then
843                         for _, d in pairs(new_data) do
844                                 table_insert(data, d);
845                         end
846                         new_data = {};
847                 end
848
849                 local next_time = math_huge;
850                 for i, d in pairs(data) do
851                         local t, callback = d[1], d[2];
852                         if t <= current_time then
853                                 data[i] = nil;
854                                 local r = callback(current_time);
855                                 if type(r) == "number" then
856                                         add_task(r, callback);
857                                         next_time = math_min(next_time, r);
858                                 end
859                         else
860                                 next_time = math_min(next_time, t - current_time);
861                         end
862                 end
863                 return next_time;
864         end);
865 end
866
867 stats = function( )
868         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
869 end
870
871 local quitting;
872
873 local function setquitting(quit)
874         quitting = not not quit;
875 end
876
877 loop = function(once) -- this is the main loop of the program
878         if quitting then return "quitting"; end
879         if once then quitting = "once"; end
880         _currenttime = luasocket_gettime( )
881         repeat
882                 -- Fire timers
883                 local next_timer_time = math_huge;
884                 for i = 1, _timerlistlen do
885                         local t = _timerlist[ i ]( _currenttime ) -- fire timers
886                         if t then next_timer_time = math_min(next_timer_time, t); end
887                 end
888
889                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
890                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
891                         local handler = _socketlist[ socket ]
892                         if handler then
893                                 handler.sendbuffer( )
894                         else
895                                 closesocket( socket )
896                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
897                         end
898                 end
899                 for i, socket in ipairs( read ) do -- receive data
900                         local handler = _socketlist[ socket ]
901                         if handler then
902                                 handler.readbuffer( )
903                         else
904                                 closesocket( socket )
905                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
906                         end
907                 end
908                 for handler, err in pairs( _closelist ) do
909                         handler.disconnect( )( handler, err )
910                         handler:force_close()    -- forced disconnect
911                         _closelist[ handler ] = nil;
912                 end
913                 _currenttime = luasocket_gettime( )
914
915                 -- Check for socket timeouts
916                 if _currenttime - _starttime > _checkinterval then
917                         _starttime = _currenttime
918                         for handler, timestamp in pairs( _writetimes ) do
919                                 if _currenttime - timestamp > _sendtimeout then
920                                         handler.disconnect( )( handler, "send timeout" )
921                                         handler:force_close()    -- forced disconnect
922                                 end
923                         end
924                         for handler, timestamp in pairs( _readtimes ) do
925                                 if _currenttime - timestamp > _readtimeout then
926                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
927                                                 handler.disconnect( )( handler, "read timeout" )
928                                                 handler:close( )        -- forced disconnect?
929                                         else
930                                                 _readtimes[ handler ] = _currenttime -- reset timer
931                                         end
932                                 end
933                         end
934                 end
935         until quitting;
936         if once and quitting == "once" then quitting = nil; return; end
937         return "quitting"
938 end
939
940 local function step()
941         return loop(true);
942 end
943
944 local function get_backend()
945         return "select";
946 end
947
948 --// EXPERIMENTAL //--
949
950 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
951         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
952         if not handler then return nil, err end
953         _socketlist[ socket ] = handler
954         if not sslctx then
955                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
956                 if listeners.onconnect then
957                         -- When socket is writeable, call onconnect
958                         local _sendbuffer = handler.sendbuffer;
959                         handler.sendbuffer = function ()
960                                 handler.sendbuffer = _sendbuffer;
961                                 listeners.onconnect(handler);
962                                 return _sendbuffer(); -- Send any queued outgoing data
963                         end
964                 end
965         end
966         return handler, socket
967 end
968
969 local addclient = function( address, port, listeners, pattern, sslctx, typ )
970         local err
971         if type( listeners ) ~= "table" then
972                 err = "invalid listener table"
973         elseif type ( address ) ~= "string" then
974                 err = "invalid address"
975         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
976                 err = "invalid port"
977         elseif sslctx and not has_luasec then
978                 err = "luasec not found"
979         end
980         if getaddrinfo and not typ then
981                 local addrinfo, err = getaddrinfo(address)
982                 if not addrinfo then return nil, err end
983                 if addrinfo[1] and addrinfo[1].family == "inet6" then
984                         typ = "tcp6"
985                 end
986         end
987         local create = luasocket[typ or "tcp"]
988         if type( create ) ~= "function"  then
989                 err = "invalid socket type"
990         end
991
992         if err then
993                 out_error( "server.lua, addclient: ", err )
994                 return nil, err
995         end
996
997         local client, err = create( )
998         if err then
999                 return nil, err
1000         end
1001         client:settimeout( 0 )
1002         local ok, err = client:connect( address, port )
1003         if ok or err == "timeout" or err == "Operation already in progress" then
1004                 return wrapclient( client, address, port, listeners, pattern, sslctx )
1005         else
1006                 return nil, err
1007         end
1008 end
1009
1010 ----------------------------------// BEGIN //--
1011
1012 use "setmetatable" ( _socketlist, { __mode = "k" } )
1013 use "setmetatable" ( _readtimes, { __mode = "k" } )
1014 use "setmetatable" ( _writetimes, { __mode = "k" } )
1015
1016 _starttime = luasocket_gettime( )
1017
1018 local function setlogger(new_logger)
1019         local old_logger = log;
1020         if new_logger then
1021                 log = new_logger;
1022         end
1023         return old_logger;
1024 end
1025
1026 ----------------------------------// PUBLIC INTERFACE //--
1027
1028 return {
1029         _addtimer = addtimer,
1030         add_task = add_task;
1031
1032         addclient = addclient,
1033         wrapclient = wrapclient,
1034
1035         loop = loop,
1036         link = link,
1037         step = step,
1038         stats = stats,
1039         closeall = closeall,
1040         addserver = addserver,
1041         getserver = getserver,
1042         setlogger = setlogger,
1043         getsettings = getsettings,
1044         setquitting = setquitting,
1045         removeserver = removeserver,
1046         get_backend = get_backend,
1047         changesettings = changesettings,
1048 }