plugins/mod_s2s/s2sout.lib.lua
changeset 6685 63f5870f9afe
parent 6683 ae34b12c4335
child 6688 3f05b255937f
child 7095 bee63de49663
equal deleted inserted replaced
6684:0217a04722c7 6685:63f5870f9afe
    16 local rfc6724_dest = require "util.rfc6724".destination;
    16 local rfc6724_dest = require "util.rfc6724".destination;
    17 local socket = require "socket";
    17 local socket = require "socket";
    18 local adns = require "net.adns";
    18 local adns = require "net.adns";
    19 local dns = require "net.dns";
    19 local dns = require "net.dns";
    20 local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs;
    20 local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs;
    21 local local_addresses = require "util.net".local_addresses;
       
    22 
    21 
    23 local s2s_destroy_session = require "core.s2smanager".destroy_session;
    22 local s2s_destroy_session = require "core.s2smanager".destroy_session;
    24 
    23 
    25 local log = module._log;
    24 local log = module._log;
    26 
    25 
    27 local sources = {};
    26 local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" };
       
    27 local function get_sources(addrs)
       
    28 	local sources = {};
       
    29 	for _, IP in ipairs(addrs) do
       
    30 		local sock;
       
    31 		if IP.proto == "IPv4" then
       
    32 			sock = socket.udp();
       
    33 		elseif IP.proto == "IPv6" then
       
    34 			sock = socket.udp6();
       
    35 		end
       
    36 		sock:setpeername(IP.addr, 9);
       
    37 		local localaddr = sock:getsockname() or anysource[IP.proto];
       
    38 		sock:close();
       
    39 		if not sources[localaddr] then
       
    40 			sources[localaddr] = true;
       
    41 			t_insert(sources, new_ip(localaddr, IP.proto));
       
    42 		end
       
    43 	end
       
    44 	return sources;
       
    45 end
    28 local has_ipv4, has_ipv6;
    46 local has_ipv4, has_ipv6;
    29 
    47 
    30 local dns_timeout = module:get_option_number("dns_timeout", 15);
    48 local dns_timeout = module:get_option_number("dns_timeout", 15);
    31 dns.settimeout(dns_timeout);
    49 dns.settimeout(dns_timeout);
    32 
    50 
   175 					end
   193 					end
   176 				end
   194 				end
   177 
   195 
   178 				if have_other_result then
   196 				if have_other_result then
   179 					if #IPs > 0 then
   197 					if #IPs > 0 then
   180 						rfc6724_dest(host_session.ip_hosts, sources);
   198 						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
   181 						for i = 1, #IPs do
   199 						for i = 1, #IPs do
   182 							IPs[i] = {ip = IPs[i], port = connect_port};
   200 							IPs[i] = {ip = IPs[i], port = connect_port};
   183 						end
   201 						end
   184 						host_session.ip_choice = 0;
   202 						host_session.ip_choice = 0;
   185 						s2sout.try_next_ip(host_session);
   203 						s2sout.try_next_ip(host_session);
   211 					end
   229 					end
   212 				end
   230 				end
   213 
   231 
   214 				if have_other_result then
   232 				if have_other_result then
   215 					if #IPs > 0 then
   233 					if #IPs > 0 then
   216 						rfc6724_dest(host_session.ip_hosts, sources);
   234 						rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts));
   217 						for i = 1, #IPs do
   235 						for i = 1, #IPs do
   218 							IPs[i] = {ip = IPs[i], port = connect_port};
   236 							IPs[i] = {ip = IPs[i], port = connect_port};
   219 						end
   237 						end
   220 						host_session.ip_choice = 0;
   238 						host_session.ip_choice = 0;
   221 						s2sout.try_next_ip(host_session);
   239 						s2sout.try_next_ip(host_session);
   313 	if not s2s_sources then
   331 	if not s2s_sources then
   314 		module:log("warn", "s2s not listening on any ports, outgoing connections may fail");
   332 		module:log("warn", "s2s not listening on any ports, outgoing connections may fail");
   315 		return;
   333 		return;
   316 	end
   334 	end
   317 	for source, _ in pairs(s2s_sources) do
   335 	for source, _ in pairs(s2s_sources) do
   318 		if source == "*" or source == "0.0.0.0" then
   336 		if source:find(":") then
   319 			for _, addr in ipairs(local_addresses("ipv4", true)) do
   337 			has_ipv6 = true;
   320 				sources[#sources + 1] = new_ip(addr, "IPv4");
       
   321 			end
       
   322 		elseif source == "::" then
       
   323 			for _, addr in ipairs(local_addresses("ipv6", true)) do
       
   324 				sources[#sources + 1] = new_ip(addr, "IPv6");
       
   325 			end
       
   326 		else
   338 		else
   327 			sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4");
       
   328 		end
       
   329 	end
       
   330 	for i = 1,#sources do
       
   331 		if sources[i].proto == "IPv6" then
       
   332 			has_ipv6 = true;
       
   333 		elseif sources[i].proto == "IPv4" then
       
   334 			has_ipv4 = true;
   339 			has_ipv4 = true;
   335 		end
   340 		end
   336 	end
   341 	end
   337 	if not (has_ipv4 or has_ipv6)  then
       
   338 		module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail");
       
   339 	end
       
   340 end);
   342 end);
   341 
   343 
   342 return s2sout;
   344 return s2sout;