mirror of
https://github.com/esphome/esphome.git
synced 2026-02-28 09:54:19 -07:00
[wifi] Use DHCP_STATE_BOUND check instead of netif_is_link_up
netif_is_link_up() is insufficient — if wifi_station_connect() completes quickly (e.g. fast_connect), the setup() call at line 710 could reach dhcp_renew() with link up but DHCP still in SELECTING or REQUESTING state, causing the same state corruption. Check dhcp->state == DHCP_STATE_BOUND directly to ensure dhcp_renew() is only called when there is an actual lease to renew. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,8 @@ extern "C" {
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/init.h" // LWIP_VERSION_
|
||||
#include "lwip/prot/dhcp.h" // DHCP_STATE_BOUND
|
||||
#include "lwip/init.h" // LWIP_VERSION_
|
||||
#include "lwip/apps/sntp.h"
|
||||
#include "lwip/netif.h" // struct netif
|
||||
#include <AddrList.h>
|
||||
@@ -224,13 +225,14 @@ bool WiFiComponent::wifi_apply_hostname_() {
|
||||
#else
|
||||
intf->hostname = wifi_station_get_hostname();
|
||||
#endif
|
||||
if (netif_dhcp_data(intf) != nullptr && netif_is_link_up(intf)) {
|
||||
// Renew already started DHCP leases to inform server of hostname change.
|
||||
// Only attempt when the interface has link — calling dhcp_renew() without
|
||||
// an active connection corrupts lwIP's DHCP state machine (it unconditionally
|
||||
// sets state to RENEWING before attempting to send, and never rolls back on
|
||||
// failure). This causes dhcp_network_changed() to call dhcp_reboot() instead
|
||||
// of dhcp_discover() when WiFi later connects, sending a bogus DHCP REQUEST
|
||||
struct dhcp *dhcp_data = netif_dhcp_data(intf);
|
||||
if (dhcp_data != nullptr && dhcp_data->state == DHCP_STATE_BOUND) {
|
||||
// Renew already-bound DHCP leases to inform server of hostname change.
|
||||
// Only attempt when DHCP is BOUND — calling dhcp_renew() in any other
|
||||
// state corrupts lwIP's DHCP state machine (it unconditionally sets state
|
||||
// to RENEWING before attempting to send, and never rolls back on failure).
|
||||
// This causes dhcp_network_changed() to call dhcp_reboot() instead of
|
||||
// dhcp_discover() when WiFi later connects, sending a bogus DHCP REQUEST
|
||||
// for IP 0.0.0.0 that can put some routers into a persistent bad state.
|
||||
err_t lwipret = dhcp_renew(intf);
|
||||
if (lwipret != ERR_OK) {
|
||||
|
||||
Reference in New Issue
Block a user