8// Fast lookup table for intersection of a single IP address within a collection of CIDR networks.
10// Supports 4-byte (IPv4) and 16-byte (IPv6) networks.
12// Provides O(1) best-case, O(log(n)) worst-case performance.
13// In practice netmasks included will generally only be of standard lengths:
14// - /8, /16, /24, and /32 for IPv4
15// - /64 and /128 for IPv6.
16// As a result, typical lookup times will lean closer to best-case rather than worst-case even when most of the internet
23// Create a new NetSet with all of the provided networks.
24func NewNetSet() *NetSet {
26 ip4NetMaps: make([]ipNetMap, 0),
27 ip6NetMaps: make([]ipNetMap, 0),
31// Check if `ip` is in the set, true if within the set otherwise false.
32func (w *NetSet) Has(ip net.IP) bool {
33 netMaps := w.getNetMaps(ip)
35 // Check all ipNetMaps for intersection with `ip`.
36 for _, netMap := range *netMaps {
44// Add an CIDR network to the set.
45func (w *NetSet) AddIPNet(ipNet net.IPNet) {
46 netMaps := w.getNetMaps(ipNet.IP)
48 // Determine the size / number of ones in the CIDR network mask.
49 ones, _ := ipNet.Mask.Size()
53 // Search for the ipNetMap containing networks with the same number of ones.
54 for i := 0; len(*netMaps) > i; i++ {
55 if netMapOnes, _ := (*netMaps)[i].mask.Size(); netMapOnes == ones {
56 netMap = &(*netMaps)[i]
61 // Create a new ipNetMap if none with this number of ones have been created yet.
65 ips: make(map[string]bool),
67 *netMaps = append(*netMaps, *netMap)
68 // Recurse once now that there exists an netMap.
73 // Add the IP to the ipNetMap.
74 netMap.ips[ipNet.IP.String()] = true
77// Get the appropriate array of networks for the given IP version.
78func (w *NetSet) getNetMaps(ip net.IP) (netMaps *[]ipNetMap) {
81 netMaps = &w.ip4NetMaps
82 case ip.To16() != nil:
83 netMaps = &w.ip6NetMaps
85 panic(fmt.Sprintf("IP (%s) is neither 4-byte nor 16-byte?", ip.String()))
91// Hash-set of CIDR networks with the same mask size.
97// Check if the IP is in any of the CIDR networks contained in this map.
98func (m ipNetMap) has(ip net.IP) bool {
99 // Apply the mask to the IP to remove any irrelevant bits in the IP.
100 ipMasked := ip.Mask(m.mask)
103 "Mismatch in net.IPMask and net.IP protocol version, cannot apply mask %s to %s",
104 m.mask.String(), ip.String()))
107 // Check if the masked IP is the same as any of the networks.
108 if _, ok := m.ips[ipMasked.String()]; ok {
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list