From fec54c232cd3aa19c0da00e89a0c35143f606b5e Mon Sep 17 00:00:00 2001 From: Rob Adams Date: Wed, 31 Jan 2018 14:37:11 -0800 Subject: [PATCH] Fix bug in covering logic and add new Covers() method for network. Signed-off-by: Rob Adams --- brute.go | 6 +++++- net/ip.go | 7 +++++++ net/ip_test.go | 25 +++++++++++++++++++++++++ trie.go | 2 +- trie_test.go | 9 +++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/brute.go b/brute.go index 8da7425..4173256 100644 --- a/brute.go +++ b/brute.go @@ -98,7 +98,11 @@ func (b *bruteRanger) CoveredNetworks(network net.IPNet) ([]RangerEntry, error) var results []RangerEntry for _, entry := range entries { entrynetwork := entry.Network() - if network.Contains(entrynetwork.IP) { + + searchMaskSize, _ := network.Mask.Size() + entryMaskSize, _ := entrynetwork.Mask.Size() + + if network.Contains(entrynetwork.IP) && searchMaskSize <= entryMaskSize { results = append(results, entry) } } diff --git a/net/ip.go b/net/ip.go index f26044c..d310f17 100644 --- a/net/ip.go +++ b/net/ip.go @@ -208,6 +208,13 @@ func (n Network) Contains(nn NetworkNumber) bool { return true } +// Contains returns true if Network covers o, false otherwise +func (n Network) Covers(o Network) bool { + nMaskSize, _ := n.IPNet.Mask.Size() + oMaskSize, _ := o.IPNet.Mask.Size() + return n.Contains(o.Number) && nMaskSize <= oMaskSize +} + // LeastCommonBitPosition returns the smallest position of the preceding common // bits of the 2 networks, and returns an error ErrNoGreatestCommonBit // if the two network number diverges from the first bit. diff --git a/net/ip_test.go b/net/ip_test.go index 538983a..6a9d2b1 100644 --- a/net/ip_test.go +++ b/net/ip_test.go @@ -412,6 +412,31 @@ func TestPreviousIP(t *testing.T) { } } +func TestNetworkCovers(t *testing.T) { + cases := []struct { + network string + covers string + result bool + name string + }{ + {"10.0.0.0/24", "10.0.0.1/25", true, "contains"}, + {"10.0.0.0/24", "11.0.0.1/25", false, "not contains"}, + {"10.0.0.0/16", "10.0.0.0/15", false, "prefix false"}, + {"10.0.0.0/15", "10.0.0.0/16", true, "prefix true"}, + {"10.0.0.0/15", "10.0.0.0/15", true, "same"}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + _, n, _ := net.ParseCIDR(tc.network) + network := NewNetwork(*n) + _, n, _ = net.ParseCIDR(tc.covers) + covers := NewNetwork(*n) + assert.Equal(t, tc.result, network.Covers(covers)) + }) + } +} + /* ********************************* Benchmarking ip manipulations. diff --git a/trie.go b/trie.go index 0b9c9e2..34dd544 100644 --- a/trie.go +++ b/trie.go @@ -186,7 +186,7 @@ func (p *prefixTrie) containingNetworks(number rnet.NetworkNumber) ([]RangerEntr func (p *prefixTrie) coveredNetworks(network rnet.Network) ([]RangerEntry, error) { var results []RangerEntry - if p.hasEntry() && network.Contains(p.network.Number) { + if p.hasEntry() && network.Covers(p.network) { results = []RangerEntry{p.entry} } if p.targetBitPosition() < 0 { diff --git a/trie_test.go b/trie_test.go index 8955e2b..29125fd 100644 --- a/trie_test.go +++ b/trie_test.go @@ -404,6 +404,15 @@ var coveredNetworkTests = []coveredNetworkTest{ []string{"192.168.0.0/24", "192.168.1.1/32"}, "path not taken", }, + { + rnet.IPv4, + []string{ + "192.168.0.0/15", + }, + "192.168.0.0/16", + nil, + "only masks different", + }, } func TestPrefixTrieCoveredNetworks(t *testing.T) { -- GitLab