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
14 local function commonPrefixLength(ipA
, ipB
)
15 local len
= ip_commonPrefixLength(ipA
, ipB
);
16 return len
< 64 and len
or 64;
19 local function t_sort(t
, comp
)
20 for i
= 1, (#t
- 1) do
21 for j
= (i
+ 1), #t
do
22 local a
, b
= t
[i
], t
[j
];
30 local function source(dest
, candidates
)
31 local function comp(ipA
, ipB
)
32 -- Rule 1: Prefer same address
35 elseif dest
== ipB
then
39 -- Rule 2: Prefer appropriate scope
40 if ipA
.scope
< ipB
.scope
then
41 if ipA
.scope
< dest
.scope
then
46 elseif ipA
.scope
> ipB
.scope
then
47 if ipB
.scope
< dest
.scope
then
54 -- Rule 3: Avoid deprecated addresses
55 -- XXX: No way to determine this
56 -- Rule 4: Prefer home addresses
57 -- XXX: Mobility Address related, no way to determine this
58 -- Rule 5: Prefer outgoing interface
59 -- XXX: Interface to address relation. No way to determine this
60 -- Rule 6: Prefer matching label
61 if ipA
.label
== dest
.label
and ipB
.label
~= dest
.label
then
63 elseif ipB
.label
== dest
.label
and ipA
.label
~= dest
.label
then
67 -- Rule 7: Prefer temporary addresses (over public ones)
68 -- XXX: No way to determine this
69 -- Rule 8: Use longest matching prefix
70 if commonPrefixLength(ipA
, dest
) > commonPrefixLength(ipB
, dest
) then
77 t_sort(candidates
, comp
);
81 local function destination(candidates
, sources
)
82 local sourceAddrs
= {};
83 local function comp(ipA
, ipB
)
84 local ipAsource
= sourceAddrs
[ipA
];
85 local ipBsource
= sourceAddrs
[ipB
];
86 -- Rule 1: Avoid unusable destinations
87 -- XXX: No such information
88 -- Rule 2: Prefer matching scope
89 if ipA
.scope
== ipAsource
.scope
and ipB
.scope
~= ipBsource
.scope
then
91 elseif ipA
.scope
~= ipAsource
.scope
and ipB
.scope
== ipBsource
.scope
then
95 -- Rule 3: Avoid deprecated addresses
96 -- XXX: No way to determine this
97 -- Rule 4: Prefer home addresses
98 -- XXX: Mobility Address related, no way to determine this
99 -- Rule 5: Prefer matching label
100 if ipAsource
.label
== ipA
.label
and ipBsource
.label
~= ipB
.label
then
102 elseif ipBsource
.label
== ipB
.label
and ipAsource
.label
~= ipA
.label
then
106 -- Rule 6: Prefer higher precedence
107 if ipA
.precedence
> ipB
.precedence
then
109 elseif ipA
.precedence
< ipB
.precedence
then
113 -- Rule 7: Prefer native transport
114 -- XXX: No way to determine this
115 -- Rule 8: Prefer smaller scope
116 if ipA
.scope
< ipB
.scope
then
118 elseif ipA
.scope
> ipB
.scope
then
122 -- Rule 9: Use longest matching prefix
123 if commonPrefixLength(ipA
, ipAsource
) > commonPrefixLength(ipB
, ipBsource
) then
125 elseif commonPrefixLength(ipA
, ipAsource
) < commonPrefixLength(ipB
, ipBsource
) then
129 -- Rule 10: Otherwise, leave order unchanged
132 for _
, ip
in ipairs(candidates
) do
133 sourceAddrs
[ip
] = source(ip
, sources
);
136 t_sort(candidates
, comp
);
140 return {source
= source
,
141 destination
= destination
};