Pull request 1771: AG-20352-dhcpd-lease-netip-addr

Merge in DNS/adguard-home from AG-20352-dhcpd-lease-netip-addr to master

Squashed commit of the following:

commit 4acd094e2d6ed972bac99cdb671670f6d8e61721
Merge: 51f61c19 df61741f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 23 16:44:17 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-netip-addr

commit 51f61c193fdd31ee675be5598fc361228e407eb3
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 22 18:25:30 2023 +0300

    dhcpd: fix typo

commit 2e64ad55475957925d2a3010c649e0adc5f18c4f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 22 17:20:31 2023 +0300

    dhcpd: add todo

commit 668d4f62fd2c5b2e168025bf0b6bb36d7b617c80
Merge: 0020006e 306c1983
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 22 15:09:38 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-netip-addr

commit 0020006e89f336dc58db1a2ca3ce90d2e7a5ca16
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 22 15:08:58 2023 +0300

    all: imp code

commit 9a77f79869cdbde6de760734c0d8cf504e0464ef
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 20 18:13:35 2023 +0300

    dhcpd: add todo

commit 638c4ce2af72235bf065a6492d58f3f1b1e7644a
Merge: c82b18f1 48431f8b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 20 13:57:19 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-netip-addr

commit c82b18f1408d9e353aec517f4283e2f3eb260890
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 20 13:56:31 2023 +0300

    all: imp code

commit 27e518120024103c292ac1cf134c6801fffc967e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 17 12:14:02 2023 +0300

    dhcpd: imp tests

commit 8e919b0ceb0b20d1935587e717c7965cd8a33ad9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 17 11:02:50 2023 +0300

    dhcpd: add tests

commit 78ddefa73a255509af1c788147d6b1c332bb66ba
Merge: c68e85c4 9f7a582d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 16 14:15:24 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-netip-addr

commit c68e85c40947b6c83516424a2bd7af89b99447b4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 16 14:14:43 2023 +0300

    all: add tests

commit f338086309a68c4b71036fa14f757e39358702d4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 15 12:44:06 2023 +0300

    all: dhcpd lease netip addr
This commit is contained in:
Stanislav Chzhen
2023-03-23 16:52:01 +03:00
parent df61741f60
commit bea39934bd
16 changed files with 562 additions and 197 deletions

View File

