dhcp4d: implement permanent leases (no expiration)
This commit is contained in:
parent
d21822f531
commit
4c69109db5
@ -27,7 +27,7 @@ func loadLeases(h *dhcp4d.Handler, fn string) error {
|
||||
return err
|
||||
}
|
||||
var leases []*dhcp4d.Lease
|
||||
if err := json.Unmarshal(b, leases); err != nil {
|
||||
if err := json.Unmarshal(b, &leases); err != nil {
|
||||
return err
|
||||
}
|
||||
h.SetLeases(leases)
|
||||
|
@ -21,6 +21,10 @@ type Lease struct {
|
||||
Expiry time.Time `json:"expiry"`
|
||||
}
|
||||
|
||||
func (l *Lease) Expired(at time.Time) bool {
|
||||
return !l.Expiry.IsZero() && at.After(l.Expiry)
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
serverIP net.IP
|
||||
start net.IP // first IP address to hand out
|
||||
@ -80,11 +84,11 @@ func (h *Handler) findLease() int {
|
||||
if len(h.leasesIP) < h.leaseRange {
|
||||
// TODO: hash the hwaddr like dnsmasq
|
||||
i := rand.Intn(h.leaseRange)
|
||||
if l, ok := h.leasesIP[i]; !ok || now.After(l.Expiry) {
|
||||
if l, ok := h.leasesIP[i]; !ok || l.Expired(now) {
|
||||
return i
|
||||
}
|
||||
for i := 0; i < h.leaseRange; i++ {
|
||||
if l, ok := h.leasesIP[i]; !ok || now.After(l.Expiry) {
|
||||
if l, ok := h.leasesIP[i]; !ok || l.Expired(now) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
@ -111,7 +115,7 @@ func (h *Handler) canLease(reqIP net.IP, hwaddr string) int {
|
||||
return leaseNum // lease already owned by requestor
|
||||
}
|
||||
|
||||
if h.timeNow().After(l.Expiry) {
|
||||
if l.Expired(h.timeNow()) {
|
||||
return leaseNum // lease expired
|
||||
}
|
||||
|
||||
@ -174,8 +178,14 @@ func (h *Handler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
|
||||
Hostname: string(options[dhcp4.OptionHostName]),
|
||||
}
|
||||
|
||||
// Release any old leases for this client
|
||||
if l, ok := h.leasesHW[lease.HardwareAddr]; ok {
|
||||
if l.Expiry.IsZero() {
|
||||
// Retain permanent lease properties
|
||||
lease.Expiry = time.Time{}
|
||||
lease.Hostname = l.Hostname
|
||||
}
|
||||
|
||||
// Release any old leases for this client
|
||||
delete(h.leasesIP, l.Num)
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,43 @@ func TestPreviousLease(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPermanentLease(t *testing.T) {
|
||||
handler, cleanup := testHandler(t)
|
||||
defer cleanup()
|
||||
now := time.Now()
|
||||
handler.timeNow = func() time.Time { return now }
|
||||
|
||||
var (
|
||||
addr = net.IP{192, 168, 42, 23}
|
||||
hardwareAddr = net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
||||
)
|
||||
|
||||
handler.SetLeases([]*Lease{
|
||||
{
|
||||
Num: 2,
|
||||
Addr: addr,
|
||||
HardwareAddr: hardwareAddr.String(),
|
||||
},
|
||||
})
|
||||
|
||||
p := request(addr, hardwareAddr)
|
||||
resp := handler.ServeDHCP(p, dhcp4.Request, p.ParseOptions())
|
||||
if got, want := resp.YIAddr().To4(), addr.To4(); !bytes.Equal(got, want) {
|
||||
t.Errorf("DHCPREQUEST resulted in wrong IP: got %v, want %v", got, want)
|
||||
}
|
||||
|
||||
now = now.Add(3 * time.Hour)
|
||||
|
||||
hardwareAddr[len(hardwareAddr)-1] = 0x77
|
||||
|
||||
p = request(addr, hardwareAddr)
|
||||
resp = handler.ServeDHCP(p, dhcp4.Request, p.ParseOptions())
|
||||
opts := resp.ParseOptions()
|
||||
if got, want := dhcp4.MessageType(opts[dhcp4.OptionDHCPMessageType][0]), dhcp4.NAK; got != want {
|
||||
t.Errorf("DHCPREQUEST resulted in unexpected message type: got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiration(t *testing.T) {
|
||||
handler, cleanup := testHandler(t)
|
||||
defer cleanup()
|
||||
|
Loading…
x
Reference in New Issue
Block a user