mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
dhcp: renew at half the lease when the server omits T1
Option 58 is optional, and dhcp_state.renewal is only ever written by parse_opts(), so a server that leaves it out keeps it at zero. The ACK handler then sets dhcp_timer to zero, and the callback treats a zero timer in LEASING as time to renew, so it sends a REQUEST on the next pass. That REQUEST does set a 30 second timeout, but the ACK that answers it comes back through the same path and zeroes the timer again, so the two sides trade REQUEST and ACK as fast as the round trip allows, with the console printing the whole lease each time round. RFC 2131 has the client renew at half the lease when the server does not say, so use that, and fall back to a fixed value if there is no lease either. Both only fill in a value that is missing: a server that asks for a short renewal still gets exactly what it asked for, which a blanket lower bound would have overridden. Not reproduced here, that needs a server configured without the option.
This commit is contained in:
1 parent
6488433584
commit
eab17f8a3f
1 file changed
+12
@@ -332,6 +332,18 @@ void parse_dhcp(void)
|
||||
uip_ipaddr(&uip_hostaddr, dhcp_state.current_ip[0], dhcp_state.current_ip[1], dhcp_state.current_ip[2], dhcp_state.current_ip[3]);
|
||||
uip_ipaddr(&uip_draddr, dhcp_state.router[0], dhcp_state.router[1], dhcp_state.router[2], dhcp_state.router[3]);
|
||||
uip_ipaddr(&uip_netmask, dhcp_state.subnet[0], dhcp_state.subnet[1], dhcp_state.subnet[2], dhcp_state.subnet[3]);
|
||||
/* T1 is optional. Without it the renewal time stays zero, which
|
||||
* makes dhcp_timer zero, and the callback then sends a REQUEST on
|
||||
* every pass through LEASING: client and server trade REQUEST and
|
||||
* ACK as fast as the round trip allows. RFC 2131 has the client
|
||||
* renew at half the lease when the server does not say, and if
|
||||
* there is no lease either, pick something rather than zero. Only
|
||||
* filled in when absent, so a server that asks for a short renewal
|
||||
* still gets it. */
|
||||
if (!dhcp_state.renewal)
|
||||
dhcp_state.renewal = dhcp_state.lease / 2;
|
||||
if (!dhcp_state.renewal)
|
||||
dhcp_state.renewal = 60;
|
||||
dhcp_state.state = DHCP_LEASING;
|
||||
dhcp_state.ticks = SYS_TICK_HZ;
|
||||
dhcp_state.dhcp_timer = dhcp_state.renewal > 0xffff ? 0xffff : dhcp_state.renewal;
|
||||
|
||||
Reference in new issue
Block a user