Pull request 2256: 4923 Better interfaces
Updates #4923. Squashed commit of the following: commit 0e40b41aa1e517a62d6076c4e7a57c607792ef01 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Jul 10 15:28:16 2024 +0300 dhcpsvc: imp code, docs commit 5463fdde473f84caaca229b53027e8183d5c6bdc Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Jul 9 20:31:20 2024 +0300 dhcpsvc: imp ifaces
This commit is contained in:
@@ -3,42 +3,74 @@ package dhcpsvc
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// netInterface is a common part of any network interface within the DHCP
|
||||
// server.
|
||||
// macKey contains hardware address as byte array of 6, 8, or 20 bytes.
|
||||
//
|
||||
// TODO(e.burkov): Move to aghnet or even to netutil.
|
||||
type macKey any
|
||||
|
||||
// macToKey converts mac into macKey, which is used as the key for the lease
|
||||
// maps. mac must be a valid hardware address of length 6, 8, or 20 bytes, see
|
||||
// [netutil.ValidateMAC].
|
||||
func macToKey(mac net.HardwareAddr) (key macKey) {
|
||||
switch len(mac) {
|
||||
case 6:
|
||||
return [6]byte(mac)
|
||||
case 8:
|
||||
return [8]byte(mac)
|
||||
case 20:
|
||||
return [20]byte(mac)
|
||||
default:
|
||||
panic(fmt.Errorf("invalid mac address %#v", mac))
|
||||
}
|
||||
}
|
||||
|
||||
// netInterface is a common part of any interface within the DHCP server.
|
||||
//
|
||||
// TODO(e.burkov): Add other methods as [DHCPServer] evolves.
|
||||
type netInterface struct {
|
||||
// logger logs the events related to the network interface.
|
||||
logger *slog.Logger
|
||||
|
||||
// leases is the set of DHCP leases assigned to this interface.
|
||||
leases map[macKey]*Lease
|
||||
|
||||
// name is the name of the network interface.
|
||||
name string
|
||||
|
||||
// leases is a set of leases sorted by hardware address.
|
||||
leases []*Lease
|
||||
|
||||
// leaseTTL is the default Time-To-Live value for leases.
|
||||
leaseTTL time.Duration
|
||||
}
|
||||
|
||||
// reset clears all the slices in iface for reuse.
|
||||
func (iface *netInterface) reset() {
|
||||
iface.leases = iface.leases[:0]
|
||||
// newNetInterface creates a new netInterface with the given name, leaseTTL, and
|
||||
// logger.
|
||||
func newNetInterface(name string, l *slog.Logger, leaseTTL time.Duration) (iface *netInterface) {
|
||||
return &netInterface{
|
||||
logger: l,
|
||||
leases: map[macKey]*Lease{},
|
||||
name: name,
|
||||
leaseTTL: leaseTTL,
|
||||
}
|
||||
}
|
||||
|
||||
// insertLease inserts the given lease into iface. It returns an error if the
|
||||
// reset clears all the slices in iface for reuse.
|
||||
func (iface *netInterface) reset() {
|
||||
clear(iface.leases)
|
||||
}
|
||||
|
||||
// addLease inserts the given lease into iface. It returns an error if the
|
||||
// lease can't be inserted.
|
||||
func (iface *netInterface) insertLease(l *Lease) (err error) {
|
||||
i, found := slices.BinarySearchFunc(iface.leases, l, compareLeaseMAC)
|
||||
func (iface *netInterface) addLease(l *Lease) (err error) {
|
||||
mk := macToKey(l.HWAddr)
|
||||
_, found := iface.leases[mk]
|
||||
if found {
|
||||
return fmt.Errorf("lease for mac %s already exists", l.HWAddr)
|
||||
}
|
||||
|
||||
iface.leases = slices.Insert(iface.leases, i, l)
|
||||
iface.leases[mk] = l
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -46,12 +78,13 @@ func (iface *netInterface) insertLease(l *Lease) (err error) {
|
||||
// updateLease replaces an existing lease within iface with the given one. It
|
||||
// returns an error if there is no lease with such hardware address.
|
||||
func (iface *netInterface) updateLease(l *Lease) (prev *Lease, err error) {
|
||||
i, found := slices.BinarySearchFunc(iface.leases, l, compareLeaseMAC)
|
||||
mk := macToKey(l.HWAddr)
|
||||
prev, found := iface.leases[mk]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("no lease for mac %s", l.HWAddr)
|
||||
}
|
||||
|
||||
prev, iface.leases[i] = iface.leases[i], l
|
||||
iface.leases[mk] = l
|
||||
|
||||
return prev, nil
|
||||
}
|
||||
@@ -59,12 +92,13 @@ func (iface *netInterface) updateLease(l *Lease) (prev *Lease, err error) {
|
||||
// removeLease removes an existing lease from iface. It returns an error if
|
||||
// there is no lease equal to l.
|
||||
func (iface *netInterface) removeLease(l *Lease) (err error) {
|
||||
i, found := slices.BinarySearchFunc(iface.leases, l, compareLeaseMAC)
|
||||
mk := macToKey(l.HWAddr)
|
||||
_, found := iface.leases[mk]
|
||||
if !found {
|
||||
return fmt.Errorf("no lease for mac %s", l.HWAddr)
|
||||
}
|
||||
|
||||
iface.leases = slices.Delete(iface.leases, i, i+1)
|
||||
delete(iface.leases, mk)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user