From 33195b91559c36cf2197679ae23e6a732e5c8c04 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Wed, 8 Apr 2020 11:55:58 +0300 Subject: [PATCH] - DHCP: when adding a new static lease: remove dynamic lease with the same MAC --- dhcpd/dhcpd.go | 23 +++++++++++++++++++++++ dhcpd/dhcpd_test.go | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/dhcpd/dhcpd.go b/dhcpd/dhcpd.go index 5719b0de..f95a9867 100644 --- a/dhcpd/dhcpd.go +++ b/dhcpd/dhcpd.go @@ -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 diff --git a/dhcpd/dhcpd_test.go b/dhcpd/dhcpd_test.go index b41121a3..b08ffb86 100644 --- a/dhcpd/dhcpd_test.go +++ b/dhcpd/dhcpd_test.go @@ -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