Skip to content

Commit 2c813bc

Browse files
pabigotjukkar
authored andcommitted
net: dhcp: fix invalid timeout on send failure
If send_request() fails it would return UINT32_MAX as the next timeout. Callers pass the returned value to update_timeout_work without validating it. This has worked only because update_timeout_work will not set a timeout if an existing timeout would fire earlier, and the way the state is currently structured it is likely there will be an existing timeout. However, if work thread retransmission from REQUESTING failed the timer would not be rescheduled, causing the state machine to stop. A more clean solution, which matches the behavior of send_discover(), is to return the timeout for the next transmission even in the case when the send fails. The observed behavior is the same as if the network, rather than the sender, failed to transport the request. Signed-off-by: Peter Bigot <[email protected]>
1 parent 508496f commit 2c813bc

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

subsys/net/ip/dhcpv4.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,11 @@ static uint32_t dhcpv4_update_message_timeout(struct net_if_dhcpv4 *dhcpv4)
297297
return timeout;
298298
}
299299

300-
/* Prepare DHCPv4 Message request and send it to peer */
300+
/* Prepare DHCPv4 Message request and send it to peer.
301+
*
302+
* Returns the number of seconds until the next time-triggered event,
303+
* or UINT32_MAX if the client is in an invalid state.
304+
*/
301305
static uint32_t dhcpv4_send_request(struct net_if *iface)
302306
{
303307
const struct in_addr *server_addr = net_ipv4_broadcast_address();
@@ -306,7 +310,7 @@ static uint32_t dhcpv4_send_request(struct net_if *iface)
306310
bool with_server_id = false;
307311
bool with_requested_ip = false;
308312
struct net_pkt *pkt = NULL;
309-
uint32_t timeout;
313+
uint32_t timeout = UINT32_MAX;
310314

311315
iface->config.dhcpv4.xid++;
312316

@@ -346,6 +350,8 @@ static uint32_t dhcpv4_send_request(struct net_if *iface)
346350
break;
347351
}
348352

353+
timeout = dhcpv4_update_message_timeout(&iface->config.dhcpv4);
354+
349355
pkt = dhcpv4_create_message(iface, DHCPV4_MSG_TYPE_REQUEST,
350356
ciaddr, src_addr, server_addr,
351357
with_server_id, with_requested_ip);
@@ -357,8 +363,6 @@ static uint32_t dhcpv4_send_request(struct net_if *iface)
357363
goto fail;
358364
}
359365

360-
timeout = dhcpv4_update_message_timeout(&iface->config.dhcpv4);
361-
362366
NET_DBG("send request dst=%s xid=0x%x ciaddr=%s%s%s timeout=%us",
363367
log_strdup(net_sprint_ipv4_addr(server_addr)),
364368
iface->config.dhcpv4.xid,
@@ -375,7 +379,7 @@ static uint32_t dhcpv4_send_request(struct net_if *iface)
375379
net_pkt_unref(pkt);
376380
}
377381

378-
return UINT32_MAX;
382+
return timeout;
379383
}
380384

381385
/* Prepare DHCPv4 Discover message and broadcast it */

0 commit comments

Comments
 (0)