I have a device (STM32F4 with FreeRTOS, LWIP, MbedTLS) that establishes a TLS connection with a server. I want to keep this connection up all the time for two-way message exchange in time intervals of 30 seconds to 10 minutes. Sometimes I want to close this connection to temporarily free RAM (~40kB) for other tasks. Most of the time the task is blocked on the mbedtls_ssl_read() function.
The question is how to interrupt this TLS connection from another task so as to exit the mbedtls_ssl_read function and free RAM as it happens when the server terminates the connection.
I tried to close connection with the functions:
shutdown(sock, SHUT_RDWR);
mbedtls_net_close(net_context);
called from another task. On Wireshark I see that the device (client) sends a FIN, ACK packet, to which the server responds with an ACK packet and nothing else happens. The call stack is identical before and after calling one of the above functions (stack ends with the xQueueGenericReceive() function, as below). The connection is established with the 3rd party custom server see screenshot, but the behavior with the regular https server is very similar see screenshot (4 packets instead of 2).
Before connecting I set the socket timeout
timeOut.tv_sec = 20 * 60;
timeOut.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeOut, sizeof(struct timeval));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (void*)&timeOut, sizeof(struct timeval));
If I set a short timeout, the connection is terminated, but I don’t want the timeout to occur during normal operation.
The TLS task works like this (pseudo code):
loop:
if(TLS connection enabled)
prepare TLS structs includes certs (malloc)
set socket options (timeouts)
set bio
handshake
verify cert
loop2:
mbedtls_ssl_read
mbedtls_ssl_write or exit loop
mbedtls_ssl_close_notify
free all allocated structs
Callstack when waiting for data
Thread #5 (Suspended : Container)
xQueueGenericReceive() at queue.c
sys_arch_mbox_fetch() at sys_arch.c
netconn_recv_data() at api_lib.c
netconn_recv_data_tcp() at api_lib.c
netconn_recv_tcp_pbuf_flags() at api_lib.c
lwip_recv_tcp() at sockets.c
lwip_recvfrom() at sockets.c
lwip_read() at sockets.c
mbedtls_net_recv() at net_sockets.c
mbedtls_ssl_fetch_input() at ssl_msg.c
ssl_get_next_record() at ssl_msg.c
mbedtls_ssl_read_record() at ssl_msg.c
mbedtls_ssl_read() at ssl_msg.c
HTTPD_SocketRead() at httpd.c
HTML_Process() at html.c
HTTPD_Cloud_Serve() at httpd.c
Cloud_Task() at acloud.c
Michelangelo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.