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