Mercurial > prosody-hg
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}; |
