Commit Graph
27 Commits
Author SHA1 Message Date
J. Nick Koston 884dab4a6a [socket] Null cached_sock_ in close() to prevent post-close UAF
Restore the cached_sock_ = nullptr assignment inside close() on the
fast-select path. The lwip slot can be recycled for a new connection
as soon as the underlying close() returns, so any dereference of
cached_sock_ afterwards would touch an unrelated socket's pcb.

No current caller does this — setsockopt(TCP_NODELAY) and ready() are
the only consumers and neither is invoked post-close today — but
leaving the pointer dangling is a footgun for future changes. The
fd_ = -1 sentinel alone would catch the ready() path via closed
semantics, but setsockopt() reaches cached_sock_ directly and would
not be protected. Null the pointer so the protection is by
construction rather than by caller discipline.
2026-04-10 21:12:51 -10:00
J. Nick Koston b9541cd5db [socket] Eliminate closed_ and loop_monitored_ redundancy
Replace the separate closed_ bool with fd_ < 0 as the 'not open'
sentinel. close() now sets fd_ = -1 after the underlying close call,
so the destructor and double-close paths just check fd_ < 0. As a
side benefit, get_fd() on a closed socket now returns -1, making
use-after-close visible to callers instead of returning a stale
descriptor.

Drop loop_monitored_ on the USE_LWIP_FAST_SELECT path — the pointer
cached_sock_ already encodes monitoring state (non-null iff
monitored). On USE_HOST the bool is still needed because there is no
cached pointer to derive from.

Combined effect on the fast-select path:

  Before:  fd_(4) + cached_sock_(4) + closed_(1) + loop_monitored_(1)
           + pad(2) = 12 bytes per socket
  After:   fd_(4) + cached_sock_(4)
           = 8 bytes per socket (aligned, no tail padding)

Saves 4 bytes per Socket instance on ESP32/LibreTiny. With typical
workloads running 5-10 sockets (API listen + clients + mDNS) that's
20-40 bytes of RAM.
2026-04-10 21:05:21 -10:00
J. Nick Koston 107915fe36 [socket] Dedupe fast_select hook logic into shared helper
Lift the lwip_sock resolve + event-callback hook sequence into
socket::fast_select_hook_fd() in socket.h so the USE_LWIP_FAST_SELECT
constructor blocks in lwip_sockets_impl.cpp and bsd_sockets_impl.cpp
stop drifting in lockstep. Both impls now collapse to a two-line call
site.
2026-04-10 20:59:12 -10:00
J. Nick Koston 4a9d3da962 [core] fast_select scan removal: address review feedback
- Drop redundant cached_sock_ = nullptr assignment in close(). After
  closed_ = true the socket is a corpse and no ready() or other member
  access is valid, so the nulling is not load-bearing. The comment now
  explains why on both impl variants.

- Reword the yield_with_select_ comment so the wake-source sentence
  reads as a complete list rather than a trailing fragment.
2026-04-10 20:58:12 -10:00
J. Nick Koston 7ce49089a0 [core] Remove pre-sleep socket scan from fast select path
The pre-sleep scan in Application::yield_with_select_() walks
monitored_sockets_ on every loop iteration, issuing a volatile
cross-thread read on each socket's lwip_sock::rcvevent to preserve
select() semantics when the FreeRTOS task notification counter had
been consumed but a socket still had unread data.

