This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 4ca4c700ddc5058088ef80e34f2e11301408cd26 Author: Erik Englund <[email protected]> AuthorDate: Fri Oct 2 19:34:25 2026 +0200 netutils/dhcpc: Send the REQUEST before using the offered address. dhcpc_request() assigned the offered address to the interface as soon as the OFFER arrived, so that it could receive a unicast ACK. The REQUEST then went out with the offered address as IP source, while RFC 2131 section 4.1 requires 0.0.0.0 until the server has assigned the address. Some routers treat such a client as one with a static address; TP-Link Deco mesh routers, for example, list it as offline and do not offer address reservation for it. Send each REQUEST from the address the interface had before and only then use the offered address while waiting for the ACK, so unicast ACKs are still received. Also restore the old address when no ACK arrives instead of leaving the unconfirmed offered address in place. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Erik Englund <[email protected]> --- netutils/dhcpc/dhcpc.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index a449c96ca..8d3d4df22 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -866,13 +866,6 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult) (uint32_t)ntohl(presult->serverid.s_addr)); pdhcpc->ipaddr.s_addr = presult->ipaddr.s_addr; pdhcpc->serverid.s_addr = presult->serverid.s_addr; - - /* Temporarily use the address offered by the server - * and break out of the loop. - */ - - netlib_set_ipv4addr(pdhcpc->interface, - &presult->ipaddr); state = STATE_HAVE_OFFER; } } @@ -916,15 +909,25 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult) } /* Send the REQUEST message to obtain the lease that was offered to - * us. + * us. The offered address must not be used before the server has + * acknowledged it, so the REQUEST is sent from the address we had + * before (0.0.0.0 when unconfigured), as RFC 2131 requires. */ + netlib_set_ipv4addr(pdhcpc->interface, &oldaddr); + ninfo("Send REQUEST\n"); if (dhcpc_sendmsg(pdhcpc, presult, DHCPREQUEST) < 0) { return ERROR; } + /* Temporarily use the offered address so that a unicast ACK can be + * received. Without UDP write buffers sendto() has returned only + * after the REQUEST was sent with the old source address. + */ + + netlib_set_ipv4addr(pdhcpc->interface, &pdhcpc->ipaddr); retries++; /* Get the ACK/NAK response to the REQUEST (or timeout) */ @@ -1001,10 +1004,13 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult) while (state == STATE_HAVE_OFFER && retries < CONFIG_NETUTILS_DHCPC_RETRIES); - /* If no DHCPLEASE received here, error out */ + /* If no DHCPLEASE received here, drop the offered address and error + * out. + */ if (state != STATE_HAVE_LEASE) { + netlib_set_ipv4addr(pdhcpc->interface, &oldaddr); return ERROR; }
