comparison util/rfc3484.lua @ 4797:e239668aa6d2

Merge 0.9->trunk
author Matthew Wild <mwild1@gmail.com>
date Sun, 29 Apr 2012 02:10:55 +0100
parents ded726418b16
children ea907059a90e
comparison
equal deleted inserted replaced
4796:04a34287dc12 4797:e239668aa6d2
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 commonPrefixLength = require"util.ip".commonPrefixLength
9 local new_ip = require"util.ip".new_ip;
10
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];
15 if not comp(a,b) then
16 t[i], t[j] = b, a;
17 end
18 end
19 end
20 end
21
22 function source(dest, candidates)
23 local function comp(ipA, ipB)
24 -- Rule 1: Prefer same address
25 if dest == ipA then
26 return true;
27 elseif dest == ipB then
28 return false;
29 end
30
31 -- Rule 2: Prefer appropriate scope
32 if ipA.scope < ipB.scope then
33 if ipA.scope < dest.scope then
34 return false;
35 else
36 return true;
37 end
38 elseif ipA.scope > ipB.scope then
39 if ipB.scope < dest.scope then
40 return true;
41 else
42 return false;
43 end
44 end
45
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
54 return true;
55 elseif ipB.label == dest.label and ipA.label ~= dest.label then
56 return false;
57 end
58
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
63 return true;
64 else
65 return false;
66 end
67 end
68
69 t_sort(candidates, comp);
70 return candidates[1];
71 end
72
73 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
82 return true;
83 elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
84 return false;
85 end
86
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
93 return true;
94 elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
95 return false;
96 end
97
98 -- Rule 6: Prefer higher precedence
99 if ipA.precedence > ipB.precedence then
100 return true;
101 elseif ipA.precedence < ipB.precedence then
102 return false;
103 end
104
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
109 return true;
110 elseif ipA.scope > ipB.scope then
111 return false;
112 end
113
114 -- Rule 9: Use longest matching prefix
115 if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
116 return true;
117 elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
118 return false;
119 end
120
121 -- Rule 10: Otherwise, leave order unchanged
122 return true;
123 end
124 for _, ip in ipairs(candidates) do
125 sourceAddrs[ip] = source(ip, sources);
126 end
127
128 t_sort(candidates, comp);
129 return candidates;
130 end
131
132 return {source = source,
133 destination = destination};