2
0

ip.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mesh
  15. import (
  16. "net"
  17. "sort"
  18. )
  19. // sortIPs sorts IPs so the result is stable.
  20. // It will first sort IPs by type, to prefer selecting
  21. // IPs of the same type, and then by value.
  22. func sortIPs(ips []*net.IPNet) {
  23. sort.Slice(ips, func(i, j int) bool {
  24. i4, j4 := ips[i].IP.To4(), ips[j].IP.To4()
  25. if i4 != nil && j4 == nil {
  26. return true
  27. }
  28. if j4 != nil && i4 == nil {
  29. return false
  30. }
  31. return ips[i].String() < ips[j].String()
  32. })
  33. }
  34. func isLocal(ip net.IP) bool {
  35. return ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast()
  36. }
  37. func isPublic(ip net.IP) bool {
  38. // Check RFC 1918 addresses.
  39. if ip4 := ip.To4(); ip4 != nil {
  40. switch {
  41. // Check for 10.0.0.0/8.
  42. case ip4[0] == 10:
  43. return false
  44. // Check for 172.16.0.0/12.
  45. case ip4[0] == 172 && ip4[1]&0xf0 == 0x10:
  46. return false
  47. // Check for 192.168.0.0/16.
  48. case ip4[0] == 192 && ip4[1] == 168:
  49. return false
  50. default:
  51. return true
  52. }
  53. }
  54. // Check RFC 4193 addresses.
  55. if len(ip) == net.IPv6len {
  56. switch {
  57. // Check for fd00::/8.
  58. case ip[0] == 0xfd && ip[1] == 0x00:
  59. return false
  60. default:
  61. return true
  62. }
  63. }
  64. return false
  65. }
  66. type allocator struct {
  67. bits int
  68. ones int
  69. cidr *net.IPNet
  70. current net.IP
  71. }
  72. func newAllocator(cidr net.IPNet) *allocator {
  73. ones, bits := cidr.Mask.Size()
  74. current := make(net.IP, len(cidr.IP))
  75. copy(current, cidr.IP)
  76. if ip4 := current.To4(); ip4 != nil {
  77. current = ip4
  78. }
  79. return &allocator{
  80. bits: bits,
  81. ones: ones,
  82. cidr: &cidr,
  83. current: current,
  84. }
  85. }
  86. func (a *allocator) next() *net.IPNet {
  87. if a.current == nil {
  88. return nil
  89. }
  90. for i := len(a.current) - 1; i >= 0; i-- {
  91. a.current[i]++
  92. // if we haven't overflowed, then we can exit.
  93. if a.current[i] != 0 {
  94. break
  95. }
  96. }
  97. if !a.cidr.Contains(a.current) {
  98. a.current = nil
  99. }
  100. ip := make(net.IP, len(a.current))
  101. copy(ip, a.current)
  102. return &net.IPNet{IP: ip, Mask: net.CIDRMask(a.ones, a.bits)}
  103. }