Browse code

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby authored on 2014/01/23 17:28:24
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,229 @@
0
+package ipallocator
1
+
2
+import (
3
+	"encoding/binary"
4
+	"errors"
5
+	"github.com/dotcloud/docker/pkg/netlink"
6
+	"net"
7
+	"sync"
8
+)
9
+
10
+type networkSet map[iPNet]*iPSet
11
+
12
+type iPNet struct {
13
+	IP   string
14
+	Mask string
15
+}
16
+
17
+var (
18
+	ErrNetworkAlreadyAllocated = errors.New("requested network overlaps with existing network")
19
+	ErrNetworkAlreadyRegisterd = errors.New("requested network is already registered")
20
+	ErrNoAvailableIps          = errors.New("no available ips on network")
21
+	ErrIPAlreadyAllocated      = errors.New("ip already allocated")
22
+
23
+	lock         = sync.Mutex{}
24
+	allocatedIPs = networkSet{}
25
+	availableIPS = networkSet{}
26
+)
27
+
28
+func RegisterNetwork(network *net.IPNet) error {
29
+	lock.Lock()
30
+	defer lock.Unlock()
31
+
32
+	routes, err := netlink.NetworkGetRoutes()
33
+	if err != nil {
34
+		return err
35
+	}
36
+
37
+	if err := checkRouteOverlaps(routes, network); err != nil {
38
+		return err
39
+	}
40
+
41
+	if err := checkExistingNetworkOverlaps(network); err != nil {
42
+		return err
43
+	}
44
+	n := newIPNet(network)
45
+
46
+	allocatedIPs[n] = &iPSet{}
47
+	availableIPS[n] = &iPSet{}
48
+
49
+	return nil
50
+}
51
+
52
+func RequestIP(network *net.IPNet, ip *net.IP) (*net.IP, error) {
53
+	lock.Lock()
54
+	defer lock.Unlock()
55
+
56
+	if ip == nil {
57
+		next, err := getNextIp(network)
58
+		if err != nil {
59
+			return nil, err
60
+		}
61
+		return next, nil
62
+	}
63
+
64
+	if err := registerIP(network, ip); err != nil {
65
+		return nil, err
66
+	}
67
+	return ip, nil
68
+}
69
+
70
+func ReleaseIP(network *net.IPNet, ip *net.IP) error {
71
+	lock.Lock()
72
+	defer lock.Unlock()
73
+
74
+	var (
75
+		first, _  = networkRange(network)
76
+		base      = ipToInt(&first)
77
+		n         = newIPNet(network)
78
+		existing  = allocatedIPs[n]
79
+		available = availableIPS[n]
80
+		i         = ipToInt(ip)
81
+		pos       = i - base
82
+	)
83
+
84
+	existing.Remove(int(pos))
85
+	available.Push(int(pos))
86
+
87
+	return nil
88
+}
89
+
90
+func getNextIp(network *net.IPNet) (*net.IP, error) {
91
+	var (
92
+		n         = newIPNet(network)
93
+		ownIP     = ipToInt(&network.IP)
94
+		available = availableIPS[n]
95
+		allocated = allocatedIPs[n]
96
+
97
+		first, _ = networkRange(network)
98
+		base     = ipToInt(&first)
99
+
100
+		pos = int32(available.Pop())
101
+	)
102
+
103
+	// We pop and push the position not the ip
104
+	if pos != 0 {
105
+		ip := intToIP(int32(base + pos))
106
+		allocated.Push(int(pos))
107
+
108
+		return ip, nil
109
+	}
110
+
111
+	var (
112
+		size = int(networkSize(network.Mask))
113
+		max  = int32(size - 2) // size -1 for the broadcast address, -1 for the gateway address
114
+	)
115
+
116
+	if pos = int32(allocated.PullBack()); pos == 0 {
117
+		pos = 1
118
+	}
119
+
120
+	for i := int32(0); i < max; i++ {
121
+		next := int32(base + pos)
122
+		pos = pos%max + 1
123
+
124
+		if next == ownIP {
125
+			continue
126
+		}
127
+
128
+		ip := intToIP(next)
129
+		allocated.Push(int(pos))
130
+
131
+		return ip, nil
132
+	}
133
+	return nil, ErrNoAvailableIps
134
+}
135
+
136
+func registerIP(network *net.IPNet, ip *net.IP) error {
137
+	existing := allocatedIPs[newIPNet(network)]
138
+	// checking position not ip
139
+	if existing.Exists(int(ipToInt(ip))) {
140
+		return ErrIPAlreadyAllocated
141
+	}
142
+	return nil
143
+}
144
+
145
+func checkRouteOverlaps(networks []netlink.Route, toCheck *net.IPNet) error {
146
+	for _, network := range networks {
147
+		if network.IPNet != nil && networkOverlaps(toCheck, network.IPNet) {
148
+			return ErrNetworkAlreadyAllocated
149
+		}
150
+	}
151
+	return nil
152
+}
153
+
154
+// Detects overlap between one IPNet and another
155
+func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
156
+	if firstIP, _ := networkRange(netX); netY.Contains(firstIP) {
157
+		return true
158
+	}
159
+	if firstIP, _ := networkRange(netY); netX.Contains(firstIP) {
160
+		return true
161
+	}
162
+	return false
163
+}
164
+
165
+func checkExistingNetworkOverlaps(network *net.IPNet) error {
166
+	for existing := range allocatedIPs {
167
+		if newIPNet(network) == existing {
168
+			return ErrNetworkAlreadyRegisterd
169
+		}
170
+
171
+		ex := newNetIPNet(existing)
172
+		if networkOverlaps(network, ex) {
173
+			return ErrNetworkAlreadyAllocated
174
+		}
175
+	}
176
+	return nil
177
+}
178
+
179
+// Calculates the first and last IP addresses in an IPNet
180
+func networkRange(network *net.IPNet) (net.IP, net.IP) {
181
+	var (
182
+		netIP   = network.IP.To4()
183
+		firstIP = netIP.Mask(network.Mask)
184
+		lastIP  = net.IPv4(0, 0, 0, 0).To4()
185
+	)
186
+
187
+	for i := 0; i < len(lastIP); i++ {
188
+		lastIP[i] = netIP[i] | ^network.Mask[i]
189
+	}
190
+	return firstIP, lastIP
191
+}
192
+
193
+func newIPNet(network *net.IPNet) iPNet {
194
+	return iPNet{
195
+		IP:   string(network.IP),
196
+		Mask: string(network.Mask),
197
+	}
198
+}
199
+
200
+func newNetIPNet(network iPNet) *net.IPNet {
201
+	return &net.IPNet{
202
+		IP:   []byte(network.IP),
203
+		Mask: []byte(network.Mask),
204
+	}
205
+}
206
+
207
+// Converts a 4 bytes IP into a 32 bit integer
208
+func ipToInt(ip *net.IP) int32 {
209
+	return int32(binary.BigEndian.Uint32(ip.To4()))
210
+}
211
+
212
+// Converts 32 bit integer into a 4 bytes IP address
213
+func intToIP(n int32) *net.IP {
214
+	b := make([]byte, 4)
215
+	binary.BigEndian.PutUint32(b, uint32(n))
216
+	ip := net.IP(b)
217
+	return &ip
218
+}
219
+
220
+// Given a netmask, calculates the number of available hosts
221
+func networkSize(mask net.IPMask) int32 {
222
+	m := net.IPv4Mask(0, 0, 0, 0)
223
+	for i := 0; i < net.IPv4len; i++ {
224
+		m[i] = ^mask[i]
225
+	}
226
+
227
+	return int32(binary.BigEndian.Uint32(m)) + 1
228
+}
0 229
new file mode 100644
... ...
@@ -0,0 +1,163 @@
0
+package ipallocator
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"testing"
6
+)
7
+
8
+func reset() {
9
+	allocatedIPs = networkSet{}
10
+	availableIPS = networkSet{}
11
+}
12
+
13
+func TestRegisterNetwork(t *testing.T) {
14
+	defer reset()
15
+	network := &net.IPNet{
16
+		IP:   []byte{192, 168, 0, 1},
17
+		Mask: []byte{255, 255, 255, 0},
18
+	}
19
+
20
+	if err := RegisterNetwork(network); err != nil {
21
+		t.Fatal(err)
22
+	}
23
+
24
+	n := newIPNet(network)
25
+	if _, exists := allocatedIPs[n]; !exists {
26
+		t.Fatal("IPNet should exist in allocated IPs")
27
+	}
28
+
29
+	if _, exists := availableIPS[n]; !exists {
30
+		t.Fatal("IPNet should exist in available IPs")
31
+	}
32
+}
33
+
34
+func TestRegisterTwoNetworks(t *testing.T) {
35
+	defer reset()
36
+	network := &net.IPNet{
37
+		IP:   []byte{192, 168, 0, 1},
38
+		Mask: []byte{255, 255, 255, 0},
39
+	}
40
+
41
+	if err := RegisterNetwork(network); err != nil {
42
+		t.Fatal(err)
43
+	}
44
+
45
+	network2 := &net.IPNet{
46
+		IP:   []byte{10, 1, 42, 1},
47
+		Mask: []byte{255, 255, 255, 0},
48
+	}
49
+
50
+	if err := RegisterNetwork(network2); err != nil {
51
+		t.Fatal(err)
52
+	}
53
+}
54
+
55
+func TestRegisterNetworkThatExists(t *testing.T) {
56
+	defer reset()
57
+	network := &net.IPNet{
58
+		IP:   []byte{192, 168, 0, 1},
59
+		Mask: []byte{255, 255, 255, 0},
60
+	}
61
+
62
+	if err := RegisterNetwork(network); err != nil {
63
+		t.Fatal(err)
64
+	}
65
+
66
+	if err := RegisterNetwork(network); err != ErrNetworkAlreadyRegisterd {
67
+		t.Fatalf("Expected error of %s got %s", ErrNetworkAlreadyRegisterd, err)
68
+	}
69
+}
70
+
71
+func TestRequestNewIps(t *testing.T) {
72
+	defer reset()
73
+	network := &net.IPNet{
74
+		IP:   []byte{192, 168, 0, 1},
75
+		Mask: []byte{255, 255, 255, 0},
76
+	}
77
+
78
+	if err := RegisterNetwork(network); err != nil {
79
+		t.Fatal(err)
80
+	}
81
+
82
+	for i := 2; i < 10; i++ {
83
+		ip, err := RequestIP(network, nil)
84
+		if err != nil {
85
+			t.Fatal(err)
86
+		}
87
+
88
+		if expected := fmt.Sprintf("192.168.0.%d", i); ip.String() != expected {
89
+			t.Fatalf("Expected ip %s got %s", expected, ip.String())
90
+		}
91
+	}
92
+}
93
+
94
+func TestReleaseIp(t *testing.T) {
95
+	defer reset()
96
+	network := &net.IPNet{
97
+		IP:   []byte{192, 168, 0, 1},
98
+		Mask: []byte{255, 255, 255, 0},
99
+	}
100
+
101
+	if err := RegisterNetwork(network); err != nil {
102
+		t.Fatal(err)
103
+	}
104
+
105
+	ip, err := RequestIP(network, nil)
106
+	if err != nil {
107
+		t.Fatal(err)
108
+	}
109
+
110
+	if err := ReleaseIP(network, ip); err != nil {
111
+		t.Fatal(err)
112
+	}
113
+}
114
+
115
+func TestGetReleasedIp(t *testing.T) {
116
+	defer reset()
117
+	network := &net.IPNet{
118
+		IP:   []byte{192, 168, 0, 1},
119
+		Mask: []byte{255, 255, 255, 0},
120
+	}
121
+
122
+	if err := RegisterNetwork(network); err != nil {
123
+		t.Fatal(err)
124
+	}
125
+
126
+	ip, err := RequestIP(network, nil)
127
+	if err != nil {
128
+		t.Fatal(err)
129
+	}
130
+
131
+	value := ip.String()
132
+	if err := ReleaseIP(network, ip); err != nil {
133
+		t.Fatal(err)
134
+	}
135
+
136
+	ip, err = RequestIP(network, nil)
137
+	if err != nil {
138
+		t.Fatal(err)
139
+	}
140
+
141
+	if ip.String() != value {
142
+		t.Fatalf("Expected to receive same ip %s got %s", value, ip.String())
143
+	}
144
+}
145
+
146
+func TestRequesetSpecificIp(t *testing.T) {
147
+	defer reset()
148
+	network := &net.IPNet{
149
+		IP:   []byte{192, 168, 0, 1},
150
+		Mask: []byte{255, 255, 255, 0},
151
+	}
152
+
153
+	if err := RegisterNetwork(network); err != nil {
154
+		t.Fatal(err)
155
+	}
156
+
157
+	ip := net.ParseIP("192.168.1.5")
158
+
159
+	if _, err := RequestIP(network, &ip); err != nil {
160
+		t.Fatal(err)
161
+	}
162
+}
0 163
new file mode 100644
... ...
@@ -0,0 +1,84 @@
0
+package ipallocator
1
+
2
+import (
3
+	"sort"
4
+	"sync"
5
+)
6
+
7
+// iPSet is a thread-safe sorted set and a stack.
8
+type iPSet struct {
9
+	sync.RWMutex
10
+	set []int
11
+}
12
+
13
+// Push takes a string and adds it to the set. If the elem aready exists, it has no effect.
14
+func (s *iPSet) Push(elem int) {
15
+	s.RLock()
16
+	for _, e := range s.set {
17
+		if e == elem {
18
+			s.RUnlock()
19
+			return
20
+		}
21
+	}
22
+	s.RUnlock()
23
+
24
+	s.Lock()
25
+	s.set = append(s.set, elem)
26
+	// Make sure the list is always sorted
27
+	sort.Ints(s.set)
28
+	s.Unlock()
29
+}
30
+
31
+// Pop is an alias to PopFront()
32
+func (s *iPSet) Pop() int {
33
+	return s.PopFront()
34
+}
35
+
36
+// Pop returns the first elemen from the list and removes it.
37
+// If the list is empty, it returns 0
38
+func (s *iPSet) PopFront() int {
39
+	s.RLock()
40
+
41
+	for i, e := range s.set {
42
+		ret := e
43
+		s.RUnlock()
44
+		s.Lock()
45
+		s.set = append(s.set[:i], s.set[i+1:]...)
46
+		s.Unlock()
47
+		return ret
48
+	}
49
+	s.RUnlock()
50
+
51
+	return 0
52
+}
53
+
54
+// PullBack retrieve the last element of the list.
55
+// The element is not removed.
56
+// If the list is empty, an empty element is returned.
57
+func (s *iPSet) PullBack() int {
58
+	if len(s.set) == 0 {
59
+		return 0
60
+	}
61
+	return s.set[len(s.set)-1]
62
+}
63
+
64
+// Exists checks if the given element present in the list.
65
+func (s *iPSet) Exists(elem int) bool {
66
+	for _, e := range s.set {
67
+		if e == elem {
68
+			return true
69
+		}
70
+	}
71
+	return false
72
+}
73
+
74
+// Remove removes an element from the list.
75
+// If the element is not found, it has no effect.
76
+func (s *iPSet) Remove(elem int) {
77
+	for i, e := range s.set {
78
+		if e == elem {
79
+			s.set = append(s.set[:i], s.set[i+1:]...)
80
+			return
81
+		}
82
+	}
83
+}
0 84
deleted file mode 100644
... ...
@@ -1,229 +0,0 @@
1
-package ipallocator
2
-
3
-import (
4
-	"encoding/binary"
5
-	"errors"
6
-	"github.com/dotcloud/docker/pkg/netlink"
7
-	"net"
8
-	"sync"
9
-)
10
-
11
-type networkSet map[iPNet]*iPSet
12
-
13
-type iPNet struct {
14
-	IP   string
15
-	Mask string
16
-}
17
-
18
-var (
19
-	ErrNetworkAlreadyAllocated = errors.New("requested network overlaps with existing network")
20
-	ErrNetworkAlreadyRegisterd = errors.New("requested network is already registered")
21
-	ErrNoAvailableIps          = errors.New("no available ips on network")
22
-	ErrIPAlreadyAllocated      = errors.New("ip already allocated")
23
-
24
-	lock         = sync.Mutex{}
25
-	allocatedIPs = networkSet{}
26
-	availableIPS = networkSet{}
27
-)
28
-
29
-func RegisterNetwork(network *net.IPNet) error {
30
-	lock.Lock()
31
-	defer lock.Unlock()
32
-
33
-	routes, err := netlink.NetworkGetRoutes()
34
-	if err != nil {
35
-		return err
36
-	}
37
-
38
-	if err := checkRouteOverlaps(routes, network); err != nil {
39
-		return err
40
-	}
41
-
42
-	if err := checkExistingNetworkOverlaps(network); err != nil {
43
-		return err
44
-	}
45
-	n := newIPNet(network)
46
-
47
-	allocatedIPs[n] = &iPSet{}
48
-	availableIPS[n] = &iPSet{}
49
-
50
-	return nil
51
-}
52
-
53
-func RequestIP(network *net.IPNet, ip *net.IP) (*net.IP, error) {
54
-	lock.Lock()
55
-	defer lock.Unlock()
56
-
57
-	if ip == nil {
58
-		next, err := getNextIp(network)
59
-		if err != nil {
60
-			return nil, err
61
-		}
62
-		return next, nil
63
-	}
64
-
65
-	if err := registerIP(network, ip); err != nil {
66
-		return nil, err
67
-	}
68
-	return ip, nil
69
-}
70
-
71
-func ReleaseIP(network *net.IPNet, ip *net.IP) error {
72
-	lock.Lock()
73
-	defer lock.Unlock()
74
-
75
-	var (
76
-		first, _  = networkRange(network)
77
-		base      = ipToInt(&first)
78
-		n         = newIPNet(network)
79
-		existing  = allocatedIPs[n]
80
-		available = availableIPS[n]
81
-		i         = ipToInt(ip)
82
-		pos       = i - base
83
-	)
84
-
85
-	existing.Remove(int(pos))
86
-	available.Push(int(pos))
87
-
88
-	return nil
89
-}
90
-
91
-func getNextIp(network *net.IPNet) (*net.IP, error) {
92
-	var (
93
-		n         = newIPNet(network)
94
-		ownIP     = ipToInt(&network.IP)
95
-		available = availableIPS[n]
96
-		allocated = allocatedIPs[n]
97
-
98
-		first, _ = networkRange(network)
99
-		base     = ipToInt(&first)
100
-
101
-		pos = int32(available.Pop())
102
-	)
103
-
104
-	// We pop and push the position not the ip
105
-	if pos != 0 {
106
-		ip := intToIP(int32(base + pos))
107
-		allocated.Push(int(pos))
108
-
109
-		return ip, nil
110
-	}
111
-
112
-	var (
113
-		size = int(networkSize(network.Mask))
114
-		max  = int32(size - 2) // size -1 for the broadcast address, -1 for the gateway address
115
-	)
116
-
117
-	if pos = int32(allocated.PullBack()); pos == 0 {
118
-		pos = 1
119
-	}
120
-
121
-	for i := int32(0); i < max; i++ {
122
-		next := int32(base + pos)
123
-		pos = pos%max + 1
124
-
125
-		if next == ownIP {
126
-			continue
127
-		}
128
-
129
-		ip := intToIP(next)
130
-		allocated.Push(int(pos))
131
-
132
-		return ip, nil
133
-	}
134
-	return nil, ErrNoAvailableIps
135
-}
136
-
137
-func registerIP(network *net.IPNet, ip *net.IP) error {
138
-	existing := allocatedIPs[newIPNet(network)]
139
-	// checking position not ip
140
-	if existing.Exists(int(ipToInt(ip))) {
141
-		return ErrIPAlreadyAllocated
142
-	}
143
-	return nil
144
-}
145
-
146
-func checkRouteOverlaps(networks []netlink.Route, toCheck *net.IPNet) error {
147
-	for _, network := range networks {
148
-		if network.IPNet != nil && networkOverlaps(toCheck, network.IPNet) {
149
-			return ErrNetworkAlreadyAllocated
150
-		}
151
-	}
152
-	return nil
153
-}
154
-
155
-// Detects overlap between one IPNet and another
156
-func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
157
-	if firstIP, _ := networkRange(netX); netY.Contains(firstIP) {
158
-		return true
159
-	}
160
-	if firstIP, _ := networkRange(netY); netX.Contains(firstIP) {
161
-		return true
162
-	}
163
-	return false
164
-}
165
-
166
-func checkExistingNetworkOverlaps(network *net.IPNet) error {
167
-	for existing := range allocatedIPs {
168
-		if newIPNet(network) == existing {
169
-			return ErrNetworkAlreadyRegisterd
170
-		}
171
-
172
-		ex := newNetIPNet(existing)
173
-		if networkOverlaps(network, ex) {
174
-			return ErrNetworkAlreadyAllocated
175
-		}
176
-	}
177
-	return nil
178
-}
179
-
180
-// Calculates the first and last IP addresses in an IPNet
181
-func networkRange(network *net.IPNet) (net.IP, net.IP) {
182
-	var (
183
-		netIP   = network.IP.To4()
184
-		firstIP = netIP.Mask(network.Mask)
185
-		lastIP  = net.IPv4(0, 0, 0, 0).To4()
186
-	)
187
-
188
-	for i := 0; i < len(lastIP); i++ {
189
-		lastIP[i] = netIP[i] | ^network.Mask[i]
190
-	}
191
-	return firstIP, lastIP
192
-}
193
-
194
-func newIPNet(network *net.IPNet) iPNet {
195
-	return iPNet{
196
-		IP:   string(network.IP),
197
-		Mask: string(network.Mask),
198
-	}
199
-}
200
-
201
-func newNetIPNet(network iPNet) *net.IPNet {
202
-	return &net.IPNet{
203
-		IP:   []byte(network.IP),
204
-		Mask: []byte(network.Mask),
205
-	}
206
-}
207
-
208
-// Converts a 4 bytes IP into a 32 bit integer
209
-func ipToInt(ip *net.IP) int32 {
210
-	return int32(binary.BigEndian.Uint32(ip.To4()))
211
-}
212
-
213
-// Converts 32 bit integer into a 4 bytes IP address
214
-func intToIP(n int32) *net.IP {
215
-	b := make([]byte, 4)
216
-	binary.BigEndian.PutUint32(b, uint32(n))
217
-	ip := net.IP(b)
218
-	return &ip
219
-}
220
-
221
-// Given a netmask, calculates the number of available hosts
222
-func networkSize(mask net.IPMask) int32 {
223
-	m := net.IPv4Mask(0, 0, 0, 0)
224
-	for i := 0; i < net.IPv4len; i++ {
225
-		m[i] = ^mask[i]
226
-	}
227
-
228
-	return int32(binary.BigEndian.Uint32(m)) + 1
229
-}
230 1
deleted file mode 100644
... ...
@@ -1,163 +0,0 @@
1
-package ipallocator
2
-
3
-import (
4
-	"fmt"
5
-	"net"
6
-	"testing"
7
-)
8
-
9
-func reset() {
10
-	allocatedIPs = networkSet{}
11
-	availableIPS = networkSet{}
12
-}
13
-
14
-func TestRegisterNetwork(t *testing.T) {
15
-	defer reset()
16
-	network := &net.IPNet{
17
-		IP:   []byte{192, 168, 0, 1},
18
-		Mask: []byte{255, 255, 255, 0},
19
-	}
20
-
21
-	if err := RegisterNetwork(network); err != nil {
22
-		t.Fatal(err)
23
-	}
24
-
25
-	n := newIPNet(network)
26
-	if _, exists := allocatedIPs[n]; !exists {
27
-		t.Fatal("IPNet should exist in allocated IPs")
28
-	}
29
-
30
-	if _, exists := availableIPS[n]; !exists {
31
-		t.Fatal("IPNet should exist in available IPs")
32
-	}
33
-}
34
-
35
-func TestRegisterTwoNetworks(t *testing.T) {
36
-	defer reset()
37
-	network := &net.IPNet{
38
-		IP:   []byte{192, 168, 0, 1},
39
-		Mask: []byte{255, 255, 255, 0},
40
-	}
41
-
42
-	if err := RegisterNetwork(network); err != nil {
43
-		t.Fatal(err)
44
-	}
45
-
46
-	network2 := &net.IPNet{
47
-		IP:   []byte{10, 1, 42, 1},
48
-		Mask: []byte{255, 255, 255, 0},
49
-	}
50
-
51
-	if err := RegisterNetwork(network2); err != nil {
52
-		t.Fatal(err)
53
-	}
54
-}
55
-
56
-func TestRegisterNetworkThatExists(t *testing.T) {
57
-	defer reset()
58
-	network := &net.IPNet{
59
-		IP:   []byte{192, 168, 0, 1},
60
-		Mask: []byte{255, 255, 255, 0},
61
-	}
62
-
63
-	if err := RegisterNetwork(network); err != nil {
64
-		t.Fatal(err)
65
-	}
66
-
67
-	if err := RegisterNetwork(network); err != ErrNetworkAlreadyRegisterd {
68
-		t.Fatalf("Expected error of %s got %s", ErrNetworkAlreadyRegisterd, err)
69
-	}
70
-}
71
-
72
-func TestRequestNewIps(t *testing.T) {
73
-	defer reset()
74
-	network := &net.IPNet{
75
-		IP:   []byte{192, 168, 0, 1},
76
-		Mask: []byte{255, 255, 255, 0},
77
-	}
78
-
79
-	if err := RegisterNetwork(network); err != nil {
80
-		t.Fatal(err)
81
-	}
82
-
83
-	for i := 2; i < 10; i++ {
84
-		ip, err := RequestIP(network, nil)
85
-		if err != nil {
86
-			t.Fatal(err)
87
-		}
88
-
89
-		if expected := fmt.Sprintf("192.168.0.%d", i); ip.String() != expected {
90
-			t.Fatalf("Expected ip %s got %s", expected, ip.String())
91
-		}
92
-	}
93
-}
94
-
95
-func TestReleaseIp(t *testing.T) {
96
-	defer reset()
97
-	network := &net.IPNet{
98
-		IP:   []byte{192, 168, 0, 1},
99
-		Mask: []byte{255, 255, 255, 0},
100
-	}
101
-
102
-	if err := RegisterNetwork(network); err != nil {
103
-		t.Fatal(err)
104
-	}
105
-
106
-	ip, err := RequestIP(network, nil)
107
-	if err != nil {
108
-		t.Fatal(err)
109
-	}
110
-
111
-	if err := ReleaseIP(network, ip); err != nil {
112
-		t.Fatal(err)
113
-	}
114
-}
115
-
116
-func TestGetReleasedIp(t *testing.T) {
117
-	defer reset()
118
-	network := &net.IPNet{
119
-		IP:   []byte{192, 168, 0, 1},
120
-		Mask: []byte{255, 255, 255, 0},
121
-	}
122
-
123
-	if err := RegisterNetwork(network); err != nil {
124
-		t.Fatal(err)
125
-	}
126
-
127
-	ip, err := RequestIP(network, nil)
128
-	if err != nil {
129
-		t.Fatal(err)
130
-	}
131
-
132
-	value := ip.String()
133
-	if err := ReleaseIP(network, ip); err != nil {
134
-		t.Fatal(err)
135
-	}
136
-
137
-	ip, err = RequestIP(network, nil)
138
-	if err != nil {
139
-		t.Fatal(err)
140
-	}
141
-
142
-	if ip.String() != value {
143
-		t.Fatalf("Expected to receive same ip %s got %s", value, ip.String())
144
-	}
145
-}
146
-
147
-func TestRequesetSpecificIp(t *testing.T) {
148
-	defer reset()
149
-	network := &net.IPNet{
150
-		IP:   []byte{192, 168, 0, 1},
151
-		Mask: []byte{255, 255, 255, 0},
152
-	}
153
-
154
-	if err := RegisterNetwork(network); err != nil {
155
-		t.Fatal(err)
156
-	}
157
-
158
-	ip := net.ParseIP("192.168.1.5")
159
-
160
-	if _, err := RequestIP(network, &ip); err != nil {
161
-		t.Fatal(err)
162
-	}
163
-}
164 1
deleted file mode 100644
... ...
@@ -1,84 +0,0 @@
1
-package ipallocator
2
-
3
-import (
4
-	"sort"
5
-	"sync"
6
-)
7
-
8
-// iPSet is a thread-safe sorted set and a stack.
9
-type iPSet struct {
10
-	sync.RWMutex
11
-	set []int
12
-}
13
-
14
-// Push takes a string and adds it to the set. If the elem aready exists, it has no effect.
15
-func (s *iPSet) Push(elem int) {
16
-	s.RLock()
17
-	for _, e := range s.set {
18
-		if e == elem {
19
-			s.RUnlock()
20
-			return
21
-		}
22
-	}
23
-	s.RUnlock()
24
-
25
-	s.Lock()
26
-	s.set = append(s.set, elem)
27
-	// Make sure the list is always sorted
28
-	sort.Ints(s.set)
29
-	s.Unlock()
30
-}
31
-
32
-// Pop is an alias to PopFront()
33
-func (s *iPSet) Pop() int {
34
-	return s.PopFront()
35
-}
36
-
37
-// Pop returns the first elemen from the list and removes it.
38
-// If the list is empty, it returns 0
39
-func (s *iPSet) PopFront() int {
40
-	s.RLock()
41
-
42
-	for i, e := range s.set {
43
-		ret := e
44
-		s.RUnlock()
45
-		s.Lock()
46
-		s.set = append(s.set[:i], s.set[i+1:]...)
47
-		s.Unlock()
48
-		return ret
49
-	}
50
-	s.RUnlock()
51
-
52
-	return 0
53
-}
54
-
55
-// PullBack retrieve the last element of the list.
56
-// The element is not removed.
57
-// If the list is empty, an empty element is returned.
58
-func (s *iPSet) PullBack() int {
59
-	if len(s.set) == 0 {
60
-		return 0
61
-	}
62
-	return s.set[len(s.set)-1]
63
-}
64
-
65
-// Exists checks if the given element present in the list.
66
-func (s *iPSet) Exists(elem int) bool {
67
-	for _, e := range s.set {
68
-		if e == elem {
69
-			return true
70
-		}
71
-	}
72
-	return false
73
-}
74
-
75
-// Remove removes an element from the list.
76
-// If the element is not found, it has no effect.
77
-func (s *iPSet) Remove(elem int) {
78
-	for i, e := range s.set {
79
-		if e == elem {
80
-			s.set = append(s.set[:i], s.set[i+1:]...)
81
-			return
82
-		}
83
-	}
84
-}