util.rfc{3484,6724}: Update to RFC 6724
authorFlorian Zeitz <florob@babelmonkeys.de>
Tue, 30 Apr 2013 18:34:03 +0200
changeset 5552 40e7a6cf15ff
parent 5550 557583904dc5
child 5553 7baf59444b31
util.rfc{3484,6724}: Update to RFC 6724
plugins/mod_s2s/s2sout.lib.lua
util/ip.lua
util/rfc3484.lua
util/rfc6724.lua
--- a/plugins/mod_s2s/s2sout.lib.lua	Mon Apr 29 19:40:39 2013 +0200
+++ b/plugins/mod_s2s/s2sout.lib.lua	Tue Apr 30 18:34:03 2013 +0200
@@ -13,7 +13,7 @@
 local initialize_filters = require "util.filters".initialize;
 local idna_to_ascii = require "util.encodings".idna.to_ascii;
 local new_ip = require "util.ip".new_ip;
-local rfc3484_dest = require "util.rfc3484".destination;
+local rfc6724_dest = require "util.rfc6724".destination;
 local socket = require "socket";
 local adns = require "net.adns";
 local dns = require "net.dns";
@@ -191,7 +191,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc3484_dest(host_session.ip_hosts, sources);
+						rfc6724_dest(host_session.ip_hosts, sources);
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
@@ -227,7 +227,7 @@
 
 				if have_other_result then
 					if #IPs > 0 then
-						rfc3484_dest(host_session.ip_hosts, sources);
+						rfc6724_dest(host_session.ip_hosts, sources);
 						for i = 1, #IPs do
 							IPs[i] = {ip = IPs[i], port = connect_port};
 						end
--- a/util/ip.lua	Mon Apr 29 19:40:39 2013 +0200
+++ b/util/ip.lua	Tue Apr 30 18:34:03 2013 +0200
@@ -64,9 +64,6 @@
 	-- Link-local unicast:
 	elseif fields[1] == 169 and fields[2] == 254 then
 		return 0x2;
-	-- Site-local unicast:
-	elseif (fields[1] == 10) or (fields[1] == 192 and fields[2] == 168) or (fields[1] == 172 and (fields[2] >= 16 and fields[2] < 32)) then
-		return 0x5;
 	-- Global unicast:
 	else
 		return 0xE;
@@ -97,6 +94,14 @@
 		return 0;
 	elseif commonPrefixLength(ip, new_ip("2002::", "IPv6")) >= 16 then
 		return 2;
+	elseif commonPrefixLength(ip, new_ip("2001::", "IPv6")) >= 32 then
+		return 5;
+	elseif commonPrefixLength(ip, new_ip("fc00::", "IPv6")) >= 7 then
+		return 13;
+	elseif commonPrefixLength(ip, new_ip("fec0::", "IPv6")) >= 10 then
+		return 11;
+	elseif commonPrefixLength(ip, new_ip("3ffe::", "IPv6")) >= 16 then
+		return 12;
 	elseif commonPrefixLength(ip, new_ip("::", "IPv6")) >= 96 then
 		return 3;
 	elseif commonPrefixLength(ip, new_ip("::ffff:0:0", "IPv6")) >= 96 then
@@ -111,10 +116,18 @@
 		return 50;
 	elseif commonPrefixLength(ip, new_ip("2002::", "IPv6")) >= 16 then
 		return 30;
+	elseif commonPrefixLength(ip, new_ip("2001::", "IPv6")) >= 32 then
+		return 5;
+	elseif commonPrefixLength(ip, new_ip("fc00::", "IPv6")) >= 7 then
+		return 3;
+	elseif commonPrefixLength(ip, new_ip("fec0::", "IPv6")) >= 10 then
+		return 1;
+	elseif commonPrefixLength(ip, new_ip("3ffe::", "IPv6")) >= 16 then
+		return 1;
 	elseif commonPrefixLength(ip, new_ip("::", "IPv6")) >= 96 then
