From 259da9a233f199f4652c382dfd0bf1d136541429 Mon Sep 17 00:00:00 2001 From: Toh Xin Yi <141562742+xinyitohh@users.noreply.github.com> Date: Fri, 6 Nov 2026 09:24:05 +0800 Subject: [PATCH] tport_ws: read WSS frames that OpenSSL already decrypted tport_recv_stream_ws() reads one WebSocket frame per call and returns 1, and tport_recv_event() only loops again when the receive function returns more than 1. Over TLS, a second frame in the same TLS record is already in OpenSSL's buffer, so the socket is not readable and nothing wakes the poll for it. The frame is processed only when more data arrives. The plain TLS transport avoids this with "tls_pending() ? 2 : 1". Do the same for WSS with SSL_pending(). Seen as: a client sending ACK and the authenticated INVITE back to back after a 407. The INVITE sat unprocessed, so the first outbound call after idle hung until Timer B (408). --- libsofia-sip-ua/tport/tport_type_ws.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libsofia-sip-ua/tport/tport_type_ws.c b/libsofia-sip-ua/tport/tport_type_ws.c index eb8c1ce49..0bd868972 100644 --- a/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libsofia-sip-ua/tport/tport_type_ws.c @@ -260,6 +260,16 @@ int tport_recv_stream_ws(tport_t *self) * flags it, and the reply path answers 413. */ msg_recv_commit(msg, n, 0); + /* ws_read_frame() reads one frame at a time. Over TLS, OpenSSL has already + * pulled the whole TLS record off the socket and decrypted it, so a second + * WebSocket frame in the same record sits in OpenSSL's buffer while the + * socket itself reads as empty: the event loop is not woken for it and the + * frame stays unprocessed until more data arrives on the connection. + * Returning 2 makes tport_recv_event() call us again, exactly as the plain + * TLS transport does with tls_pending(). */ + if (wstp->ws.ssl && SSL_pending(wstp->ws.ssl) > 0) + return 2; + return 1; }