Software /
code /
prosody
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}; |