Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
p2p
go-cidranger
Commits
2b3e05f8
Commit
2b3e05f8
authored
Aug 22, 2017
by
Yulin Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add benchmark cases
parent
954cc32b
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
6389 additions
and
11 deletions
+6389
-11
cidranger_test.go
cidranger_test.go
+100
-0
ranger/trie/trie.go
ranger/trie/trie.go
+5
-5
testdata/aws_ip_ranges.json
testdata/aws_ip_ranges.json
+6253
-0
util/cidr/cidr.go
util/cidr/cidr.go
+2
-2
util/ip/ip.go
util/ip/ip.go
+9
-2
util/ip/ip_test.go
util/ip/ip_test.go
+20
-2
No files found.
cidranger_test.go
0 → 100644
View file @
2b3e05f8
package
cidranger
import
(
"encoding/json"
"io/ioutil"
"math/rand"
"net"
"testing"
"github.com/stretchr/testify/assert"
"github.com/yl2chen/cidranger/util/ip"
)
type
AWSRanges
struct
{
Prefixes
[]
Prefix
`json:"prefixes"`
}
type
Prefix
struct
{
IPPrefix
string
`json:"ip_prefix"`
Region
string
`json:"region"`
Service
string
`json:"service"`
}
func
TestContains
(
t
*
testing
.
T
)
{
rangers
:=
[]
Ranger
{
NewLPCTrieRanger
()}
groundRanger
:=
NewBruteRanger
()
for
_
,
ranger
:=
range
rangers
{
configureRangerWithAWSRanges
(
t
,
ranger
)
}
configureRangerWithAWSRanges
(
t
,
groundRanger
)
for
i
:=
0
;
i
<
100000
;
i
++
{
nn
:=
ip
.
Uint32ToIPv4
(
rand
.
Uint32
())
expected
,
err
:=
groundRanger
.
Contains
(
nn
)
for
_
,
ranger
:=
range
rangers
{
assert
.
NoError
(
t
,
err
)
actual
,
err
:=
ranger
.
Contains
(
nn
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
expected
,
actual
)
}
}
}
func
TestContainingNetworks
(
t
*
testing
.
T
)
{
rangers
:=
[]
Ranger
{
NewLPCTrieRanger
()}
groundRanger
:=
NewBruteRanger
()
for
_
,
ranger
:=
range
rangers
{
configureRangerWithAWSRanges
(
t
,
ranger
)
}
configureRangerWithAWSRanges
(
t
,
groundRanger
)
for
i
:=
0
;
i
<
100000
;
i
++
{
nn
:=
ip
.
Uint32ToIPv4
(
rand
.
Uint32
())
expected
,
err
:=
groundRanger
.
ContainingNetworks
(
nn
)
for
_
,
ranger
:=
range
rangers
{
assert
.
NoError
(
t
,
err
)
actual
,
err
:=
ranger
.
ContainingNetworks
(
nn
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
expected
),
len
(
actual
))
for
_
,
network
:=
range
actual
{
assert
.
Contains
(
t
,
expected
,
network
)
}
}
}
}
func
BenchmarkLPCTrieUsingAWSRanges
(
b
*
testing
.
B
)
{
benchmarkContainsUsingAWSRanges
(
b
,
NewLPCTrieRanger
())
}
func
BenchmarkBruteRangerUsingAWSRanges
(
b
*
testing
.
B
)
{
benchmarkContainsUsingAWSRanges
(
b
,
NewBruteRanger
())
}
func
configureRangerWithAWSRanges
(
tb
testing
.
TB
,
ranger
Ranger
)
{
ranges
:=
loadAWSRanges
(
tb
)
for
_
,
prefix
:=
range
ranges
.
Prefixes
{
_
,
network
,
err
:=
net
.
ParseCIDR
(
prefix
.
IPPrefix
)
assert
.
NoError
(
tb
,
err
)
ranger
.
Insert
(
*
network
)
}
}
func
benchmarkContainsUsingAWSRanges
(
tb
testing
.
TB
,
ranger
Ranger
)
{
configureRangerWithAWSRanges
(
tb
,
ranger
)
ip
:=
net
.
ParseIP
(
"52.95.110.1"
)
for
n
:=
0
;
n
<
tb
.
(
*
testing
.
B
)
.
N
;
n
++
{
ranger
.
Contains
(
ip
)
}
}
func
loadAWSRanges
(
tb
testing
.
TB
)
*
AWSRanges
{
file
,
err
:=
ioutil
.
ReadFile
(
"./testdata/aws_ip_ranges.json"
)
assert
.
NoError
(
tb
,
err
)
var
ranges
AWSRanges
err
=
json
.
Unmarshal
(
file
,
&
ranges
)
assert
.
NoError
(
tb
,
err
)
return
&
ranges
}
ranger/trie/trie.go
View file @
2b3e05f8
...
@@ -65,7 +65,7 @@ func newPathPrefixTrie(network *net.IPNet, numBitsSkipped uint8) (*PrefixTrie, e
...
@@ -65,7 +65,7 @@ func newPathPrefixTrie(network *net.IPNet, numBitsSkipped uint8) (*PrefixTrie, e
path
:=
NewPrefixTree
()
path
:=
NewPrefixTree
()
path
.
numBitsSkipped
=
numBitsSkipped
path
.
numBitsSkipped
=
numBitsSkipped
path
.
network
=
cidr
.
MaskNetwork
(
network
,
int
(
numBitsSkipped
))
path
.
network
=
cidr
.
MaskNetwork
(
network
,
int
(
numBitsSkipped
))
networkNumber
,
err
:=
iputil
.
IPv4To
BigEndian
Uint32
(
path
.
network
.
IP
)
networkNumber
,
err
:=
iputil
.
IPv4ToUint32
(
path
.
network
.
IP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -86,7 +86,7 @@ func newEntryTrie(network *net.IPNet) (*PrefixTrie, error) {
...
@@ -86,7 +86,7 @@ func newEntryTrie(network *net.IPNet) (*PrefixTrie, error) {
// Insert inserts the given cidr range into prefix trie.
// Insert inserts the given cidr range into prefix trie.
func
(
p
*
PrefixTrie
)
Insert
(
network
net
.
IPNet
)
error
{
func
(
p
*
PrefixTrie
)
Insert
(
network
net
.
IPNet
)
error
{
networkNumber
,
err
:=
iputil
.
IPv4To
BigEndian
Uint32
(
network
.
IP
)
networkNumber
,
err
:=
iputil
.
IPv4ToUint32
(
network
.
IP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -95,7 +95,7 @@ func (p *PrefixTrie) Insert(network net.IPNet) error {
...
@@ -95,7 +95,7 @@ func (p *PrefixTrie) Insert(network net.IPNet) error {
// Remove removes network from trie.
// Remove removes network from trie.
func
(
p
*
PrefixTrie
)
Remove
(
network
net
.
IPNet
)
(
*
net
.
IPNet
,
error
)
{
func
(
p
*
PrefixTrie
)
Remove
(
network
net
.
IPNet
)
(
*
net
.
IPNet
,
error
)
{
networkNumber
,
err
:=
iputil
.
IPv4To
BigEndian
Uint32
(
network
.
IP
)
networkNumber
,
err
:=
iputil
.
IPv4ToUint32
(
network
.
IP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -147,7 +147,7 @@ func (p *PrefixTrie) childrenCount() int {
...
@@ -147,7 +147,7 @@ func (p *PrefixTrie) childrenCount() int {
// Contains returns boolean indicating whether given ip is contained in any
// Contains returns boolean indicating whether given ip is contained in any
// of the inserted networks.
// of the inserted networks.
func
(
p
*
PrefixTrie
)
Contains
(
ip
net
.
IP
)
(
bool
,
error
)
{
func
(
p
*
PrefixTrie
)
Contains
(
ip
net
.
IP
)
(
bool
,
error
)
{
ipUint32
,
err
:=
iputil
.
IPv4To
BigEndian
Uint32
(
ip
)
ipUint32
,
err
:=
iputil
.
IPv4ToUint32
(
ip
)
if
err
!=
nil
{
if
err
!=
nil
{
return
false
,
err
return
false
,
err
}
}
...
@@ -161,7 +161,7 @@ func (p *PrefixTrie) Contains(ip net.IP) (bool, error) {
...
@@ -161,7 +161,7 @@ func (p *PrefixTrie) Contains(ip net.IP) (bool, error) {
// ContainingNetworks returns the list of networks given ip is a part of in
// ContainingNetworks returns the list of networks given ip is a part of in
// ascending prefix order.
// ascending prefix order.
func
(
p
*
PrefixTrie
)
ContainingNetworks
(
ip
net
.
IP
)
([]
net
.
IPNet
,
error
)
{
func
(
p
*
PrefixTrie
)
ContainingNetworks
(
ip
net
.
IP
)
([]
net
.
IPNet
,
error
)
{
ipUint32
,
err
:=
iputil
.
IPv4To
BigEndian
Uint32
(
ip
)
ipUint32
,
err
:=
iputil
.
IPv4ToUint32
(
ip
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
testdata/aws_ip_ranges.json
0 → 100644
View file @
2b3e05f8
This diff is collapsed.
Click to expand it.
util/cidr/cidr.go
View file @
2b3e05f8
...
@@ -17,11 +17,11 @@ var ErrNoGreatestCommonBit = fmt.Errorf("No greatest common bit")
...
@@ -17,11 +17,11 @@ var ErrNoGreatestCommonBit = fmt.Errorf("No greatest common bit")
// GreatestCommonBitPosition returns the greatest common bit position of
// GreatestCommonBitPosition returns the greatest common bit position of
// given cidr blocks.
// given cidr blocks.
func
GreatestCommonBitPosition
(
network1
*
net
.
IPNet
,
network2
*
net
.
IPNet
)
(
uint8
,
error
)
{
func
GreatestCommonBitPosition
(
network1
*
net
.
IPNet
,
network2
*
net
.
IPNet
)
(
uint8
,
error
)
{
ip1
,
err
:=
ip
.
IPv4To
BigEndian
Uint32
(
network1
.
IP
)
ip1
,
err
:=
ip
.
IPv4ToUint32
(
network1
.
IP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
ip2
,
err
:=
ip
.
IPv4To
BigEndian
Uint32
(
network2
.
IP
)
ip2
,
err
:=
ip
.
IPv4ToUint32
(
network2
.
IP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
...
...
util/ip/ip.go
View file @
2b3e05f8
...
@@ -17,8 +17,8 @@ var ErrBitsNotValid = fmt.Errorf("bits requested not valid")
...
@@ -17,8 +17,8 @@ var ErrBitsNotValid = fmt.Errorf("bits requested not valid")
const
ipv4BitLength
=
32
const
ipv4BitLength
=
32
// IPv4To
BigEndian
Uint32 converts
IPv
4 to uint32.
// IPv4ToUint32 converts
ipV
4 to uint32.
func
IPv4To
BigEndian
Uint32
(
ip
net
.
IP
)
(
uint32
,
error
)
{
func
IPv4ToUint32
(
ip
net
.
IP
)
(
uint32
,
error
)
{
ip
=
ip
.
To4
()
ip
=
ip
.
To4
()
if
ip
==
nil
{
if
ip
==
nil
{
return
0
,
ErrNotIPv4Error
return
0
,
ErrNotIPv4Error
...
@@ -26,6 +26,13 @@ func IPv4ToBigEndianUint32(ip net.IP) (uint32, error) {
...
@@ -26,6 +26,13 @@ func IPv4ToBigEndianUint32(ip net.IP) (uint32, error) {
return
binary
.
BigEndian
.
Uint32
(
ip
),
nil
return
binary
.
BigEndian
.
Uint32
(
ip
),
nil
}
}
// Uint32ToIPv4 converts uint32 to ipV4 net.IP.
func
Uint32ToIPv4
(
nn
uint32
)
net
.
IP
{
ip
:=
make
(
net
.
IP
,
4
)
binary
.
BigEndian
.
PutUint32
(
ip
,
nn
)
return
ip
}
// IPv4BitsAsUint returns uint32 representing bits at position of length
// IPv4BitsAsUint returns uint32 representing bits at position of length
// numberOfBits, position is a number in [0, 31] representing the starting
// numberOfBits, position is a number in [0, 31] representing the starting
// position in ip, with 31 being the most significant bit.
// position in ip, with 31 being the most significant bit.
...
...
util/ip/ip_test.go
View file @
2b3e05f8
...
@@ -7,7 +7,7 @@ import (
...
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
)
)
func
TestIPv4To
LittleEndian
Uint32
(
t
*
testing
.
T
)
{
func
TestIPv4ToUint32
(
t
*
testing
.
T
)
{
cases
:=
[]
struct
{
cases
:=
[]
struct
{
ip
string
ip
string
ipUint32
uint32
ipUint32
uint32
...
@@ -20,13 +20,31 @@ func TestIPv4ToLittleEndianUint32(t *testing.T) {
...
@@ -20,13 +20,31 @@ func TestIPv4ToLittleEndianUint32(t *testing.T) {
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
c
.
ip
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
c
.
ip
,
func
(
t
*
testing
.
T
)
{
ret
,
err
:=
IPv4To
BigEndian
Uint32
(
net
.
ParseIP
(
c
.
ip
))
ret
,
err
:=
IPv4ToUint32
(
net
.
ParseIP
(
c
.
ip
))
assert
.
Equal
(
t
,
c
.
expectedErr
,
err
)
assert
.
Equal
(
t
,
c
.
expectedErr
,
err
)
assert
.
Equal
(
t
,
c
.
ipUint32
,
ret
)
assert
.
Equal
(
t
,
c
.
ipUint32
,
ret
)
})
})
}
}
}
}
func
TestUint32ToIPv4
(
t
*
testing
.
T
)
{
cases
:=
[]
struct
{
ip
uint32
expected
net
.
IP
name
string
}{
{
2147483648
,
net
.
ParseIP
(
"128.0.0.0"
)
.
To4
(),
"128.0.0.0"
},
{
2147483649
,
net
.
ParseIP
(
"128.0.0.1"
)
.
To4
(),
"128.0.0.1"
},
{
4294967295
,
net
.
ParseIP
(
"255.255.255.255"
)
.
To4
(),
"255.255.255.255"
},
}
for
_
,
tc
:=
range
cases
{
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
assert
.
Equal
(
t
,
tc
.
expected
,
Uint32ToIPv4
(
tc
.
ip
))
})
}
}
func
TestIPv4BitsAsUint
(
t
*
testing
.
T
)
{
func
TestIPv4BitsAsUint
(
t
*
testing
.
T
)
{
cases
:=
[]
struct
{
cases
:=
[]
struct
{
ip
string
ip
string
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment