Add IPv6-aware Wi-Fi state, HTTPS/SSH listeners, mDNS service reconciliation, and browser Wi-Fi administration. Include a guarded build-local fix for mDNS 1.12.0 membership handling, focused regression suites, and Phase 12 acceptance documentation.
Phase 12 SSH listener regression
Run python3 tests/ssh_phase12/run.py from the repository root. Requires Python 3
and a host C compiler (cc). It extracts the production functions without rewriting
them and compiles with -std=c11 -Wall -Wextra -Werror.
Coverage:
- One AF_INET6/TCP wildcard listener, explicitly checked IPV6_V6ONLY=0 before bind.
- Failures at socket, dual-stack option, bind, listen and both nonblocking steps: no published descriptor, exactly one close after socket allocation.
- Permanent accept errors withdraw availability, invalidate the service generation without wrap, and request owner-side session cleanup; temporary errors retain the listener. Capacity rejection respects the existing four-accept budget.
- IPv4, global IPv6, scoped link-local IPv6, mapped IPv4, maximum numeric scope, unknown families, and bounded/truncated peer formatting.
tests/ssh_management/runtime.py additionally tests availability across real
production start/stop functions with context/listener/cleanup doubles, including
failed session cleanup retaining the context, successful restart, and failed start.
Existing management/security regressions remain responsible for authentication,
identity ownership and generation fencing.
SDK contract checked during implementation
Read-only inspection of installed ESP-IDF 5.5.0
(framework-espidf@3.50500.0, not the separately installed 5.5.3):
components/lwip/lwip/src/include/lwip/sockets.h:sockaddr_in6.sin6_scope_idisu32_t;IPV6_V6ONLYis supported.components/lwip/lwip/src/include/lwip/inet.h:IN6ADDR_ANY_INIT.components/lwip/lwip/src/api/sockets.c:lwip_setsockopt_implappliesnetconn_set_ipv6only;IP6ADDR_PORT_TO_SOCKADDRcopies the interface zone;lwip_acceptpublishes the peer address and maps a closed listener to EINVAL, non-TCP sockets to EOPNOTSUPP, and descriptor exhaustion to ENFILE.components/lwip/lwip/src/api/api_msg.c: wildcard IPv6 bind/listen with V6ONLY disabled selectsIPADDR_TYPE_ANY, accepting both families on one listener.
These host doubles do not execute lwIP, actual networking, wolfSSH handshakes, RTOS concurrency, discovery traffic or hardware. No PlatformIO build is required or claimed. Device follow-up must verify IPv4-only, IPv6-only and dual-stack connections, scoped link-local access, address changes/reconnects, simultaneous clients and binary UART traffic, advertisement convergence after start/stop/error, and independent UART0/native USB recovery.
Resource and handoff notes
No extra socket, task, session, queue, I/O buffer or heap allocation is introduced. Peer arrays grow from 48 to 65 bytes: 68 additional raw bytes across the two owner slots and two published snapshots, plus ABI padding. Public snapshot copies also grow. Exact linked RAM/flash and stack headroom were not measured without a target build; host tests do not establish ESP32 memory headroom.
Project agent memory is intentionally not edited under the exclusive-write scope. The parent should record the one-socket dual-stack contract, scoped peer capacity, and owner-driven mDNS availability (eventual Wi-Fi-manager reconciliation) in the relevant durable memory when integrating Phase 12.