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 os = use "os"
35 local table = use "table"
36 local string = use "string"
37 local coroutine = use "coroutine"
38
39 --// lua lib methods //--
40
41 local os_difftime = os.difftime
42 local math_min = math.min
43 local math_huge = math.huge
44 local table_concat = table.concat
45 local string_sub = string.sub
46 local coroutine_wrap = coroutine.wrap
47 local coroutine_yield = coroutine.yield
48
49 --// extern libs //--
50
51 local 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_sleep = luasocket.sleep
61 local socket_select = luasocket.select
62
63 --// functions //--
64
65 local id
66 local loop
67 local stats
68 local idfalse
69 local closeall
70 local addsocket
71 local addserver
72 local addtimer
73 local getserver
74 local wrapserver
75 local getsettings
76 local closesocket
77 local removesocket
78 local removeserver
79 local wrapconnection
80 local changesettings
81
82 --// tables //--
83
84 local _server
85 local _readlist
86 local _timerlist
87 local _sendlist
88 local _socketlist
89 local _closelist
90 local _readtimes
91 local _writetimes
92
93 --// simple data types //--
94
95 local _
96 local _readlistlen
97 local _sendlistlen
98 local _timerlistlen
99
100 local _sendtraffic
101 local _readtraffic
102
103 local _selecttimeout
104 local _sleeptime
105 local _tcpbacklog
106
107 local _starttime
108 local _currenttime
109
110 local _maxsendlen
111 local _maxreadlen
112
113 local _checkinterval
114 local _sendtimeout
115 local _readtimeout
116
117 local _timer
118
119 local _maxselectlen
120 local _maxfd
121
122 local _maxsslhandshake
123
124 ----------------------------------// DEFINITION //--
125
126 _server = { } -- key = port, value = table; list of listening servers
127 _readlist = { } -- array with sockets to read from
128 _sendlist = { } -- arrary with sockets to write to
129 _timerlist = { } -- array of timer functions
130 _socketlist = { } -- key = socket, value = wrapped socket (handlers)
131 _readtimes = { } -- key = handler, value = timestamp of last data reading
132 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
133 _closelist = { } -- handlers to close
134
135 _readlistlen = 0 -- length of readlist
136 _sendlistlen = 0 -- length of sendlist
137 _timerlistlen = 0 -- lenght of timerlist
138
139 _sendtraffic = 0 -- some stats
140 _readtraffic = 0
141
142 _selecttimeout = 1 -- timeout of socket.select
143 _sleeptime = 0 -- time to wait at the end of every loop
144 _tcpbacklog = 128 -- some kind of hint to the OS
145
146 _maxsendlen = 51000 * 1024 -- max len of send buffer
147 _maxreadlen = 25000 * 1024 -- max len of read buffer
148
149 _checkinterval = 30 -- interval in secs to check idle clients
150 _sendtimeout = 60000 -- allowed send idle time in secs
151 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs
152
153 local is_windows = package.config:sub(1,1) == "\\" -- check the directory separator, to detemine whether this is Windows
154 _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
155 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows
156
157 _maxsslhandshake = 30 -- max handshake round-trips
158
159 ----------------------------------// PRIVATE //--
160
161 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd
162
163         if socket:getfd() >= _maxfd then
164                 out_error("server.lua: Disallowed FD number: "..socket:getfd())
165                 socket:close()
166                 return nil, "fd-too-large"
167         end
168
169         local connections = 0
170
171         local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect
172
173         local accept = socket.accept
174
175         --// public methods of the object //--
176
177         local handler = { }
178
179         handler.shutdown = function( ) end
180
181         handler.ssl = function( )
182                 return sslctx ~= nil
183         end
184         handler.sslctx = function( )
185                 return sslctx
186         end
187         handler.remove = function( )
188                 connections = connections - 1
189                 if handler then
190                         handler.resume( )
191                 end
192         end
193         handler.close = function()
194                 socket:close( )
195                 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
196                 _readlistlen = removesocket( _readlist, socket, _readlistlen )
197                 _server[ip..":"..serverport] = nil;
198                 _socketlist[ socket ] = nil
199                 handler = nil
200                 socket = nil
201                 --mem_free( )
202                 out_put "server.lua: closed server handler and removed sockets from list"
203         end
204         handler.pause = function( hard )
205                 if not handler.paused then
206                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
207                         if hard then
208                                 _socketlist[ socket ] = nil
209                                 socket:close( )
210                                 socket = nil;
211                         end
212                         handler.paused = true;
213                 end
214         end
215         handler.resume = function( )
216                 if handler.paused then
217                         if not socket then
218                                 socket = socket_bind( ip, serverport, _tcpbacklog );
219                                 socket:settimeout( 0 )
220                         end
221                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
222                         _socketlist[ socket ] = handler
223                         handler.paused = false;
224                 end
225         end
226         handler.ip = function( )
227                 return ip
228         end
229         handler.serverport = function( )
230                 return serverport
231         end
232         handler.socket = function( )
233                 return socket
234         end
235         handler.readbuffer = function( )
236                 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
237                         handler.pause( )
238                         out_put( "server.lua: refused new client connection: server full" )
239                         return false
240                 end
241                 local client, err = accept( socket )    -- try to accept
242                 if client then
243                         local ip, clientport = client:getpeername( )
244                         local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
245                         if err then -- error while wrapping ssl socket
246                                 return false
247                         end
248                         connections = connections + 1
249                         out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport))
250                         if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes
251                                 return dispatch( handler );
252                         end
253                         return;
254                 elseif err then -- maybe timeout or something else
255                         out_put( "server.lua: error with new client connection: ", tostring(err) )
256                         return false
257                 end
258         end
259         return handler
260 end
261
262 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object
263
264         if socket:getfd() >= _maxfd then
265                 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
266                 socket:close( ) -- Should we send some kind of error here?
267                 if server then
268                         server.pause( )
269                 end
270                 return nil, nil, "fd-too-large"
271         end
272         socket:settimeout( 0 )
273
274         --// local import of socket methods //--
275
276         local send
277         local receive
278         local shutdown
279
280         --// private closures of the object //--
281
282         local ssl
283
284         local dispatch = listeners.onincoming
285         local status = listeners.onstatus
286         local disconnect = listeners.ondisconnect
287         local drain = listeners.ondrain
288         local onreadtimeout = listeners.onreadtimeout;
289
290         local bufferqueue = { } -- buffer array
291         local bufferqueuelen = 0        -- end of buffer array
292
293         local toclose
294         local fatalerror
295         local needtls
296
297         local bufferlen = 0
298
299         local noread = false
300         local nosend = false
301
302         local sendtraffic, readtraffic = 0, 0
303
304         local maxsendlen = _maxsendlen
305         local maxreadlen = _maxreadlen
306
307         --// public methods of the object //--
308
309         local handler = bufferqueue -- saves a table ^_^
310
311         handler.dispatch = function( )
312                 return dispatch
313         end
314         handler.disconnect = function( )
315                 return disconnect
316         end
317         handler.onreadtimeout = onreadtimeout;
318
319         handler.setlistener = function( self, listeners )
320                 dispatch = listeners.onincoming
321                 disconnect = listeners.ondisconnect
322                 status = listeners.onstatus
323                 drain = listeners.ondrain
324                 handler.onreadtimeout = listeners.onreadtimeout
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         local write = function( self, data )
406                 bufferlen = bufferlen + #data
407                 if bufferlen > maxsendlen then
408                         _closelist[ handler ] = "send buffer exceeded"   -- cannot close the client at the moment, have to wait to the end of the cycle
409                         handler.write = idfalse -- dont write anymore
410                         return false
411                 elseif socket and not _sendlist[ socket ] then
412                         _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
413                 end
414                 bufferqueuelen = bufferqueuelen + 1
415                 bufferqueue[ bufferqueuelen ] = data
416                 if handler then
417                         _writetimes[ handler ] = _writetimes[ handler ] or _currenttime
418                 end
419                 return true
420         end
421         handler.write = write
422         handler.bufferqueue = function( self )
423                 return bufferqueue
424         end
425         handler.socket = function( self )
426                 return socket
427         end
428         handler.set_mode = function( self, new )
429                 pattern = new or pattern
430                 return pattern
431         end
432         handler.set_send = function ( self, newsend )
433                 send = newsend or send
434                 return send
435         end
436         handler.bufferlen = function( self, readlen, sendlen )
437                 maxsendlen = sendlen or maxsendlen
438                 maxreadlen = readlen or maxreadlen
439                 return bufferlen, maxreadlen, maxsendlen
440         end
441         --TODO: Deprecate
442         handler.lock_read = function (self, switch)
443                 if switch == true then
444                         local tmp = _readlistlen
445                         _readlistlen = removesocket( _readlist, socket, _readlistlen )
446                         _readtimes[ handler ] = nil
447                         if _readlistlen ~= tmp then
448                                 noread = true
449                         end
450                 elseif switch == false then
451                         if noread then
452                                 noread = false
453                                 _readlistlen = addsocket(_readlist, socket, _readlistlen)
454                                 _readtimes[ handler ] = _currenttime
455                         end
456                 end
457                 return noread
458         end
459         handler.pause = function (self)
460                 return self:lock_read(true);
461         end
462         handler.resume = function (self)
463                 return self:lock_read(false);
464         end
465         handler.lock = function( self, switch )
466                 handler.lock_read (switch)
467                 if switch == true then
468                         handler.write = idfalse
469                         local tmp = _sendlistlen
470                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
471                         _writetimes[ handler ] = nil
472                         if _sendlistlen ~= tmp then
473                                 nosend = true
474                         end
475                 elseif switch == false then
476                         handler.write = write
477                         if nosend then
478                                 nosend = false
479                                 write( "" )
480                         end
481                 end
482                 return noread, nosend
483         end
484         local _readbuffer = function( ) -- this function reads data
485                 local buffer, err, part = receive( socket, pattern )    -- receive buffer with "pattern"
486                 if not err or (err == "wantread" or err == "timeout") then -- received something
487                         local buffer = buffer or part or ""
488                         local len = #buffer
489                         if len > maxreadlen then
490                                 handler:close( "receive buffer exceeded" )
491                                 return false
492                         end
493                         local count = len * STAT_UNIT
494                         readtraffic = readtraffic + count
495                         _readtraffic = _readtraffic + count
496                         _readtimes[ handler ] = _currenttime
497                         --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
498                         return dispatch( handler, buffer, err )
499                 else    -- connections was closed or fatal error
500                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
501                         fatalerror = true
502                         _ = handler and handler:force_close( err )
503                         return false
504                 end
505         end
506         local _sendbuffer = function( ) -- this function sends data
507                 local succ, err, byte, buffer, count;
508                 if socket then
509                         buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
510                         succ, err, byte = send( socket, buffer, 1, bufferlen )
511                         count = ( succ or byte or 0 ) * STAT_UNIT
512                         sendtraffic = sendtraffic + count
513                         _sendtraffic = _sendtraffic + count
514                         for i = bufferqueuelen,1,-1 do
515                                 bufferqueue[ i ] = nil
516                         end
517                         --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
518                 else
519                         succ, err, count = false, "unexpected close", 0;
520                 end
521                 if succ then    -- sending succesful
522                         bufferqueuelen = 0
523                         bufferlen = 0
524                         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist
525                         _writetimes[ handler ] = nil
526                         if drain then
527                                 drain(handler)
528                         end
529                         _ = needtls and handler:starttls(nil)
530                         _ = toclose and handler:force_close( )
531                         return true
532                 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
533                         buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
534                         bufferqueue[ 1 ] = buffer        -- insert new buffer in queue
535                         bufferqueuelen = 1
536                         bufferlen = bufferlen - byte
537                         _writetimes[ handler ] = _currenttime
538                         return true
539                 else    -- connection was closed during sending or fatal error
540                         out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
541                         fatalerror = true
542                         _ = handler and handler:force_close( err )
543                         return false
544                 end
545         end
546
547         -- Set the sslctx
548         local handshake;
549         function handler.set_sslctx(self, new_sslctx)
550                 sslctx = new_sslctx;
551                 local read, wrote
552                 handshake = coroutine_wrap( function( client ) -- create handshake coroutine
553                                 local err
554                                 for i = 1, _maxsslhandshake do
555                                         _sendlistlen = ( wrote and removesocket( _sendlist, client, _sendlistlen ) ) or _sendlistlen
556                                         _readlistlen = ( read and removesocket( _readlist, client, _readlistlen ) ) or _readlistlen
557                                         read, wrote = nil, nil
558                                         _, err = client:dohandshake( )
559                                         if not err then
560                                                 out_put( "server.lua: ssl handshake done" )
561                                                 handler.readbuffer = _readbuffer        -- when handshake is done, replace the handshake function with regular functions
562                                                 handler.sendbuffer = _sendbuffer
563                                                 _ = status and status( handler, "ssl-handshake-complete" )
564                                                 if self.autostart_ssl and listeners.onconnect then
565                                                         listeners.onconnect(self);
566                                                 end
567                                                 _readlistlen = addsocket(_readlist, client, _readlistlen)
568                                                 return true
569                                         else
570                                                 if err == "wantwrite" then
571                                                         _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
572                                                         wrote = true
573                                                 elseif err == "wantread" then
574                                                         _readlistlen = addsocket(_readlist, client, _readlistlen)
575                                                         read = true
576                                                 else
577                                                         break;
578                                                 end
579                                                 err = nil;
580                                                 coroutine_yield( ) -- handshake not finished
581                                         end
582                                 end
583                                 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
584                                 _ = handler and handler:force_close("ssl handshake failed")
585                                 return false, err -- handshake failed
586                         end
587                 )
588         end
589         if 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 end
713
714 ----------------------------------// PUBLIC //--
715
716 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
717         addr = addr or "*"
718         local err
719         if type( listeners ) ~= "table" then
720                 err = "invalid listener table"
721         elseif type ( addr ) ~= "string" then
722                 err = "invalid address"
723         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
724                 err = "invalid port"
725         elseif _server[ addr..":"..port ] then
726                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
727         elseif sslctx and not has_luasec then
728                 err = "luasec not found"
729         end
730         if err then
731                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
732                 return nil, err
733         end
734         local server, err = socket_bind( addr, port, _tcpbacklog )
735         if err then
736                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
737                 return nil, err
738         end
739         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
740         if not handler then
741                 server:close( )
742                 return nil, err
743         end
744         server:settimeout( 0 )
745         _readlistlen = addsocket(_readlist, server, _readlistlen)
746         _server[ addr..":"..port ] = handler
747         _socketlist[ server ] = handler
748         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
749         return handler
750 end
751
752 getserver = function ( addr, port )
753         return _server[ addr..":"..port ];
754 end
755
756 removeserver = function( addr, port )
757         local handler = _server[ addr..":"..port ]
758         if not handler then
759                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
760         end
761         handler:close( )
762         _server[ addr..":"..port ] = nil
763         return true
764 end
765
766 closeall = function( )
767         for _, handler in pairs( _socketlist ) do
768                 handler:close( )
769                 _socketlist[ _ ] = nil
770         end
771         _readlistlen = 0
772         _sendlistlen = 0
773         _timerlistlen = 0
774         _server = { }
775         _readlist = { }
776         _sendlist = { }
777         _timerlist = { }
778         _socketlist = { }
779         --mem_free( )
780 end
781
782 getsettings = function( )
783         return {
784                 select_timeout = _selecttimeout;
785                 select_sleep_time = _sleeptime;
786                 tcp_backlog = _tcpbacklog;
787                 max_send_buffer_size = _maxsendlen;
788                 max_receive_buffer_size = _maxreadlen;
789                 select_idle_check_interval = _checkinterval;
790                 send_timeout = _sendtimeout;
791                 read_timeout = _readtimeout;
792                 max_connections = _maxselectlen;
793                 max_ssl_handshake_roundtrips = _maxsslhandshake;
794                 highest_allowed_fd = _maxfd;
795         }
796 end
797
798 changesettings = function( new )
799         if type( new ) ~= "table" then
800                 return nil, "invalid settings table"
801         end
802         _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout
803         _sleeptime = tonumber( new.select_sleep_time ) or _sleeptime
804         _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
805         _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
806         _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
807         _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
808         _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
809         _readtimeout = tonumber( new.read_timeout ) or _readtimeout
810         _maxselectlen = new.max_connections or _maxselectlen
811         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
812         _maxfd = new.highest_allowed_fd or _maxfd
813         return true
814 end
815
816 addtimer = function( listener )
817         if type( listener ) ~= "function" then
818                 return nil, "invalid listener function"
819         end
820         _timerlistlen = _timerlistlen + 1
821         _timerlist[ _timerlistlen ] = listener
822         return true
823 end
824
825 stats = function( )
826         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
827 end
828
829 local quitting;
830
831 local function setquitting(quit)
832         quitting = not not quit;
833 end
834
835 loop = function(once) -- this is the main loop of the program
836         if quitting then return "quitting"; end
837         if once then quitting = "once"; end
838         local next_timer_time = math_huge;
839         repeat
840                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
841                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
842                         local handler = _socketlist[ socket ]
843                         if handler then
844                                 handler.sendbuffer( )
845                         else
846                                 closesocket( socket )
847                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
848                         end
849                 end
850                 for i, socket in ipairs( read ) do -- receive data
851                         local handler = _socketlist[ socket ]
852                         if handler then
853                                 handler.readbuffer( )
854                         else
855                                 closesocket( socket )
856                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
857                         end
858                 end
859                 for handler, err in pairs( _closelist ) do
860                         handler.disconnect( )( handler, err )
861                         handler:force_close()    -- forced disconnect
862                         _closelist[ handler ] = nil;
863                 end
864                 _currenttime = luasocket_gettime( )
865
866                 -- Check for socket timeouts
867                 local difftime = os_difftime( _currenttime - _starttime )
868                 if difftime > _checkinterval then
869                         _starttime = _currenttime
870                         for handler, timestamp in pairs( _writetimes ) do
871                                 if os_difftime( _currenttime - timestamp ) > _sendtimeout then
872                                         handler.disconnect( )( handler, "send timeout" )
873                                         handler:force_close()    -- forced disconnect
874                                 end
875                         end
876                         for handler, timestamp in pairs( _readtimes ) do
877                                 if os_difftime( _currenttime - timestamp ) > _readtimeout then
878                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
879                                                 handler.disconnect( )( handler, "read timeout" )
880                                                 handler:close( )        -- forced disconnect?
881                                         end
882                                 end
883                         end
884                 end
885
886                 -- Fire timers
887                 if _currenttime - _timer >= math_min(next_timer_time, 1) then
888                         next_timer_time = math_huge;
889                         for i = 1, _timerlistlen do
890                                 local t = _timerlist[ i ]( _currenttime ) -- fire timers
891                                 if t then next_timer_time = math_min(next_timer_time, t); end
892                         end
893                         _timer = _currenttime
894                 else
895                         next_timer_time = next_timer_time - (_currenttime - _timer);
896                 end
897
898                 -- wait some time (0 by default)
899                 socket_sleep( _sleeptime )
900         until quitting;
901         if once and quitting == "once" then quitting = nil; return; end
902         return "quitting"
903 end
904
905 local function step()
906         return loop(true);
907 end
908
909 local function get_backend()
910         return "select";
911 end
912
913 --// EXPERIMENTAL //--
914
915 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
916         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
917         if not handler then return nil, err end
918         _socketlist[ socket ] = handler
919         if not sslctx then
920                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
921                 if listeners.onconnect then
922                         -- When socket is writeable, call onconnect
923                         local _sendbuffer = handler.sendbuffer;
924                         handler.sendbuffer = function ()
925                                 handler.sendbuffer = _sendbuffer;
926                                 listeners.onconnect(handler);
927                                 return _sendbuffer(); -- Send any queued outgoing data
928                         end
929                 end
930         end
931         return handler, socket
932 end
933
934 local addclient = function( address, port, listeners, pattern, sslctx, typ )
935         local err
936         if type( listeners ) ~= "table" then
937                 err = "invalid listener table"
938         elseif type ( address ) ~= "string" then
939                 err = "invalid address"
940         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
941                 err = "invalid port"
942         elseif sslctx and not has_luasec then
943                 err = "luasec not found"
944         end
945         if getaddrinfo and not typ then
946                 local addrinfo, err = getaddrinfo(address)
947                 if not addrinfo then return nil, err end
948                 if addrinfo[1] and addrinfo[1].family == "inet6" then
949                         typ = "tcp6"
950                 end
951         end
952         local create = luasocket[typ or "tcp"]
953         if type( create ) ~= "function"  then
954                 err = "invalid socket type"
955         end
956
957         if err then
958                 out_error( "server.lua, addclient: ", err )
959                 return nil, err
960         end
961
962         local client, err = create( )
963         if err then
964                 return nil, err
965         end
966         client:settimeout( 0 )
967         local ok, err = client:connect( address, port )
968         if ok or err == "timeout" then
969                 return wrapclient( client, address, port, listeners, pattern, sslctx )
970         else
971                 return nil, err
972         end
973 end
974
975 --// EXPERIMENTAL //--
976
977 ----------------------------------// BEGIN //--
978
979 use "setmetatable" ( _socketlist, { __mode = "k" } )
980 use "setmetatable" ( _readtimes, { __mode = "k" } )
981 use "setmetatable" ( _writetimes, { __mode = "k" } )
982
983 _timer = luasocket_gettime( )
984 _starttime = luasocket_gettime( )
985
986 local function setlogger(new_logger)
987         local old_logger = log;
988         if new_logger then
989                 log = new_logger;
990         end
991         return old_logger;
992 end
993
994 ----------------------------------// PUBLIC INTERFACE //--
995
996 return {
997         _addtimer = addtimer,
998
999         addclient = addclient,
1000         wrapclient = wrapclient,
1001
1002         loop = loop,
1003         link = link,
1004         step = step,
1005         stats = stats,
1006         closeall = closeall,
1007         addserver = addserver,
1008         getserver = getserver,
1009         setlogger = setlogger,
1010         getsettings = getsettings,
1011         setquitting = setquitting,
1012         removeserver = removeserver,
1013         get_backend = get_backend,
1014         changesettings = changesettings,
1015 }