AutoIP ACD rate-limit state is overwritten and mDNS does not re-probe after IPv4 Link-Local address changes (IDFGH-18293)
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
Environment
- Development framework: ESP-IDF v5.4.2
- Target: ESP32-S3
- Network interface under test: Wi-Fi station and ethernet connection
- lwIP features:
- DHCP client enabled
- AutoIP enabled
- DHCP/AutoIP cooperation enabled
- IPv4 Address Conflict Detection enabled
- Test tool: Bonjour Conformance Test 1.5.4
- Test type: Wi-Fi, using an access point connected to the isolated BCT network
- Device Wi-Fi MAC address: omitted from this public report
- Device type: Zigbee Gateway
Summary
While running the Bonjour Conformance Test against an ESP32-S3 Wi-Fi station using ESP-IDF 5.4.2, I found two issues related to the interaction between DHCP, AutoIP, ACD and mDNS:
- The AutoIP ACD rate-limit state can be overwritten by a subsequent call to
autoip_start(). - After an AutoIP Link-Local address conflict causes the IPv4 address to change, the mDNS responder updates the A record but does not appear to restart mDNS probing for the unique records.
The first issue causes the BCT Link-Local Address Allocation tests to fail. I implemented two experimental changes in autoip.c and acd.c, after which the entire Link-Local Address Allocation section passed.
The remaining failure is now in Multicast DNS / INITIAL PROBING.
Original BCT failures
With the original ESP-IDF 5.4.2 behavior, the following Link-Local tests failed:
PROBING: RATE LIMITINGSUBSEQUENT CONFLICTSCABLE CHANGE HANDLINGwas aborted- The mDNS tests were skipped because the Link-Local Address Allocation section could not recover
Instrumentation was added temporarily to acd.c and autoip.c to log:
- ACD instance address
- ACD state
- Conflict counter
- Rate-limit timer
- AutoIP state
- AutoIP candidate address
- ACD callback events
Issue 1: AutoIP ACD rate limiting is overwritten
The instrumentation confirmed that DHCP and AutoIP use separate ACD instances on the same network interface.
Example:
text DHCP ACD: acd=0x3c2c19ac ip=192.168.1.x
AutoIP ACD: acd=0x3c2c1bfc ip=169.254.181.x
Attached, you could find my sdkconfig file.
Issue 2: Passive AutoIP ACD conflict does not select a new address
When DHCP obtains a routable IPv4 address after an AutoIP address has already been configured, the AutoIP ACD instance is moved to ACD_STATE_PASSIVE_ONGOING
When a conflicting ARP packet is received for that Link-Local address, the current implementation executes: acd_stop(acd); acd->acd_conflict_callback(netif, ACD_DECLINE);
The AutoIP callback clears the conflicting Link-Local address and stops AutoIP, but no ACD_RESTART_CLIENT callback is generated. The observed sequence was: [BCT_ACD] PASSIVE RETREAT [BCT_AUTOIP] CALLBACK DECLINE [BCT_AUTOIP] DECLINE COMPLETE
No new AutoIP address was selected and no new ARP probe was sent. This caused the BCT SUBSEQUENT CONFLICTS test to fail.
Remaining issue: mDNS does not re-probe after the IPv4 address changes:
After the Link-Local section passed, the BCT proceeded to the Multicast DNS section. The remaining failure is:
Multicast DNS
WARNING: INITIAL PROBING FAILED: INITIAL PROBING
The BCT forces an ARP conflict on the current Link-Local address. The device correctly selects another Link-Local address.
Example: 169.254.181.235 -> 169.254.181.236
The BCT then receives an updated mDNS A record: Received updated name record: ED**-xxxxxxxxxxxx.local. -> 169.254.181.236 This confirms that the mDNS responder detects the address change and updates the hostname address record.
However, after receiving the updated A record, the BCT waits for a new mDNS probe and repeatedly reports: Receive New Probe: Timeout
The behavior is repeatable for multiple address changes: 169.254.181.235 -> 169.254.181.236 169.254.181.236 -> 169.254.181.237 169.254.181.237 -> 169.254.181.238 169.254.181.238 -> 169.254.181.239 169.254.181.239 -> 169.254.181.240 169.254.181.240 -> 169.254.181.241 169.254.181.241 -> 169.254.181.242
For every transition: ACD detects the conflict. AutoIP selects a new address. ARP probing completes. The new address is bound. The mDNS A record is updated. No new mDNS probe for the unique records is observed by the BCT.
The BCT eventually fails with: RETRY FAILED (INITIAL PROBING) Unable to recover from failures. Aborting multicast DNS test.
Expected behavior
After a Link-Local IPv4 address change, the mDNS responder should update the affected address records and perform the required probing/announcement sequence for unique records, as expected by the Bonjour Conformance Test.
Actual behavior
The mDNS responder updates or announces the new A record, but the BCT does not observe a new mDNS probing sequence after the address change.
Questions
Is blocking autoip_start() while autoip->acd.state == ACD_STATE_RATE_LIMIT the correct way to preserve the ACD rate-limit period? Should ACD_STATE_PASSIVE_ONGOING generate ACD_RESTART_CLIENT after ACD_DECLINE when the ACD client belongs to AutoIP? Is there an existing ESP-IDF mDNS API or internal event that should restart probing of unique records after an IPv4 address change? Should the ESP-IDF mDNS component automatically restart probing when an IP_EVENT_STA_GOT_IP event reports a changed IPv4 address? Are these issues already addressed in a later ESP-IDF 5.4.x release?
Reproduction procedure
Configure an ESP32-S3 Wi-Fi station with DHCP, AutoIP cooperation and ACD enabled. Connect the device and the BCT host through an isolated Wi-Fi network. Run Bonjour Conformance Test 1.5.4 in Wi-Fi mode. Allow the BCT to deny the proposed DHCP and AutoIP addresses. Observe the ACD rate-limit behavior. Continue until the Multicast DNS INITIAL PROBING test. Allow the BCT to force a conflict on the current Link-Local address. Observe that AutoIP selects a new address and that mDNS updates the A record. Observe that no new mDNS probe is detected by the BCT. Logs available
I can provide:
Full Bonjour Conformance Test summary (available attached) Full BCT debug log with timestamps (available attached) ESP32-S3 serial console log
Source: espressif/esp-idf