2015-03-24 16:56:52 -04:00
|
|
|
|
package ipallocator
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"math/big"
|
|
|
|
|
"net"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestConversion(t *testing.T) {
|
|
|
|
|
ip := net.ParseIP("127.0.0.1")
|
|
|
|
|
i := ipToBigInt(ip)
|
|
|
|
|
if i.Cmp(big.NewInt(0x7f000001)) != 0 {
|
|
|
|
|
t.Fatal("incorrect conversion")
|
|
|
|
|
}
|
|
|
|
|
conv := bigIntToIP(i)
|
|
|
|
|
if !ip.Equal(conv) {
|
|
|
|
|
t.Error(conv.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestConversionIPv6(t *testing.T) {
|
|
|
|
|
ip := net.ParseIP("2a00:1450::1")
|
|
|
|
|
ip2 := net.ParseIP("2a00:1450::2")
|
|
|
|
|
ip3 := net.ParseIP("2a00:1450::1:1")
|
|
|
|
|
i := ipToBigInt(ip)
|
|
|
|
|
val, success := big.NewInt(0).SetString("2a001450000000000000000000000001", 16)
|
|
|
|
|
if !success {
|
|
|
|
|
t.Fatal("Hex-String to BigInt conversion failed.")
|
|
|
|
|
}
|
|
|
|
|
if i.Cmp(val) != 0 {
|
|
|
|
|
t.Fatal("incorrent conversion")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conv := bigIntToIP(i)
|
|
|
|
|
conv2 := bigIntToIP(big.NewInt(0).Add(i, big.NewInt(1)))
|
|
|
|
|
conv3 := bigIntToIP(big.NewInt(0).Add(i, big.NewInt(0x10000)))
|
|
|
|
|
|
|
|
|
|
if !ip.Equal(conv) {
|
|
|
|
|
t.Error("2a00:1450::1 should be equal to " + conv.String())
|
|
|
|
|
}
|
|
|
|
|
if !ip2.Equal(conv2) {
|
|
|
|
|
t.Error("2a00:1450::2 should be equal to " + conv2.String())
|
|
|
|
|
}
|
|
|
|
|
if !ip3.Equal(conv3) {
|
|
|
|
|
t.Error("2a00:1450::1:1 should be equal to " + conv3.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRequestNewIps(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ip net.IP
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
for i := 1; i < 10; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if expected := fmt.Sprintf("192.168.0.%d", i); ip.String() != expected {
|
|
|
|
|
t.Fatalf("Expected ip %s got %s", expected, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
value := bigIntToIP(big.NewInt(0).Add(ipToBigInt(ip), big.NewInt(1))).String()
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if ip.String() != value {
|
|
|
|
|
t.Fatalf("Expected to receive the next ip %s got %s", value, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRequestNewIpV6(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ip net.IP
|
|
|
|
|
var err error
|
|
|
|
|
for i := 1; i < 10; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if expected := fmt.Sprintf("2a00:1450::%d", i); ip.String() != expected {
|
|
|
|
|
t.Fatalf("Expected ip %s got %s", expected, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
value := bigIntToIP(big.NewInt(0).Add(ipToBigInt(ip), big.NewInt(1))).String()
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if ip.String() != value {
|
|
|
|
|
t.Fatalf("Expected to receive the next ip %s got %s", value, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestReleaseIp(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestReleaseIpV6(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGetReleasedIp(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value := ip.String()
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 253; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
_, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
err = a.ReleaseIP(network, ip)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ip.String() != value {
|
|
|
|
|
t.Fatalf("Expected to receive same ip %s got %s", value, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGetReleasedIpV6(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value := ip.String()
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 253; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
_, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
err = a.ReleaseIP(network, ip)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ip.String() != value {
|
|
|
|
|
t.Fatalf("Expected to receive same ip %s got %s", value, ip.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRequestSpecificIp(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 224},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ip := net.ParseIP("192.168.0.5")
|
|
|
|
|
|
|
|
|
|
// Request a "good" IP.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Request the same IP again.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, ip); err != ErrIPAlreadyAllocated {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Got the same IP twice: %#v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Request an out of range IP.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, net.ParseIP("192.168.0.42")); err != ErrIPOutOfRange {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Got an out of range IP: %#v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRequestSpecificIpV6(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ip := net.ParseIP("2a00:1450::5")
|
|
|
|
|
|
|
|
|
|
// Request a "good" IP.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Request the same IP again.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, ip); err != ErrIPAlreadyAllocated {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Got the same IP twice: %#v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Request an out of range IP.
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, net.ParseIP("2a00:1500::1")); err != ErrIPOutOfRange {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Got an out of range IP: %#v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestIPAllocator(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
expectedIPs := []net.IP{
|
|
|
|
|
0: net.IPv4(127, 0, 0, 1),
|
|
|
|
|
1: net.IPv4(127, 0, 0, 2),
|
|
|
|
|
2: net.IPv4(127, 0, 0, 3),
|
|
|
|
|
3: net.IPv4(127, 0, 0, 4),
|
|
|
|
|
4: net.IPv4(127, 0, 0, 5),
|
|
|
|
|
5: net.IPv4(127, 0, 0, 6),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gwIP, n, _ := net.ParseCIDR("127.0.0.1/29")
|
|
|
|
|
|
|
|
|
|
network := &net.IPNet{IP: gwIP, Mask: n.Mask}
|
|
|
|
|
// Pool after initialisation (f = free, u = used)
|
|
|
|
|
// 1(f) - 2(f) - 3(f) - 4(f) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// Check that we get 6 IPs, from 127.0.0.1–127.0.0.6, in that
|
|
|
|
|
// order.
|
|
|
|
|
for i := 0; i < 6; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, expectedIPs[i], ip)
|
|
|
|
|
}
|
|
|
|
|
// Before loop begin
|
|
|
|
|
// 1(f) - 2(f) - 3(f) - 4(f) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 0
|
|
|
|
|
// 1(u) - 2(f) - 3(f) - 4(f) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 1
|
|
|
|
|
// 1(u) - 2(u) - 3(f) - 4(f) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 2
|
|
|
|
|
// 1(u) - 2(u) - 3(u) - 4(f) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 3
|
|
|
|
|
// 1(u) - 2(u) - 3(u) - 4(u) - 5(f) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 4
|
|
|
|
|
// 1(u) - 2(u) - 3(u) - 4(u) - 5(u) - 6(f)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// After i = 5
|
|
|
|
|
// 1(u) - 2(u) - 3(u) - 4(u) - 5(u) - 6(u)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// Check that there are no more IPs
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("There shouldn't be any IP addresses at this point, got %s\n", ip)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Release some IPs in non-sequential order
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, expectedIPs[3]); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
// 1(u) - 2(u) - 3(u) - 4(f) - 5(u) - 6(u)
|
|
|
|
|
// ↑
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, expectedIPs[2]); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
// 1(u) - 2(u) - 3(f) - 4(f) - 5(u) - 6(u)
|
|
|
|
|
// ↑
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, expectedIPs[4]); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
// 1(u) - 2(u) - 3(f) - 4(f) - 5(f) - 6(u)
|
|
|
|
|
// ↑
|
|
|
|
|
|
|
|
|
|
// Make sure that IPs are reused in sequential order, starting
|
|
|
|
|
// with the first released IP
|
|
|
|
|
newIPs := make([]net.IP, 3)
|
|
|
|
|
for i := 0; i < 3; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newIPs[i] = ip
|
|
|
|
|
}
|
|
|
|
|
assertIPEquals(t, expectedIPs[2], newIPs[0])
|
|
|
|
|
assertIPEquals(t, expectedIPs[3], newIPs[1])
|
|
|
|
|
assertIPEquals(t, expectedIPs[4], newIPs[2])
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
_, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatal("There shouldn't be any IP addresses at this point")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAllocateFirstIP(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 0},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
firstIP := network.IP.To4().Mask(network.Mask)
|
|
|
|
|
first := big.NewInt(0).Add(ipToBigInt(firstIP), big.NewInt(1))
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
allocated := ipToBigInt(ip)
|
|
|
|
|
|
|
|
|
|
if allocated == first {
|
|
|
|
|
t.Fatalf("allocated ip should not equal first ip: %d == %d", first, allocated)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAllocateAllIps(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
current, first net.IP
|
|
|
|
|
err error
|
|
|
|
|
isFirst = true
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
for err == nil {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
current, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if isFirst {
|
|
|
|
|
first = current
|
|
|
|
|
isFirst = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != ErrNoAvailableIPs {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, first); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
again, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, first, again)
|
|
|
|
|
|
|
|
|
|
// ensure that alloc.last == alloc.begin won't result in dead loop
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test by making alloc.last the only free ip and ensure we get it back
|
|
|
|
|
// #1. first of the range, (alloc.last == ipToInt(first) already)
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, first); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ret, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, first, ret)
|
|
|
|
|
|
|
|
|
|
// #2. last of the range, note that current is the last one
|
|
|
|
|
last := net.IPv4(192, 168, 0, 254)
|
2015-04-10 14:59:05 -04:00
|
|
|
|
setLastTo(t, a, network, last)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ret, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, last, ret)
|
|
|
|
|
|
|
|
|
|
// #3. middle of the range
|
|
|
|
|
mid := net.IPv4(192, 168, 0, 7)
|
2015-04-10 14:59:05 -04:00
|
|
|
|
setLastTo(t, a, network, mid)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ret, err = a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, mid, ret)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure the pool is full when calling setLastTo.
|
|
|
|
|
// we don't cheat here
|
2015-04-10 14:59:05 -04:00
|
|
|
|
func setLastTo(t *testing.T, a *IPAllocator, network *net.IPNet, ip net.IP) {
|
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ret, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertIPEquals(t, ip, ret)
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.ReleaseIP(network, ip); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAllocateDifferentSubnets(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network1 := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
network2 := &net.IPNet{
|
|
|
|
|
IP: []byte{127, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
network3 := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
|
|
|
|
|
}
|
|
|
|
|
network4 := &net.IPNet{
|
|
|
|
|
IP: []byte{0x2a, 0x00, 0x16, 0x32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
|
|
|
|
|
}
|
|
|
|
|
expectedIPs := []net.IP{
|
|
|
|
|
0: net.IPv4(192, 168, 0, 1),
|
|
|
|
|
1: net.IPv4(192, 168, 0, 2),
|
|
|
|
|
2: net.IPv4(127, 0, 0, 1),
|
|
|
|
|
3: net.IPv4(127, 0, 0, 2),
|
|
|
|
|
4: net.ParseIP("2a00:1450::1"),
|
|
|
|
|
5: net.ParseIP("2a00:1450::2"),
|
|
|
|
|
6: net.ParseIP("2a00:1450::3"),
|
|
|
|
|
7: net.ParseIP("2a00:1632::1"),
|
|
|
|
|
8: net.ParseIP("2a00:1632::2"),
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip11, err := a.RequestIP(network1, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip12, err := a.RequestIP(network1, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip21, err := a.RequestIP(network2, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip22, err := a.RequestIP(network2, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip31, err := a.RequestIP(network3, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip32, err := a.RequestIP(network3, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip33, err := a.RequestIP(network3, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip41, err := a.RequestIP(network4, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
ip42, err := a.RequestIP(network4, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
assertIPEquals(t, expectedIPs[0], ip11)
|
|
|
|
|
assertIPEquals(t, expectedIPs[1], ip12)
|
|
|
|
|
assertIPEquals(t, expectedIPs[2], ip21)
|
|
|
|
|
assertIPEquals(t, expectedIPs[3], ip22)
|
|
|
|
|
assertIPEquals(t, expectedIPs[4], ip31)
|
|
|
|
|
assertIPEquals(t, expectedIPs[5], ip32)
|
|
|
|
|
assertIPEquals(t, expectedIPs[6], ip33)
|
|
|
|
|
assertIPEquals(t, expectedIPs[7], ip41)
|
|
|
|
|
assertIPEquals(t, expectedIPs[8], ip42)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRegisterBadTwice(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 1, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
subnet := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 1, 8},
|
|
|
|
|
Mask: []byte{255, 255, 255, 248},
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.RegisterSubnet(network, subnet); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
subnet = &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 1, 16},
|
|
|
|
|
Mask: []byte{255, 255, 255, 248},
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.RegisterSubnet(network, subnet); err != ErrNetworkAlreadyRegistered {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Expecteded ErrNetworkAlreadyRegistered error, got %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRegisterBadRange(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 1, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
subnet := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 1, 1},
|
|
|
|
|
Mask: []byte{255, 255, 0, 0},
|
|
|
|
|
}
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.RegisterSubnet(network, subnet); err != ErrBadSubnet {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Expected ErrBadSubnet error, got %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAllocateFromRange(t *testing.T) {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
2015-03-24 16:56:52 -04:00
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
// 192.168.1.9 - 192.168.1.14
|
|
|
|
|
subnet := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 8},
|
|
|
|
|
Mask: []byte{255, 255, 255, 248},
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if err := a.RegisterSubnet(network, subnet); err != nil {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
expectedIPs := []net.IP{
|
|
|
|
|
0: net.IPv4(192, 168, 0, 9),
|
|
|
|
|
1: net.IPv4(192, 168, 0, 10),
|
|
|
|
|
2: net.IPv4(192, 168, 0, 11),
|
|
|
|
|
3: net.IPv4(192, 168, 0, 12),
|
|
|
|
|
4: net.IPv4(192, 168, 0, 13),
|
|
|
|
|
5: net.IPv4(192, 168, 0, 14),
|
|
|
|
|
}
|
|
|
|
|
for _, ip := range expectedIPs {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
rip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
assertIPEquals(t, ip, rip)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-10 14:59:05 -04:00
|
|
|
|
if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
|
2015-03-24 16:56:52 -04:00
|
|
|
|
t.Fatalf("Expected ErrNoAvailableIPs error, got %v", err)
|
|
|
|
|
}
|
|
|
|
|
for _, ip := range expectedIPs {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a.ReleaseIP(network, ip)
|
|
|
|
|
rip, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
assertIPEquals(t, ip, rip)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func assertIPEquals(t *testing.T, ip1, ip2 net.IP) {
|
|
|
|
|
if !ip1.Equal(ip2) {
|
|
|
|
|
t.Fatalf("Expected IP %s, got %s", ip1, ip2)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func BenchmarkRequestIP(b *testing.B) {
|
|
|
|
|
network := &net.IPNet{
|
|
|
|
|
IP: []byte{192, 168, 0, 1},
|
|
|
|
|
Mask: []byte{255, 255, 255, 0},
|
|
|
|
|
}
|
|
|
|
|
b.ResetTimer()
|
2015-04-10 14:59:05 -04:00
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
for i := 0; i < b.N; i++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
a := New()
|
|
|
|
|
|
2015-03-24 16:56:52 -04:00
|
|
|
|
for j := 0; j < 253; j++ {
|
2015-04-10 14:59:05 -04:00
|
|
|
|
_, err := a.RequestIP(network, nil)
|
2015-03-24 16:56:52 -04:00
|
|
|
|
if err != nil {
|
|
|
|
|
b.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|