|
@@ -2,6 +2,7 @@ package ipallocator
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "math/big"
|
|
|
"net"
|
|
|
"testing"
|
|
|
)
|
|
@@ -10,6 +11,46 @@ func reset() {
|
|
|
allocatedIPs = networkSet{}
|
|
|
}
|
|
|
|
|
|
+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) {
|
|
|
defer reset()
|
|
|
network := &net.IPNet{
|
|
@@ -19,6 +60,7 @@ func TestRequestNewIps(t *testing.T) {
|
|
|
|
|
|
var ip net.IP
|
|
|
var err error
|
|
|
+
|
|
|
for i := 2; i < 10; i++ {
|
|
|
ip, err = RequestIP(network, nil)
|
|
|
if err != nil {
|
|
@@ -29,7 +71,39 @@ func TestRequestNewIps(t *testing.T) {
|
|
|
t.Fatalf("Expected ip %s got %s", expected, ip.String())
|
|
|
}
|
|
|
}
|
|
|
- value := intToIP(ipToInt(ip) + 1).String()
|
|
|
+ value := bigIntToIP(big.NewInt(0).Add(ipToBigInt(ip), big.NewInt(1))).String()
|
|
|
+ if err := ReleaseIP(network, ip); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ ip, err = RequestIP(network, nil)
|
|
|
+ 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) {
|
|
|
+ defer reset()
|
|
|
+ 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++ {
|
|
|
+ ip, err = RequestIP(network, nil)
|
|
|
+ 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()
|
|
|
if err := ReleaseIP(network, ip); err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
@@ -59,6 +133,23 @@ func TestReleaseIp(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func TestReleaseIpV6(t *testing.T) {
|
|
|
+ defer reset()
|
|
|
+ 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, err := RequestIP(network, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := ReleaseIP(network, ip); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func TestGetReleasedIp(t *testing.T) {
|
|
|
defer reset()
|
|
|
network := &net.IPNet{
|
|
@@ -97,6 +188,44 @@ func TestGetReleasedIp(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func TestGetReleasedIpV6(t *testing.T) {
|
|
|
+ defer reset()
|
|
|
+ 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},
|
|
|
+ }
|
|
|
+
|
|
|
+ ip, err := RequestIP(network, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ value := ip.String()
|
|
|
+ if err := ReleaseIP(network, ip); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := 0; i < 253; i++ {
|
|
|
+ _, err = RequestIP(network, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ err = ReleaseIP(network, ip)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ip, err = RequestIP(network, nil)
|
|
|
+ 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) {
|
|
|
defer reset()
|
|
|
network := &net.IPNet{
|
|
@@ -122,15 +251,28 @@ func TestRequestSpecificIp(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func TestConversion(t *testing.T) {
|
|
|
- ip := net.ParseIP("127.0.0.1")
|
|
|
- i := ipToInt(ip)
|
|
|
- if i == 0 {
|
|
|
- t.Fatal("converted to zero")
|
|
|
+func TestRequestSpecificIpV6(t *testing.T) {
|
|
|
+ defer reset()
|
|
|
+ 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
|
|
|
}
|
|
|
- conv := intToIP(i)
|
|
|
- if !ip.Equal(conv) {
|
|
|
- t.Error(conv.String())
|
|
|
+
|
|
|
+ ip := net.ParseIP("2a00:1450::5")
|
|
|
+
|
|
|
+ // Request a "good" IP.
|
|
|
+ if _, err := RequestIP(network, ip); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Request the same IP again.
|
|
|
+ if _, err := RequestIP(network, ip); err != ErrIPAlreadyAllocated {
|
|
|
+ t.Fatalf("Got the same IP twice: %#v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Request an out of range IP.
|
|
|
+ if _, err := RequestIP(network, net.ParseIP("2a00:1500::1")); err != ErrIPOutOfRange {
|
|
|
+ t.Fatalf("Got an out of range IP: %#v", err)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -144,6 +286,7 @@ func TestIPAllocator(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
gwIP, n, _ := net.ParseCIDR("127.0.0.1/29")
|
|
|
+
|
|
|
network := &net.IPNet{IP: gwIP, Mask: n.Mask}
|
|
|
// Pool after initialisation (f = free, u = used)
|
|
|
// 2(f) - 3(f) - 4(f) - 5(f) - 6(f)
|
|
@@ -237,13 +380,13 @@ func TestAllocateFirstIP(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
firstIP := network.IP.To4().Mask(network.Mask)
|
|
|
- first := ipToInt(firstIP) + 1
|
|
|
+ first := big.NewInt(0).Add(ipToBigInt(firstIP), big.NewInt(1))
|
|
|
|
|
|
ip, err := RequestIP(network, nil)
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
- allocated := ipToInt(ip)
|
|
|
+ allocated := ipToBigInt(ip)
|
|
|
|
|
|
if allocated == first {
|
|
|
t.Fatalf("allocated ip should not equal first ip: %d == %d", first, allocated)
|
|
@@ -301,11 +444,24 @@ func TestAllocateDifferentSubnets(t *testing.T) {
|
|
|
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, 2),
|
|
|
1: net.IPv4(192, 168, 0, 3),
|
|
|
2: net.IPv4(127, 0, 0, 2),
|
|
|
3: net.IPv4(127, 0, 0, 3),
|
|
|
+ 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"),
|
|
|
}
|
|
|
|
|
|
ip11, err := RequestIP(network1, nil)
|
|
@@ -324,11 +480,37 @@ func TestAllocateDifferentSubnets(t *testing.T) {
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
+ ip31, err := RequestIP(network3, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ ip32, err := RequestIP(network3, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ ip33, err := RequestIP(network3, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ ip41, err := RequestIP(network4, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ ip42, err := RequestIP(network4, nil)
|
|
|
+ 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) {
|
|
|
defer reset()
|
|
|
network := &net.IPNet{
|
|
@@ -378,6 +560,7 @@ func TestAllocateFromRange(t *testing.T) {
|
|
|
IP: []byte{192, 168, 0, 8},
|
|
|
Mask: []byte{255, 255, 255, 248},
|
|
|
}
|
|
|
+
|
|
|
if err := RegisterSubnet(network, subnet); err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|