@@ -98,7 +98,7 @@ func normalizeHostname(hostname string) (norm string, err error) {
// validHostnameForClient accepts the hostname sent by the client and its IP and
// returns either a normalized version of that hostname, or a new hostname
// generated from the IP address, or an empty string.
func (s *v4Server) validHostnameForClient(cliHostname string, ip net.IP) (hostname string) {
func (s *v4Server) validHostnameForClient(cliHostname string, ip netip.Addr) (hostname string) {
hostname, err := normalizeHostname(cliHostname)
if err != nil {
log.Info("dhcpv4: %s", err)
@@ -211,9 +211,8 @@ func (s *v4Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) {
return nil
}
netIP := ip.AsSlice()
for _, l := range s.leases {
if l.IP.Equal(netIP) {
if l.IP == ip {
if l.Expiry.After(now) || l.IsStatic() {
return l.HWAddr
}
@@ -247,7 +246,8 @@ func (s *v4Server) rmLeaseByIndex(i int) {
s.leases = append(s.leases[:i], s.leases[i+1:]...)
r := s.conf.ipRange
offset, ok := r.offset(l.IP)
leaseIP := net.IP(l.IP.AsSlice())
offset, ok := r.offset(leaseIP)
if ok {
s.leasedOffsets.set(offset, false)
}
@@ -263,7 +263,7 @@ func (s *v4Server) rmDynamicLease(lease *Lease) (err error) {
for i, l := range s.leases {
isStatic := l.IsStatic()
if bytes.Equal(l.HWAddr, lease.HWAddr) || l.IP.Equal(lease.IP) {
if bytes.Equal(l.HWAddr, lease.HWAddr) || l.IP == lease.IP {
if isStatic {
return errors.Error("static lease already exists")
}
@@ -291,13 +291,13 @@ const ErrDupHostname = errors.Error("hostname is not unique")
// addLease adds a dynamic or static lease.
func (s *v4Server) addLease(l *Lease) (err error) {
r := s.conf.ipRange
offset, inOffset := r.offset(l.IP)
leaseIP := net.IP(l.IP.AsSlice())
offset, inOffset := r.offset(leaseIP)
if l.IsStatic() {
// TODO(a.garipov, d.seregin): Subnet can be nil when dhcp server is
// disabled.
addr := netip.AddrFrom4(*(*[4]byte)(l.IP.To4()))
if sn := s.conf.subnet; !sn.Contains(addr) {
if sn := s.conf.subnet; !sn.Contains(l.IP) {
return fmt.Errorf("subnet %s does not contain the ip %q", sn, l.IP)
}
} else if !inOffset {
@@ -325,7 +325,7 @@ func (s *v4Server) rmLease(lease *Lease) (err error) {
}
for i, l := range s.leases {
if l.IP.Equal(lease.IP) {
if l.IP == lease.IP {
if !bytes.Equal(l.HWAddr, lease.HWAddr) || l.Hostname != lease.Hostname {
return fmt.Errorf("lease for ip %s is different: %+v", lease.IP, l)
}
@@ -352,10 +352,11 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) {
return ErrUnconfigured
}
ip := l.IP.To4()
if ip == nil {
l.IP = l.IP.Unmap()
if !l.IP.Is4() {
return fmt.Errorf("invalid ip %q, only ipv4 is supported", l.IP)
} else if gwIP := s.conf.GatewayIP; gwIP == netip.AddrFrom4(*(*[4]byte)(ip)) {
} else if gwIP := s.conf.GatewayIP; gwIP == l.IP {
return fmt.Errorf("can't assign the gateway IP %s to the lease", gwIP)
}
@@ -396,7 +397,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) {
if err != nil {
err = fmt.Errorf(
"removing dynamic leases for %s (%s): %w",
ip,
l.IP,
l.HWAddr,
err,
)
@@ -406,7 +407,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) {
err = s.addLease(l)
if err != nil {
err = fmt.Errorf("adding static lease for %s (%s): %w", ip, l.HWAddr, err)
err = fmt.Errorf("adding static lease for %s (%s): %w", l.IP, l.HWAddr, err)
return
}
@@ -429,7 +430,7 @@ func (s *v4Server) RemoveStaticLease(l *Lease) (err error) {
return ErrUnconfigured
}
if len(l.IP) != 4 {
if !l.IP.Is4() {
return fmt.Errorf("invalid IP")
}
@@ -542,8 +543,8 @@ func (s *v4Server) findExpiredLease() int {
func (s *v4Server) reserveLease(mac net.HardwareAddr) (l *Lease, err error) {
l = &Lease{HWAddr: slices.Clone(mac)}
l.IP = s.nextIP()
if l.IP == nil {
nextIP := s.nextIP()
if nextIP == nil {
i := s.findExpiredLease()
if i < 0 {
return nil, nil
@@ -554,6 +555,13 @@ func (s *v4Server) reserveLease(mac net.HardwareAddr) (l *Lease, err error) {
return s.leases[i], nil
}
netIP, ok := netip.AddrFromSlice(nextIP)
if !ok {
return nil, errors.Error("invalid ip")
}
l.IP = netIP
err = s.addLease(l)
if err != nil {
return nil, err
@@ -603,7 +611,8 @@ func (s *v4Server) allocateLease(mac net.HardwareAddr) (l *Lease, err error) {
return nil, nil
}
if s.addrAvailable(l.IP) {
leaseIP := l.IP.AsSlice()
if s.addrAvailable(leaseIP) {
return l, nil
}
@@ -623,8 +632,9 @@ func (s *v4Server) handleDiscover(req, resp *dhcpv4.DHCPv4) (l *Lease, err error
l = s.findLease(mac)
if l != nil {
reqIP := req.RequestedIPAddress()
if len(reqIP) != 0 && !reqIP.Equal(l.IP) {
log.Debug("dhcpv4: different RequestedIP: %s != %s", reqIP, l.IP)
leaseIP := net.IP(l.IP.AsSlice())
if len(reqIP) != 0 && !reqIP.Equal(leaseIP) {
log.Debug("dhcpv4: different RequestedIP: %s != %s", reqIP, leaseIP)
}
resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeOffer))
@@ -674,12 +684,19 @@ func (s *v4Server) checkLease(mac net.HardwareAddr, ip net.IP) (lease *Lease, mi
s.leasesLock.Lock()
defer s.leasesLock.Unlock()
netIP, ok := netip.AddrFromSlice(ip)
if !ok {
log.Info("check lease: invalid IP: %s", ip)
return nil, false
}
for _, l := range s.leases {
if !bytes.Equal(l.HWAddr, mac) {
continue
}
if l.IP.Equal(ip) {
if l.IP == netIP {
return l, false
}
@@ -878,9 +895,16 @@ func (s *v4Server) handleDecline(req, resp *dhcpv4.DHCPv4) (err error) {
reqIP = req.ClientIPAddr
}
netIP, ok := netip.AddrFromSlice(reqIP)
if !ok {
log.Info("dhcpv4: invalid IP: %s", reqIP)
return nil
}
var oldLease *Lease
for _, l := range s.leases {
if bytes.Equal(l.HWAddr, mac) && l.IP.Equal(reqIP) {
if bytes.Equal(l.HWAddr, mac) && l.IP == netIP {
oldLease = l
break
@@ -920,8 +944,7 @@ func (s *v4Server) handleDecline(req, resp *dhcpv4.DHCPv4) (err error) {
log.Info("dhcpv4: changed ip from %s to %s for %s", reqIP, newLease.IP, mac)
resp.YourIPAddr = make([]byte, 4)
copy(resp.YourIPAddr, newLease.IP)
resp.YourIPAddr = net.IP(newLease.IP.AsSlice())
resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeAck))
@@ -944,8 +967,15 @@ func (s *v4Server) handleRelease(req, resp *dhcpv4.DHCPv4) (err error) {
s.leasesLock.Lock()
defer s.leasesLock.Unlock()
netIP, ok := netip.AddrFromSlice(reqIP)
if !ok {
log.Info("dhcpv4: invalid IP: %s", reqIP)
return nil
}
for _, l := range s.leases {
if !bytes.Equal(l.HWAddr, mac) || !l.IP.Equal(reqIP) {
if !bytes.Equal(l.HWAddr, mac) || l.IP != netIP {
continue
}
@@ -1018,7 +1048,7 @@ func (s *v4Server) handle(req, resp *dhcpv4.DHCPv4) int {
}
if l != nil {
resp.YourIPAddr = slices.Clone(l.IP)
resp.YourIPAddr = net.IP(l.IP.AsSlice())
}
s.updateOptions(req, resp)