ipaddrs.go 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package sockaddr
  2. import "bytes"
  3. type IPAddrs []IPAddr
  4. func (s IPAddrs) Len() int { return len(s) }
  5. func (s IPAddrs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  6. // // SortIPAddrsByCmp is a type that satisfies sort.Interface and can be used
  7. // // by the routines in this package. The SortIPAddrsByCmp type is used to
  8. // // sort IPAddrs by Cmp()
  9. // type SortIPAddrsByCmp struct{ IPAddrs }
  10. // // Less reports whether the element with index i should sort before the
  11. // // element with index j.
  12. // func (s SortIPAddrsByCmp) Less(i, j int) bool {
  13. // // Sort by Type, then address, then port number.
  14. // return Less(s.IPAddrs[i], s.IPAddrs[j])
  15. // }
  16. // SortIPAddrsBySpecificMaskLen is a type that satisfies sort.Interface and
  17. // can be used by the routines in this package. The
  18. // SortIPAddrsBySpecificMaskLen type is used to sort IPAddrs by smallest
  19. // network (most specific to largest network).
  20. type SortIPAddrsByNetworkSize struct{ IPAddrs }
  21. // Less reports whether the element with index i should sort before the
  22. // element with index j.
  23. func (s SortIPAddrsByNetworkSize) Less(i, j int) bool {
  24. // Sort masks with a larger binary value (i.e. fewer hosts per network
  25. // prefix) after masks with a smaller value (larger number of hosts per
  26. // prefix).
  27. switch bytes.Compare([]byte(*s.IPAddrs[i].NetIPMask()), []byte(*s.IPAddrs[j].NetIPMask())) {
  28. case 0:
  29. // Fall through to the second test if the net.IPMasks are the
  30. // same.
  31. break
  32. case 1:
  33. return true
  34. case -1:
  35. return false
  36. default:
  37. panic("bad, m'kay?")
  38. }
  39. // Sort IPs based on the length (i.e. prefer IPv4 over IPv6).
  40. iLen := len(*s.IPAddrs[i].NetIP())
  41. jLen := len(*s.IPAddrs[j].NetIP())
  42. if iLen != jLen {
  43. return iLen > jLen
  44. }
  45. // Sort IPs based on their network address from lowest to highest.
  46. switch bytes.Compare(s.IPAddrs[i].NetIPNet().IP, s.IPAddrs[j].NetIPNet().IP) {
  47. case 0:
  48. break
  49. case 1:
  50. return false
  51. case -1:
  52. return true
  53. default:
  54. panic("lol wut?")
  55. }
  56. // If a host does not have a port set, it always sorts after hosts
  57. // that have a port (e.g. a host with a /32 and port number is more
  58. // specific and should sort first over a host with a /32 but no port
  59. // set).
  60. if s.IPAddrs[i].IPPort() == 0 || s.IPAddrs[j].IPPort() == 0 {
  61. return false
  62. }
  63. return s.IPAddrs[i].IPPort() < s.IPAddrs[j].IPPort()
  64. }
  65. // SortIPAddrsBySpecificMaskLen is a type that satisfies sort.Interface and
  66. // can be used by the routines in this package. The
  67. // SortIPAddrsBySpecificMaskLen type is used to sort IPAddrs by smallest
  68. // network (most specific to largest network).
  69. type SortIPAddrsBySpecificMaskLen struct{ IPAddrs }
  70. // Less reports whether the element with index i should sort before the
  71. // element with index j.
  72. func (s SortIPAddrsBySpecificMaskLen) Less(i, j int) bool {
  73. return s.IPAddrs[i].Maskbits() > s.IPAddrs[j].Maskbits()
  74. }
  75. // SortIPAddrsByBroadMaskLen is a type that satisfies sort.Interface and can
  76. // be used by the routines in this package. The SortIPAddrsByBroadMaskLen
  77. // type is used to sort IPAddrs by largest network (i.e. largest subnets
  78. // first).
  79. type SortIPAddrsByBroadMaskLen struct{ IPAddrs }
  80. // Less reports whether the element with index i should sort before the
  81. // element with index j.
  82. func (s SortIPAddrsByBroadMaskLen) Less(i, j int) bool {
  83. return s.IPAddrs[i].Maskbits() < s.IPAddrs[j].Maskbits()
  84. }