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