Comparison

plugins/mod_s2s/s2sout.lib.lua @ 6682:63f5870f9afe

mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses
author Kim Alvefur <zash@zash.se>
date Wed, 13 May 2015 21:47:39 +0200
parent 6680:ae34b12c4335
child 6685:3f05b255937f
child 7092:bee63de49663
comparison
equal deleted inserted replaced
6681:0217a04722c7 6682: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;