dhcp4d: add header describing whether lease is active

Should be interpreted by the DHCP server so that other programs don’t need to
hard-code the lease time.
This commit is contained in:
Michael Stapelberg 2020-01-31 19:11:08 +01:00
parent a2ea8c2f95
commit a543cb9a34
3 changed files with 24 additions and 5 deletions

View File

@ -283,6 +283,7 @@ func newSrv(permDir string) (*srv, error) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return 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 { if _, err := io.Copy(w, bytes.NewReader(b)); err != nil {
log.Printf("/lease/%s: %v", hostname, err) log.Printf("/lease/%s: %v", hostname, err)
} }

View File

@ -92,6 +92,24 @@ func TestLeaseHandler(t *testing.T) {
if diff := cmp.Diff(lease, got); diff != "" { if diff := cmp.Diff(lease, got); diff != "" {
t.Fatalf("/lease/midna: unexpected lease: diff (-want +got):\n%s", 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() canc()
if err := eg.Wait(); err != nil && err != context.Canceled { if err := eg.Wait(); err != nil && err != context.Canceled {
t.Fatal(err) t.Fatal(err)

View File

@ -47,7 +47,7 @@ type Handler struct {
serverIP net.IP serverIP net.IP
start net.IP // first IP address to hand out start net.IP // first IP address to hand out
leaseRange int // number of IP addresses to hand out leaseRange int // number of IP addresses to hand out
leasePeriod time.Duration LeasePeriod time.Duration
options dhcp4.Options options dhcp4.Options
leasesHW map[string]int // points into leasesIP leasesHW map[string]int // points into leasesIP
leasesIP map[int]*Lease leasesIP map[int]*Lease
@ -89,7 +89,7 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac
serverIP: serverIP, serverIP: serverIP,
start: start, start: start,
leaseRange: 230, leaseRange: 230,
leasePeriod: 20 * time.Minute, LeasePeriod: 20 * time.Minute,
options: dhcp4.Options{ options: dhcp4.Options{
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0}, dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
dhcp4.OptionRouter: []byte(serverIP), dhcp4.OptionRouter: []byte(serverIP),
@ -251,7 +251,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
dhcp4.Offer, dhcp4.Offer,
h.serverIP, h.serverIP,
dhcp4.IPAdd(h.start, free), dhcp4.IPAdd(h.start, free),
h.leasePeriod, h.LeasePeriod,
h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList])) h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
case dhcp4.Request: case dhcp4.Request:
@ -267,7 +267,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
Num: leaseNum, Num: leaseNum,
Addr: make([]byte, 4), Addr: make([]byte, 4),
HardwareAddr: p.CHAddr().String(), HardwareAddr: p.CHAddr().String(),
Expiry: h.timeNow().Add(h.leasePeriod), Expiry: h.timeNow().Add(h.LeasePeriod),
Hostname: string(options[dhcp4.OptionHostName]), Hostname: string(options[dhcp4.OptionHostName]),
} }
copy(lease.Addr, reqIP.To4()) 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) 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])) h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
} }
return nil return nil