-		return 20;
+		return 1;
 	elseif commonPrefixLength(ip, new_ip("::ffff:0:0", "IPv6")) >= 96 then
-		return 10;
+		return 35;
 	else
 		return 40;
 	end
--- a/util/rfc3484.lua	Mon Apr 29 19:40:39 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
--- Prosody IM
--- Copyright (C) 2008-2011 Florian Zeitz
---
--- This project is MIT/X11 licensed. Please see the
--- COPYING file in the source package for more information.
---
-
-local commonPrefixLength = require"util.ip".commonPrefixLength
-local new_ip = require"util.ip".new_ip;
-
-local function t_sort(t, comp)
-	for i = 1, (#t - 1) do
-		for j = (i + 1), #t do
-			local a, b = t[i], t[j];
-			if not comp(a,b) then
-				t[i], t[j] = b, a;
-			end
-		end
-	end
-end
-
-local function source(dest, candidates)
-	local function comp(ipA, ipB)
-		-- Rule 1: Prefer same address
-		if dest == ipA then
-			return true;
-		elseif dest == ipB then
-			return false;
-		end
-
-		-- Rule 2: Prefer appropriate scope
-		if ipA.scope < ipB.scope then
-			if ipA.scope < dest.scope then
-				return false;
-			else
-				return true;
-			end
-		elseif ipA.scope > ipB.scope then
-			if ipB.scope < dest.scope then
-				return true;
-			else
-				return false;
-			end
-		end
-
-		-- Rule 3: Avoid deprecated addresses
-		-- XXX: No way to determine this
-		-- Rule 4: Prefer home addresses
-		-- XXX: Mobility Address related, no way to determine this
-		-- Rule 5: Prefer outgoing interface
-		-- XXX: Interface to address relation. No way to determine this
-		-- Rule 6: Prefer matching label
-		if ipA.label == dest.label and ipB.label ~= dest.label then
-			return true;
-		elseif ipB.label == dest.label and ipA.label ~= dest.label then
-			return false;
-		end
-
-		-- Rule 7: Prefer public addresses (over temporary ones)
-		-- XXX: No way to determine this
-		-- Rule 8: Use longest matching prefix
-		if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
-			return true;
-		else
-			return false;
-		end
-	end
-
-	t_sort(candidates, comp);
-	return candidates[1];
-end
-
-local function destination(candidates, sources)
-	local sourceAddrs = {};
-	local function comp(ipA, ipB)
-		local ipAsource = sourceAddrs[ipA];
-		local ipBsource = sourceAddrs[ipB];
-		-- Rule 1: Avoid unusable destinations
-		-- XXX: No such information
-		-- Rule 2: Prefer matching scope
-		if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
-			return true;
-		elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
-			return false;
-		end
-
-		-- Rule 3: Avoid deprecated addresses
-		-- XXX: No way to determine this
-		-- Rule 4: Prefer home addresses
-		-- XXX: Mobility Address related, no way to determine this
-		-- Rule 5: Prefer matching label
-		if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
-			return true;
-		elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
-			return false;
-		end
-
-		-- Rule 6: Prefer higher precedence
-		if ipA.precedence > ipB.precedence then
-			return true;
-		elseif ipA.precedence < ipB.precedence then
-			return false;
-		end
-
-		-- Rule 7: Prefer native transport
-		-- XXX: No way to determine this
-		-- Rule 8: Prefer smaller scope
-		if ipA.scope < ipB.scope then
-			return true;
-		elseif ipA.scope > ipB.scope then
-			return false;
-		end
-
-		-- Rule 9: Use longest matching prefix
-		if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
-			return true;
-		elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
-			return false;
-		end
-
-		-- Rule 10: Otherwise, leave order unchanged
-		return true;
-	end
-	for _, ip in ipairs(candidates) do
-		sourceAddrs[ip] = source(ip, sources);
-	end
-
-	t_sort(candidates, comp);
-	return candidates;
-end
-
-return {source = source,
-	destination = destination};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/rfc6724.lua	Tue Apr 30 18:34:03 2013 +0200
@@ -0,0 +1,142 @@
+-- Prosody IM
+-- Copyright (C) 2011-2013 Florian Zeitz
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+-- This is used to sort destination addresses by preference
+-- during S2S connections.
+-- We can't hand this off to getaddrinfo, since it blocks
+
+local ip_commonPrefixLength = require"util.ip".commonPrefixLength
+local new_ip = require"util.ip".new_ip;
+
+local function commonPrefixLength(ipA, ipB)
+	local len = ip_commonPrefixLength(ipA, ipB);
+	return len < 64 and len or 64;
+end
+
+local function t_sort(t, comp)
+	for i = 1, (#t - 1) do
+		for j = (i + 1), #t do
+			local a, b = t[i], t[j];
+			if not comp(a,b) then
+				t[i], t[j] = b, a;
+			end
+		end
+	end
+end
+
+local function source(dest, candidates)
+	local function comp(ipA, ipB)
+		-- Rule 1: Prefer same address
+		if dest == ipA then
+			return true;
+		elseif dest == ipB then
+			return false;
+		end
+
+		-- Rule 2: Prefer appropriate scope
+		if ipA.scope < ipB.scope then
+			if ipA.scope < dest.scope then
+				return false;
+			else
+				return true;
+			end
+		elseif ipA.scope > ipB.scope then
+			if ipB.scope < dest.scope then
+				return true;
+			else
+				return false;
+			end
+		end
+
+		-- Rule 3: Avoid deprecated addresses
+		-- XXX: No way to determine this
+		-- Rule 4: Prefer home addresses
+		-- XXX: Mobility Address related, no way to determine this
+		-- Rule 5: Prefer outgoing interface
+		-- XXX: Interface to address relation. No way to determine this
+		-- Rule 6: Prefer matching label
+		if ipA.label == dest.label and ipB.label ~= dest.label then
+			return true;
+		elseif ipB.label == dest.label and ipA.label ~= dest.label then
+			return false;
+		end
+
+		-- Rule 7: Prefer temporary addresses (over public ones)
+		-- XXX: No way to determine this
+		-- Rule 8: Use longest matching prefix
+		if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
+			return true;
+		else
+			return false;
+		end
+	end
+
+	t_sort(candidates, comp);
+	return candidates[1];
+end
+
+local function destination(candidates, sources)
+	local sourceAddrs = {};
+	local function comp(ipA, ipB)
+		local ipAsource = sourceAddrs[ipA];
+		local ipBsource = sourceAddrs[ipB];
+		-- Rule 1: Avoid unusable destinations
+		-- XXX: No such information
+		-- Rule 2: Prefer matching scope
+		if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
+			return true;
+		elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
+			return false;
+		end
+
+		-- Rule 3: Avoid deprecated addresses
+		-- XXX: No way to determine this
+		-- Rule 4: Prefer home addresses
+		-- XXX: Mobility Address related, no way to determine this
+		-- Rule 5: Prefer matching label
+		if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
+			return true;
+		elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
+			return false;
+		end
+
+		-- Rule 6: Prefer higher precedence
+		if ipA.precedence > ipB.precedence then
+			return true;
+		elseif ipA.precedence < ipB.precedence then
+			return false;
+		end
+
+		-- Rule 7: Prefer native transport
+		-- XXX: No way to determine this
+		-- Rule 8: Prefer smaller scope
+		if ipA.scope < ipB.scope then
+			return true;
+		elseif ipA.scope > ipB.scope then
+			return false;
+		end
+
+		-- Rule 9: Use longest matching prefix
+		if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
+			return true;
+		elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
+			return false;
+		end
+
+		-- Rule 10: Otherwise, leave order unchanged
+		return true;
+	end
+	for _, ip in ipairs(candidates) do
+		sourceAddrs[ip] = source(ip, sources);
+	end
+
+	t_sort(candidates, comp);
+	return candidates;
+end
+
+return {source = source,
+	destination = destination};