From 2c31800ffd75921d142bceeb654b463b1c99b08f Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Thu, 21 Jan 2016 22:26:46 +0100
Subject: net.dns: Remember query only after it was sent, in case it was not
 (fixes #598)

---
 net/dns.lua | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'net')

diff --git a/net/dns.lua b/net/dns.lua
index f56157d0..d123731c 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -763,16 +763,16 @@ function resolver:query(qname, qtype, qclass)    -- - - - - - - - - - -- query
 	self.active[id] = self.active[id] or {};
 	self.active[id][question] = o;
 
-	-- remember which coroutine wants the answer
-	if co then
-		set(self.wanted, qclass, qtype, qname, co, true);
-	end
-
 	local conn, err = self:getsocket(o.server)
 	if not conn then
 		return nil, err;
 	end
 	conn:send (o.packet)
+
+	-- remember which coroutine wants the answer
+	if co then
+		set(self.wanted, qclass, qtype, qname, co, true);
+	end
 	
 	if timer and self.timeout then
 		local num_servers = #self.server;
-- 
cgit v1.2.3


From f4631dda0590cb3db8c4f0c350b455be8408b52f Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Fri, 22 Jan 2016 01:58:39 +0100
Subject: server_select: Keep track of which server listeners are full

---
 net/server_select.lua | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'net')

diff --git a/net/server_select.lua b/net/server_select.lua
index 7ac41523..0a060c9e 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -88,6 +88,7 @@ local _socketlist
 local _closelist
 local _readtimes
 local _writetimes
+local _fullservers
 
 --// simple data types //--
 
@@ -130,6 +131,7 @@ _socketlist = { } -- key = socket, value = wrapped socket (handlers)
 _readtimes = { } -- key = handler, value = timestamp of last data reading
 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
 _closelist = { } -- handlers to close
+_fullservers = { } -- servers in a paused state while there are too many clients
 
 _readlistlen = 0 -- length of readlist
 _sendlistlen = 0 -- length of sendlist
@@ -219,6 +221,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
 			end
 			_readlistlen = addsocket(_readlist, socket, _readlistlen)
 			_socketlist[ socket ] = handler
+			_fullservers[ handler ] = nil
 			handler.paused = false;
 		end
 	end
@@ -234,6 +237,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
 	handler.readbuffer = function( )
 		if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
 			handler.pause( )
+			_fullservers[ handler ] = _currenttime
 			out_put( "server.lua: refused new client connection: server full" )
 			return false
 		end
@@ -264,6 +268,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
 		out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
 		socket:close( ) -- Should we send some kind of error here?
 		if server then
+			_fullservers[ server ] = _currenttime
 			server.pause( )
 		end
 		return nil, nil, "fd-too-large"
-- 
cgit v1.2.3


From 773269db7c0f608adeec17ec9376d77d4ccfe935 Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Fri, 22 Jan 2016 01:59:25 +0100
Subject: server_select: Retry accepting clients from full servers after 10s
 (matches libevent behaviour)

---
 net/server.lua        |  2 +-
 net/server_select.lua | 11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

(limited to 'net')

diff --git a/net/server.lua b/net/server.lua
index 375e7081..9b0d27e1 100644
--- a/net/server.lua
+++ b/net/server.lua
@@ -50,7 +50,7 @@ if prosody then
 		local settings = config_get("*", "network_settings") or {};
 		if use_luaevent then
 			local event_settings = {
-				ACCEPT_DELAY = settings.event_accept_retry_interval;
+				ACCEPT_DELAY = settings.accept_retry_interval;
 				ACCEPT_QUEUE = settings.tcp_backlog;
 				CLEAR_DELAY = settings.event_clear_interval;
 				CONNECT_TIMEOUT = settings.connect_timeout;
diff --git a/net/server_select.lua b/net/server_select.lua
index 0a060c9e..f9d8dba1 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -103,6 +103,7 @@ local _readtraffic
 local _selecttimeout
 local _sleeptime
 local _tcpbacklog
+local _accepretry
 
 local _starttime
 local _currenttime
@@ -143,6 +144,7 @@ _readtraffic = 0
 _selecttimeout = 1 -- timeout of socket.select
 _sleeptime = 0 -- time to wait at the end of every loop
 _tcpbacklog = 128 -- some kind of hint to the OS
+_accepretry = 10 -- seconds to wait until the next attempt of a full server to accept
 
 _maxsendlen = 51000 * 1024 -- max len of send buffer
 _maxreadlen = 25000 * 1024 -- max len of read buffer
@@ -798,6 +800,7 @@ getsettings = function( )
 		max_connections = _maxselectlen;
 		max_ssl_handshake_roundtrips = _maxsslhandshake;
 		highest_allowed_fd = _maxfd;
+		accept_retry_interval = _accepretry;
 	}
 end
 
@@ -813,6 +816,7 @@ changesettings = function( new )
 	_tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
 	_sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
 	_readtimeout = tonumber( new.read_timeout ) or _readtimeout
+	_accepretry = tonumber( new.accept_retry_interval ) or _accepretry
 	_maxselectlen = new.max_connections or _maxselectlen
 	_maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
 	_maxfd = new.highest_allowed_fd or _maxfd
@@ -901,6 +905,13 @@ loop = function(once) -- this is the main loop of the program
 			next_timer_time = next_timer_time - (_currenttime - _timer);
 		end
 
+		for server, paused_time in pairs( _fullservers ) do
+			if _currenttime - paused_time > _accepretry then
+				_fullservers[ server ] = nil;
+				server.resume();
+			end
+		end
+
 		-- wait some time (0 by default)
 		socket_sleep( _sleeptime )
 	until quitting;
-- 
cgit v1.2.3


From 1b285192b284aa72cc0cbe468455252183510763 Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Fri, 22 Jan 2016 02:00:27 +0100
Subject: server_select: Pause and mark server as full if accepting a client
 fails (fixes #597)

---
 net/server_select.lua | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'net')

diff --git a/net/server_select.lua b/net/server_select.lua
index f9d8dba1..891151ac 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -258,6 +258,8 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
 			return;
 		elseif err then -- maybe timeout or something else
 			out_put( "server.lua: error with new client connection: ", tostring(err) )
+			handler.pause( )
+			_fullservers[ handler ] = _currenttime
 			return false
 		end
 	end
-- 
cgit v1.2.3


From 48feb105c43a32c3e956ade72946551efed82b93 Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Fri, 22 Jan 2016 02:00:43 +0100
Subject: server_select: Add logging of when servers are paused and resumed

---
 net/server_select.lua | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'net')

diff --git a/net/server_select.lua b/net/server_select.lua
index 891151ac..c50a6ce1 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -213,6 +213,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
 				socket = nil;
 			end
 			handler.paused = true;
+			out_put("server.lua: server [", ip, "]:", serverport, " paused")
 		end
 	end
 	handler.resume = function( )
@@ -225,6 +226,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t
 			_socketlist[ socket ] = handler
 			_fullservers[ handler ] = nil
 			handler.paused = false;
+			out_put("server.lua: server [", ip, "]:", serverport, " resumed")
 		end
 	end
 	handler.ip = function( )
-- 
cgit v1.2.3