IPAllocator: Ensure the allocated IPs are within network range.
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>
This commit is contained in:
parent
827634d355
commit
a471eb4d93
|
@ -34,8 +34,9 @@ type networkSet map[string]*allocatedMap
|
||||||
var (
|
var (
|
||||||
ErrNoAvailableIPs = errors.New("no available ip addresses on network")
|
ErrNoAvailableIPs = errors.New("no available ip addresses on network")
|
||||||
ErrIPAlreadyAllocated = errors.New("ip already allocated")
|
ErrIPAlreadyAllocated = errors.New("ip already allocated")
|
||||||
|
ErrIPOutOfRange = errors.New("requested ip is out of range")
|
||||||
ErrNetworkAlreadyRegistered = errors.New("network already registered")
|
ErrNetworkAlreadyRegistered = errors.New("network already registered")
|
||||||
ErrBadSubnet = errors.New("network not contains specified subnet")
|
ErrBadSubnet = errors.New("network does not contain specified subnet")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -100,11 +101,21 @@ func ReleaseIP(network *net.IPNet, ip net.IP) error {
|
||||||
|
|
||||||
func (allocated *allocatedMap) checkIP(ip net.IP) (net.IP, error) {
|
func (allocated *allocatedMap) checkIP(ip net.IP) (net.IP, error) {
|
||||||
pos := ipToInt(ip)
|
pos := ipToInt(ip)
|
||||||
|
|
||||||
|
// Verify that the IP address has not been already allocated.
|
||||||
if _, ok := allocated.p[pos]; ok {
|
if _, ok := allocated.p[pos]; ok {
|
||||||
return nil, ErrIPAlreadyAllocated
|
return nil, ErrIPAlreadyAllocated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the IP address is within our network range.
|
||||||
|
if pos < allocated.begin || pos > allocated.end {
|
||||||
|
return nil, ErrIPOutOfRange
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the IP.
|
||||||
allocated.p[pos] = struct{}{}
|
allocated.p[pos] = struct{}{}
|
||||||
allocated.last = pos
|
allocated.last = pos
|
||||||
|
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,18 +97,29 @@ func TestGetReleasedIp(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequesetSpecificIp(t *testing.T) {
|
func TestRequestSpecificIp(t *testing.T) {
|
||||||
defer reset()
|
defer reset()
|
||||||
network := &net.IPNet{
|
network := &net.IPNet{
|
||||||
IP: []byte{192, 168, 0, 1},
|
IP: []byte{192, 168, 0, 1},
|
||||||
Mask: []byte{255, 255, 255, 0},
|
Mask: []byte{255, 255, 255, 224},
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := net.ParseIP("192.168.1.5")
|
ip := net.ParseIP("192.168.0.5")
|
||||||
|
|
||||||
|
// Request a "good" IP.
|
||||||
if _, err := RequestIP(network, ip); err != nil {
|
if _, err := RequestIP(network, ip); err != nil {
|
||||||
t.Fatal(err)
|
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("192.168.0.42")); err != ErrIPOutOfRange {
|
||||||
|
t.Fatalf("Got an out of range IP: %#v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConversion(t *testing.T) {
|
func TestConversion(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue