From 41e0ec96cb10580c8d77156ed51c2e34bc2fc0ac Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 5 Jun 2025 15:32:01 +1000 Subject: [PATCH 1/4] extmod/mbedtls: Implement DTLS HelloVerify cookie support. This is already enabled in the ESP-IDF mbedTLS config, so provide an implementation of the cookie store functions. This allows DTLS connections between two esp32 boards. The session cookie store is a very simple dictionary associated with the SSLContext. To work, the server needs to reuse the same SSLContext (but cookies are never cleaned up, so a server with a high number of clients should recycle the context periodically.) Server code still needs to handle the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED error by waiting for the next UDP packet from the client. Signed-off-by: Angus Gratton --- extmod/modtls_mbedtls.c | 53 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/extmod/modtls_mbedtls.c b/extmod/modtls_mbedtls.c index 71a14adcff12d..4bd0aea9ab3ec 100644 --- a/extmod/modtls_mbedtls.c +++ b/extmod/modtls_mbedtls.c @@ -62,6 +62,9 @@ #include "mbedtls/ecdsa.h" #include "mbedtls/asn1.h" #endif +#ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY +#include "mbedtls/ssl_cookie.h" +#endif #ifndef MICROPY_MBEDTLS_CONFIG_BARE_METAL #define MICROPY_MBEDTLS_CONFIG_BARE_METAL (0) @@ -92,6 +95,9 @@ typedef struct _mp_obj_ssl_context_t { #if MICROPY_PY_SSL_ECDSA_SIGN_ALT mp_obj_t ecdsa_sign_callback; #endif + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + mbedtls_ssl_cookie_ctx cookie_ctx; + #endif } mp_obj_ssl_context_t; // This corresponds to an SSLSocket object. @@ -117,7 +123,8 @@ static const mp_obj_type_t ssl_socket_type; static const MP_DEFINE_STR_OBJ(mbedtls_version_obj, MBEDTLS_VERSION_STRING_FULL); static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock, - bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname); + bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname, + mp_obj_t client_id); /******************************************************************************/ // Helper functions. @@ -320,6 +327,16 @@ static mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args mbedtls_ssl_conf_dbg(&self->conf, mbedtls_debug, NULL); #endif + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + mbedtls_ssl_cookie_init(&self->cookie_ctx); + ret = mbedtls_ssl_cookie_setup(&self->cookie_ctx, mbedtls_ctr_drbg_random, &self->ctr_drbg); + if (ret != 0) { + mbedtls_raise_error(ret); + } + mbedtls_ssl_conf_dtls_cookies(&self->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, + &self->cookie_ctx); + #endif + return MP_OBJ_FROM_PTR(self); } @@ -366,6 +383,11 @@ static mp_obj_t ssl_context___del__(mp_obj_t self_in) { mbedtls_ctr_drbg_free(&self->ctr_drbg); mbedtls_entropy_free(&self->entropy); mbedtls_ssl_config_free(&self->conf); + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + if (self->is_dtls_server) { + mbedtls_ssl_cookie_free(&self->cookie_ctx); + } + #endif return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(ssl_context___del___obj, ssl_context___del__); @@ -468,11 +490,14 @@ static mp_obj_t ssl_context_load_verify_locations(mp_obj_t self_in, mp_obj_t cad static MP_DEFINE_CONST_FUN_OBJ_2(ssl_context_load_verify_locations_obj, ssl_context_load_verify_locations); static mp_obj_t ssl_context_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_server_side, ARG_do_handshake_on_connect, ARG_server_hostname }; + enum { ARG_server_side, ARG_do_handshake_on_connect, ARG_server_hostname, ARG_client_id }; static const mp_arg_t allowed_args[] = { { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_do_handshake_on_connect, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + { MP_QSTR_client_id, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + #endif }; // Parse arguments. @@ -481,9 +506,14 @@ static mp_obj_t ssl_context_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_obj_t client_id = mp_const_none; + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + client_id = args[ARG_client_id].u_obj; + #endif + // Create and return the new SSLSocket object. return ssl_socket_make_new(self, sock, args[ARG_server_side].u_bool, - args[ARG_do_handshake_on_connect].u_bool, args[ARG_server_hostname].u_obj); + args[ARG_do_handshake_on_connect].u_bool, args[ARG_server_hostname].u_obj, client_id); } static MP_DEFINE_CONST_FUN_OBJ_KW(ssl_context_wrap_socket_obj, 2, ssl_context_wrap_socket); @@ -580,7 +610,7 @@ static int _mbedtls_timing_get_delay(void *ctx) { #endif static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock, - bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname) { + bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname, mp_obj_t client_id) { // Store the current SSL context. store_active_context(ssl_context); @@ -634,6 +664,21 @@ static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t #ifdef MBEDTLS_SSL_PROTO_DTLS mbedtls_ssl_set_timer_cb(&o->ssl, o, _mbedtls_timing_set_delay, _mbedtls_timing_get_delay); #endif + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + if (client_id != mp_const_none) { + mp_buffer_info_t buf; + if (mp_get_buffer(client_id, &buf, MP_BUFFER_READ)) { + ret = mbedtls_ssl_set_client_transport_id(&o->ssl, buf.buf, buf.len); + } else { + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (ret != 0) { + goto cleanup; + } + } else { + // TODO: should it be an error not to provide this argument for DTLS server? + } + #endif mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); From 9b7d85227e67a7edd608aab4ff7eb4a838651f75 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 5 Jun 2025 15:32:38 +1000 Subject: [PATCH 2/4] extmod/mbedtls: Implement recommended DTLS features, make optional. - DTLS spec recommends HelloVerify and Anti Replay protection be enabled, and these are enabled in the default mbedTLS config. Implement them here. - To help compensate for the possible increase in code size, add a MICROPY_PY_SSL_DTLS build config macro that's enabled for EXTRA and above by default. This allows bare metal mbedTLS ports to use DTLS with HelloVerify support. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- docs/library/ssl.rst | 48 ++++++++++++++++++++++---- extmod/mbedtls/mbedtls_config_common.h | 10 +++++- extmod/modtls_mbedtls.c | 29 +++++++++------- py/mpconfig.h | 5 +++ tests/extmod/tls_dtls.py | 12 ++++++- tests/extmod/tls_dtls.py.exp | 1 + 6 files changed, 84 insertions(+), 21 deletions(-) diff --git a/docs/library/ssl.rst b/docs/library/ssl.rst index 4327c74bad6c8..c86101872c364 100644 --- a/docs/library/ssl.rst +++ b/docs/library/ssl.rst @@ -66,7 +66,7 @@ class SSLContext Set the available ciphers for sockets created with this context. *ciphers* should be a list of strings in the `IANA cipher suite format `_ . -.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None) +.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None, client_id=None) Takes a `stream` *sock* (usually socket.socket instance of ``SOCK_STREAM`` type), and returns an instance of ssl.SSLSocket, wrapping the underlying stream. @@ -89,6 +89,9 @@ class SSLContext server certificate. It also sets the name for Server Name Indication (SNI), allowing the server to present the proper certificate. + - *client_id* is a MicroPython-specific extension argument used only when implementing a DTLS + Server. See :ref:`dtls` for details. + .. warning:: Some implementations of ``ssl`` module do NOT validate server certificates, @@ -117,6 +120,8 @@ Exceptions This exception does NOT exist. Instead its base class, OSError, is used. +.. _dtls: + DTLS support ------------ @@ -125,16 +130,47 @@ DTLS support This is a MicroPython extension. -This module supports DTLS in client and server mode via the `PROTOCOL_DTLS_CLIENT` -and `PROTOCOL_DTLS_SERVER` constants that can be used as the ``protocol`` argument -of `SSLContext`. +On most ports, this module supports DTLS in client and server mode via the +`PROTOCOL_DTLS_CLIENT` and `PROTOCOL_DTLS_SERVER` constants that can be used as +the ``protocol`` argument of `SSLContext`. In this case the underlying socket is expected to behave as a datagram socket (i.e. like the socket opened with ``socket.socket`` with ``socket.AF_INET`` as ``af`` and ``socket.SOCK_DGRAM`` as ``type``). -DTLS is only supported on ports that use mbed TLS, and it is not enabled by default: -it requires enabling ``MBEDTLS_SSL_PROTO_DTLS`` in the specific port configuration. +DTLS is only supported on ports that use mbedTLS, and it is enabled by default +in most configurations but can be manually disabled by defining +``MICROPY_PY_SSL_DTLS`` to 0. + +DTLS server support +^^^^^^^^^^^^^^^^^^^ + +MicroPython's DTLS server support is configured with "Hello Verify" as required +for DTLS 1.2. This is transparent for DTLS clients, but there are relevant +considerations when implementing a DTLS server in MicroPython: + +- The server should pass an additional argument *client_id* when calling + `SSLContext.wrap_socket()`. This ID must be a `bytes` object (or similar) with + a transport-specific identifier representing the client. + + The simplest approach is to convert the tuple of ``(client_ip, client_port)`` + returned from ``socket.recv_from()`` into a byte string, i.e.:: + + _, client_addr = sock.recvfrom(1, socket.MSG_PEEK) + sock.connect(client_addr) # Connect back to the client + sock = ssl_ctx.wrap_socket(sock, server_side=True, + client_id=repr(client_addr).encode()) + +- The first time a client connects, the server call to ``wrap_socket`` will fail + with a `OSError` error "Hello Verify Required". This is because the DTLS + "Hello Verify" cookie is not yet known by the client. If the same client + connects a second time then ``wrap_socket`` will succeed. + +- DTLS cookies for "Hello Verify" are associated with the `SSLContext` object, + so the same `SSLContext` object should be used to wrap a subsequent connection + from the same client. The cookie implementation includes a timeout and has + constant memory use regardless of how many clients connect, so it's OK to + reuse the same `SSLContext` object for the lifetime of the server. Constants --------- diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 6cd14befc3196..1f7ac88180d62 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H #define MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H +#include "py/mpconfig.h" + // If you want to debug MBEDTLS uncomment the following and // pass "3" to mbedtls_debug_set_threshold in socket_new. // #define MBEDTLS_DEBUG_C @@ -89,12 +91,18 @@ #define MBEDTLS_SHA384_C #define MBEDTLS_SHA512_C #define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_PROTO_DTLS #define MBEDTLS_SSL_SRV_C #define MBEDTLS_SSL_TLS_C #define MBEDTLS_X509_CRT_PARSE_C #define MBEDTLS_X509_USE_C +#if MICROPY_PY_SSL_DTLS +#define MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY +#define MBEDTLS_SSL_COOKIE_C +#endif + // A port may enable this option to select additional bare-metal configuration. #if MICROPY_MBEDTLS_CONFIG_BARE_METAL diff --git a/extmod/modtls_mbedtls.c b/extmod/modtls_mbedtls.c index 4bd0aea9ab3ec..418275440f309 100644 --- a/extmod/modtls_mbedtls.c +++ b/extmod/modtls_mbedtls.c @@ -78,7 +78,7 @@ #define MP_PROTOCOL_TLS_CLIENT 0 #define MP_PROTOCOL_TLS_SERVER MP_ENDPOINT_IS_SERVER #define MP_PROTOCOL_DTLS_CLIENT MP_TRANSPORT_IS_DTLS -#define MP_PROTOCOL_DTLS_SERVER MP_ENDPOINT_IS_SERVER | MP_TRANSPORT_IS_DTLS +#define MP_PROTOCOL_DTLS_SERVER (MP_ENDPOINT_IS_SERVER | MP_TRANSPORT_IS_DTLS) // This corresponds to an SSLContext object. typedef struct _mp_obj_ssl_context_t { @@ -96,6 +96,7 @@ typedef struct _mp_obj_ssl_context_t { mp_obj_t ecdsa_sign_callback; #endif #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY + bool is_dtls_server; mbedtls_ssl_cookie_ctx cookie_ctx; #endif } mp_obj_ssl_context_t; @@ -328,14 +329,17 @@ static mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args #endif #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY - mbedtls_ssl_cookie_init(&self->cookie_ctx); - ret = mbedtls_ssl_cookie_setup(&self->cookie_ctx, mbedtls_ctr_drbg_random, &self->ctr_drbg); - if (ret != 0) { - mbedtls_raise_error(ret); + self->is_dtls_server = (protocol == MP_PROTOCOL_DTLS_SERVER); + if (self->is_dtls_server) { + mbedtls_ssl_cookie_init(&self->cookie_ctx); + ret = mbedtls_ssl_cookie_setup(&self->cookie_ctx, mbedtls_ctr_drbg_random, &self->ctr_drbg); + if (ret != 0) { + mbedtls_raise_error(ret); + } + mbedtls_ssl_conf_dtls_cookies(&self->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, + &self->cookie_ctx); } - mbedtls_ssl_conf_dtls_cookies(&self->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, - &self->cookie_ctx); - #endif + #endif // MBEDTLS_SSL_DTLS_HELLO_VERIFY return MP_OBJ_FROM_PTR(self); } @@ -664,19 +668,18 @@ static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t #ifdef MBEDTLS_SSL_PROTO_DTLS mbedtls_ssl_set_timer_cb(&o->ssl, o, _mbedtls_timing_set_delay, _mbedtls_timing_get_delay); #endif + #ifdef MBEDTLS_SSL_DTLS_HELLO_VERIFY - if (client_id != mp_const_none) { + if (ssl_context->is_dtls_server) { + // require the client_id parameter for DTLS (as per mbedTLS requirement) + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; mp_buffer_info_t buf; if (mp_get_buffer(client_id, &buf, MP_BUFFER_READ)) { ret = mbedtls_ssl_set_client_transport_id(&o->ssl, buf.buf, buf.len); - } else { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } if (ret != 0) { goto cleanup; } - } else { - // TODO: should it be an error not to provide this argument for DTLS server? } #endif diff --git a/py/mpconfig.h b/py/mpconfig.h index 4c1276275964d..a1025fe5e1b18 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1941,6 +1941,11 @@ typedef time_t mp_timestamp_t; #define MICROPY_PY_SSL_MBEDTLS_NEED_ACTIVE_CONTEXT (MICROPY_PY_SSL_ECDSA_SIGN_ALT) #endif +// Whether to support DTLS protocol (non-CPython feature) +#ifndef MICROPY_PY_SSL_DTLS +#define MICROPY_PY_SSL_DTLS (MICROPY_SSL_MBEDTLS && MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide the "vfs" module #ifndef MICROPY_PY_VFS #define MICROPY_PY_VFS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES && MICROPY_VFS) diff --git a/tests/extmod/tls_dtls.py b/tests/extmod/tls_dtls.py index b2d716769d3f7..a475cce8c112b 100644 --- a/tests/extmod/tls_dtls.py +++ b/tests/extmod/tls_dtls.py @@ -34,9 +34,19 @@ def ioctl(self, req, arg): # Wrap the DTLS Server dtls_server_ctx = SSLContext(PROTOCOL_DTLS_SERVER) dtls_server_ctx.verify_mode = CERT_NONE -dtls_server = dtls_server_ctx.wrap_socket(server_socket, do_handshake_on_connect=False) +dtls_server = dtls_server_ctx.wrap_socket( + server_socket, do_handshake_on_connect=False, client_id=b'dummy_client_id' +) print("Wrapped DTLS Server") +# wrap DTLS server with invalid client_id +try: + dtls_server = dtls_server_ctx.wrap_socket( + server_socket, do_handshake_on_connect=False, client_id=4 + ) +except OSError: + print("Failed to wrap DTLS Server with invalid client_id") + # Wrap the DTLS Client dtls_client_ctx = SSLContext(PROTOCOL_DTLS_CLIENT) dtls_client_ctx.verify_mode = CERT_NONE diff --git a/tests/extmod/tls_dtls.py.exp b/tests/extmod/tls_dtls.py.exp index 78d72bff18816..dbd005d0edfb8 100644 --- a/tests/extmod/tls_dtls.py.exp +++ b/tests/extmod/tls_dtls.py.exp @@ -1,3 +1,4 @@ Wrapped DTLS Server +Failed to wrap DTLS Server with invalid client_id Wrapped DTLS Client OK From 89f9ee9d7c08bb0912b94fe6190646c4d37508a2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 5 Jun 2025 15:33:56 +1000 Subject: [PATCH 3/4] tests/multi_net: Update DTLS multi-net test. The original version of this test had to exchange a 1 byte UDP packet before the DTLS handshake. This is no longer needed due to MSG_PEEK support. The test also doesn't work with HelloVerify enabled, as the first connection attempt always fails with an MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED result. Anticipate this by listening for the client twice on the server side. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- tests/multi_net/tls_dtls_server_client.py | 55 ++++++++++--------- tests/multi_net/tls_dtls_server_client.py.exp | 23 ++++---- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/tests/multi_net/tls_dtls_server_client.py b/tests/multi_net/tls_dtls_server_client.py index d50deb354ed4d..a81c4cb28230c 100644 --- a/tests/multi_net/tls_dtls_server_client.py +++ b/tests/multi_net/tls_dtls_server_client.py @@ -34,28 +34,36 @@ def instance0(): multitest.next() - # Wait for the client to connect. - data, client_addr = s.recvfrom(1) - print("incoming connection", data) - - # Connect back to the client, so the UDP socket can be used like a stream. - s.connect(client_addr) - - # Create the DTLS context and load the certificate. ctx = tls.SSLContext(tls.PROTOCOL_DTLS_SERVER) ctx.load_cert_chain(cert, key) - # Wrap the UDP socket in server mode. - print("wrap socket") - s = ctx.wrap_socket(s, server_side=1) - - # Transfer some data. - for _ in range(4): - print(s.recv(16)) - s.send(b"server to client") - - # Close the DTLS and UDP connection. - s.close() + # Because of "hello verify required", we expect the peer + # to connect twice: once to set the cookie, then second time + # successfully. + # + # As this isn't a real server, we hard-code two connection attempts + for _ in range(2): + print("waiting") + # Wait for the client to connect so we know their address + _, client_addr = s.recvfrom(1, socket.MSG_PEEK) + print("incoming connection") + s.connect(client_addr) # Connect back to the client + + # Wrap the UDP socket in server mode. + try: + s = ctx.wrap_socket(s, server_side=1, client_id=repr(client_addr).encode()) + except OSError as e: + print(e) + continue # wait for second connection + + # Transfer some data. + for i in range(4): + print(s.recv(32)) + s.send(b"server to client " + str(i).encode()) + + # Close the DTLS and UDP connection. + s.close() + break # DTLS client. @@ -68,9 +76,6 @@ def instance1(): print("connect") s.connect(addr) - # Send one byte to indicate a connection, and so the server can obtain our address. - s.write("X") - # Create a DTLS context and load the certificate. ctx = tls.SSLContext(tls.PROTOCOL_DTLS_CLIENT) ctx.verify_mode = tls.CERT_REQUIRED @@ -81,9 +86,9 @@ def instance1(): s = ctx.wrap_socket(s, server_hostname="micropython.local") # Transfer some data. - for _ in range(4): - s.send(b"client to server") - print(s.recv(16)) + for i in range(4): + s.send(b"client to server " + str(i).encode()) + print(s.recv(32)) # Close the DTLS and UDP connection. s.close() diff --git a/tests/multi_net/tls_dtls_server_client.py.exp b/tests/multi_net/tls_dtls_server_client.py.exp index f2ff396e181df..3de03056740da 100644 --- a/tests/multi_net/tls_dtls_server_client.py.exp +++ b/tests/multi_net/tls_dtls_server_client.py.exp @@ -1,14 +1,17 @@ --- instance0 --- -incoming connection b'X' -wrap socket -b'client to server' -b'client to server' -b'client to server' -b'client to server' +waiting +incoming connection +(-27264, 'MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED') +waiting +incoming connection +b'client to server 0' +b'client to server 1' +b'client to server 2' +b'client to server 3' --- instance1 --- connect wrap socket -b'server to client' -b'server to client' -b'server to client' -b'server to client' +b'server to client 0' +b'server to client 1' +b'server to client 2' +b'server to client 3' From 28082d1d25c55a513677441c8053b82f6786aa3d Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 12 Jun 2025 10:36:59 +1000 Subject: [PATCH 4/4] extmod/mbedtls: Undefine ARRAY_SIZE if defined by platform. This is an annoying regression caused by including mpconfig.h in 36922df - the mimxrt platform headers define ARRAY_SIZE and mbedtls also defines in some source files, using a different parameter name which is a warning in gcc. Technically mimxrt SDK is to blame here, but as this isn't a named warning in gcc the only way to work around it in the mimxrt port would be to disable all warnings when building this particular mbedTLS source file. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- extmod/mbedtls/mbedtls_config_common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extmod/mbedtls/mbedtls_config_common.h b/extmod/mbedtls/mbedtls_config_common.h index 1f7ac88180d62..040b0598dce8d 100644 --- a/extmod/mbedtls/mbedtls_config_common.h +++ b/extmod/mbedtls/mbedtls_config_common.h @@ -123,4 +123,8 @@ void m_tracked_free(void *ptr); #endif +// Workaround for a mimxrt platform driver header that defines ARRAY_SIZE, +// which is also defined in some mbedtls source files. +#undef ARRAY_SIZE + #endif // MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy