net.server_select: Remove socket.sleep call from main loop
[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 math_min = math.min
42 local math_huge = math.huge
43 local table_concat = table.concat
44 local table_insert = table.insert
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 has_luasec, luasec = pcall ( require , "ssl" )
52 local luasocket = use "socket" or require "socket"
53 local luasocket_gettime = luasocket.gettime
54 local getaddrinfo = luasocket.dns.getaddrinfo
55
56 --// extern lib methods //--
57
58 local ssl_wrap = ( has_luasec and luasec.wrap )
59 local socket_bind = luasocket.bind
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 _tcpbacklog
104
105 local _starttime
106 local _currenttime
107
108 local _maxsendlen
109 local _maxreadlen
110
111 local _checkinterval
112 local _sendtimeout
113 local _readtimeout
114
115 local _maxselectlen
116 local _maxfd
117
118 local _maxsslhandshake
119
120 ----------------------------------// DEFINITION //--
121
122 _server = { } -- key = port, value = table; list of listening servers
123 _readlist = { } -- array with sockets to read from
124 _sendlist = { } -- arrary with sockets to write to
125 _timerlist = { } -- array of timer functions
126 _socketlist = { } -- key = socket, value = wrapped socket (handlers)
127 _readtimes = { } -- key = handler, value = timestamp of last data reading
128 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
129 _closelist = { } -- handlers to close
130
131 _readlistlen = 0 -- length of readlist
132 _sendlistlen = 0 -- length of sendlist
133 _timerlistlen = 0 -- lenght of timerlist
134
135 _sendtraffic = 0 -- some stats
136 _readtraffic = 0
137
138 _selecttimeout = 1 -- timeout of socket.select
139 _tcpbacklog = 128 -- some kind of hint to the OS
140
141 _maxsendlen = 51000 * 1024 -- max len of send buffer
142 _maxreadlen = 25000 * 1024 -- max len of read buffer
143
144 _checkinterval = 30 -- interval in secs to check idle clients
145 _sendtimeout = 60000 -- allowed send idle time in secs
146 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
147
148 local is_windows = package.config:sub(1,1) == "\\" -- check the directory separator, to detemine whether this is Windows
149 _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
150 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows
151
152 _maxsslhandshake = 30 -- max handshake round-trips
153
154 ----------------------------------// PRIVATE //--
155
156 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd
157
158         if socket:getfd() >= _maxfd then
159                 out_error("server.lua: Disallowed FD number: "..socket:getfd())
160                 socket:close()
161                 return nil, "fd-too-large"
162         end
163
164         local connections = 0
165
166         local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect
167
168         local accept = socket.accept
169
170         --// public methods of the object //--
171
172         local handler = { }
173
174         handler.shutdown = function( ) end
175
176         handler.ssl = function( )
177                 return sslctx ~= nil
178         end
179         handler.sslctx = function( )
180                 return sslctx
181         end
182         handler.remove = function( )
183                 connections = connections - 1
184                 if handler then
185                         handler.resume( )
186                 end
187         end
188         handler.close = function()
189                 socket:close( )
190                 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
191                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
192                 _server[ip..":"..serverport] = nil;
193                 _socketlist[ socket ] = nil
194                 handler = nil
195                 socket = nil
196                 --mem_free( )
197                 out_put "server.lua: closed server handler and removed sockets from list"
198         end
199         handler.pause = function( hard )
200                 if not handler.paused then
201                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
202                         if hard then
203                                 _socketlist[ socket ] = nil
204                                 socket:close( )
205                                 socket = nil;
206                         end
207                         handler.paused = true;
208                 end
209         end
210         handler.resume = function( )
211                 if handler.paused then
212                         if not socket then
213                                 socket = socket_bind( ip, serverport, _tcpbacklog );
214                                 socket:settimeout( 0 )
215                         end
216                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
217                         _socketlist[ socket ] = handler
218                         handler.paused = false;
219                 end
220         end
221         handler.ip = function( )
222                 return ip
223         end
224         handler.serverport = function( )
225                 return serverport
226         end
227         handler.socket = function( )
228                 return socket
229         end
230         handler.readbuffer = function( )
231                 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
232                         handler.pause( )
233                         out_put( "server.lua: refused new client connection: server full" )
234                         return false
235                 end
236                 local client, err = accept( socket )    -- try to accept
237                 if client then
238                         local ip, clientport = client:getpeername( )
239                         local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
240                         if err then -- error while wrapping ssl socket
241                                 return false
242                         end
243                         connections = connections + 1
244                         out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
245                         if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes
246                                 return dispatch( handler );
247                         end
248                         return;
249                 elseif err then -- maybe timeout or something else
250                         out_put( "server.lua: error with new client connection: ", tostring(err) )
251                         return false
252                 end
253         end
254         return handler
255 end
256
257 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object
258
259         if socket:getfd() >= _maxfd then
260                 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
261                 socket:close( ) -- Should we send some kind of error here?
262                 if server then
263                         server.pause( )
264                 end
265                 return nil, nil, "fd-too-large"
266         end
267         socket:settimeout( 0 )
268
269         --// local import of socket methods //--
270
271         local send
272         local receive
273         local shutdown
274
275         --// private closures of the object //--
276
277         local ssl
278
279         local dispatch = listeners.onincoming
280         local status = listeners.onstatus
281         local disconnect = listeners.ondisconnect
282         local drain = listeners.ondrain
283         local onreadtimeout = listeners.onreadtimeout;
284         local detach = listeners.ondetach
285
286         local bufferqueue = { } -- buffer array
287         local bufferqueuelen = 0        -- end of buffer array
288
289         local toclose
290         local fatalerror
291         local needtls
292
293         local bufferlen = 0
294
295         local noread = false
296         local nosend = false
297
298         local sendtraffic, readtraffic = 0, 0
299
300         local maxsendlen = _maxsendlen
301         local maxreadlen = _maxreadlen
302
303         --// public methods of the object //--
304
305         local handler = bufferqueue -- saves a table ^_^
306
307         handler.dispatch = function( )
308                 return dispatch
309         end
310         handler.disconnect = function( )
311                 return disconnect
312         end
313         handler.onreadtimeout = onreadtimeout;
314
315         handler.setlistener = function( self, listeners )
316                 if detach then
317                         detach(self) -- Notify listener that it is no longer responsible for this connection
318                 end
319                 dispatch = listeners.onincoming
320                 disconnect = listeners.ondisconnect
321                 status = listeners.onstatus
322                 drain = listeners.ondrain
323                 handler.onreadtimeout = listeners.onreadtimeout
324                 detach = listeners.ondetach
325         end
326         handler.getstats = function( )
327                 return readtraffic, sendtraffic
328         end
329         handler.ssl = function( )
330                 return ssl
331         end
332         handler.sslctx = function ( )
333                 return sslctx
334         end
335         handler.send = function( _, data, i, j )
336                 return send( socket, data, i, j )
337         end
338         handler.receive = function( pattern, prefix )
339                 return receive( socket, pattern, prefix )
340         end
341         handler.shutdown = function( pattern )
342                 return shutdown( socket, pattern )
343         end
344         handler.setoption = function (self, option, value)
345                 if socket.setoption then
346                         return socket:setoption(option, value);
347                 end
348                 return false, "setoption not implemented";
349         end
350         handler.force_close = function ( self, err )
351                 if bufferqueuelen ~= 0 then
352                         out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
353                         bufferqueuelen = 0;
354                 end
355                 return self:close(err);
356         end
357         handler.close = function( self, err )
358                 if not handler then return true; end
359                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
360                 _readtimes[ handler ] = nil
361                 if bufferqueuelen ~= 0 then
362                         handler.sendbuffer() -- Try now to send any outstanding data
363                         if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later
364                                 if handler then
365                                         handler.write = nil -- ... but no further writing allowed
366                                 end
367                                 toclose = true
368                                 return false
369                         end
370                 end
371                 if socket then
372                         _ = shutdown and shutdown( socket )
373                         socket:close( )
374                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
375                         _socketlist[ socket ] = nil
376                         socket = nil
377                 else
378                         out_put "server.lua: socket already closed"
379                 end
380                 if handler then
381                         _writetimes[ handler ] = nil
382                         _closelist[ handler ] = nil
383                         local _handler = handler;
384                         handler = nil
385                         if disconnect then
386                                 disconnect(_handler, err or false);
387                                 disconnect = nil
388                         end
389                 end
390                 if server then
391                         server.remove( )
392                 end
393                 out_put "server.lua: closed client handler and removed socket from list"
394                 return true
395         end
396         handler.ip = function( )
397                 return ip
398         end
399         handler.serverport = function( )
400                 return serverport
401         end
402         handler.clientport = function( )
403                 return clientport
404         end
405         handler.port = handler.clientport -- COMPAT server_event
406         local write = function( self, data )
407                 bufferlen = bufferlen + #data
408                 if bufferlen > maxsendlen then
409                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
410                         handler.write = idfalse -- dont write anymore
411                         return false
412                 elseif socket and not _sendlist[ socket ] then
413                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
414                 end
415                 bufferqueuelen = bufferqueuelen + 1
416                 bufferqueue[ bufferqueuelen ] = data
417                 if handler then
418                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
419                 end
420                 return true
421         end
422         handler.write = write
423         handler.bufferqueue = function( self )
424                 return bufferqueue
425         end
426         handler.socket = function( self )
427                 return socket
428         end
429         handler.set_mode = function( self, new )
430                 pattern = new or pattern
431                 return pattern
432         end
433         handler.set_send = function ( self, newsend )
434                 send = newsend or send
435                 return send
436         end
437         handler.bufferlen = function( self, readlen, sendlen )
438                 maxsendlen = sendlen or maxsendlen
439                 maxreadlen = readlen or maxreadlen
440                 return bufferlen, maxreadlen, maxsendlen
441         end
442         --TODO: Deprecate
443         handler.lock_read = function (self, switch)
444                 if switch == true then
445                         local tmp = _readlistlen
446                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
447                         _readtimes[ handler ] = nil
448                         if _readlistlen ~= tmp then
449                                 noread = true
450                         end
451                 elseif switch == false then
452                         if noread then
453                                 noread = false
454                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
455                                 _readtimes[ handler ] = _currenttime
456                         end
457                 end
458                 return noread
459         end
460         handler.pause = function (self)
461                 return self:lock_read(true);
462         end
463         handler.resume = function (self)
464                 return self:lock_read(false);
465         end
466         handler.lock = function( self, switch )
467                 handler.lock_read (switch)
468                 if switch == true then
469                         handler.write = idfalse
470                         local tmp = _sendlistlen
471                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
472                         _writetimes[ handler ] = nil
473                         if _sendlistlen ~= tmp then
474                                 nosend = true
475                         end
476                 elseif switch == false then
477                         handler.write = write
478                         if nosend then
479                                 nosend = false
480                                 write( "" )
481                         end
482                 end
483                 return noread, nosend
484         end
485         local _readbuffer = function( ) -- this function reads data
486                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
487                 if not err or (err == "wantread" or err == "timeout") then -- received something
488                         local buffer = buffer or part or ""
489                         local len = #buffer
490                         if len > maxreadlen then
491                                 handler:close( "receive buffer exceeded" )
492                                 return false
493                         end
494                         local count = len * STAT_UNIT
495                         readtraffic = readtraffic + count
496                         _readtraffic = _readtraffic + count
497                         _readtimes[ handler ] = _currenttime
498                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
499                         return dispatch( handler, buffer, err )
500                 else    -- connections was closed or fatal error
501                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
502                         fatalerror = true
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                         fatalerror = true
543                         _ = handler and handler:force_close( err )
544                         return false
545                 end
546         end
547
548         -- Set the sslctx
549         local handshake;
550         function handler.set_sslctx(self, new_sslctx)
551                 sslctx = new_sslctx;
552                 local read, wrote
553                 handshake = coroutine_wrap( function( client ) -- create handshake coroutine
554                                 local err
555                                 for i = 1, _maxsslhandshake do
556                                         _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
557                                         _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
558                                         read, wrote = nil, nil
559                                         _, err = client:dohandshake( )
560                                         if not err then
561                                                 out_put( "server.lua: ssl handshake done" )
562                                                 handler.readbuffer = _readbuffer        -- when handshake is done, replace the handshake function with regular functions
563                                                 handler.sendbuffer = _sendbuffer
564                                                 _ = status and status( handler, "ssl-handshake-complete" )
565                                                 if self.autostart_ssl and listeners.onconnect then
566                                                         listeners.onconnect(self);
567                                                         if bufferqueuelen ~= 0 then
568                                                                 _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
569                                                         end
570                                                 end
571                                                 _readlistlen = addsocket(_readlist, client, _readlistlen)
572                                                 return true
573                                         else
574                                                 if err == "wantwrite" then
575                                                         _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
576                                                         wrote = true
577                                                 elseif err == "wantread" then
578                                                         _readlistlen = addsocket(_readlist, client, _readlistlen)
579                                                         read = true
580                                                 else
581                                                         break;
582                                                 end
583                                                 err = nil;
584                                                 coroutine_yield( ) -- handshake not finished
585                                         end
586                                 end
587                                 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
588                                 _ = handler and handler:force_close("ssl handshake failed")
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         return "quitting"
942 end
943
944 local function step()
945         return loop(true);
946 end
947
948 local function get_backend()
949         return "select";
950 end
951
952 --// EXPERIMENTAL //--
953
954 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
955         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
956         if not handler then return nil, err end
957         _socketlist[ socket ] = handler
958         if not sslctx then
959                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
960                 if listeners.onconnect then
961                         -- When socket is writeable, call onconnect
962                         local _sendbuffer = handler.sendbuffer;
963                         handler.sendbuffer = function ()
964                                 handler.sendbuffer = _sendbuffer;
965                                 listeners.onconnect(handler);
966                                 return _sendbuffer(); -- Send any queued outgoing data
967                         end
968                 end
969         end
970         return handler, socket
971 end
972
973 local addclient = function( address, port, listeners, pattern, sslctx, typ )
974         local err
975         if type( listeners ) ~= "table" then
976                 err = "invalid listener table"
977         elseif type ( address ) ~= "string" then
978                 err = "invalid address"
979         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
980                 err = "invalid port"
981         elseif sslctx and not has_luasec then
982                 err = "luasec not found"
983         end
984         if getaddrinfo and not typ then
985                 local addrinfo, err = getaddrinfo(address)
986                 if not addrinfo then return nil, err end
987                 if addrinfo[1] and addrinfo[1].family == "inet6" then
988                         typ = "tcp6"
989                 end
990         end
991         local create = luasocket[typ or "tcp"]
992         if type( create ) ~= "function"  then
993                 err = "invalid socket type"
994         end
995
996         if err then
997                 out_error( "server.lua, addclient: ", err )
998                 return nil, err
999         end
1000
1001         local client, err = create( )
1002         if err then
1003                 return nil, err
1004         end
1005         client:settimeout( 0 )
1006         local ok, err = client:connect( address, port )
1007         if ok or err == "timeout" or err == "Operation already in progress" then
1008                 return wrapclient( client, address, port, listeners, pattern, sslctx )
1009         else
1010                 return nil, err
1011         end
1012 end
1013
1014 --// EXPERIMENTAL //--
1015
1016 ----------------------------------// BEGIN //--
1017
1018 use "setmetatable" ( _socketlist, { __mode = "k" } )
1019 use "setmetatable" ( _readtimes, { __mode = "k" } )
1020 use "setmetatable" ( _writetimes, { __mode = "k" } )
1021
1022 _starttime = luasocket_gettime( )
1023
1024 local function setlogger(new_logger)
1025         local old_logger = log;
1026         if new_logger then
1027                 log = new_logger;
1028         end
1029         return old_logger;
1030 end
1031
1032 ----------------------------------// PUBLIC INTERFACE //--
1033
1034 return {
1035         _addtimer = addtimer,
1036         add_task = add_task;
1037
1038         addclient = addclient,
1039         wrapclient = wrapclient,
1040
1041         loop = loop,
1042         link = link,
1043         step = step,
1044         stats = stats,
1045         closeall = closeall,
1046         addserver = addserver,
1047         getserver = getserver,
1048         setlogger = setlogger,
1049         getsettings = getsettings,
1050         setquitting = setquitting,
1051         removeserver = removeserver,
1052         get_backend = get_backend,
1053         changesettings = changesettings,
1054 }