That scenario only existed because of a Socket::ready() contract
violation: callers could stop reading with rcvevent > 0, leaving
data behind with no pending notification. That contract is now
documented and enforced (#15590), and #15589 (the first failure
that reverted the earlier removal attempt #14475) has been fixed.

With the contract honoured, every rcvevent > 0 is paired with a
pending xTaskNotifyGive from the lwip event_callback wrapper (see
lwip_fast_select.c). ulTaskNotifyTake either returns immediately
(counter non-zero) or wakes the moment the notify lands — the scan
has nothing left to rescue.

Evidence: https://github.com/esphome/esphome/pull/15638 — an
instrumentation PR ran across 5 devices (ESP32 rev1/rev3.1/C3 on
Ethernet and WiFi, plus LibreTiny RTL8720CF) through Home Assistant
disconnect/reconnect cycles, multi-client API logger bursts, and
BLE GATT connect storms. Across ~275,000 scans and 4 observed
load-bearing candidates, every hit was in the 2–14µs range — the
instruction-level window between the lwip callback writing
rcvevent and calling xTaskNotifyGive a few instructions later.
Zero hits exceeded 100µs. No hit came anywhere near loop_interval
(16ms), which is the latency scale the scan was added to prevent.

In addition to being unused, the scan is actively harmful on the
hot path: N volatile 16-bit loads against cache-cold cross-thread
lwip_sock structures on every main-loop iteration, just to
reproduce a microsecond-scale ordering artifact the notification
path is already handling authoritatively.

This also removes the now-unused monitored_sockets_ vector and
Application::{register,unregister}_socket() on the fast-select
path. Socket implementations now call esphome_lwip_hook_socket()
directly to install the netconn event callback wrapper.
2026-04-10 20:50:47 -10:00
J. Nick Koston d53ff7892a [socket] Cache lwip_sock pointers and inline ready() chain (#14408) 2026-03-03 07:03:02 -10:00
J. Nick Koston 585e195044 [socket] Devirtualize socket abstraction layer (#14398) 2026-03-02 06:58:31 -10:00
c9c125aa8d [socket] Devirtualize Socket::ready() and implement working ready() for LWIP raw TCP (#13913)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-02-11 17:54:58 +00:00
J. Nick Koston df4a3e8915 [socket] Call lwip_read/lwip_write directly on ESP32 to reduce network I/O latency (#13179) 2026-01-13 01:47:11 -06:00
J. Nick KostonandKeith Burzinski 2147ddf8c7 [api] Eliminate std::string from ClientInfo struct (#12566)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
2026-01-06 21:32:23 +00:00
J. Nick Koston 2cf6ed2af7 [socket] Refactor socket implementations for memory efficiency and code quality (#12550) 2025-12-18 09:07:35 -07:00
Jonathan Swoboda cf02a08209 [esp32] Bump IDF version to 5.5.1 and Arduino version to 3.3.2 (#9839) 2025-10-15 08:45:33 -10:00
J. Nick Koston 43e88af28a Optimize socket operations by checking readiness in the main loop (#8918) 2025-05-28 18:16:37 -05:00
Kevin Ahrendt 3410aee42e [socket] add connect method (#8308) 2025-02-25 09:32:54 +13:00
Clyde Stubbs 8267b3274c Enable networking and some other components on host platform (#6114) 2024-01-19 10:10:23 +09:00
Clyde Stubbs 3854203037 Socket: Add recvfrom method to receive UDP with source address. (#6103) 2024-01-17 08:12:31 +09:00
Jimmy Hedman 0af8d0b7ea Remove support for ESP-IDF version < 4 (#5261) 2023-08-18 08:02:57 +12:00
Jesse Hills b60c08dd28 Add push to talk voice assistant (#4648)
* Add push to talk voice assistant

* Refactor most code into voice_assistant

* Make voice_assistant the component and remove push_to_talk (can be done in yaml)

* Fix component setup

* Always AF_INET to match serverside

* Fix microphone and media player co-existence

* Format

* Update codeowners

* Update test file

* Fix endifs

* nullptr not NULL

* clang-tidy

* Format

* fixup: Add VA event data

* Generate proto

* Parse and log events

* Add default to switch

* Fix

* Add mic/va to test5
2023-04-11 23:45:10 +00:00
Jesse Hills d42f35de5d Wrap ipv6 code a bit more (#4574)
* Wrap ipv6 code a bit more for when ipv6 support should not be compiled in

* More checks

* More uses

* Fix
2023-03-21 20:24:14 +00:00
Oxan van Leeuwen 499cb615f1 socket: Format IPv4-mapped IPv6 addresses as regular IPv4 address (#4382) 2023-02-09 18:17:45 +13:00
Oxan van LeeuwenandJesse Hills 80d03a631e Force braces around multi-line statements (#3094)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2022-01-25 08:56:36 +13:00
Oxan van Leeuwen 7da12a878f Enable readability-redundant-member-init check (#3097) 2022-01-23 20:34:43 +13:00
Otto WinterandJesse Hills ac0d921413 ESP-IDF support and generic target platforms (#2303)
* Socket refactor and SSL

* esp-idf temp

* Fixes

* Echo component and noise

* Add noise API transport support

* Updates

* ESP-IDF

* Complete

* Fixes

* Fixes

* Versions update

* New i2c APIs

* Complete i2c refactor

* SPI migration

* Revert ESP Preferences migration, too complex for now

* OTA support

* Remove echo again

* Remove ssl again

* GPIOFlags updates

* Rename esphal and ICACHE_RAM_ATTR

* Make ESP32 arduino compilable again

* Fix GPIO flags

* Complete pin registry refactor and fixes

* Fixes to make test1 compile

* Remove sdkconfig file

* Ignore sdkconfig file

* Fixes in reviewing

* Make test2 compile

* Make test4 compile

* Make test5 compile

* Run clang-format

* Fix lint errors

* Use esp-idf APIs instead of btStart

* Another round of fixes

* Start implementing ESP8266

* Make test3 compile

* Guard esp8266 code

* Lint

* Reformat

* Fixes

* Fixes v2

* more fixes

* ESP-IDF tidy target

* Convert ARDUINO_ARCH_ESPxx

* Update WiFiSignalSensor

* Update time ifdefs

* OTA needs millis from hal

* RestartSwitch needs delay from hal

* ESP-IDF Uart

* Fix OTA blank password

* Allow setting sdkconfig

* Fix idf partitions and allow setting sdkconfig from yaml

* Re-add read/write compat APIs and fix esp8266 uart

* Fix esp8266 store log strings in flash

* Fix ESP32 arduino preferences not initialized

* Update ifdefs

* Change how sdkconfig change is detected

* Add checks to ci-custom and fix them

* Run clang-format

* Add esp-idf clang-tidy target and fix errors

* Fixes from clang-tidy idf round 2

* Fixes from compiling tests with esp-idf

* Run clang-format

* Switch test5.yaml to esp-idf

* Implement ESP8266 Preferences

* Lint

* Re-do PIO package version selection a bit

* Fix arduinoespressif32 package version

* Fix unit tests

* Lint

* Lint fixes

* Fix readv/writev not defined

* Fix graphing component

* Re-add all old options from core/config.py

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2021-09-20 11:47:51 +02:00
Otto Winter a990898256 Add readv and writev for more efficient API packets (#2342) 2021-09-20 10:33:10 +12:00
Oxan van Leeuwen 716039e452 Use standard version of make_unique when available (#2292) 2021-09-14 14:27:35 +02:00
40c474cd83 Run clang-tidy against ESP32 (#2147)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Otto winter <otto@otto-winter.com>
2021-09-13 18:11:27 +02:00
Otto Winter f924e80f43 Socket component (#2250) 2021-09-08 15:41:42 +12:00