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,
|
reqIP,
|
||||||
h.leasePeriodForDevice(hwAddr),
|
h.leasePeriodForDevice(hwAddr),
|
||||||
h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
|
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
|
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)
|
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 = `
|
const goldenInterfaces = `
|
||||||
{
|
{
|
||||||
"interfaces":[
|
"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