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