[api] Drop connection instead of crashing when buffer allocation fails (#18803)

This commit is contained in:
J. Nick Koston
2026-08-27 14:49:12 +12:00
committed by GitHub
parent a8094ed548
commit e55a8aeabe
15 changed files with 148 additions and 96 deletions
+8 -14
View File
@@ -352,22 +352,13 @@ class APIConnection final : public APIServerConnectionBase {
}
}
void prepare_first_message_buffer(APIBuffer &shared_buf, size_t header_padding, size_t total_size) {
shared_buf.clear();
// Reserve space for header padding + message + footer
// - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
// - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
// Reserve full size but only set initial size to header padding
// so message encoding starts at the correct position
shared_buf.reserve_and_resize(total_size, header_padding);
}
/// Clear the shared write buffer and reserve space for the first message.
/// Returns false if the allocation fails (out of memory).
/// Defined in api_connection_buffer.h (needs APIServer complete).
[[nodiscard]] bool prepare_first_message_buffer(size_t header_padding, size_t total_size);
// Convenience overload - computes frame overhead internally
void prepare_first_message_buffer(APIBuffer &shared_buf, size_t payload_size) {
const uint8_t header_padding = this->helper_->frame_header_padding();
const uint8_t footer_size = this->helper_->frame_footer_size();
this->prepare_first_message_buffer(shared_buf, header_padding, payload_size + header_padding + footer_size);
}
[[nodiscard]] bool prepare_first_message_buffer(size_t payload_size);
bool try_to_clear_buffer(bool log_out_of_space) {
if (this->flags_.remove)
@@ -853,6 +844,9 @@ class APIConnection final : public APIServerConnectionBase {
this->on_fatal_error();
this->log_warning_(message, err);
}
// Shared cold path for buffer allocation failures — noinline keeps the
// OOM handling out of the hot send paths
void __attribute__((noinline)) fatal_out_of_memory_();
};
} // namespace esphome::api