internal/dhcp4d: handle DHCPDECLINE and fix bug regarding MacBook declining leases (#48)
Fixes #40 Signed-off-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
parent
fe68c2dd52
commit
7aeb51e9ec
@ -353,6 +353,35 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
|
||||
reqIP,
|
||||
h.leasePeriodForDevice(hwAddr),
|
||||
h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
|
||||
case dhcp4.Decline:
|
||||
if h.expireLease(hwAddr) {
|
||||
log.Printf("Expired leases for %v upon DHCPDECLINE", hwAddr)
|
||||
}
|
||||
// Decline does not expect an ACK response.
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// expireLease expires the lease for hwAddr and reports whether or not the
|
||||
// lease was actually expired by this call.
|
||||
func (h *Handler) expireLease(hwAddr string) bool {
|
||||
h.leasesMu.Lock()
|
||||
defer h.leasesMu.Unlock()
|
||||
|
||||
// TODO: deduplicate with h.leaseHW which also acquires h.leasesMu.
|
||||
|
||||
num, ok := h.leasesHW[hwAddr]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
l, ok := h.leasesIP[num]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if l.HardwareAddr != hwAddr {
|
||||
return false
|
||||
}
|
||||
l.Expiry = time.Now()
|
||||
return true
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ func discover(addr net.IP, hwaddr net.HardwareAddr, opts ...dhcp4.Option) dhcp4.
|
||||
return packet(dhcp4.Discover, addr, hwaddr, opts)
|
||||
}
|
||||
|
||||
func decline(addr net.IP, hwaddr net.HardwareAddr, opts ...dhcp4.Option) dhcp4.Packet {
|
||||
return packet(dhcp4.Decline, addr, hwaddr, opts)
|
||||
}
|
||||
|
||||
const goldenInterfaces = `
|
||||
{
|
||||
"interfaces":[
|
||||
@ -500,3 +504,56 @@ func TestMinimumLeaseTime(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDecline(t *testing.T) {
|
||||
handler, cleanup := testHandler(t)
|
||||
defer cleanup()
|
||||
|
||||
now := time.Now()
|
||||
handler.timeNow = func() time.Time { return now }
|
||||
|
||||
addr := net.IP{192, 168, 42, 23}
|
||||
|
||||
hardwareAddr := net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
|
||||
|
||||
// macbook requests a new lease
|
||||
t.Run("mbp grabs an address", func(t *testing.T) {
|
||||
p := request(addr, hardwareAddr)
|
||||
resp := handler.serveDHCP(p, dhcp4.Request, p.ParseOptions())
|
||||
if got, want := messageType(resp), dhcp4.ACK; got != want {
|
||||
t.Errorf("DHCPREQUEST resulted in unexpected message type: got %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
// macbook lease expires
|
||||
now = now.Add(3 * time.Hour)
|
||||
|
||||
t.Run("mbp requests previous address", func(t *testing.T) {
|
||||
p := request(addr, hardwareAddr)
|
||||
resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions())
|
||||
if got, want := resp.YIAddr().To4(), addr.To4(); !got.Equal(want) {
|
||||
t.Errorf("DHCPOFFER for wrong IP: got %v, want %v", got, want)
|
||||
}
|
||||
p = request(addr, hardwareAddr)
|
||||
resp = handler.serveDHCP(p, dhcp4.Request, p.ParseOptions())
|
||||
if got, want := messageType(resp), dhcp4.ACK; got != want {
|
||||
t.Errorf("DHCPREQUEST resulted in unexpected message type: got %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("mbp declines address", func(t *testing.T) {
|
||||
p := decline(addr, hardwareAddr)
|
||||
resp := handler.serveDHCP(p, dhcp4.Decline, p.ParseOptions())
|
||||
if resp != nil {
|
||||
t.Fatalf("DHCPDECLINE was unexpectedly answered: %v", messageType(resp))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("mbp requests any address", func(t *testing.T) {
|
||||
p := request(net.IPv4zero, hardwareAddr)
|
||||
resp := handler.serveDHCP(p, dhcp4.Discover, p.ParseOptions())
|
||||
if got, want := resp.YIAddr().To4(), addr.To4(); got.Equal(want) {
|
||||
t.Errorf("DHCPOFFER returned unexpected address: %v", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user