From 63ced127b864459eb5d50651811c165151ca12df Mon Sep 17 00:00:00 2001 From: DL6ER 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=,
,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 --- 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