Skip to content

Commit

Permalink
dhcpsvc: imp code
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Jan 30, 2024
1 parent 9a60d35 commit e4c2cae
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 25 deletions.
7 changes: 3 additions & 4 deletions internal/dhcpsvc/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ type netInterface struct {
leaseTTL time.Duration
}

// reset clears all the slices in the interface for reuse.
// reset clears all the slices in iface for reuse.
func (iface *netInterface) reset() {
iface.leases = iface.leases[:0]
}

// insertLease inserts the given lease into the interface. It returns an
// error if the lease can't be inserted. The error should be informative
// enough to be returned as is.
// insertLease 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)
if found {
Expand Down
30 changes: 11 additions & 19 deletions internal/dhcpsvc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,15 @@ func (srv *DHCPServer) AddLease(l *Lease) (err error) {
func (srv *DHCPServer) netInterfaceForLease(l *Lease) (iface *netInterface, err error) {
if addr := l.IP; addr.Is4() {
var iface4 *netInterfaceV4
iface4, err = srv.netInterfaceForLease4(addr)
iface4, err = netInterfaceForAddr(srv.interfaces4, addr)
if err != nil {
return nil, err
}

iface = &iface4.netInterface
} else {
var iface6 *netInterfaceV6
iface6, err = srv.netInterfaceForLease6(addr)
iface6, err = netInterfaceForAddr(srv.interfaces6, addr)
if err != nil {
return nil, err
}
Expand All @@ -224,28 +224,20 @@ func (srv *DHCPServer) netInterfaceForLease(l *Lease) (iface *netInterface, err
return iface, nil
}

// netInterfaceForLease4 returns the iface responsible for addr, if any. addr
// must be a valid IPv4.
func (srv *DHCPServer) netInterfaceForLease4(addr netip.Addr) (iface *netInterfaceV4, err error) {
i := slices.IndexFunc(srv.interfaces4, func(iface *netInterfaceV4) (ok bool) {
return iface.contains(addr)
})
if i < 0 {
return nil, fmt.Errorf("no interface for IP address %s", addr)
}

return srv.interfaces4[i], nil
// netInterface is a network interface.
type netInterfaceAny interface {
contains(addr netip.Addr) (ok bool)
}

// netInterfaceForLease6 returns the iface responsible for addr, if any. addr
// must be a valid IPv6.
func (srv *DHCPServer) netInterfaceForLease6(addr netip.Addr) (iface *netInterfaceV6, err error) {
i := slices.IndexFunc(srv.interfaces6, func(iface *netInterfaceV6) (ok bool) {
// netInterfaceForAddr returns the first network interface from ifaces that
// contains addr. It returns an error if there is no such interface in ifaces.
func netInterfaceForAddr[I netInterfaceAny](ifaces []I, addr netip.Addr) (iface I, err error) {
i := slices.IndexFunc(ifaces, func(iface I) (ok bool) {
return iface.contains(addr)
})
if i < 0 {
return nil, fmt.Errorf("no interface for IP address %s", addr)
return iface, fmt.Errorf("no interface for IP address %s", addr)
}

return srv.interfaces6[i], nil
return ifaces[i], nil
}
5 changes: 4 additions & 1 deletion internal/dhcpsvc/v4.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ func newNetInterfaceV4(name string, conf *IPv4Config) (i *netInterfaceV4, err er
return i, nil
}

// type check
var _ netInterfaceAny = (*netInterfaceV4)(nil)

// contains returns true if ip is within the address space allocated for i.
//
// TODO(e.burkov): Add type check for [netutil.SubnetSet] if it'll make sense.
// TODO(e.burkov): Make this a method of [netInterface].
func (i *netInterfaceV4) contains(ip netip.Addr) (ok bool) { return i.subnet.Contains(ip) }
5 changes: 4 additions & 1 deletion internal/dhcpsvc/v6.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,16 @@ func newNetInterfaceV6(name string, conf *IPv6Config) (i *netInterfaceV6) {
return i
}

// type check
var _ netInterfaceAny = (*netInterfaceV4)(nil)

// contains returns true if ip is within the address space allocated for i.
//
// TODO(e.burkov): DHCPv6 inherits the weird behavior of legacy implementation
// where the allocated range constrained by the first address and the first
// address with last byte set to 0xff. Proper prefixes should be used instead.
//
// TODO(e.burkov): Add type check for [netutil.SubnetSet] if it'll make sense.
// TODO(e.burkov): Make this a method of [netInterface].
func (i *netInterfaceV6) contains(ip netip.Addr) (ok bool) {
return !i.rangeStart.Less(ip) && netip.PrefixFrom(i.rangeStart, 120).Contains(ip)
}

0 comments on commit e4c2cae

Please sign in to comment.