Comparison

util/rfc3484.lua @ 4420:4314eeeed394

util.rfc3484: New util implementing RFC3484 sorting
author Florian Zeitz <florob@babelmonkeys.de>
date Sat, 22 Oct 2011 17:59:33 +0200
child 4423:ded726418b16
comparison
equal deleted inserted replaced
4419:b1e49cc314cb 4420:4314eeeed394
1 -- Prosody IM
2 -- Copyright (C) 2008-2011 Florian Zeitz
3 --
4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information.
6 --
7
8 local t_sort = table.sort;
9 local commonPrefixLength = require"util.ip".commonPrefixLength
10 local new_ip = require"util.ip".new_ip;
11
12 function source(dest, candidates)
13 local function comp(ipA, ipB)
14 -- Rule 1: Prefer same address
15 if dest == ipA then
16 return true;
17 elseif dest == ipB then
18 return false;
19 end
20
21 -- Rule 2: Prefer appropriate scope
22 if ipA.scope < ipB.scope then
23 if ipA.scope < dest.scope then
24 return false;
25 else
26 return true;
27 end
28 elseif ipA.scope > ipB.scope then
29 if ipB.scope < dest.scope then
30 return true;
31 else
32 return false;
33 end
34 end
35
36 -- Rule 3: Avoid deprecated addresses
37 -- XXX: No way to determine this
38 -- Rule 4: Prefer home addresses
39 -- XXX: Mobility Address related, no way to determine this
40 -- Rule 5: Prefer outgoing interface
41 -- XXX: Interface to address relation. No way to determine this
42 -- Rule 6: Prefer matching label
43 if ipA.label == dest.label and ipB.label ~= dest.label then
44 return true;
45 elseif ipB.label == dest.label and ipA.label ~= dest.label then
46 return false;
47 end
48
49 -- Rule 7: Prefer public addresses (over temporary ones)
50 -- XXX: No way to determine this
51 -- Rule 8: Use longest matching prefix
52 if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
53 return true;
54 else
55 return false;
56 end
57 end
58
59 t_sort(candidates, comp);
60 return candidates[1];
61 end
62
63 function destination(candidates, sources)
64 local t_sort = table.sort;
65 local sourceAddrs = {};
66 local function comp(ipA, ipB)
67 local ipAsource = sourceAddrs[ipA];
68 local ipBsource = sourceAddrs[ipB];
69 -- Rule 1: Avoid unusable destinations
70 -- XXX: No such information
71 -- Rule 2: Prefer matching scope
72 if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
73 return true;
74 elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
75 return false;
76 end
77
78 -- Rule 3: Avoid deprecated addresses
79 -- XXX: No way to determine this
80 -- Rule 4: Prefer home addresses
81 -- XXX: Mobility Address related, no way to determine this
82 -- Rule 5: Prefer matching label
83 if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
84 return true;
85 elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
86 return false;
87 end
88
89 -- Rule 6: Prefer higher precedence
90 if ipA.precedence > ipB.precedence then
91 return true;
92 elseif ipA.precedence < ipB.precedence then
93 return false;
94 end
95
96 -- Rule 7: Prefer native transport
97 -- XXX: No way to determine this
98 -- Rule 8: Prefer smaller scope
99 if ipA.scope < ipB.scope then
100 return true;
101 elseif ipA.scope > ipB.scope then
102 return false;
103 end
104
105 -- Rule 9: Use longest matching prefix
106 if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
107 return true;
108 elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
109 return false;
110 end
111
112 -- Rule 10: Otherwise, leave order unchanged
113 return true;
114 end
115 for _, ip in ipairs(candidates) do
116 sourceAddrs[ip] = source(ip, sources);
117 end
118
119 t_sort(candidates, comp);
120 return candidates;
121 end
122
123 return {source = source,
124 destination = destination};