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