From a543cb9a34b89a632516a82823a32b4b365260c1 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 31 Jan 2020 19:11:08 +0100 Subject: [PATCH] dhcp4d: add header describing whether lease is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should be interpreted by the DHCP server so that other programs don’t need to hard-code the lease time. --- cmd/dhcp4d/dhcp4d.go | 1 + cmd/dhcp4d/dhcp4d_test.go | 18 ++++++++++++++++++ internal/dhcp4d/dhcp4d.go | 10 +++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cmd/dhcp4d/dhcp4d.go b/cmd/dhcp4d/dhcp4d.go index ab68829..ae3324a 100644 --- a/cmd/dhcp4d/dhcp4d.go +++ b/cmd/dhcp4d/dhcp4d.go @@ -283,6 +283,7 @@ func newSrv(permDir string) (*srv, error) { http.Error(w, err.Error(), http.StatusInternalServerError) return } + w.Header().Set("X-Lease-Active", fmt.Sprint(lease.Expiry.After(time.Now().Add(handler.LeasePeriod/2)))) if _, err := io.Copy(w, bytes.NewReader(b)); err != nil { log.Printf("/lease/%s: %v", hostname, err) } diff --git a/cmd/dhcp4d/dhcp4d_test.go b/cmd/dhcp4d/dhcp4d_test.go index ecdb9ca..6667f53 100644 --- a/cmd/dhcp4d/dhcp4d_test.go +++ b/cmd/dhcp4d/dhcp4d_test.go @@ -92,6 +92,24 @@ func TestLeaseHandler(t *testing.T) { if diff := cmp.Diff(lease, got); diff != "" { t.Fatalf("/lease/midna: unexpected lease: diff (-want +got):\n%s", diff) } + + if got, want := resp.Header.Get("X-Lease-Active"), "true"; got != want { + t.Fatalf("Unexpected X-Lease-Active header: got %q, want %s", got, want) + } + lease.Expiry = time.Now().Add(-1 * time.Minute) + srv.leases([]*dhcp4d.Lease{&lease}, &lease) + resp, err = http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + if got, want := resp.StatusCode, http.StatusOK; got != want { + b, _ := ioutil.ReadAll(resp.Body) + t.Fatalf("unexpected HTTP response code: got %v (%s), want %v", resp.Status, strings.TrimSpace(string(b)), want) + } + if got, want := resp.Header.Get("X-Lease-Active"), "false"; got != want { + t.Fatalf("Unexpected X-Lease-Active header: got %q, want %s", got, want) + } + canc() if err := eg.Wait(); err != nil && err != context.Canceled { t.Fatal(err) diff --git a/internal/dhcp4d/dhcp4d.go b/internal/dhcp4d/dhcp4d.go index de7cb55..a84b8d0 100644 --- a/internal/dhcp4d/dhcp4d.go +++ b/internal/dhcp4d/dhcp4d.go @@ -47,7 +47,7 @@ type Handler struct { serverIP net.IP start net.IP // first IP address to hand out leaseRange int // number of IP addresses to hand out - leasePeriod time.Duration + LeasePeriod time.Duration options dhcp4.Options leasesHW map[string]int // points into leasesIP leasesIP map[int]*Lease @@ -89,7 +89,7 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac serverIP: serverIP, start: start, leaseRange: 230, - leasePeriod: 20 * time.Minute, + LeasePeriod: 20 * time.Minute, options: dhcp4.Options{ dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0}, dhcp4.OptionRouter: []byte(serverIP), @@ -251,7 +251,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d dhcp4.Offer, h.serverIP, dhcp4.IPAdd(h.start, free), - h.leasePeriod, + h.LeasePeriod, h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList])) case dhcp4.Request: @@ -267,7 +267,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d Num: leaseNum, Addr: make([]byte, 4), HardwareAddr: p.CHAddr().String(), - Expiry: h.timeNow().Add(h.leasePeriod), + Expiry: h.timeNow().Add(h.LeasePeriod), Hostname: string(options[dhcp4.OptionHostName]), } copy(lease.Addr, reqIP.To4()) @@ -296,7 +296,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d } h.Leases(leases, lease) } - return dhcp4.ReplyPacket(p, dhcp4.ACK, h.serverIP, reqIP, h.leasePeriod, + return dhcp4.ReplyPacket(p, dhcp4.ACK, h.serverIP, reqIP, h.LeasePeriod, h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList])) } return nil