|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
Layer: L7 Application ยท Build flags: PC_ENABLE_MDNS, PC_ENABLE_PROMISC, PC_ENABLE_WIFI_SNIFFER, PC_ENABLE_MDNS_ADAPTIVE
An mDNS record lapses from network caches at its TTL, so a device has to re-announce to stay discoverable. But hammering announces on a busy 2.4 GHz channel just adds collisions. This ties three shipped pieces together so the announce cadence tracks the air:
This was tried once with a second socket bound to 224.0.0.251:5353 to count announcements, and it broke the responder: bound after the ESP-IDF mdns responder the join fails; bound before it, the responder goes announce-only - its service still appears in avahi-browse but every SRV/TXT/A query times out, so the device silently stops resolving. lwIP hands a datagram to the first matching PCB, and a raw PCB sharing the port with the responder's socket-layer one does not get a copy.
Promiscuous mode is a radio-layer callback, not a socket. It never touches the responder's sockets, so the record keeps resolving while the count runs - which this example verifies on hardware. The cost is that it owns the radio in promiscuous mode, pinned to the station's own channel, so it cannot run at the same time as the wifi_sniffer live channel-hop binding.
You cannot back off past the TTL - the record would lapse from caches before the next refresh, making the device undiscoverable, which is the exact opposite of the point. So:
pc_mdns_adaptive_begin(), whatever max_interval_ms you request.The adaptive range is therefore fundamentally [TTL/2, ~TTL). A short TTL is a narrow range; a longer TTL buys more absolute room to back off. This example uses a 30 s TTL so the cadence is easy to watch.
HW-verified (2026-07-19) on an ESP32-S3, with avahi on a LAN peer.
Coexistence - the thing that broke before. While promiscuous capture and adaptive announcing run:
A, SRV, and TXT all resolve - the responder is fully healthy with the capture running.
Backoff from real contention - a build with the threshold lowered below the ambient traffic on the connected channel, so real frames cross it:
The interval climbed from the real per-window frame count crossing the threshold, and stopped at the safe ceiling rather than running past the TTL. Recovery (a fully silent window halves the interval back toward the base) is host-tested - a live channel will not reliably go silent for a whole window, so it is not shown here.
| Route | What it does |
|---|---|
/mdns | {"interval_ms":N,"contention":N,"announces":N,"channel":N} |
| Board | Flash |
|---|---|
| ESP32 | 780,361 B (59%) |
| ESP32-S3 | 939,995 B (71%) |
The flags must reach the library build, so pass them as build flags: