aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2015-05-13 21:47:39 +0200
committerKim Alvefur <zash@zash.se>2015-05-13 21:47:39 +0200
commit3391b867193c3c1c772d4b1b0a5a0940948b63f1 (patch)
tree1c64c9ceb8f77c762607e1f0df61a78953682301
parent8389ecb795287b1d0c053c76bb0e65badd48c2a6 (diff)
downloadprosody-3391b867193c3c1c772d4b1b0a5a0940948b63f1.tar.gz
prosody-3391b867193c3c1c772d4b1b0a5a0940948b63f1.zip
mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses
-rw-r--r--plugins/mod_s2s/s2sout.lib.lua46
1 files changed, 24 insertions, 22 deletions
diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua
index dc122af7..5728f67b 100644
--- a/plugins/mod_s2s/s2sout.lib.lua
+++ b/plugins/mod_s2s/s2sout.lib.lua
@@ -18,13 +18,31 @@ local socket = require "socket";
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 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err)
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 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err)
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 @@ module:hook_global("service-added", function (event)
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
- 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
+ if source:find(":") then
has_ipv6 = true;
- elseif sources[i].proto == "IPv4" then
+ else
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;