Changeset

7104:352270bc0439 0.9.10

Merge
author Kim Alvefur <zash@zash.se>
date Wed, 27 Jan 2016 00:06:30 +0100
parents 7100:301d58705667 (diff) 7103:5c6e78dc1864 (current diff)
children 7105:01bd0ac9cf0c
files
diffstat 6 files changed, 50 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/net/dns.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/net/dns.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -763,16 +763,16 @@
 	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;
--- a/net/server.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/net/server.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -50,7 +50,7 @@
 		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;
--- a/net/server_select.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/net/server_select.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -88,6 +88,7 @@
 local _closelist
 local _readtimes
 local _writetimes
+local _fullservers
 
 --// simple data types //--
 
@@ -102,6 +103,7 @@
 local _selecttimeout
 local _sleeptime
 local _tcpbacklog
+local _accepretry
 
 local _starttime
 local _currenttime
@@ -130,6 +132,7 @@
 _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
@@ -141,6 +144,7 @@
 _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
@@ -209,6 +213,7 @@
 				socket = nil;
 			end
 			handler.paused = true;
+			out_put("server.lua: server [", ip, "]:", serverport, " paused")
 		end
 	end
 	handler.resume = function( )
@@ -219,7 +224,9 @@
 			end
 			_readlistlen = addsocket(_readlist, socket, _readlistlen)
 			_socketlist[ socket ] = handler
+			_fullservers[ handler ] = nil
 			handler.paused = false;
+			out_put("server.lua: server [", ip, "]:", serverport, " resumed")
 		end
 	end
 	handler.ip = function( )
@@ -234,6 +241,7 @@
 	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
@@ -252,6 +260,8 @@
 			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
@@ -264,6 +274,7 @@
 		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"
@@ -793,6 +804,7 @@
 		max_connections = _maxselectlen;
 		max_ssl_handshake_roundtrips = _maxsslhandshake;
 		highest_allowed_fd = _maxfd;
+		accept_retry_interval = _accepretry;
 	}
 end
 
@@ -808,6 +820,7 @@
 	_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
@@ -896,6 +909,13 @@
 			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;
--- a/plugins/mod_c2s.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/plugins/mod_c2s.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -275,7 +275,7 @@
 	for _, session in pairs(sessions) do
 		session:close{ condition = "system-shutdown", text = reason };
 	end
-end, 1000);
+end, -100);
 
 
 
--- a/plugins/mod_s2s/mod_s2s.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/plugins/mod_s2s/mod_s2s.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -671,7 +671,7 @@
 	for _, session in pairs(sessions) do
 		session:close{ condition = "system-shutdown", text = reason };
 	end
-end,500);
+end, -200);
 
 
 
--- a/plugins/mod_s2s/s2sout.lib.lua	Tue Jan 19 21:31:02 2016 +0100
+++ b/plugins/mod_s2s/s2sout.lib.lua	Wed Jan 27 00:06:30 2016 +0100
@@ -18,31 +18,13 @@
 local adns = require "net.adns";
 local dns = require "net.dns";
 local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs;
+local local_addresses = require "util.net".local_addresses;
 
 local s2s_destroy_session = require "core.s2smanager".destroy_session;
 
 local log = module._log;
 
-local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" };
-local function get_sources(addrs)
-	local sources = {};
-	for _, IP in ipairs(addrs) do
-		local sock;
-		if IP.proto == "IPv4" then
-			sock = socket.udp();
-		elseif IP.proto == "IPv6" then
-			sock = socket.udp6();
-		end
-		sock:setpeername(IP.addr, 9);
-		local localaddr = sock:getsockname() or anysource[IP.proto];
-		sock:close();
-		if not sources[localaddr] then
-			sources[localaddr] = true;
-			t_insert(sources, new_ip(localaddr, IP.proto));
-		end
-	end
-	return sources;
-end
+local sources = {};
 local has_ipv4, has_ipv6;
 
 local dns_timeout = module:get_option_number("dns_timeout", 15);
@@ -195,7 +177,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
+						rfc6724_dest(host_session.ip_hosts, sources);
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
@@ -231,7 +213,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
+						rfc6724_dest(host_session.ip_hosts, sources);
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
@@ -333,12 +315,28 @@
 		return;
 	end
 	for source, _ in pairs(s2s_sources) do
-		if source:find(":") then
+		if source == "*" or source == "0.0.0.0" then
+			for _, addr in ipairs(local_addresses("ipv4", true)) do
+				sources[#sources + 1] = new_ip(addr, "IPv4");
+			end
+		elseif source == "::" then
+			for _, addr in ipairs(local_addresses("ipv6", true)) do
+				sources[#sources + 1] = new_ip(addr, "IPv6");
+			end
+		else
+			sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4");
+		end
+	end
+	for i = 1,#sources do
+		if sources[i].proto == "IPv6" then
 			has_ipv6 = true;
-		else
+		elseif sources[i].proto == "IPv4" then
 			has_ipv4 = true;
 		end
 	end
+	if not (has_ipv4 or has_ipv6)  then
+		module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail");
+	end
 end);
 
 return s2sout;