Comparison

util/rfc6724.lua @ 5552:40e7a6cf15ff

util.rfc{3484,6724}: Update to RFC 6724
author Florian Zeitz <florob@babelmonkeys.de>
date Tue, 30 Apr 2013 18:34:03 +0200
parent 4830:util/rfc3484.lua@ea907059a90e
child 7259:d8300985f2bb
comparison
equal deleted inserted replaced
5550:557583904dc5 5552:40e7a6cf15ff
1 -- Prosody IM
2 -- Copyright (C) 2011-2013 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 -- 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
11
12 local ip_commonPrefixLength = require"util.ip".commonPrefixLength
13 local new_ip = require"util.ip".new_ip;
14
15 local function commonPrefixLength(ipA, ipB)
16 local len = ip_commonPrefixLength(ipA, ipB);
17 return len < 64 and len or 64;
18 end
19
20 local function t_sort(t, comp)
21 for i = 1, (#t - 1) do
22 for j = (i + 1), #t do
23 local a, b = t[i], t[j];
24 if not comp(a,b) then
25 t[i], t[j] = b, a;
26 end
27 end
28 end
29 end
30
31 local function source(dest, candidates)
32 local function comp(ipA, ipB)
33 -- Rule 1: Prefer same address
34 if dest == ipA then
35 return true;
36 elseif dest == ipB then
37 return false;
38 end
39
40 -- Rule 2: Prefer appropriate scope
41 if ipA.scope < ipB.scope then
42 if ipA.scope < dest.scope then
43 return false;
44 else
45 return true;
46 end
47 elseif ipA.scope > ipB.scope then
48 if ipB.scope < dest.scope then
49 return true;
50 else
51 return false;
52 end
53 end
54
55 -- Rule 3: Avoid deprecated addresses
56 -- XXX: No way to determine this
57 -- Rule 4: Prefer home addresses
58 -- XXX: Mobility Address related, no way to determine this
59 -- Rule 5: Prefer outgoing interface
60 -- XXX: Interface to address relation. No way to determine this
61 -- Rule 6: Prefer matching label
62 if ipA.label == dest.label and ipB.label ~= dest.label then
63 return true;
64 elseif ipB.label == dest.label and ipA.label ~= dest.label then
65 return false;
66 end
67
68 -- Rule 7: Prefer temporary addresses (over public ones)
69 -- XXX: No way to determine this
70 -- Rule 8: Use longest matching prefix
71 if commonPrefixLength(ipA, dest) > commonPrefixLength(ipB, dest) then
72 return true;
73 else
74 return false;
75 end
76 end
77
78 t_sort(candidates, comp);
79 return candidates[1];
80 end
81
82 local function destination(candidates, sources)
83 local sourceAddrs = {};
84 local function comp(ipA, ipB)
85 local ipAsource = sourceAddrs[ipA];
86 local ipBsource = sourceAddrs[ipB];
87 -- Rule 1: Avoid unusable destinations
88 -- XXX: No such information
89 -- Rule 2: Prefer matching scope
90 if ipA.scope == ipAsource.scope and ipB.scope ~= ipBsource.scope then
91 return true;
92 elseif ipA.scope ~= ipAsource.scope and ipB.scope == ipBsource.scope then
93 return false;
94 end
95
96 -- Rule 3: Avoid deprecated addresses
97 -- XXX: No way to determine this
98 -- Rule 4: Prefer home addresses
99 -- XXX: Mobility Address related, no way to determine this
100 -- Rule 5: Prefer matching label
101 if ipAsource.label == ipA.label and ipBsource.label ~= ipB.label then
102 return true;
103 elseif ipBsource.label == ipB.label and ipAsource.label ~= ipA.label then
104 return false;
105 end
106
107 -- Rule 6: Prefer higher precedence
108 if ipA.precedence > ipB.precedence then
109 return true;
110 elseif ipA.precedence < ipB.precedence then
111 return false;
112 end
113
114 -- Rule 7: Prefer native transport
115 -- XXX: No way to determine this
116 -- Rule 8: Prefer smaller scope
117 if ipA.scope < ipB.scope then
118 return true;
119 elseif ipA.scope > ipB.scope then
120 return false;
121 end
122
123 -- Rule 9: Use longest matching prefix
124 if commonPrefixLength(ipA, ipAsource) > commonPrefixLength(ipB, ipBsource) then
125 return true;
126 elseif commonPrefixLength(ipA, ipAsource) < commonPrefixLength(ipB, ipBsource) then
127 return false;
128 end
129
130 -- Rule 10: Otherwise, leave order unchanged
131 return true;
132 end
133 for _, ip in ipairs(candidates) do
134 sourceAddrs[ip] = source(ip, sources);
135 end
136
137 t_sort(candidates, comp);
138 return candidates;
139 end
140
141 return {source = source,
142 destination = destination};