Skip to content

Commit 97f444b

Browse files
projectgusdpgeorge
authored andcommitted
extmod/mbedtls: Try GC before failing to setup socket on esp32, unix.
On mbedTLS ports with non-baremetal configs (mostly esp32, technically also unix port), mbedTLS memory is allocated from the libc heap. This means an old SSL socket may be holding large SSL buffers and preventing a new SSL socket from being allocated. As a workaround, trigger a GC pass and retry before failing outright. This was originally implemented as a global mbedTLS calloc function, but there is complexity around the possibility of C user modules calling into mbedTLS without holding the GIL. It would be interesting to try making a generic version for any malloc which fails, but this would require checking for a Python thread and probably making the GIL recursive. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent 195bf05 commit 97f444b

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

extmod/modtls_mbedtls.c

+15
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "py/stream.h"
3838
#include "py/objstr.h"
3939
#include "py/reader.h"
40+
#include "py/gc.h"
4041
#include "extmod/vfs.h"
4142

4243
// mbedtls_time_t
@@ -58,6 +59,10 @@
5859
#include "mbedtls/asn1.h"
5960
#endif
6061

62+
#ifndef MICROPY_MBEDTLS_CONFIG_BARE_METAL
63+
#define MICROPY_MBEDTLS_CONFIG_BARE_METAL (0)
64+
#endif
65+
6166
#define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)
6267

6368
// This corresponds to an SSLContext object.
@@ -545,6 +550,16 @@ static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
545550
mbedtls_ssl_init(&o->ssl);
546551

547552
ret = mbedtls_ssl_setup(&o->ssl, &ssl_context->conf);
553+
#if !MICROPY_MBEDTLS_CONFIG_BARE_METAL
554+
if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
555+
// If mbedTLS relies on platform libc heap for buffers (i.e. esp32
556+
// port), then run a GC pass and then try again. This is useful because
557+
// it may free a Python object (like an old SSL socket) whose finaliser
558+
// frees some platform-level heap.
559+
gc_collect();
560+
ret = mbedtls_ssl_setup(&o->ssl, &ssl_context->conf);
561+
}
562+
#endif
548563
if (ret != 0) {
549564
goto cleanup;
550565
}

0 commit comments

Comments
 (0)