2 -- Copyright (C) 2011-2013 Florian Zeitz
4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information.
8 -- This is used to sort destination addresses by preference
9 -- during S2S connections.
10 -- We can't hand this off to getaddrinfo, since it blocks
12 local ip_commonPrefixLength = require"util.ip".commonPrefixLength
13 local new_ip = require"util.ip".new_ip;
15 local function commonPrefixLength(ipA, ipB)
16 local len = ip_commonPrefixLength(ipA, ipB);
17 return len < 64 and len or 64;
20 local function t_sort(t, comp)
21 for i = 1, (#t - 1) do
22 for j = (i + 1), #t do
23 local a, b = t[i], t[j];
31 local function source(dest, candidates)
32 local function comp(ipA, ipB)
33 -- Rule 1: Prefer same address
36 elseif dest == ipB then
40 -- Rule 2: Prefer appropriate scope
41 if ipA.scope < ipB.scope then
42 if ipA.scope < dest.scope then
47 elseif ipA.scope > ipB.scope then
48 if ipB.scope < dest.scope then
55 -- Rule 3: Avoid deprecated addresses
56 -- XXX: No way to determine this
57 -- Rule 4: Prefer home addresses
58 -- XXX: Mobility Address related, no way to determine this
59 -- Rule 5: Prefer outgoing interface
60 -- XXX: Interface to address relation. No way to determine this
61 -- Rule 6: Prefer matching label
62 if ipA.label == dest.label and ipB.label ~= dest.label then
64 elseif ipB.label == dest.label and ipA.label ~= dest.label then
68 -- Rule 7: Prefer temporary addresses (over public ones)
69 -- XXX: No way to determine this
70 -- Rule 8: Use longest matching prefix
71 if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
78 t_sort(candidates, comp);
82 local function destination(candidates, sources)
83 local sourceAddrs = {};
84 local function comp(ipA, ipB)
85 local ipAsource = sourceAddrs[ipA];
86 local ipBsource = sourceAddrs[ipB];
87 -- Rule 1: Avoid unusable destinations
88 -- XXX: No such information
89 -- Rule 2: Prefer matching scope
90 if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
92 elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
96 -- Rule 3: Avoid deprecated addresses
97 -- XXX: No way to determine this
98 -- Rule 4: Prefer home addresses
99 -- XXX: Mobility Address related, no way to determine this
100 -- Rule 5: Prefer matching label
101 if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
103 elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
107 -- Rule 6: Prefer higher precedence
108 if ipA.precedence > ipB.precedence then
110 elseif ipA.precedence < ipB.precedence then
114 -- Rule 7: Prefer native transport
115 -- XXX: No way to determine this
116 -- Rule 8: Prefer smaller scope
117 if ipA.scope < ipB.scope then
119 elseif ipA.scope > ipB.scope then
123 -- Rule 9: Use longest matching prefix
124 if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
126 elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
130 -- Rule 10: Otherwise, leave order unchanged
133 for _, ip in ipairs(candidates) do
134 sourceAddrs[ip] = source(ip, sources);
137 t_sort(candidates, comp);
141 return {source = source,
142 destination = destination};