mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(mbedtls): Add configuration to control dynamic buffer strategy in mbedtls
Problem: 1. In low-memory scenarios, the dynamic buffer feature can fail due to memory fragmentation. 2. It requires a contiguous 16KB heap chunk, but continuous allocation and deallocation of the RX buffer can lead to fragmentation. 3. If another component allocates memory between these operations, it can break up the available 16KB block, causing allocation failure. Solution: 1. Introduce configurable strategy for using dynamic buffers in TLS connections. 2. For example, convert RX buffers to static after the TLS handshake. 3. Allow users to select the strategy via a new field in the esp_http_client_cfg_t structure. 4. The strategy can be controlled independently for each TLS session.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -18,6 +18,17 @@
|
||||
|
||||
#define TX_IDLE_BUFFER_SIZE (MBEDTLS_SSL_HEADER_LEN + CACHE_BUFFER_SIZE)
|
||||
|
||||
#define ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl) \
|
||||
do { \
|
||||
if (ssl->MBEDTLS_PRIVATE(in_buf)) { \
|
||||
esp_mbedtls_ssl_buf_states state = esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(in_buf)); \
|
||||
if (state == ESP_MBEDTLS_SSL_BUF_STATIC) { \
|
||||
return 0; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
static const char *TAG = "Dynamic Impl";
|
||||
|
||||
static void esp_mbedtls_set_buf_state(unsigned char *buf, esp_mbedtls_ssl_buf_states state)
|
||||
@@ -140,6 +151,29 @@ static void init_rx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf)
|
||||
ssl->MBEDTLS_PRIVATE(in_left) = 0;
|
||||
}
|
||||
|
||||
esp_err_t esp_mbedtls_dynamic_set_rx_buf_static(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
unsigned char cache_buf[16];
|
||||
memcpy(cache_buf, ssl->MBEDTLS_PRIVATE(in_buf), 16);
|
||||
esp_mbedtls_reset_free_rx_buffer(ssl);
|
||||
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
int buffer_len = tx_buffer_len(ssl, MBEDTLS_SSL_IN_BUFFER_LEN);
|
||||
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
|
||||
if (!esp_buf) {
|
||||
ESP_LOGE(TAG, "rx buf alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
|
||||
init_rx_buffer(ssl, esp_buf->buf);
|
||||
|
||||
memcpy(ssl->MBEDTLS_PRIVATE(in_ctr), cache_buf, 8);
|
||||
memcpy(ssl->MBEDTLS_PRIVATE(in_iv), cache_buf + 8, 8);
|
||||
esp_mbedtls_set_buf_state(ssl->MBEDTLS_PRIVATE(in_buf), ESP_MBEDTLS_SSL_BUF_STATIC);
|
||||
return ESP_OK;
|
||||
|
||||
}
|
||||
|
||||
static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len)
|
||||
{
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
@@ -324,6 +358,12 @@ exit:
|
||||
|
||||
int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
/*
|
||||
* If RX buffer is set to static mode, this macro will return early
|
||||
* and skip dynamic buffer allocation logic below
|
||||
*/
|
||||
ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl);
|
||||
|
||||
int cached = 0;
|
||||
int ret = 0;
|
||||
int buffer_len;
|
||||
@@ -403,6 +443,12 @@ exit:
|
||||
|
||||
int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
/*
|
||||
* If RX buffer is set to static mode, this macro will return early
|
||||
* and skip dynamic buffer free logic below
|
||||
*/
|
||||
ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl);
|
||||
|
||||
int ret = 0;
|
||||
unsigned char buf[16];
|
||||
struct esp_mbedtls_ssl_buf *esp_buf;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "mbedtls/esp_mbedtls_dynamic.h"
|
||||
|
||||
#define TRACE_CHECK(_fn, _state) \
|
||||
({ \
|
||||
ESP_LOGV(TAG, "%d " _state " to do \"%s\"", __LINE__, # _fn); \
|
||||
@@ -48,8 +50,9 @@
|
||||
})
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SSL_BUF_CACHED,
|
||||
ESP_MBEDTLS_SSL_BUF_CACHED = 0,
|
||||
ESP_MBEDTLS_SSL_BUF_NO_CACHED,
|
||||
ESP_MBEDTLS_SSL_BUF_STATIC,
|
||||
} esp_mbedtls_ssl_buf_states;
|
||||
|
||||
struct esp_mbedtls_ssl_buf {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the dynamic buffer rx statically after the handshake. This is to avoid frequent allocation and deallocation of dynamic buffer.
|
||||
*
|
||||
* @param ssl mbedtls ssl context
|
||||
* @return esp_err_t
|
||||
* - ESP_OK: Successfully set the rx buffer to static
|
||||
* - ESP_ERR_NO_MEM: Failed to allocate memory for the rx buffer
|
||||
*/
|
||||
esp_err_t esp_mbedtls_dynamic_set_rx_buf_static(mbedtls_ssl_context *ssl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user