mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses
authorKim Alvefur <zash@zash.se>
Wed, 13 May 2015 21:47:39 +0200
changeset 6685 63f5870f9afe
parent 6684 0217a04722c7
child 6686 873ad1023eb0
mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses
plugins/mod_s2s/s2sout.lib.lua
--- a/plugins/mod_s2s/s2sout.lib.lua	Wed May 13 21:44:13 2015 +0200
+++ b/plugins/mod_s2s/s2sout.lib.lua	Wed May 13 21:47:39 2015 +0200
@@ -18,13 +18,31 @@
 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 sources = {};
+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 has_ipv4, has_ipv6;
 
 local dns_timeout = module:get_option_number("dns_timeout", 15);
@@ -177,7 +195,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc6724_dest(host_session.ip_hosts, sources);
+						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
@@ -213,7 +231,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc6724_dest(host_session.ip_hosts, sources);
+						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
@@ -315,28 +333,12 @@
 		return;
 	end
 	for source, _ in pairs(s2s_sources) do
-		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
+		if source:find(":") then
+			has_ipv6 = true;
 		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;
-		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;