forked from AdguardTeam/AdGuardHome
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pull request 2152: 4923 gopacket DHCP vol.7
Updates AdguardTeam#4923. Squashed commit of the following: commit 0f90eb3 Merge: 38b3165 bd99e3e Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Feb 19 20:11:38 2024 +0300 Merge branch 'master' into 4923-gopacket-dhcp-vol.7 commit 38b3165 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Feb 19 14:52:01 2024 +0300 dhcpsvc: imp docs commit 0a07892 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Feb 19 14:48:19 2024 +0300 dhcpsvc: imp code commit 30691f0 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Feb 15 19:57:41 2024 +0300 dhcpsvc: imp code, dry commit 20f5ef8 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Feb 15 15:57:09 2024 +0300 dhcpsvc: finish leases methods
- Loading branch information
1 parent
bd99e3e
commit 6fd0a62
Showing
6 changed files
with
637 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package dhcpsvc | ||
|
||
import ( | ||
"fmt" | ||
"net/netip" | ||
"slices" | ||
"strings" | ||
) | ||
|
||
// leaseIndex is the set of leases indexed by their identifiers for quick | ||
// lookup. | ||
type leaseIndex struct { | ||
// byAddr is a lookup shortcut for leases by their IP addresses. | ||
byAddr map[netip.Addr]*Lease | ||
|
||
// byName is a lookup shortcut for leases by their hostnames. | ||
// | ||
// TODO(e.burkov): Use a slice of leases with the same hostname? | ||
byName map[string]*Lease | ||
} | ||
|
||
// newLeaseIndex returns a new index for [Lease]s. | ||
func newLeaseIndex() *leaseIndex { | ||
return &leaseIndex{ | ||
byAddr: map[netip.Addr]*Lease{}, | ||
byName: map[string]*Lease{}, | ||
} | ||
} | ||
|
||
// leaseByAddr returns a lease by its IP address. | ||
func (idx *leaseIndex) leaseByAddr(addr netip.Addr) (l *Lease, ok bool) { | ||
l, ok = idx.byAddr[addr] | ||
|
||
return l, ok | ||
} | ||
|
||
// leaseByName returns a lease by its hostname. | ||
func (idx *leaseIndex) leaseByName(name string) (l *Lease, ok bool) { | ||
// TODO(e.burkov): Probably, use a case-insensitive comparison and store in | ||
// slice. This would require a benchmark. | ||
l, ok = idx.byName[strings.ToLower(name)] | ||
|
||
return l, ok | ||
} | ||
|
||
// clear removes all leases from idx. | ||
func (idx *leaseIndex) clear() { | ||
clear(idx.byAddr) | ||
clear(idx.byName) | ||
} | ||
|
||
// add adds l into idx and into iface. l must be valid, iface should be | ||
// responsible for l's IP. It returns an error if l duplicates at least a | ||
// single value of another lease. | ||
func (idx *leaseIndex) add(l *Lease, iface *netInterface) (err error) { | ||
loweredName := strings.ToLower(l.Hostname) | ||
|
||
if _, ok := idx.byAddr[l.IP]; ok { | ||
return fmt.Errorf("lease for ip %s already exists", l.IP) | ||
} else if _, ok = idx.byName[loweredName]; ok { | ||
return fmt.Errorf("lease for hostname %s already exists", l.Hostname) | ||
} | ||
|
||
err = iface.insertLease(l) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
idx.byAddr[l.IP] = l | ||
idx.byName[loweredName] = l | ||
|
||
return nil | ||
} | ||
|
||
// remove removes l from idx and from iface. l must be valid, iface should | ||
// contain the same lease or the lease itself. It returns an error if the lease | ||
// not found. | ||
func (idx *leaseIndex) remove(l *Lease, iface *netInterface) (err error) { | ||
loweredName := strings.ToLower(l.Hostname) | ||
|
||
if _, ok := idx.byAddr[l.IP]; !ok { | ||
return fmt.Errorf("no lease for ip %s", l.IP) | ||
} else if _, ok = idx.byName[loweredName]; !ok { | ||
return fmt.Errorf("no lease for hostname %s", l.Hostname) | ||
} | ||
|
||
err = iface.removeLease(l) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
delete(idx.byAddr, l.IP) | ||
delete(idx.byName, loweredName) | ||
|
||
return nil | ||
} | ||
|
||
// update updates l in idx and in iface. l must be valid, iface should be | ||
// responsible for l's IP. It returns an error if l duplicates at least a | ||
// single value of another lease, except for the updated lease itself. | ||
func (idx *leaseIndex) update(l *Lease, iface *netInterface) (err error) { | ||
loweredName := strings.ToLower(l.Hostname) | ||
|
||
existing, ok := idx.byAddr[l.IP] | ||
if ok && !slices.Equal(l.HWAddr, existing.HWAddr) { | ||
return fmt.Errorf("lease for ip %s already exists", l.IP) | ||
} | ||
|
||
existing, ok = idx.byName[loweredName] | ||
if ok && !slices.Equal(l.HWAddr, existing.HWAddr) { | ||
return fmt.Errorf("lease for hostname %s already exists", l.Hostname) | ||
} | ||
|
||
prev, err := iface.updateLease(l) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
delete(idx.byAddr, prev.IP) | ||
delete(idx.byName, strings.ToLower(prev.Hostname)) | ||
|
||
idx.byAddr[l.IP] = l | ||
idx.byName[loweredName] = l | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.