net/server_*: Fix addclient: LuaSocket 3.0-rc1 sometimes returns EALREADY instead...
[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         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                                                 end
568                                                 _readlistlen = addsocket(_readlist, client, _readlistlen)
569                                                 return true
570                                         else
571                                                 if err == "wantwrite" then
572                                                         _sendlistlen = addsocket(_sendlist, client, _sendlistlen)
573                                                         wrote = true
574                                                 elseif err == "wantread" then
575                                                         _readlistlen = addsocket(_readlist, client, _readlistlen)
576                                                         read = true
577                                                 else
578                                                         break;
579                                                 end
580                                                 err = nil;
581                                                 coroutine_yield( ) -- handshake not finished
582                                         end
583                                 end
584                                 out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
585                                 _ = handler and handler:force_close("ssl handshake failed")
586                                 return false, err -- handshake failed
587                         end
588                 )
589         end
590         if has_luasec then
591                 handler.starttls = function( self, _sslctx)
592                         if _sslctx then
593                                 handler:set_sslctx(_sslctx);
594                         end
595                         if bufferqueuelen > 0 then
596                                 out_put "server.lua: we need to do tls, but delaying until send buffer empty"
597                                 needtls = true
598                                 return
599                         end
600                         out_put( "server.lua: attempting to start tls on " .. tostring( socket ) )
601                         local oldsocket, err = socket
602                         socket, err = ssl_wrap( socket, sslctx )        -- wrap socket
603                         if not socket then
604                                 out_put( "server.lua: error while starting tls on client: ", tostring(err or "unknown error") )
605                                 return nil, err -- fatal error
606                         end
607
608                         socket:settimeout( 0 )
609
610                         -- add the new socket to our system
611                         send = socket.send
612                         receive = socket.receive
613                         shutdown = id
614                         _socketlist[ socket ] = handler
615                         _readlistlen = addsocket(_readlist, socket, _readlistlen)
616
617                         -- remove traces of the old socket
618                         _readlistlen = removesocket( _readlist, oldsocket, _readlistlen )
619                         _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen )
620                         _socketlist[ oldsocket ] = nil
621
622                         handler.starttls = nil
623                         needtls = nil
624
625                         -- Secure now (if handshake fails connection will close)
626                         ssl = true
627
628                         handler.readbuffer = handshake
629                         handler.sendbuffer = handshake
630                         return handshake( socket ) -- do handshake
631                 end
632         end
633
634         handler.readbuffer = _readbuffer
635         handler.sendbuffer = _sendbuffer
636         send = socket.send
637         receive = socket.receive
638         shutdown = ( ssl and id ) or socket.shutdown
639
640         _socketlist[ socket ] = handler
641         _readlistlen = addsocket(_readlist, socket, _readlistlen)
642
643         if sslctx and has_luasec then
644                 out_put "server.lua: auto-starting ssl negotiation..."
645                 handler.autostart_ssl = true;
646                 local ok, err = handler:starttls(sslctx);
647                 if ok == false then
648                         return nil, nil, err
649                 end
650         end
651
652         return handler, socket
653 end
654
655 id = function( )
656 end
657
658 idfalse = function( )
659         return false
660 end
661
662 addsocket = function( list, socket, len )
663         if not list[ socket ] then
664                 len = len + 1
665                 list[ len ] = socket
666                 list[ socket ] = len
667         end
668         return len;
669 end
670
671 removesocket = function( list, socket, len )    -- this function removes sockets from a list ( copied from copas )
672         local pos = list[ socket ]
673         if pos then
674                 list[ socket ] = nil
675                 local last = list[ len ]
676                 list[ len ] = nil
677                 if last ~= socket then
678                         list[ last ] = pos
679                         list[ pos ] = last
680                 end
681                 return len - 1
682         end
683         return len
684 end
685
686 closesocket = function( socket )
687         _sendlistlen = removesocket( _sendlist, socket, _sendlistlen )
688         _readlistlen = removesocket( _readlist, socket, _readlistlen )
689         _socketlist[ socket ] = nil
690         socket:close( )
691         --mem_free( )
692 end
693
694 local function link(sender, receiver, buffersize)
695         local sender_locked;
696         local _sendbuffer = receiver.sendbuffer;
697         function receiver.sendbuffer()
698                 _sendbuffer();
699                 if sender_locked and receiver.bufferlen() < buffersize then
700                         sender:lock_read(false); -- Unlock now
701                         sender_locked = nil;
702                 end
703         end
704
705         local _readbuffer = sender.readbuffer;
706         function sender.readbuffer()
707                 _readbuffer();
708                 if not sender_locked and receiver.bufferlen() >= buffersize then
709                         sender_locked = true;
710                         sender:lock_read(true);
711                 end
712         end
713 end
714
715 ----------------------------------// PUBLIC //--
716
717 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server
718         addr = addr or "*"
719         local err
720         if type( listeners ) ~= "table" then
721                 err = "invalid listener table"
722         elseif type ( addr ) ~= "string" then
723                 err = "invalid address"
724         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
725                 err = "invalid port"
726         elseif _server[ addr..":"..port ] then
727                 err = "listeners on '[" .. addr .. "]:" .. port .. "' already exist"
728         elseif sslctx and not has_luasec then
729                 err = "luasec not found"
730         end
731         if err then
732                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
733                 return nil, err
734         end
735         local server, err = socket_bind( addr, port, _tcpbacklog )
736         if err then
737                 out_error( "server.lua, [", addr, "]:", port, ": ", err )
738                 return nil, err
739         end
740         local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket
741         if not handler then
742                 server:close( )
743                 return nil, err
744         end
745         server:settimeout( 0 )
746         _readlistlen = addsocket(_readlist, server, _readlistlen)
747         _server[ addr..":"..port ] = handler
748         _socketlist[ server ] = handler
749         out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" )
750         return handler
751 end
752
753 getserver = function ( addr, port )
754         return _server[ addr..":"..port ];
755 end
756
757 removeserver = function( addr, port )
758         local handler = _server[ addr..":"..port ]
759         if not handler then
760                 return nil, "no server found on '[" .. addr .. "]:" .. tostring( port ) .. "'"
761         end
762         handler:close( )
763         _server[ addr..":"..port ] = nil
764         return true
765 end
766
767 closeall = function( )
768         for _, handler in pairs( _socketlist ) do
769                 handler:close( )
770                 _socketlist[ _ ] = nil
771         end
772         _readlistlen = 0
773         _sendlistlen = 0
774         _timerlistlen = 0
775         _server = { }
776         _readlist = { }
777         _sendlist = { }
778         _timerlist = { }
779         _socketlist = { }
780         --mem_free( )
781 end
782
783 getsettings = function( )
784         return {
785                 select_timeout = _selecttimeout;
786                 select_sleep_time = _sleeptime;
787                 tcp_backlog = _tcpbacklog;
788                 max_send_buffer_size = _maxsendlen;
789                 max_receive_buffer_size = _maxreadlen;
790                 select_idle_check_interval = _checkinterval;
791                 send_timeout = _sendtimeout;
792                 read_timeout = _readtimeout;
793                 max_connections = _maxselectlen;
794                 max_ssl_handshake_roundtrips = _maxsslhandshake;
795                 highest_allowed_fd = _maxfd;
796         }
797 end
798
799 changesettings = function( new )
800         if type( new ) ~= "table" then
801                 return nil, "invalid settings table"
802         end
803         _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout
804         _sleeptime = tonumber( new.select_sleep_time ) or _sleeptime
805         _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen
806         _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen
807         _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval
808         _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
809         _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
810         _readtimeout = tonumber( new.read_timeout ) or _readtimeout
811         _maxselectlen = new.max_connections or _maxselectlen
812         _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
813         _maxfd = new.highest_allowed_fd or _maxfd
814         return true
815 end
816
817 addtimer = function( listener )
818         if type( listener ) ~= "function" then
819                 return nil, "invalid listener function"
820         end
821         _timerlistlen = _timerlistlen + 1
822         _timerlist[ _timerlistlen ] = listener
823         return true
824 end
825
826 stats = function( )
827         return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen
828 end
829
830 local quitting;
831
832 local function setquitting(quit)
833         quitting = not not quit;
834 end
835
836 loop = function(once) -- this is the main loop of the program
837         if quitting then return "quitting"; end
838         if once then quitting = "once"; end
839         local next_timer_time = math_huge;
840         repeat
841                 local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) )
842                 for i, socket in ipairs( write ) do -- send data waiting in writequeues
843                         local handler = _socketlist[ socket ]
844                         if handler then
845                                 handler.sendbuffer( )
846                         else
847                                 closesocket( socket )
848                                 out_put "server.lua: found no handler and closed socket (writelist)"    -- this should not happen
849                         end
850                 end
851                 for i, socket in ipairs( read ) do -- receive data
852                         local handler = _socketlist[ socket ]
853                         if handler then
854                                 handler.readbuffer( )
855                         else
856                                 closesocket( socket )
857                                 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen
858                         end
859                 end
860                 for handler, err in pairs( _closelist ) do
861                         handler.disconnect( )( handler, err )
862                         handler:force_close()    -- forced disconnect
863                         _closelist[ handler ] = nil;
864                 end
865                 _currenttime = luasocket_gettime( )
866
867                 -- Check for socket timeouts
868                 local difftime = os_difftime( _currenttime - _starttime )
869                 if difftime > _checkinterval then
870                         _starttime = _currenttime
871                         for handler, timestamp in pairs( _writetimes ) do
872                                 if os_difftime( _currenttime - timestamp ) > _sendtimeout then
873                                         handler.disconnect( )( handler, "send timeout" )
874                                         handler:force_close()    -- forced disconnect
875                                 end
876                         end
877                         for handler, timestamp in pairs( _readtimes ) do
878                                 if os_difftime( _currenttime - timestamp ) > _readtimeout then
879                                         if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
880                                                 handler.disconnect( )( handler, "read timeout" )
881                                                 handler:close( )        -- forced disconnect?
882                                         end
883                                 end
884                         end
885                 end
886
887                 -- Fire timers
888                 if _currenttime - _timer >= math_min(next_timer_time, 1) then
889                         next_timer_time = math_huge;
890                         for i = 1, _timerlistlen do
891                                 local t = _timerlist[ i ]( _currenttime ) -- fire timers
892                                 if t then next_timer_time = math_min(next_timer_time, t); end
893                         end
894                         _timer = _currenttime
895                 else
896                         next_timer_time = next_timer_time - (_currenttime - _timer);
897                 end
898
899                 -- wait some time (0 by default)
900                 socket_sleep( _sleeptime )
901         until quitting;
902         if once and quitting == "once" then quitting = nil; return; end
903         return "quitting"
904 end
905
906 local function step()
907         return loop(true);
908 end
909
910 local function get_backend()
911         return "select";
912 end
913
914 --// EXPERIMENTAL //--
915
916 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx )
917         local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx )
918         if not handler then return nil, err end
919         _socketlist[ socket ] = handler
920         if not sslctx then
921                 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
922                 if listeners.onconnect then
923                         -- When socket is writeable, call onconnect
924                         local _sendbuffer = handler.sendbuffer;
925                         handler.sendbuffer = function ()
926                                 handler.sendbuffer = _sendbuffer;
927                                 listeners.onconnect(handler);
928                                 return _sendbuffer(); -- Send any queued outgoing data
929                         end
930                 end
931         end
932         return handler, socket
933 end
934
935 local addclient = function( address, port, listeners, pattern, sslctx, typ )
936         local err
937         if type( listeners ) ~= "table" then
938                 err = "invalid listener table"
939         elseif type ( address ) ~= "string" then
940                 err = "invalid address"
941         elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then
942                 err = "invalid port"
943         elseif sslctx and not has_luasec then
944                 err = "luasec not found"
945         end
946         if getaddrinfo and not typ then
947                 local addrinfo, err = getaddrinfo(address)
948                 if not addrinfo then return nil, err end
949                 if addrinfo[1] and addrinfo[1].family == "inet6" then
950                         typ = "tcp6"
951                 end
952         end
953         local create = luasocket[typ or "tcp"]
954         if type( create ) ~= "function"  then
955                 err = "invalid socket type"
956         end
957
958         if err then
959                 out_error( "server.lua, addclient: ", err )
960                 return nil, err
961         end
962
963         local client, err = create( )
964         if err then
965                 return nil, err
966         end
967         client:settimeout( 0 )
968         local ok, err = client:connect( address, port )
969         if ok or err == "timeout" or err == "Operation already in progress" then
970                 return wrapclient( client, address, port, listeners, pattern, sslctx )
971         else
972                 return nil, err
973         end
974 end
975
976 --// EXPERIMENTAL //--
977
978 ----------------------------------// BEGIN //--
979
980 use "setmetatable" ( _socketlist, { __mode = "k" } )
981 use "setmetatable" ( _readtimes, { __mode = "k" } )
982 use "setmetatable" ( _writetimes, { __mode = "k" } )
983
984 _timer = luasocket_gettime( )
985 _starttime = luasocket_gettime( )
986
987 local function setlogger(new_logger)
988         local old_logger = log;
989         if new_logger then
990                 log = new_logger;
991         end
992         return old_logger;
993 end
994
995 ----------------------------------// PUBLIC INTERFACE //--
996
997 return {
998         _addtimer = addtimer,
999
1000         addclient = addclient,
1001         wrapclient = wrapclient,
1002
1003         loop = loop,
1004         link = link,
1005         step = step,
1006         stats = stats,
1007         closeall = closeall,
1008         addserver = addserver,
1009         getserver = getserver,
1010         setlogger = setlogger,
1011         getsettings = getsettings,
1012         setquitting = setquitting,
1013         removeserver = removeserver,
1014         get_backend = get_backend,
1015         changesettings = changesettings,
1016 }