util.rfc{3484,6724}: Update to RFC 6724
authorFlorian Zeitz <florob@babelmonkeys.de>
Tue, 30 Apr 2013 16:34:03 +0000 (18:34 +0200)
committerFlorian Zeitz <florob@babelmonkeys.de>
Tue, 30 Apr 2013 16:34:03 +0000 (18:34 +0200)
plugins/mod_s2s/s2sout.lib.lua
util/ip.lua
util/rfc3484.lua [deleted file]
util/rfc6724.lua [new file with mode: 0644]

index a22846dbe73407046468a6123389141e0842ef94..cb2f8be4f8e791cc7c10ba3dbcd0ce04c885dc22 100644 (file)
@@ -13,7 +13,7 @@ local wrapclient = require "net.server".wrapclient;
 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 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err)
 
                                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 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err)
 
                                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
index 2f09c03406964b4c516c407177bb50fb3e98f135..de287b163b90a1b48e827a57f18680954608b0b8 100644 (file)
@@ -64,9 +64,6 @@ local function v4scope(ip)
        -- 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 @@ local function label(ip)
                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 @@ local function precedence(ip)
                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
diff --git a/util/rfc3484.lua b/util/rfc3484.lua
deleted file mode 100644 (file)
index 5ee572a..0000000
+++ /dev/null
@@ -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};
diff --git a/util/rfc6724.lua b/util/rfc6724.lua
new file mode 100644 (file)
index 0000000..c8aec63
--- /dev/null
@@ -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};