From a471eb4d9388dc44be0a9c81fa2f15061df636c5 Mon Sep 17 00:00:00 2001 From: Andrea Luzzardi Date: Tue, 23 Sep 2014 18:13:26 -0700 Subject: [PATCH] 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 --- daemon/networkdriver/ipallocator/allocator.go | 13 ++++++++++++- .../networkdriver/ipallocator/allocator_test.go | 17 ++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/daemon/networkdriver/ipallocator/allocator.go b/daemon/networkdriver/ipallocator/allocator.go index ad7547a4a0..a1aaabbdfe 100644 --- a/daemon/networkdriver/ipallocator/allocator.go +++ b/daemon/networkdriver/ipallocator/allocator.go @@ -34,8 +34,9 @@ type networkSet map[string]*allocatedMap var ( ErrNoAvailableIPs = errors.New("no available ip addresses on network") ErrIPAlreadyAllocated = errors.New("ip already allocated") + ErrIPOutOfRange = errors.New("requested ip is out of range") ErrNetworkAlreadyRegistered = errors.New("network already registered") - ErrBadSubnet = errors.New("network not contains specified subnet") + ErrBadSubnet = errors.New("network does not contain specified subnet") ) var ( @@ -100,11 +101,21 @@ func ReleaseIP(network *net.IPNet, ip net.IP) error { func (allocated *allocatedMap) checkIP(ip net.IP) (net.IP, error) { pos := ipToInt(ip) + + // Verify that the IP address has not been already allocated. if _, ok := allocated.p[pos]; ok { 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.last = pos + return ip, nil } diff --git a/daemon/networkdriver/ipallocator/allocator_test.go b/daemon/networkdriver/ipallocator/allocator_test.go index 0b5d97e605..056c13b647 100644 --- a/daemon/networkdriver/ipallocator/allocator_test.go +++ b/daemon/networkdriver/ipallocator/allocator_test.go @@ -97,18 +97,29 @@ func TestGetReleasedIp(t *testing.T) { } } -func TestRequesetSpecificIp(t *testing.T) { +func TestRequestSpecificIp(t *testing.T) { defer reset() network := &net.IPNet{ 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 { 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) {