Documentation ¶
Overview ¶
Package iptrie provides an IP/network tree (trie) implementation for fast IP address lookups.
Index ¶
- type Trie
- func (pt *Trie) ContainingNetworks(ip netip.Addr) []netip.Prefix
- func (pt *Trie) Contains(ip netip.Addr) bool
- func (pt *Trie) CoveredNetworks(network netip.Prefix) []netip.Prefix
- func (pt *Trie) Find(ip netip.Addr) any
- func (pt *Trie) FindLargest(ip netip.Addr) any
- func (pt *Trie) Insert(network netip.Prefix, value any)
- func (pt *Trie) Remove(network netip.Prefix) any
- func (pt *Trie) String() string
- type TrieLoader
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Trie ¶
type Trie struct {
// contains filtered or unexported fields
}
Trie is a compressed IP radix trie implementation, similar to what is described at https://vincent.bernat.im/en/blog/2017-ipv4-route-lookup-linux
Path compression merges nodes with only one child into their parent, decreasing the amount of traversals needed when looking up a value.
Example ¶
ipt := NewTrie() ipt.Insert(netip.MustParsePrefix("10.0.0.0/8"), "foo") ipt.Insert(netip.MustParsePrefix("10.1.0.0/24"), "bar") fmt.Printf("10.2.0.1: %+v\n", ipt.Find(netip.MustParseAddr("10.2.0.1"))) fmt.Printf("10.1.0.1: %+v\n", ipt.Find(netip.MustParseAddr("10.1.0.1"))) fmt.Printf("11.0.0.1: %+v\n", ipt.Find(netip.MustParseAddr("11.0.0.1")))
Output: 10.2.0.1: foo 10.1.0.1: bar 11.0.0.1: <nil>
func (*Trie) ContainingNetworks ¶
ContainingNetworks returns the list of networks containing the given ip in ascending prefix order (largest network to smallest).
Note: Inserted addresses are normalized to IPv6, so the returned list will be IPv6 only.
func (*Trie) CoveredNetworks ¶
CoveredNetworks returns the list of networks contained within the given network.
Note: Inserted addresses are normalized to IPv6, so the returned list will be IPv6 only.
func (*Trie) Find ¶
Find returns the value from the most specific network (largest prefix) containing the given address.
func (*Trie) FindLargest ¶
FindLargest returns the value from the largest network (smallest prefix) containing the given address.
func (*Trie) String ¶
String returns string representation of trie.
The result will contain implicit nodes which exist as parents for multiple entries, but can be distinguished by the lack of a value.
Note: Addresses are normalized to IPv6.
Example ¶
inserts := []string{"192.168.0.0/24", "192.168.1.0/24", "192.168.1.0/30"} trie := NewTrie() for _, insert := range inserts { network := netip.MustParsePrefix(insert) trie.Insert(network, "net="+insert) } fmt.Println(trie.String())
Output: ::/0 ├ ::ffff:192.168.0.0/119 ├ ├ ::ffff:192.168.0.0/120 • net=192.168.0.0/24 ├ ├ ::ffff:192.168.1.0/120 • net=192.168.1.0/24 ├ ├ ├ ::ffff:192.168.1.0/126 • net=192.168.1.0/30
type TrieLoader ¶
type TrieLoader struct {
// contains filtered or unexported fields
}
TrieLoader can be used to improve the performance of bulk inserts to a Trie. It caches the node of the last insert in the tree, using it as the starting point to start searching for the location of the next insert. This is highly beneficial when the addresses are pre-sorted.
Example ¶
pt := NewTrie() ptl := NewTrieLoader(pt) networks := []string{ "10.0.0.0/8", "10.1.0.0/16", "192.168.0.0/24", "192.168.1.1/32", } for _, n := range networks { ptl.Insert(netip.MustParsePrefix(n), "net="+n) } fmt.Printf("%s\n", pt.String())
Output: ::/0 ├ ::ffff:0.0.0.0/96 ├ ├ ::ffff:10.0.0.0/104 • net=10.0.0.0/8 ├ ├ ├ ::ffff:10.1.0.0/112 • net=10.1.0.0/16 ├ ├ ::ffff:192.168.0.0/119 ├ ├ ├ ::ffff:192.168.0.0/120 • net=192.168.0.0/24 ├ ├ ├ ::ffff:192.168.1.1/128 • net=192.168.1.1/32
func NewTrieLoader ¶
func NewTrieLoader(trie *Trie) *TrieLoader