dhcpd: add lease is static

This commit is contained in:
Stanislav Chzhen 2023-04-05 12:23:34 +03:00
parent 27dbb427a1
commit d722578543
8 changed files with 27 additions and 20 deletions

View File

@ -71,16 +71,17 @@ func (s *server) dbLoad() (err error) {
IP: ip, IP: ip,
Hostname: obj[i].Hostname, Hostname: obj[i].Hostname,
Expiry: time.Unix(obj[i].Expiry, 0), Expiry: time.Unix(obj[i].Expiry, 0),
IsStatic: obj[i].Expiry == leaseExpireStatic,
} }
if len(obj[i].IP) == 16 { if len(obj[i].IP) == 16 {
if obj[i].Expiry == leaseExpireStatic { if lease.IsStatic {
v6StaticLeases = append(v6StaticLeases, &lease) v6StaticLeases = append(v6StaticLeases, &lease)
} else { } else {
v6DynLeases = append(v6DynLeases, &lease) v6DynLeases = append(v6DynLeases, &lease)
} }
} else { } else {
if obj[i].Expiry == leaseExpireStatic { if lease.IsStatic {
staticLeases = append(staticLeases, &lease) staticLeases = append(staticLeases, &lease)
} else { } else {
dynLeases = append(dynLeases, &lease) dynLeases = append(dynLeases, &lease)

View File

@ -51,6 +51,9 @@ type Lease struct {
// //
// TODO(a.garipov): Migrate leases.db. // TODO(a.garipov): Migrate leases.db.
IP netip.Addr `json:"ip"` IP netip.Addr `json:"ip"`
// IsStatic defines if the lease is static.
IsStatic bool `json:"static"`
} }
// Clone returns a deep copy of l. // Clone returns a deep copy of l.
@ -64,6 +67,7 @@ func (l *Lease) Clone() (clone *Lease) {
Hostname: l.Hostname, Hostname: l.Hostname,
HWAddr: slices.Clone(l.HWAddr), HWAddr: slices.Clone(l.HWAddr),
IP: l.IP, IP: l.IP,
IsStatic: l.IsStatic,
} }
} }
@ -84,17 +88,10 @@ func (l *Lease) IsBlocklisted() (ok bool) {
return true return true
} }
// IsStatic returns true if the lease is static.
//
// TODO(a.garipov): Just make it a boolean field.
func (l *Lease) IsStatic() (ok bool) {
return l != nil && l.Expiry.Unix() == leaseExpireStatic
}
// MarshalJSON implements the json.Marshaler interface for Lease. // MarshalJSON implements the json.Marshaler interface for Lease.
func (l Lease) MarshalJSON() ([]byte, error) { func (l Lease) MarshalJSON() ([]byte, error) {
var expiryStr string var expiryStr string
if !l.IsStatic() { if !l.IsStatic {
// The front-end is waiting for RFC 3999 format of the time // The front-end is waiting for RFC 3999 format of the time
// value. It also shouldn't got an Expiry field for static // value. It also shouldn't got an Expiry field for static
// leases. // leases.

View File

@ -80,7 +80,7 @@ func TestDB(t *testing.T) {
assert.Equal(t, leases[1].HWAddr, ll[0].HWAddr) assert.Equal(t, leases[1].HWAddr, ll[0].HWAddr)
assert.Equal(t, leases[1].IP, ll[0].IP) assert.Equal(t, leases[1].IP, ll[0].IP)
assert.True(t, ll[0].IsStatic()) assert.True(t, ll[0].IsStatic)
assert.Equal(t, leases[0].HWAddr, ll[1].HWAddr) assert.Equal(t, leases[0].HWAddr, ll[1].HWAddr)
assert.Equal(t, leases[0].IP, ll[1].IP) assert.Equal(t, leases[0].IP, ll[1].IP)

View File

@ -27,6 +27,7 @@ func TestServer_handleDHCPStatus(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
} }
s, err := Create(&ServerConfig{ s, err := Create(&ServerConfig{

View File

@ -128,7 +128,7 @@ func (s *v4Server) ResetLeases(leases []*Lease) (err error) {
s.leases = nil s.leases = nil
for _, l := range leases { for _, l := range leases {
if !l.IsStatic() { if !l.IsStatic {
l.Hostname = s.validHostnameForClient(l.Hostname, l.IP) l.Hostname = s.validHostnameForClient(l.Hostname, l.IP)
} }
err = s.addLease(l) err = s.addLease(l)
@ -190,7 +190,7 @@ func (s *v4Server) GetLeases(flags GetLeasesFlags) (leases []*Lease) {
continue continue
} }
if getStatic && l.IsStatic() { if getStatic && l.IsStatic {
leases = append(leases, l.Clone()) leases = append(leases, l.Clone())
} }
} }
@ -211,7 +211,7 @@ func (s *v4Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) {
for _, l := range s.leases { for _, l := range s.leases {
if l.IP == ip { if l.IP == ip {
if l.Expiry.After(now) || l.IsStatic() { if l.Expiry.After(now) || l.IsStatic {
return l.HWAddr return l.HWAddr
} }
} }
@ -259,7 +259,7 @@ func (s *v4Server) rmLeaseByIndex(i int) {
// Return error if a static lease is found // Return error if a static lease is found
func (s *v4Server) rmDynamicLease(lease *Lease) (err error) { func (s *v4Server) rmDynamicLease(lease *Lease) (err error) {
for i, l := range s.leases { for i, l := range s.leases {
isStatic := l.IsStatic() isStatic := l.IsStatic
if bytes.Equal(l.HWAddr, lease.HWAddr) || l.IP == lease.IP { if bytes.Equal(l.HWAddr, lease.HWAddr) || l.IP == lease.IP {
if isStatic { if isStatic {
@ -292,7 +292,7 @@ func (s *v4Server) addLease(l *Lease) (err error) {
leaseIP := net.IP(l.IP.AsSlice()) leaseIP := net.IP(l.IP.AsSlice())
offset, inOffset := r.offset(leaseIP) offset, inOffset := r.offset(leaseIP)
if l.IsStatic() { if l.IsStatic {
// TODO(a.garipov, d.seregin): Subnet can be nil when dhcp server is // TODO(a.garipov, d.seregin): Subnet can be nil when dhcp server is
// disabled. // disabled.
if sn := s.conf.subnet; !sn.Contains(l.IP) { if sn := s.conf.subnet; !sn.Contains(l.IP) {
@ -359,6 +359,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) {
} }
l.Expiry = time.Unix(leaseExpireStatic, 0) l.Expiry = time.Unix(leaseExpireStatic, 0)
l.IsStatic = true
err = netutil.ValidateMAC(l.HWAddr) err = netutil.ValidateMAC(l.HWAddr)
if err != nil { if err != nil {
@ -528,7 +529,7 @@ func (s *v4Server) nextIP() (ip net.IP) {
func (s *v4Server) findExpiredLease() int { func (s *v4Server) findExpiredLease() int {
now := time.Now() now := time.Now()
for i, lease := range s.leases { for i, lease := range s.leases {
if !lease.IsStatic() && lease.Expiry.Before(now) { if !lease.IsStatic && lease.Expiry.Before(now) {
return i return i
} }
} }
@ -860,7 +861,7 @@ func (s *v4Server) handleRequest(req, resp *dhcpv4.DHCPv4) (lease *Lease, needsR
s.leasesLock.Lock() s.leasesLock.Lock()
defer s.leasesLock.Unlock() defer s.leasesLock.Unlock()
if lease.IsStatic() { if lease.IsStatic {
if lease.Hostname != "" { if lease.Hostname != "" {
// TODO(e.burkov): This option is used to update the server's DNS // TODO(e.burkov): This option is used to update the server's DNS
// mapping. The option should only be answered when it has been // mapping. The option should only be answered when it has been

View File

@ -73,6 +73,7 @@ func TestV4Server_leasing(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -82,6 +83,7 @@ func TestV4Server_leasing(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: anotherMAC, HWAddr: anotherMAC,
IP: anotherIP, IP: anotherIP,
IsStatic: true,
}) })
assert.ErrorIs(t, err, ErrDupHostname) assert.ErrorIs(t, err, ErrDupHostname)
}) })
@ -96,6 +98,7 @@ func TestV4Server_leasing(t *testing.T) {
Hostname: anotherName, Hostname: anotherName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: anotherIP, IP: anotherIP,
IsStatic: true,
}) })
testutil.AssertErrorMsg(t, wantErrMsg, err) testutil.AssertErrorMsg(t, wantErrMsg, err)
}) })
@ -110,6 +113,7 @@ func TestV4Server_leasing(t *testing.T) {
Hostname: anotherName, Hostname: anotherName,
HWAddr: anotherMAC, HWAddr: anotherMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
}) })
testutil.AssertErrorMsg(t, wantErrMsg, err) testutil.AssertErrorMsg(t, wantErrMsg, err)
}) })
@ -326,7 +330,7 @@ func TestV4_AddReplace(t *testing.T) {
for i, l := range ls { for i, l := range ls {
assert.Equal(t, stLeases[i].IP, l.IP) assert.Equal(t, stLeases[i].IP, l.IP)
assert.Equal(t, stLeases[i].HWAddr, l.HWAddr) assert.Equal(t, stLeases[i].HWAddr, l.HWAddr)
assert.True(t, l.IsStatic()) assert.True(t, l.IsStatic)
} }
} }
@ -890,6 +894,7 @@ func TestV4Server_FindMACbyIP(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
}, { }, {
Expiry: time.Unix(10, 0), Expiry: time.Unix(10, 0),
Hostname: anotherName, Hostname: anotherName,

View File

@ -121,7 +121,7 @@ func (s *v6Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) {
for _, l := range s.leases { for _, l := range s.leases {
if l.IP == ip { if l.IP == ip {
if l.Expiry.After(now) || l.IsStatic() { if l.Expiry.After(now) || l.IsStatic {
return l.HWAddr return l.HWAddr
} }
} }

View File

@ -331,6 +331,7 @@ func TestV6_FindMACbyIP(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
}, { }, {
Expiry: time.Unix(10, 0), Expiry: time.Unix(10, 0),
Hostname: anotherName, Hostname: anotherName,
@ -344,6 +345,7 @@ func TestV6_FindMACbyIP(t *testing.T) {
Hostname: staticName, Hostname: staticName,
HWAddr: staticMAC, HWAddr: staticMAC,
IP: staticIP, IP: staticIP,
IsStatic: true,
}, { }, {
Expiry: time.Unix(10, 0), Expiry: time.Unix(10, 0),
Hostname: anotherName, Hostname: anotherName,