From 7e7918ea80661ac8169f0d4496cf60df04058738 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 20 Feb 2024 10:35:05 -0600 Subject: [PATCH 01/13] socketpool: alphabetize dict names --- shared-bindings/socketpool/Socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 18784ba04dbf..669b4d71ed7b 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -413,8 +413,8 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) }, { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&socketpool_socket_sendall_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) }, From 0c1db5e0cca5839f86595d1595562a9d9e32cd23 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 20 Feb 2024 10:52:01 -0600 Subject: [PATCH 02/13] socketpool: add `type` property to Socket objects cpython socket objects have a `type` property which gives their type as an integer (e.g., SOCK_STREAM). Add this for compatibility with standard Python. It's needed for ssl, which currently just grabs the value directly from an internal structure (naughty!) --- ports/espressif/common-hal/socketpool/Socket.c | 4 ++++ .../raspberrypi/common-hal/socketpool/Socket.c | 4 ++++ shared-bindings/socketpool/Socket.c | 18 ++++++++++++++++-- shared-bindings/socketpool/Socket.h | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index a291bf510b41..942abbdb3ae5 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -602,6 +602,10 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout_ms = timeout_ms; } +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) { + return self->type; +} + int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { int err = lwip_setsockopt(self->num, level, optname, value, optlen); diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index e97dfd21a08c..2517135f5fda 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -1183,6 +1183,10 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout = timeout_ms; } +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) { + return self->type; +} + int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { if (level == SOCKETPOOL_IPPROTO_TCP && optname == SOCKETPOOL_TCP_NODELAY) { int one = 1; diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 669b4d71ed7b..417afcb96997 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -32,6 +32,7 @@ #include "py/mperrno.h" #include "py/objlist.h" +#include "py/objproperty.h" #include "py/objtuple.h" #include "py/runtime.h" #include "py/stream.h" @@ -383,7 +384,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, //| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. //| """ //| ... -//| STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t timeout_ms; @@ -401,11 +401,24 @@ STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_ } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_socket_settimeout); +//| type: int +//| """Read-only access to the socket type""" +//| +STATIC mp_obj_t socketpool_socket_obj_get_type(mp_obj_t self_in) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_socketpool_socket_get_type(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_get_type_obj, socketpool_socket_obj_get_type); + +MP_PROPERTY_GETTER(socketpool_socket_type_obj, + (mp_obj_t)&socketpool_socket_get_type_obj); + STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&socketpool_socket___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socketpool_socket_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) }, { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socketpool_socket_close_obj) }, @@ -419,6 +432,7 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socketpool_socket_settimeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&socketpool_socket_type_obj) }, }; STATIC MP_DEFINE_CONST_DICT(socketpool_socket_locals_dict, socketpool_socket_locals_dict_table); @@ -472,7 +486,7 @@ STATIC const mp_stream_p_t socket_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( socketpool_socket_type, MP_QSTR_Socket, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, locals_dict, &socketpool_socket_locals_dict, protocol, &socket_stream_p ); diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index 14022ea49e8c..ab54ea4a9c41 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -38,6 +38,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, const c bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *self); bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self); mp_uint_t common_hal_socketpool_socket_get_timeout(socketpool_socket_obj_t *self); +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self); bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog); mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self, uint8_t *buf, uint32_t len, uint8_t *ip, uint32_t *port); From 5973c4a86cca209232849a1491024e852d2646e8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 4 Mar 2024 20:28:47 -0600 Subject: [PATCH 03/13] socketpool: factor out constants This header can be used by ssl even if there's no core socketpool --- shared-bindings/socketpool/SocketPool.h | 42 +-------------- shared-bindings/socketpool/enum.h | 70 +++++++++++++++++++++++++ shared-module/ssl/SSLSocket.c | 2 + 3 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 shared-bindings/socketpool/enum.h diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 04b3ddc7e680..ab1e1daa5bd2 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -29,50 +29,12 @@ #include "common-hal/socketpool/SocketPool.h" +#include "shared-bindings/socketpool/__init__.h" +#include "shared-bindings/socketpool/enum.h" #include "shared-bindings/socketpool/Socket.h" extern const mp_obj_type_t socketpool_socketpool_type; -typedef enum { - SOCKETPOOL_SOCK_STREAM = 1, - SOCKETPOOL_SOCK_DGRAM = 2, - SOCKETPOOL_SOCK_RAW = 3 -} socketpool_socketpool_sock_t; - -typedef enum { - SOCKETPOOL_AF_INET = 2, - SOCKETPOOL_AF_INET6 = 10 -} socketpool_socketpool_addressfamily_t; - -typedef enum { - SOCKETPOOL_IPPROTO_IP = 0, - SOCKETPOOL_IPPROTO_ICMP = 1, - SOCKETPOOL_IPPROTO_TCP = 6, - SOCKETPOOL_IPPROTO_UDP = 17, - SOCKETPOOL_IPPROTO_IPV6 = 41, - SOCKETPOOL_IPPROTO_RAW = 255, -} socketpool_socketpool_ipproto_t; - -typedef enum { - SOCKETPOOL_TCP_NODELAY = 1, -} socketpool_socketpool_tcpopt_t; - -typedef enum { - SOCKETPOOL_SOL_SOCKET = 0xfff, -} socketpool_socketpool_optlevel_t; - -typedef enum { - SOCKETPOOL_SO_REUSEADDR = 0x0004, -} socketpool_socketpool_socketopt_t; - -typedef enum { - SOCKETPOOL_IP_MULTICAST_TTL = 5, -} socketpool_socketpool_ipopt_t; - -typedef enum { - SOCKETPOOL_EAI_NONAME = -2, -} socketpool_eai_t; - void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio); socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self, diff --git a/shared-bindings/socketpool/enum.h b/shared-bindings/socketpool/enum.h new file mode 100644 index 000000000000..45dab2a9e1e2 --- /dev/null +++ b/shared-bindings/socketpool/enum.h @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// Note: This file must be designed so it be included by ssl +// whether or not CIRCUITPY_SOCKETPOOL is set. +// +typedef enum { + SOCKETPOOL_SOCK_STREAM = 1, + SOCKETPOOL_SOCK_DGRAM = 2, + SOCKETPOOL_SOCK_RAW = 3 +} socketpool_socketpool_sock_t; + +typedef enum { + SOCKETPOOL_AF_INET = 2, + SOCKETPOOL_AF_INET6 = 10 +} socketpool_socketpool_addressfamily_t; + +typedef enum { + SOCKETPOOL_IPPROTO_IP = 0, + SOCKETPOOL_IPPROTO_ICMP = 1, + SOCKETPOOL_IPPROTO_TCP = 6, + SOCKETPOOL_IPPROTO_UDP = 17, + SOCKETPOOL_IPPROTO_IPV6 = 41, + SOCKETPOOL_IPPROTO_RAW = 255, +} socketpool_socketpool_ipproto_t; + +typedef enum { + SOCKETPOOL_TCP_NODELAY = 1, +} socketpool_socketpool_tcpopt_t; + +typedef enum { + SOCKETPOOL_SOL_SOCKET = 0xfff, +} socketpool_socketpool_optlevel_t; + +typedef enum { + SOCKETPOOL_SO_REUSEADDR = 0x0004, +} socketpool_socketpool_socketopt_t; + +typedef enum { + SOCKETPOOL_IP_MULTICAST_TTL = 5, +} socketpool_socketpool_ipopt_t; + +typedef enum { + SOCKETPOOL_EAI_NONAME = -2, +} socketpool_eai_t; diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 2abb4c6c4a36..38f6f80dfb1b 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -40,6 +40,8 @@ #include "py/stream.h" #include "supervisor/shared/tick.h" +#include "shared-bindings/socketpool/enum.h" + #include "mbedtls/version.h" #if defined(MBEDTLS_ERROR_C) From c793a021b8c1468606534c7ce3c827388a752855 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 20 Feb 2024 09:33:45 -0600 Subject: [PATCH 04/13] ssl: work on anything implementing the socket protocol In principle this allows core SSL code to be used with e.g., wiznet or airlift sockets. It might actually be useful with wiznet ethernet devices (it's probably not with airlift) --- shared-bindings/ssl/SSLContext.c | 4 +- shared-bindings/ssl/SSLContext.h | 3 +- shared-bindings/ssl/SSLSocket.c | 32 +-------- shared-bindings/ssl/SSLSocket.h | 6 +- shared-module/ssl/SSLContext.c | 1 - shared-module/ssl/SSLSocket.c | 118 +++++++++++++++++++++++++------ shared-module/ssl/SSLSocket.h | 11 ++- 7 files changed, 114 insertions(+), 61 deletions(-) diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index 63dbfa3816c1..6ac06ae194da 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -200,9 +200,9 @@ STATIC mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_ar mp_raise_ValueError(MP_ERROR_TEXT("Server side context cannot have hostname")); } - socketpool_socket_obj_t *sock = args[ARG_sock].u_obj; + mp_obj_t sock_obj = args[ARG_sock].u_obj; - return common_hal_ssl_sslcontext_wrap_socket(self, sock, server_side, server_hostname); + return common_hal_ssl_sslcontext_wrap_socket(self, sock_obj, server_side, server_hostname); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_wrap_socket_obj, 1, ssl_sslcontext_wrap_socket); diff --git a/shared-bindings/ssl/SSLContext.h b/shared-bindings/ssl/SSLContext.h index 73454149c5b3..671edf73d622 100644 --- a/shared-bindings/ssl/SSLContext.h +++ b/shared-bindings/ssl/SSLContext.h @@ -33,7 +33,6 @@ #include "common-hal/ssl/SSLContext.h" #endif -#include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/ssl/SSLSocket.h" extern const mp_obj_type_t ssl_sslcontext_type; @@ -41,7 +40,7 @@ extern const mp_obj_type_t ssl_sslcontext_type; void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t *self); ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, - socketpool_socket_obj_t *sock, bool server_side, const char *server_hostname); + mp_obj_t socket, bool server_side, const char *server_hostname); void common_hal_ssl_sslcontext_load_verify_locations(ssl_sslcontext_obj_t *self, const char *cadata); diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index ac8f3b2c5add..a382d8a2fc7b 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -73,15 +73,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket___exit___obj, 4, 4, ssl //| Returns a tuple of (new_socket, remote_address)""" STATIC mp_obj_t ssl_sslsocket_accept(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint8_t ip[4]; - uint32_t port; - - ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslsocket_accept(self, ip, &port); - - mp_obj_t tuple_contents[2]; - tuple_contents[0] = MP_OBJ_FROM_PTR(sslsock); - tuple_contents[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return mp_obj_new_tuple(2, tuple_contents); + return common_hal_ssl_sslsocket_accept(self); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_accept_obj, ssl_sslsocket_accept); @@ -96,14 +88,7 @@ STATIC mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_t *addr_items; mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - size_t hostlen; - const char *host = mp_obj_str_get_data(addr_items[0], &hostlen); - mp_int_t port = mp_obj_get_int(addr_items[1]); - if (port < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("port must be >= 0")); - } - - size_t error = common_hal_ssl_sslsocket_bind(self, host, hostlen, (uint32_t)port); + size_t error = common_hal_ssl_sslsocket_bind(self, addr_in); if (error != 0) { mp_raise_OSError(error); } @@ -128,18 +113,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_close_obj, ssl_sslsocket_close); //| ... STATIC mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_obj_t *addr_items; - mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - - size_t hostlen; - const char *host = mp_obj_str_get_data(addr_items[0], &hostlen); - mp_int_t port = mp_obj_get_int(addr_items[1]); - if (port < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("port must be >= 0")); - } - - common_hal_ssl_sslsocket_connect(self, host, hostlen, (uint32_t)port); + common_hal_ssl_sslsocket_connect(self, addr_in); return mp_const_none; } diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index dc3d048e099c..4e1acc1caf14 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -34,10 +34,10 @@ extern const mp_obj_type_t ssl_sslsocket_type; -ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port); -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port); +mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self); +size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr); void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self); -void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port); +void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr); bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); diff --git a/shared-module/ssl/SSLContext.c b/shared-module/ssl/SSLContext.c index cc01a8bde7cf..2c35fe8ae554 100644 --- a/shared-module/ssl/SSLContext.c +++ b/shared-module/ssl/SSLContext.c @@ -26,7 +26,6 @@ #include "shared-bindings/ssl/SSLContext.h" #include "shared-bindings/ssl/SSLSocket.h" -#include "shared-bindings/socketpool/SocketPool.h" #include "py/runtime.h" #include "py/stream.h" diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 38f6f80dfb1b..63604d23b3e3 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -27,12 +27,10 @@ */ #include "shared-bindings/ssl/SSLSocket.h" -#include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/ssl/SSLContext.h" -#include "shared-bindings/socketpool/SocketPool.h" -#include "shared-bindings/socketpool/Socket.h" #include "shared/runtime/interrupt_char.h" +#include "shared/netutils/netutils.h" #include "py/mperrno.h" #include "py/mphal.h" #include "py/objstr.h" @@ -108,11 +106,72 @@ STATIC NORETURN void mbedtls_raise_error(int err) { #endif } +STATIC int call_method_errno(size_t n_args, const mp_obj_t *args) { + nlr_buf_t nlr; + mp_int_t result = -MP_EINVAL; + if (nlr_push(&nlr) == 0) { + mp_obj_t obj_result = mp_call_method_n_kw(n_args, 0, args); + result = (obj_result == mp_const_none) ? 0 : mp_obj_get_int(obj_result); + nlr_pop(); + return result; + } else { + mp_obj_t exc = MP_OBJ_FROM_PTR(nlr.ret_val); + if (nlr_push(&nlr) == 0) { + result = -mp_obj_get_int(mp_load_attr(exc, MP_QSTR_errno)); + nlr_pop(); + } + } + return result; +} + +static int ssl_socket_send(ssl_sslsocket_obj_t *self, const byte *buf, size_t len) { + mp_obj_array_t mv; + mp_obj_memoryview_init(&mv, 'B', 0, len, (void *)buf); + + self->send_args[2] = MP_OBJ_FROM_PTR(&mv); + return call_method_errno(1, self->send_args); +} + +static int ssl_socket_recv_into(ssl_sslsocket_obj_t *self, byte *buf, size_t len) { + mp_obj_array_t mv; + mp_obj_memoryview_init(&mv, 'B' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW, 0, len, buf); + + self->recv_into_args[2] = MP_OBJ_FROM_PTR(&mv); + return call_method_errno(1, self->recv_into_args); +} + +static int ssl_socket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + self->connect_args[2] = addr_in; + return call_method_errno(1, self->connect_args); +} + +static int ssl_socket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + self->bind_args[2] = addr_in; + return call_method_errno(1, self->bind_args); +} + +static int ssl_socket_close(ssl_sslsocket_obj_t *self) { + return call_method_errno(0, self->close_args); +} + +static int ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_int_t timeout_ms) { + self->settimeout_args[2] = mp_obj_new_float(timeout_ms * MICROPY_FLOAT_CONST(1e-3)); + return call_method_errno(1, self->settimeout_args); +} + +static int ssl_socket_listen(ssl_sslsocket_obj_t *self, mp_int_t backlog) { + self->listen_args[2] = MP_OBJ_NEW_SMALL_INT(backlog); + return call_method_errno(1, self->listen_args); +} + +static mp_obj_t ssl_socket_accept(ssl_sslsocket_obj_t *self) { + return mp_call_method_n_kw(0, 0, self->accept_args); +} + STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; + ssl_sslsocket_obj_t *self = (ssl_sslsocket_obj_t *)ctx; - // mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err); - mp_int_t out_sz = socketpool_socket_send(sock, buf, len); + mp_int_t out_sz = ssl_socket_send(self, buf, len); DEBUG_PRINT("socket_send() -> %d", out_sz); if (out_sz < 0) { int err = -out_sz; @@ -128,9 +187,9 @@ STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { // _mbedtls_ssl_recv is called by mbedtls to receive bytes from the underlying socket STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; + ssl_sslsocket_obj_t *self = (ssl_sslsocket_obj_t *)ctx; - mp_int_t out_sz = socketpool_socket_recv_into(sock, buf, len); + mp_int_t out_sz = ssl_socket_recv_into(self, buf, len); DEBUG_PRINT("socket_recv() -> %d", out_sz); if (out_sz < 0) { int err = -out_sz; @@ -155,16 +214,26 @@ static int urandom_adapter(void *unused, unsigned char *buf, size_t n) { #endif ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, - socketpool_socket_obj_t *socket, bool server_side, const char *server_hostname) { + mp_obj_t socket, bool server_side, const char *server_hostname) { - if (socket->type != SOCKETPOOL_SOCK_STREAM) { + mp_int_t socket_type = mp_obj_get_int(mp_load_attr(socket, MP_QSTR_type)); + if (socket_type != SOCKETPOOL_SOCK_STREAM) { mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid socket for TLS")); } ssl_sslsocket_obj_t *o = m_new_obj_with_finaliser(ssl_sslsocket_obj_t); o->base.type = &ssl_sslsocket_type; o->ssl_context = self; - o->sock = socket; + o->sock_obj = socket; + + mp_load_method(socket, MP_QSTR_accept, o->accept_args); + mp_load_method(socket, MP_QSTR_bind, o->bind_args); + mp_load_method(socket, MP_QSTR_close, o->close_args); + mp_load_method(socket, MP_QSTR_connect, o->connect_args); + mp_load_method(socket, MP_QSTR_listen, o->listen_args); + mp_load_method(socket, MP_QSTR_recv_into, o->recv_into_args); + mp_load_method(socket, MP_QSTR_send, o->send_args); + mp_load_method(socket, MP_QSTR_settimeout, o->settimeout_args); mbedtls_ssl_init(&o->ssl); mbedtls_ssl_config_init(&o->conf); @@ -223,7 +292,7 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t } } - mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); + mbedtls_ssl_set_bio(&o->ssl, o, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); if (self->cert_buf.buf != NULL) { #if MBEDTLS_VERSION_MAJOR >= 3 @@ -292,13 +361,13 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t mbedtls_raise_error(ret); } -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { - return common_hal_socketpool_socket_bind(self->sock, host, hostlen, port); +size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + return ssl_socket_bind(self, addr_in); } void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { self->closed = true; - common_hal_socketpool_socket_close(self->sock); + ssl_socket_close(self); mbedtls_pk_free(&self->pkey); mbedtls_x509_crt_free(&self->cert); mbedtls_x509_crt_free(&self->cacert); @@ -344,8 +413,8 @@ STATIC void do_handshake(ssl_sslsocket_obj_t *self) { } } -void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { - common_hal_socketpool_socket_connect(self->sock, host, hostlen, port); +void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + ssl_socket_connect(self, addr_in); do_handshake(self); } @@ -358,16 +427,21 @@ bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self) { } bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { - return common_hal_socketpool_socket_listen(self->sock, backlog); + return ssl_socket_listen(self, backlog); } -ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port) { - socketpool_socket_obj_t *sock = common_hal_socketpool_socket_accept(self->sock, ip, port); +mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self) { + mp_obj_t accepted = ssl_socket_accept(self); + mp_obj_t sock = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, true, NULL); do_handshake(sslsock); - return sslsock; + mp_obj_t peer = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); + mp_obj_t tuple_contents[2]; + tuple_contents[0] = MP_OBJ_FROM_PTR(sslsock); + tuple_contents[1] = peer; + return mp_obj_new_tuple(2, tuple_contents); } void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms) { - common_hal_socketpool_socket_settimeout(self->sock, timeout_ms); + ssl_socket_settimeout(self, timeout_ms); } diff --git a/shared-module/ssl/SSLSocket.h b/shared-module/ssl/SSLSocket.h index 881ee400ff4a..70518abc2263 100644 --- a/shared-module/ssl/SSLSocket.h +++ b/shared-module/ssl/SSLSocket.h @@ -30,7 +30,6 @@ #include "py/obj.h" #include "shared-module/ssl/SSLContext.h" -#include "common-hal/socketpool/Socket.h" #include "mbedtls/platform.h" #include "mbedtls/ssl.h" @@ -41,7 +40,7 @@ typedef struct ssl_sslsocket_obj { mp_obj_base_t base; - socketpool_socket_obj_t *sock; + mp_obj_t sock_obj; ssl_sslcontext_obj_t *ssl_context; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; @@ -51,4 +50,12 @@ typedef struct ssl_sslsocket_obj { mbedtls_x509_crt cert; mbedtls_pk_context pkey; bool closed; + mp_obj_t accept_args[2]; + mp_obj_t bind_args[3]; + mp_obj_t close_args[2]; + mp_obj_t connect_args[3]; + mp_obj_t listen_args[3]; + mp_obj_t recv_into_args[3]; + mp_obj_t send_args[3]; + mp_obj_t settimeout_args[3]; } ssl_sslsocket_obj_t; From 40cc50094c773877d97d532430c866c4de12e65f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 28 Feb 2024 15:43:57 -0600 Subject: [PATCH 05/13] wiznet w5500: improve pin naming & enable ssl the ssl test program also works here with ```py cs = digitalio.DigitalInOut(board.W5500_CS) spi_bus = board.SPI() ``` --- .../wiznet_w5500_evb_pico/mpconfigboard.mk | 1 + .../boards/wiznet_w5500_evb_pico/pins.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk index 3789a76e0b22..127cdaba380e 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk @@ -9,3 +9,4 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 +CIRCUITPY_SSL = 1 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c index 87ff27fa4632..ca9f7969d627 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c @@ -19,12 +19,25 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_CS), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_RST), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_INT), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, @@ -36,10 +49,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, @@ -50,5 +65,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From b330989704295e0dcc4cda92028f43dbaa752e4e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 4 Mar 2024 21:34:10 -0600 Subject: [PATCH 06/13] sslsocket: Simplify handling the timeout value We're just going to pass it down to the underlying socket, so don't parse it, multiply it, etc. --- shared-bindings/ssl/SSLSocket.c | 16 +++------------- shared-bindings/ssl/SSLSocket.h | 2 +- shared-module/ssl/SSLSocket.c | 8 ++++---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index a382d8a2fc7b..84dc870276a7 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -220,17 +220,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_send_obj, ssl_sslsocket_send); //| ... STATIC mp_obj_t ssl_sslsocket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t timeout_ms; - if (timeout_in == mp_const_none) { - timeout_ms = -1; - } else { - #if MICROPY_PY_BUILTINS_FLOAT - timeout_ms = 1000 * mp_obj_get_float(timeout_in); - #else - timeout_ms = 1000 * mp_obj_get_int(timeout_in); - #endif - } - common_hal_ssl_sslsocket_settimeout(self, timeout_ms); + common_hal_ssl_sslsocket_settimeout(self, timeout_in); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_settimeout_obj, ssl_sslsocket_settimeout); @@ -245,9 +235,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_settimeout_obj, ssl_sslsocket_set STATIC mp_obj_t ssl_sslsocket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (mp_obj_is_true(blocking)) { - common_hal_ssl_sslsocket_settimeout(self, -1); + common_hal_ssl_sslsocket_settimeout(self, mp_const_none); } else { - common_hal_ssl_sslsocket_settimeout(self, 0); + common_hal_ssl_sslsocket_settimeout(self, MP_OBJ_NEW_SMALL_INT(0)); } return mp_const_none; } diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index 4e1acc1caf14..209d049d0767 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -43,4 +43,4 @@ bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len); mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms); +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj); diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 63604d23b3e3..6c450a656480 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -154,8 +154,8 @@ static int ssl_socket_close(ssl_sslsocket_obj_t *self) { return call_method_errno(0, self->close_args); } -static int ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_int_t timeout_ms) { - self->settimeout_args[2] = mp_obj_new_float(timeout_ms * MICROPY_FLOAT_CONST(1e-3)); +static int ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { + self->settimeout_args[2] = timeout_obj; return call_method_errno(1, self->settimeout_args); } @@ -442,6 +442,6 @@ mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self) { return mp_obj_new_tuple(2, tuple_contents); } -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms) { - ssl_socket_settimeout(self, timeout_ms); +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { + ssl_socket_settimeout(self, timeout_obj); } From f960c5b7c11449b69af284269c683fd3c4f430e2 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 4 Mar 2024 21:38:42 -0600 Subject: [PATCH 07/13] SSLSocket: propagate any exception from socket.settimeout directly --- shared-module/ssl/SSLSocket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 6c450a656480..2f7e10c0907b 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -154,9 +154,9 @@ static int ssl_socket_close(ssl_sslsocket_obj_t *self) { return call_method_errno(0, self->close_args); } -static int ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { +static void ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { self->settimeout_args[2] = timeout_obj; - return call_method_errno(1, self->settimeout_args); + return mp_call_method_n_kw(1, 0, self->settimeout_args); } static int ssl_socket_listen(ssl_sslsocket_obj_t *self, mp_int_t backlog) { From 8c5d9d28d8bbfdbf6d44dfb4270937aa776e747f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 17 Mar 2024 14:03:36 -0500 Subject: [PATCH 08/13] ssl: make bind & listen into void functions (they throw exceptions) --- shared-bindings/ssl/SSLSocket.c | 6 +----- shared-bindings/ssl/SSLSocket.h | 4 ++-- shared-module/ssl/SSLSocket.c | 37 ++++++++++++++++----------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index 84dc870276a7..10bca142adc1 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -88,11 +88,7 @@ STATIC mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_t *addr_items; mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - size_t error = common_hal_ssl_sslsocket_bind(self, addr_in); - if (error != 0) { - mp_raise_OSError(error); - } - + common_hal_ssl_sslsocket_bind(self, addr_in); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_bind_obj, ssl_sslsocket_bind); diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index 209d049d0767..1388c9cd4fe8 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -35,12 +35,12 @@ extern const mp_obj_type_t ssl_sslsocket_type; mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self); -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr); +void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr); void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self); void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr); bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self); -bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); +void common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len); mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj); diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 2f7e10c0907b..4a51990e6e21 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -106,6 +106,10 @@ STATIC NORETURN void mbedtls_raise_error(int err) { #endif } +// Because ssl_socket_send and ssl_socket_recv_into are callbacks from mbedtls code, +// it is not OK to exit them by raising an exception (nlr_jump'ing through +// foreign code is not permitted). Instead, preserve the error number of any OSError +// and turn anything else into -MP_EINVAL. STATIC int call_method_errno(size_t n_args, const mp_obj_t *args) { nlr_buf_t nlr; mp_int_t result = -MP_EINVAL; @@ -140,28 +144,28 @@ static int ssl_socket_recv_into(ssl_sslsocket_obj_t *self, byte *buf, size_t len return call_method_errno(1, self->recv_into_args); } -static int ssl_socket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { +static void ssl_socket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { self->connect_args[2] = addr_in; - return call_method_errno(1, self->connect_args); + mp_call_method_n_kw(1, 0, self->connect_args); } -static int ssl_socket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { +static void ssl_socket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { self->bind_args[2] = addr_in; - return call_method_errno(1, self->bind_args); + mp_call_method_n_kw(1, 0, self->bind_args); } -static int ssl_socket_close(ssl_sslsocket_obj_t *self) { - return call_method_errno(0, self->close_args); +static void ssl_socket_close(ssl_sslsocket_obj_t *self) { + mp_call_method_n_kw(0, 0, self->close_args); } static void ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { self->settimeout_args[2] = timeout_obj; - return mp_call_method_n_kw(1, 0, self->settimeout_args); + mp_call_method_n_kw(1, 0, self->settimeout_args); } -static int ssl_socket_listen(ssl_sslsocket_obj_t *self, mp_int_t backlog) { +static void ssl_socket_listen(ssl_sslsocket_obj_t *self, mp_int_t backlog) { self->listen_args[2] = MP_OBJ_NEW_SMALL_INT(backlog); - return call_method_errno(1, self->listen_args); + mp_call_method_n_kw(1, 0, self->listen_args); } static mp_obj_t ssl_socket_accept(ssl_sslsocket_obj_t *self) { @@ -179,13 +183,10 @@ STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { if (mp_is_nonblocking_error(err)) { return MBEDTLS_ERR_SSL_WANT_WRITE; } - return -err; // convert an MP_ERRNO to something mbedtls passes through as error - } else { - return out_sz; } + return out_sz; } -// _mbedtls_ssl_recv is called by mbedtls to receive bytes from the underlying socket STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { ssl_sslsocket_obj_t *self = (ssl_sslsocket_obj_t *)ctx; @@ -196,10 +197,8 @@ STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { if (mp_is_nonblocking_error(err)) { return MBEDTLS_ERR_SSL_WANT_READ; } - return -err; - } else { - return out_sz; } + return out_sz; } @@ -361,8 +360,8 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t mbedtls_raise_error(ret); } -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { - return ssl_socket_bind(self, addr_in); +void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + ssl_socket_bind(self, addr_in); } void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { @@ -426,7 +425,7 @@ bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self) { return !self->closed; } -bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { +void common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { return ssl_socket_listen(self, backlog); } From 14a19726f09674533803233fbda88fb7087f4038 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 21 Mar 2024 14:03:36 -0500 Subject: [PATCH 09/13] Fix return value of accept() The subscripting to get the `peer` object was wrong. --- shared-module/ssl/SSLSocket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 4a51990e6e21..dc9ea5a575f4 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -434,7 +434,7 @@ mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self) { mp_obj_t sock = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, true, NULL); do_handshake(sslsock); - mp_obj_t peer = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); + mp_obj_t peer = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(1), MP_OBJ_SENTINEL); mp_obj_t tuple_contents[2]; tuple_contents[0] = MP_OBJ_FROM_PTR(sslsock); tuple_contents[1] = peer; From e5f0579d6c63c788206daf86b4faa1476d8824ed Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 25 Mar 2024 09:20:36 -0500 Subject: [PATCH 10/13] SSLSocket: implement setsockopt (untested) --- shared-bindings/ssl/SSLSocket.c | 19 ++++++++++++++----- shared-bindings/ssl/SSLSocket.h | 1 + shared-module/ssl/SSLSocket.c | 12 ++++++++++++ shared-module/ssl/SSLSocket.h | 1 + 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index 10bca142adc1..4181ad3a156d 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -200,13 +200,22 @@ STATIC mp_obj_t ssl_sslsocket_send(mp_obj_t self_in, mp_obj_t buf_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_send_obj, ssl_sslsocket_send); -// //| def setsockopt(self, level: int, optname: int, value: int) -> None: +// //| def setsockopt(self, level: int, optname: int, value: int | ReadableBuffer) -> None: // //| """Sets socket options""" // //| ... // //| -// STATIC mp_obj_t ssl_sslsocket_setsockopt(size_t n_args, const mp_obj_t *args) { -// } -// STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_setsockopt_obj, 4, 4, ssl_sslsocket_setsockopt); +STATIC mp_obj_t ssl_sslsocket_setsockopt(size_t n_args, const mp_obj_t *args) { + ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_obj_t level = args[1]; + mp_obj_t optname = args[2]; + mp_obj_t optval = args[3]; + + // throws on error + common_hal_ssl_sslsocket_setsockopt(self, level, optname, optval); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_setsockopt_obj, 4, 4, ssl_sslsocket_setsockopt); //| def settimeout(self, value: int) -> None: //| """Set the timeout value for this socket. @@ -252,7 +261,7 @@ STATIC const mp_rom_map_elem_t ssl_sslsocket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&ssl_sslsocket_recv_into_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&ssl_sslsocket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&ssl_sslsocket_setblocking_obj) }, - // { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&ssl_sslsocket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&ssl_sslsocket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&ssl_sslsocket_settimeout_obj) }, }; diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index 1388c9cd4fe8..1010817e37a2 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -44,3 +44,4 @@ void common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len); mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj); +void common_hal_ssl_sslsocket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level, mp_obj_t optname, mp_obj_t optval); diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index dc9ea5a575f4..77586e9e1b3f 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -158,6 +158,13 @@ static void ssl_socket_close(ssl_sslsocket_obj_t *self) { mp_call_method_n_kw(0, 0, self->close_args); } +static void ssl_socket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level_obj, mp_obj_t opt_obj, mp_obj_t optval_obj) { + self->setsockopt_args[2] = level_obj; + self->setsockopt_args[3] = opt_obj; + self->setsockopt_args[4] = optval_obj; + mp_call_method_n_kw(3, 0, self->setsockopt_args); +} + static void ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { self->settimeout_args[2] = timeout_obj; mp_call_method_n_kw(1, 0, self->settimeout_args); @@ -233,6 +240,7 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t mp_load_method(socket, MP_QSTR_recv_into, o->recv_into_args); mp_load_method(socket, MP_QSTR_send, o->send_args); mp_load_method(socket, MP_QSTR_settimeout, o->settimeout_args); + mp_load_method(socket, MP_QSTR_setsockopt, o->setsockopt_args); mbedtls_ssl_init(&o->ssl); mbedtls_ssl_config_init(&o->conf); @@ -441,6 +449,10 @@ mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self) { return mp_obj_new_tuple(2, tuple_contents); } +void common_hal_ssl_sslsocket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level_obj, mp_obj_t optname_obj, mp_obj_t optval_obj) { + ssl_socket_setsockopt(self, level_obj, optname_obj, optval_obj); +} + void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { ssl_socket_settimeout(self, timeout_obj); } diff --git a/shared-module/ssl/SSLSocket.h b/shared-module/ssl/SSLSocket.h index 70518abc2263..6d9be05febbb 100644 --- a/shared-module/ssl/SSLSocket.h +++ b/shared-module/ssl/SSLSocket.h @@ -57,5 +57,6 @@ typedef struct ssl_sslsocket_obj { mp_obj_t listen_args[3]; mp_obj_t recv_into_args[3]; mp_obj_t send_args[3]; + mp_obj_t setsockopt_args[5]; mp_obj_t settimeout_args[3]; } ssl_sslsocket_obj_t; From 2f53c6edbbef3c5a823017219d2de9d1e5c78e52 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 17 Apr 2024 15:13:59 -0500 Subject: [PATCH 11/13] ssl: Swallow errors during socket.close() .. for reasons given in the comment --- shared-module/ssl/SSLSocket.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 77586e9e1b3f..37e24197ecea 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -155,7 +155,16 @@ static void ssl_socket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { } static void ssl_socket_close(ssl_sslsocket_obj_t *self) { - mp_call_method_n_kw(0, 0, self->close_args); + // swallow any exception raised by the underlying close method. + // This is not ideal. However, it avoids printing "MemoryError:" + // when attempting to close a userspace socket object during gc_sweep_all + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_call_method_n_kw(0, 0, self->close_args); + nlr_pop(); + } else { + nlr_pop(); + } } static void ssl_socket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level_obj, mp_obj_t opt_obj, mp_obj_t optval_obj) { From 93490c301f6cccafd97e68d3aa311d12a11623f3 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 17 Apr 2024 15:17:37 -0500 Subject: [PATCH 12/13] Don't close an SSL socket twice --- shared-module/ssl/SSLSocket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 37e24197ecea..79a01156a3af 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -382,6 +382,9 @@ void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) } void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { + if (self->closed) { + return; + } self->closed = true; ssl_socket_close(self); mbedtls_pk_free(&self->pkey); From 879f24175ea763247817419a4136349d51abe9b0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 20 Apr 2024 18:57:13 -0500 Subject: [PATCH 13/13] Disable some things for the ssl enhancements to fit --- ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk | 3 +++ ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk index 10e362399f55..72eb1db85a01 100644 --- a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk @@ -3,6 +3,8 @@ CIRCUITPY_CREATION_ID = 0x00320001 IDF_TARGET = esp32 +CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 9 + CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m @@ -17,3 +19,4 @@ CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_KEYPAD = 0 diff --git a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk index 5656781fcef4..1d370fd30e71 100644 --- a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk @@ -10,6 +10,8 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_AESIO = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_CANIO = 0 CIRCUITPY_CODEOP = 0 CIRCUITPY_ESPCAMERA = 0