[api] Avoid heap allocation in PSK update timeout lambda

The set_timeout lambda captured a psk_t (std::array<uint8_t, 32>) by
value, making the lambda 36 bytes — well beyond the std::function
small buffer optimization threshold, forcing a heap allocation.

Re-read the PSK from preferences inside the timeout callback instead.
The PSK was just saved to flash moments before the timeout was
scheduled, so re-reading it is reliable and avoids the large capture.

Extract load_and_apply_noise_psk_() helper to deduplicate the
load-from-preferences-and-apply pattern used in both setup() and
the timeout callback.
This commit is contained in:
J. Nick Koston
2026-03-18 08:47:34 -10:00
parent 9a80c980cb
commit 3187ab9208
2 changed files with 18 additions and 5 deletions
+16 -5
View File
@@ -46,10 +46,8 @@ void APIServer::setup() {
#ifndef USE_API_NOISE_PSK_FROM_YAML
// Only load saved PSK if not set from YAML
SavedNoisePsk noise_pref_saved{};
if (this->noise_pref_.load(&noise_pref_saved)) {
if (this->load_and_apply_noise_psk_()) {
ESP_LOGD(TAG, "Loaded saved Noise PSK");
this->set_noise_psk(noise_pref_saved.psk);
}
#endif
#endif
@@ -526,9 +524,14 @@ bool APIServer::update_noise_psk_(const SavedNoisePsk &new_psk, const LogString
}
ESP_LOGD(TAG, "%s", LOG_STR_ARG(save_log_msg));
if (make_active) {
this->set_timeout(100, [this, active_psk]() {
this->set_timeout(100, [this]() {
// Re-read the PSK from preferences rather than capturing the 32-byte array
// in the lambda (which would exceed std::function SBO and heap-allocate).
if (!this->load_and_apply_noise_psk_()) {
ESP_LOGW(TAG, "Failed to load saved PSK for activation");
return;
}
ESP_LOGW(TAG, "Disconnecting all clients to reset PSK");
this->set_noise_psk(active_psk);
for (auto &c : this->clients_) {
DisconnectRequest req;
c->send_message(req);
@@ -538,6 +541,14 @@ bool APIServer::update_noise_psk_(const SavedNoisePsk &new_psk, const LogString
return true;
}
bool APIServer::load_and_apply_noise_psk_() {
SavedNoisePsk saved{};
if (!this->noise_pref_.load(&saved))
return false;
this->set_noise_psk(saved.psk);
return true;
}
bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
#ifdef USE_API_NOISE_PSK_FROM_YAML
// When PSK is set from YAML, this function should never be called
+2
View File
@@ -240,6 +240,8 @@ class APIServer final : public Component,
#ifdef USE_API_NOISE
bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg,
const psk_t &active_psk, bool make_active);
/// Load saved PSK from preferences and apply it. Returns true on success.
bool load_and_apply_noise_psk_();
#endif // USE_API_NOISE
#ifdef USE_API_HOMEASSISTANT_STATES
// Helper methods to reduce code duplication