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
|
return err
|
||||||
}
|
}
|
||||||
var leases []*dhcp4d.Lease
|
var leases []*dhcp4d.Lease
|
||||||
if err := json.Unmarshal(b, leases); err != nil {
|
if err := json.Unmarshal(b, &leases); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
h.SetLeases(leases)
|
h.SetLeases(leases)
|
||||||
|
@ -21,6 +21,10 @@ type Lease struct {
|
|||||||
Expiry time.Time `json:"expiry"`
|
Expiry time.Time `json:"expiry"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Lease) Expired(at time.Time) bool {
|
||||||
|
return !l.Expiry.IsZero() && at.After(l.Expiry)
|
||||||
|
}
|
||||||
|
|
||||||
type Handler struct {
|
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
|
||||||
@ -80,11 +84,11 @@ func (h *Handler) findLease() int {
|
|||||||
if len(h.leasesIP) < h.leaseRange {
|
if len(h.leasesIP) < h.leaseRange {
|
||||||
// TODO: hash the hwaddr like dnsmasq
|
// TODO: hash the hwaddr like dnsmasq
|
||||||
i := rand.Intn(h.leaseRange)
|
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
|
return i
|
||||||
}
|
}
|
||||||
for i := 0; i < h.leaseRange; 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
|
return i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +115,7 @@ func (h *Handler) canLease(reqIP net.IP, hwaddr string) int {
|
|||||||
return leaseNum // lease already owned by requestor
|
return leaseNum // lease already owned by requestor
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.timeNow().After(l.Expiry) {
|
if l.Expired(h.timeNow()) {
|
||||||
return leaseNum // lease expired
|
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]),
|
Hostname: string(options[dhcp4.OptionHostName]),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release any old leases for this client
|
|
||||||
if l, ok := h.leasesHW[lease.HardwareAddr]; ok {
|
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)
|
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) {
|
func TestExpiration(t *testing.T) {
|
||||||
handler, cleanup := testHandler(t)
|
handler, cleanup := testHandler(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user