Since it is possible to request a specific IP, IPAllocator has to verify
that the request is within boundaries.
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
| ... | ... |
@@ -34,8 +34,9 @@ type networkSet map[string]*allocatedMap |
| 34 | 34 |
var ( |
| 35 | 35 |
ErrNoAvailableIPs = errors.New("no available ip addresses on network")
|
| 36 | 36 |
ErrIPAlreadyAllocated = errors.New("ip already allocated")
|
| 37 |
+ ErrIPOutOfRange = errors.New("requested ip is out of range")
|
|
| 37 | 38 |
ErrNetworkAlreadyRegistered = errors.New("network already registered")
|
| 38 |
- ErrBadSubnet = errors.New("network not contains specified subnet")
|
|
| 39 |
+ ErrBadSubnet = errors.New("network does not contain specified subnet")
|
|
| 39 | 40 |
) |
| 40 | 41 |
|
| 41 | 42 |
var ( |
| ... | ... |
@@ -100,11 +101,21 @@ func ReleaseIP(network *net.IPNet, ip net.IP) error {
|
| 100 | 100 |
|
| 101 | 101 |
func (allocated *allocatedMap) checkIP(ip net.IP) (net.IP, error) {
|
| 102 | 102 |
pos := ipToInt(ip) |
| 103 |
+ |
|
| 104 |
+ // Verify that the IP address has not been already allocated. |
|
| 103 | 105 |
if _, ok := allocated.p[pos]; ok {
|
| 104 | 106 |
return nil, ErrIPAlreadyAllocated |
| 105 | 107 |
} |
| 108 |
+ |
|
| 109 |
+ // Verify that the IP address is within our network range. |
|
| 110 |
+ if pos < allocated.begin || pos > allocated.end {
|
|
| 111 |
+ return nil, ErrIPOutOfRange |
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ // Register the IP. |
|
| 106 | 115 |
allocated.p[pos] = struct{}{}
|
| 107 | 116 |
allocated.last = pos |
| 117 |
+ |
|
| 108 | 118 |
return ip, nil |
| 109 | 119 |
} |
| 110 | 120 |
|
| ... | ... |
@@ -97,18 +97,29 @@ func TestGetReleasedIp(t *testing.T) {
|
| 97 | 97 |
} |
| 98 | 98 |
} |
| 99 | 99 |
|
| 100 |
-func TestRequesetSpecificIp(t *testing.T) {
|
|
| 100 |
+func TestRequestSpecificIp(t *testing.T) {
|
|
| 101 | 101 |
defer reset() |
| 102 | 102 |
network := &net.IPNet{
|
| 103 | 103 |
IP: []byte{192, 168, 0, 1},
|
| 104 |
- Mask: []byte{255, 255, 255, 0},
|
|
| 104 |
+ Mask: []byte{255, 255, 255, 224},
|
|
| 105 | 105 |
} |
| 106 | 106 |
|
| 107 |
- ip := net.ParseIP("192.168.1.5")
|
|
| 107 |
+ ip := net.ParseIP("192.168.0.5")
|
|
| 108 | 108 |
|
| 109 |
+ // Request a "good" IP. |
|
| 109 | 110 |
if _, err := RequestIP(network, ip); err != nil {
|
| 110 | 111 |
t.Fatal(err) |
| 111 | 112 |
} |
| 113 |
+ |
|
| 114 |
+ // Request the same IP again. |
|
| 115 |
+ if _, err := RequestIP(network, ip); err != ErrIPAlreadyAllocated {
|
|
| 116 |
+ t.Fatalf("Got the same IP twice: %#v", err)
|
|
| 117 |
+ } |
|
| 118 |
+ |
|
| 119 |
+ // Request an out of range IP. |
|
| 120 |
+ if _, err := RequestIP(network, net.ParseIP("192.168.0.42")); err != ErrIPOutOfRange {
|
|
| 121 |
+ t.Fatalf("Got an out of range IP: %#v", err)
|
|
| 122 |
+ } |
|
| 112 | 123 |
} |
| 113 | 124 |
|
| 114 | 125 |
func TestConversion(t *testing.T) {
|