- DHCP: when adding a new static lease: remove dynamic lease with the same MAC

This commit is contained in:
Simon Zolin 2020-04-08 11:55:58 +03:00
parent 105e2dd1ee
commit 33195b9155
2 changed files with 59 additions and 3 deletions

View File

@ -623,6 +623,12 @@ func (s *Server) AddStaticLease(l Lease) error {
s.leasesLock.Unlock()
return err
}
} else {
err := s.rmDynamicLeaseWithMAC(l.HWAddr)
if err != nil {
s.leasesLock.Unlock()
return err
}
}
s.leases = append(s.leases, &l)
s.reserveIP(l.IP, l.HWAddr)
@ -649,6 +655,23 @@ func (s *Server) rmDynamicLeaseWithIP(ip net.IP) error {
return nil
}
// Remove a dynamic lease by IP address
func (s *Server) rmDynamicLeaseWithMAC(mac net.HardwareAddr) error {
var newLeases []*Lease
for _, lease := range s.leases {
if bytes.Equal(lease.HWAddr, mac) {
if lease.Expiry.Unix() == leaseExpireStatic {
return fmt.Errorf("static lease with the same IP already exists")
}
s.unreserveIP(lease.IP)
continue
}
newLeases = append(newLeases, lease)
}
s.leases = newLeases
return nil
}
// Remove a lease
func (s *Server) rmLease(l Lease) error {
var newLeases []*Lease

View File

@ -20,6 +20,7 @@ func check(t *testing.T, result bool, msg string) {
// Tests performed:
// . Handle Discover message (lease reserve)
// . Handle Request message (lease commit)
// . Static leases
func TestDHCP(t *testing.T) {
var s = Server{}
s.conf.DBFilePath = dbFilename
@ -117,6 +118,7 @@ func TestDHCP(t *testing.T) {
s.reset()
testStaticLeases(t, &s)
testStaticLeaseReplaceByMAC(t, &s)
s.reset()
misc(t, &s)
@ -126,15 +128,46 @@ func testStaticLeases(t *testing.T, s *Server) {
var err error
var l Lease
l.IP = []byte{1, 1, 1, 1}
l.HWAddr = []byte{1, 2, 3, 4, 5, 6}
s.leases = append(s.leases, &l)
// replace dynamic lease with a static (same IP)
l.HWAddr = []byte{2, 2, 3, 4, 5, 6}
err = s.AddStaticLease(l)
check(t, err == nil, "AddStaticLease")
ll := s.Leases(LeasesStatic)
check(t, len(ll) != 0 && bytes.Equal(ll[0].IP, []byte{1, 1, 1, 1}), "StaticLeases")
ll := s.Leases(LeasesAll)
assert.True(t, len(ll) == 1)
assert.True(t, bytes.Equal(ll[0].IP, []byte{1, 1, 1, 1}))
assert.True(t, bytes.Equal(ll[0].HWAddr, []byte{2, 2, 3, 4, 5, 6}))
assert.True(t, ll[0].Expiry.Unix() == leaseExpireStatic)
err = s.RemoveStaticLease(l)
check(t, err == nil, "RemoveStaticLease")
assert.True(t, err == nil)
ll = s.Leases(LeasesAll)
assert.True(t, len(ll) == 0)
}
func testStaticLeaseReplaceByMAC(t *testing.T, s *Server) {
var err error
var l Lease
l.HWAddr = []byte{1, 2, 3, 4, 5, 6}
l.IP = []byte{1, 1, 1, 1}
l.Expiry = time.Now().Add(time.Hour)
s.leases = append(s.leases, &l)
// replace dynamic lease with a static (same MAC)
l.IP = []byte{2, 1, 1, 1}
err = s.AddStaticLease(l)
assert.True(t, err == nil)
ll := s.Leases(LeasesAll)
assert.True(t, len(ll) == 1)
assert.True(t, bytes.Equal(ll[0].IP, []byte{2, 1, 1, 1}))
assert.True(t, bytes.Equal(ll[0].HWAddr, []byte{1, 2, 3, 4, 5, 6}))
}
// Small tests that don't require a static server's state