2 -- Copyright (C) 2008-2011 Florian Zeitz
4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information.
8 local commonPrefixLength = require"util.ip".commonPrefixLength
9 local new_ip = require"util.ip".new_ip;
11 local function t_sort(t, comp)
12 for i = 1, (#t - 1) do
13 for j = (i + 1), #t do
14 local a, b = t[i], t[j];
22 local function source(dest, candidates)
23 local function comp(ipA, ipB)
24 -- Rule 1: Prefer same address
27 elseif dest == ipB then
31 -- Rule 2: Prefer appropriate scope
32 if ipA.scope < ipB.scope then
33 if ipA.scope < dest.scope then
38 elseif ipA.scope > ipB.scope then
39 if ipB.scope < dest.scope then
46 -- Rule 3: Avoid deprecated addresses
47 -- XXX: No way to determine this
48 -- Rule 4: Prefer home addresses
49 -- XXX: Mobility Address related, no way to determine this
50 -- Rule 5: Prefer outgoing interface
51 -- XXX: Interface to address relation. No way to determine this
52 -- Rule 6: Prefer matching label
53 if ipA.label == dest.label and ipB.label ~= dest.label then
55 elseif ipB.label == dest.label and ipA.label ~= dest.label then
59 -- Rule 7: Prefer public addresses (over temporary ones)
60 -- XXX: No way to determine this
61 -- Rule 8: Use longest matching prefix
62 if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
69 t_sort(candidates, comp);
73 local function destination(candidates, sources)
74 local sourceAddrs = {};
75 local function comp(ipA, ipB)
76 local ipAsource = sourceAddrs[ipA];
77 local ipBsource = sourceAddrs[ipB];
78 -- Rule 1: Avoid unusable destinations
79 -- XXX: No such information
80 -- Rule 2: Prefer matching scope
81 if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
83 elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
87 -- Rule 3: Avoid deprecated addresses
88 -- XXX: No way to determine this
89 -- Rule 4: Prefer home addresses
90 -- XXX: Mobility Address related, no way to determine this
91 -- Rule 5: Prefer matching label
92 if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
94 elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
98 -- Rule 6: Prefer higher precedence
99 if ipA.precedence > ipB.precedence then
101 elseif ipA.precedence < ipB.precedence then
105 -- Rule 7: Prefer native transport
106 -- XXX: No way to determine this
107 -- Rule 8: Prefer smaller scope
108 if ipA.scope < ipB.scope then
110 elseif ipA.scope > ipB.scope then
114 -- Rule 9: Use longest matching prefix
115 if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
117 elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
121 -- Rule 10: Otherwise, leave order unchanged
124 for _, ip in ipairs(candidates) do
125 sourceAddrs[ip] = source(ip, sources);
128 t_sort(candidates, comp);
132 return {source = source,
133 destination = destination};