addrselect.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
  5. // Minimal RFC 6724 address selection.
  6. package net
  7. import "sort"
  8. func sortByRFC6724(addrs []IPAddr) {
  9. if len(addrs) < 2 {
  10. return
  11. }
  12. sortByRFC6724withSrcs(addrs, srcAddrs(addrs))
  13. }
  14. func sortByRFC6724withSrcs(addrs []IPAddr, srcs []IP) {
  15. if len(addrs) != len(srcs) {
  16. panic("internal error")
  17. }
  18. addrAttr := make([]ipAttr, len(addrs))
  19. srcAttr := make([]ipAttr, len(srcs))
  20. for i, v := range addrs {
  21. addrAttr[i] = ipAttrOf(v.IP)
  22. srcAttr[i] = ipAttrOf(srcs[i])
  23. }
  24. sort.Stable(&byRFC6724{
  25. addrs: addrs,
  26. addrAttr: addrAttr,
  27. srcs: srcs,
  28. srcAttr: srcAttr,
  29. })
  30. }
  31. // srcsAddrs tries to UDP-connect to each address to see if it has a
  32. // route. (This doesn't send any packets). The destination port
  33. // number is irrelevant.
  34. func srcAddrs(addrs []IPAddr) []IP {
  35. srcs := make([]IP, len(addrs))
  36. dst := UDPAddr{Port: 9}
  37. for i := range addrs {
  38. dst.IP = addrs[i].IP
  39. dst.Zone = addrs[i].Zone
  40. c, err := DialUDP("udp", nil, &dst)
  41. if err == nil {
  42. if src, ok := c.LocalAddr().(*UDPAddr); ok {
  43. srcs[i] = src.IP
  44. }
  45. c.Close()
  46. }
  47. }
  48. return srcs
  49. }
  50. type ipAttr struct {
  51. Scope scope
  52. Precedence uint8
  53. Label uint8
  54. }
  55. func ipAttrOf(ip IP) ipAttr {
  56. if ip == nil {
  57. return ipAttr{}
  58. }
  59. match := rfc6724policyTable.Classify(ip)
  60. return ipAttr{
  61. Scope: classifyScope(ip),
  62. Precedence: match.Precedence,
  63. Label: match.Label,
  64. }
  65. }
  66. type byRFC6724 struct {
  67. addrs []IPAddr // addrs to sort
  68. addrAttr []ipAttr
  69. srcs []IP // or nil if unreachable
  70. srcAttr []ipAttr
  71. }
  72. func (s *byRFC6724) Len() int { return len(s.addrs) }
  73. func (s *byRFC6724) Swap(i, j int) {
  74. s.addrs[i], s.addrs[j] = s.addrs[j], s.addrs[i]
  75. s.srcs[i], s.srcs[j] = s.srcs[j], s.srcs[i]
  76. s.addrAttr[i], s.addrAttr[j] = s.addrAttr[j], s.addrAttr[i]
  77. s.srcAttr[i], s.srcAttr[j] = s.srcAttr[j], s.srcAttr[i]
  78. }
  79. // Less reports whether i is a better destination address for this
  80. // host than j.
  81. //
  82. // The algorithm and variable names comes from RFC 6724 section 6.
  83. func (s *byRFC6724) Less(i, j int) bool {
  84. DA := s.addrs[i].IP
  85. DB := s.addrs[j].IP
  86. SourceDA := s.srcs[i]
  87. SourceDB := s.srcs[j]
  88. attrDA := &s.addrAttr[i]
  89. attrDB := &s.addrAttr[j]
  90. attrSourceDA := &s.srcAttr[i]
  91. attrSourceDB := &s.srcAttr[j]
  92. const preferDA = true
  93. const preferDB = false
  94. // Rule 1: Avoid unusable destinations.
  95. // If DB is known to be unreachable or if Source(DB) is undefined, then
  96. // prefer DA. Similarly, if DA is known to be unreachable or if
  97. // Source(DA) is undefined, then prefer DB.
  98. if SourceDA == nil && SourceDB == nil {
  99. return false // "equal"
  100. }
  101. if SourceDB == nil {
  102. return preferDA
  103. }
  104. if SourceDA == nil {
  105. return preferDB
  106. }
  107. // Rule 2: Prefer matching scope.
  108. // If Scope(DA) = Scope(Source(DA)) and Scope(DB) <> Scope(Source(DB)),
  109. // then prefer DA. Similarly, if Scope(DA) <> Scope(Source(DA)) and
  110. // Scope(DB) = Scope(Source(DB)), then prefer DB.
  111. if attrDA.Scope == attrSourceDA.Scope && attrDB.Scope != attrSourceDB.Scope {
  112. return preferDA
  113. }
  114. if attrDA.Scope != attrSourceDA.Scope && attrDB.Scope == attrSourceDB.Scope {
  115. return preferDB
  116. }
  117. // Rule 3: Avoid deprecated addresses.
  118. // If Source(DA) is deprecated and Source(DB) is not, then prefer DB.
  119. // Similarly, if Source(DA) is not deprecated and Source(DB) is
  120. // deprecated, then prefer DA.
  121. // TODO(bradfitz): implement? low priority for now.
  122. // Rule 4: Prefer home addresses.
  123. // If Source(DA) is simultaneously a home address and care-of address
  124. // and Source(DB) is not, then prefer DA. Similarly, if Source(DB) is
  125. // simultaneously a home address and care-of address and Source(DA) is
  126. // not, then prefer DB.
  127. // TODO(bradfitz): implement? low priority for now.
  128. // Rule 5: Prefer matching label.
  129. // If Label(Source(DA)) = Label(DA) and Label(Source(DB)) <> Label(DB),
  130. // then prefer DA. Similarly, if Label(Source(DA)) <> Label(DA) and
  131. // Label(Source(DB)) = Label(DB), then prefer DB.
  132. if attrSourceDA.Label == attrDA.Label &&
  133. attrSourceDB.Label != attrDB.Label {
  134. return preferDA
  135. }
  136. if attrSourceDA.Label != attrDA.Label &&
  137. attrSourceDB.Label == attrDB.Label {
  138. return preferDB
  139. }
  140. // Rule 6: Prefer higher precedence.
  141. // If Precedence(DA) > Precedence(DB), then prefer DA. Similarly, if
  142. // Precedence(DA) < Precedence(DB), then prefer DB.
  143. if attrDA.Precedence > attrDB.Precedence {
  144. return preferDA
  145. }
  146. if attrDA.Precedence < attrDB.Precedence {
  147. return preferDB
  148. }
  149. // Rule 7: Prefer native transport.
  150. // If DA is reached via an encapsulating transition mechanism (e.g.,
  151. // IPv6 in IPv4) and DB is not, then prefer DB. Similarly, if DB is
  152. // reached via encapsulation and DA is not, then prefer DA.
  153. // TODO(bradfitz): implement? low priority for now.
  154. // Rule 8: Prefer smaller scope.
  155. // If Scope(DA) < Scope(DB), then prefer DA. Similarly, if Scope(DA) >
  156. // Scope(DB), then prefer DB.
  157. if attrDA.Scope < attrDB.Scope {
  158. return preferDA
  159. }
  160. if attrDA.Scope > attrDB.Scope {
  161. return preferDB
  162. }
  163. // Rule 9: Use longest matching prefix.
  164. // When DA and DB belong to the same address family (both are IPv6 or
  165. // both are IPv4 [but see below]): If CommonPrefixLen(Source(DA), DA) >
  166. // CommonPrefixLen(Source(DB), DB), then prefer DA. Similarly, if
  167. // CommonPrefixLen(Source(DA), DA) < CommonPrefixLen(Source(DB), DB),
  168. // then prefer DB.
  169. //
  170. // However, applying this rule to IPv4 addresses causes
  171. // problems (see issues 13283 and 18518), so limit to IPv6.
  172. if DA.To4() == nil && DB.To4() == nil {
  173. commonA := commonPrefixLen(SourceDA, DA)
  174. commonB := commonPrefixLen(SourceDB, DB)
  175. if commonA > commonB {
  176. return preferDA
  177. }
  178. if commonA < commonB {
  179. return preferDB
  180. }
  181. }
  182. // Rule 10: Otherwise, leave the order unchanged.
  183. // If DA preceded DB in the original list, prefer DA.
  184. // Otherwise, prefer DB.
  185. return false // "equal"
  186. }
  187. type policyTableEntry struct {
  188. Prefix *IPNet
  189. Precedence uint8
  190. Label uint8
  191. }
  192. type policyTable []policyTableEntry
  193. // RFC 6724 section 2.1.
  194. var rfc6724policyTable = policyTable{
  195. {
  196. Prefix: mustCIDR("::1/128"),
  197. Precedence: 50,
  198. Label: 0,
  199. },
  200. {
  201. Prefix: mustCIDR("::/0"),
  202. Precedence: 40,
  203. Label: 1,
  204. },
  205. {
  206. // IPv4-compatible, etc.
  207. Prefix: mustCIDR("::ffff:0:0/96"),
  208. Precedence: 35,
  209. Label: 4,
  210. },
  211. {
  212. // 6to4
  213. Prefix: mustCIDR("2002::/16"),
  214. Precedence: 30,
  215. Label: 2,
  216. },
  217. {
  218. // Teredo
  219. Prefix: mustCIDR("2001::/32"),
  220. Precedence: 5,
  221. Label: 5,
  222. },
  223. {
  224. Prefix: mustCIDR("fc00::/7"),
  225. Precedence: 3,
  226. Label: 13,
  227. },
  228. {
  229. Prefix: mustCIDR("::/96"),
  230. Precedence: 1,
  231. Label: 3,
  232. },
  233. {
  234. Prefix: mustCIDR("fec0::/10"),
  235. Precedence: 1,
  236. Label: 11,
  237. },
  238. {
  239. Prefix: mustCIDR("3ffe::/16"),
  240. Precedence: 1,
  241. Label: 12,
  242. },
  243. }
  244. func init() {
  245. sort.Sort(sort.Reverse(byMaskLength(rfc6724policyTable)))
  246. }
  247. // byMaskLength sorts policyTableEntry by the size of their Prefix.Mask.Size,
  248. // from smallest mask, to largest.
  249. type byMaskLength []policyTableEntry
  250. func (s byMaskLength) Len() int { return len(s) }
  251. func (s byMaskLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  252. func (s byMaskLength) Less(i, j int) bool {
  253. isize, _ := s[i].Prefix.Mask.Size()
  254. jsize, _ := s[j].Prefix.Mask.Size()
  255. return isize < jsize
  256. }
  257. // mustCIDR calls ParseCIDR and panics on any error, or if the network
  258. // is not IPv6.
  259. func mustCIDR(s string) *IPNet {
  260. ip, ipNet, err := ParseCIDR(s)
  261. if err != nil {
  262. panic(err.Error())
  263. }
  264. if len(ip) != IPv6len {
  265. panic("unexpected IP length")
  266. }
  267. return ipNet
  268. }
  269. // Classify returns the policyTableEntry of the entry with the longest
  270. // matching prefix that contains ip.
  271. // The table t must be sorted from largest mask size to smallest.
  272. func (t policyTable) Classify(ip IP) policyTableEntry {
  273. for _, ent := range t {
  274. if ent.Prefix.Contains(ip) {
  275. return ent
  276. }
  277. }
  278. return policyTableEntry{}
  279. }
  280. // RFC 6724 section 3.1.
  281. type scope uint8
  282. const (
  283. scopeInterfaceLocal scope = 0x1
  284. scopeLinkLocal scope = 0x2
  285. scopeAdminLocal scope = 0x4
  286. scopeSiteLocal scope = 0x5
  287. scopeOrgLocal scope = 0x8
  288. scopeGlobal scope = 0xe
  289. )
  290. func classifyScope(ip IP) scope {
  291. if ip.IsLoopback() || ip.IsLinkLocalUnicast() {
  292. return scopeLinkLocal
  293. }
  294. ipv6 := len(ip) == IPv6len && ip.To4() == nil
  295. if ipv6 && ip.IsMulticast() {
  296. return scope(ip[1] & 0xf)
  297. }
  298. // Site-local addresses are defined in RFC 3513 section 2.5.6
  299. // (and deprecated in RFC 3879).
  300. if ipv6 && ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 {
  301. return scopeSiteLocal
  302. }
  303. return scopeGlobal
  304. }
  305. // commonPrefixLen reports the length of the longest prefix (looking
  306. // at the most significant, or leftmost, bits) that the
  307. // two addresses have in common, up to the length of a's prefix (i.e.,
  308. // the portion of the address not including the interface ID).
  309. //
  310. // If a or b is an IPv4 address as an IPv6 address, the IPv4 addresses
  311. // are compared (with max common prefix length of 32).
  312. // If a and b are different IP versions, 0 is returned.
  313. //
  314. // See https://tools.ietf.org/html/rfc6724#section-2.2
  315. func commonPrefixLen(a, b IP) (cpl int) {
  316. if a4 := a.To4(); a4 != nil {
  317. a = a4
  318. }
  319. if b4 := b.To4(); b4 != nil {
  320. b = b4
  321. }
  322. if len(a) != len(b) {
  323. return 0
  324. }
  325. // If IPv6, only up to the prefix (first 64 bits)
  326. if len(a) > 8 {
  327. a = a[:8]
  328. b = b[:8]
  329. }
  330. for len(a) > 0 {
  331. if a[0] == b[0] {
  332. cpl += 8
  333. a = a[1:]
  334. b = b[1:]
  335. continue
  336. }
  337. bits := 8
  338. ab, bb := a[0], b[0]
  339. for {
  340. ab >>= 1
  341. bb >>= 1
  342. bits--
  343. if ab == bb {
  344. cpl += bits
  345. return
  346. }
  347. }
  348. }
  349. return
  350. }