Hi Simon,
a `dhcp-host` reservation with `infinite` silently ends up with a finite
lease
as soon as the client sends option 51. calc_time() treats the configured
lease
time as an upper bound, and `infinite` is an unbounded one, so whatever the
client asks for is shorter and wins. Apple devices request 7776000
seconds in
every DHCPREQUEST, so every iPhone/iPad/Watch with a reservation is
affected.
The attached patch honors `infinite` literally when it comes from
`dhcp-host`:
for a reserved address there is nothing to be gained from expiring it early.
`dhcp-range` is left alone - there, granting a client's shorter request does
return pool addresses sooner.
Reproducer, with a client sending option 51 = 7776000 for its reserved
address:
dnsmasq -d --port=0 --dhcp-authoritative \
--dhcp-range=10.99.0.100,10.99.0.200,255.255.255.0,1h \
--dhcp-host=02:aa:bb:cc:dd:ee,10.99.0.9,testhost,infinite
The DHCPACK lease time is 7776000 before and 4294967295 with the patch. A
finite `dhcp-host` lease time and pool addresses behave exactly as
before, in
both directions.
Downstream report: https://github.com/pi-hole/FTL/issues/3014
Best regards,
Dominik
From 63ced127b864459eb5d50651811c165151ca12df Mon Sep 17 00:00:00 2001
From: DL6ER <[email protected]>
Date: Sun, 9 Aug 2026 10:14:36 +0200
Subject: [PATCH] Do not shorten a host's infinite lease to the client's
requested time
`calc_time()` treats the configured lease time as an upper bound and grants
whatever shorter time the client asks for in DHCP option 51. An infinite lease
time is unbounded, so *any* time the client requests wins and a host configured
as
dhcp-host=<mac>,<address>,infinite
ends up with a finite lease. Apple clients run into this because they ask for
7776000 seconds (90 days) in every request.
A lease time given in `dhcp-host` is explicit and per-host, so `infinite` is
now honored literally - there is no pool hygiene to be gained from expiring a
reserved address earlier. `dhcp-range` is left unchanged: for pool addresses,
a client asking for less is still respected.
Signed-off-by: DL6ER <[email protected]>
---
src/rfc2131.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 7b58e69..4065c9c 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -1858,10 +1858,13 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt)
{
- unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
-
- if (opt)
- {
+ int host_time = have_config(config, CONFIG_TIME);
+ unsigned int time = host_time ? config->lease_time : context->lease_time;
+
+ /* The configured lease time is an upper bound a client may ask to shorten,
+ but an infinite lease configured for this very host is meant literally. */
+ if (opt && !(host_time && time == 0xffffffff))
+ {
unsigned int req_time = option_uint(opt, 0, 4);
if (req_time < 120 )
req_time = 120; /* sanity */
--
2.43.0
_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss