@@ -465,6 +465,11 @@ static void BrokerTls_Free(MqttBroker* broker)
465465
466466#include <libwebsockets.h>
467467
468+ /* Compatibility for older libwebsockets versions (pre-4.1) */
469+ #ifndef LWS_PROTOCOL_LIST_TERM
470+ #define LWS_PROTOCOL_LIST_TERM { NULL, NULL, 0, 0, 0, NULL, 0 }
471+ #endif
472+
468473/* Forward declaration for the no-op connect callback (defined after WS section) */
469474static int BrokerNetConnect (void * context , const char * host , word16 port ,
470475 int timeout_ms );
@@ -622,25 +627,13 @@ static int callback_broker_mqtt(struct lws *wsi,
622627 ws -> rx_len += len ;
623628 }
624629 else {
625- WBLOG_ERR (broker , "broker: ws rx buffer overflow (wsi=%p)" ,
626- (void * )wsi );
627- /* Drop oldest data to make room */
628- if (len >= sizeof (ws -> rx_buffer )) {
629- const byte * in_bytes = (const byte * )in ;
630- XMEMCPY (ws -> rx_buffer ,
631- & in_bytes [len - sizeof (ws -> rx_buffer )],
632- sizeof (ws -> rx_buffer ));
633- ws -> rx_len = sizeof (ws -> rx_buffer );
634- }
635- else {
636- size_t keep = sizeof (ws -> rx_buffer ) - len ;
637- if (keep > 0 && ws -> rx_len > 0 ) {
638- XMEMMOVE (ws -> rx_buffer ,
639- ws -> rx_buffer + (ws -> rx_len - keep ), keep );
640- }
641- XMEMCPY (ws -> rx_buffer + keep , in , len );
642- ws -> rx_len = keep + len ;
643- }
630+ /* Dropping bytes would desynchronize MQTT packet framing,
631+ * so treat overflow as a fatal protocol error. */
632+ WBLOG_ERR (broker , "broker: ws rx buffer overflow "
633+ "(wsi=%p, have=%d, need=%d, max=%d)" ,
634+ (void * )wsi , (int )ws -> rx_len , (int )len ,
635+ (int )sizeof (ws -> rx_buffer ));
636+ return -1 ; /* close connection */
644637 }
645638 }
646639 else if (reason == LWS_CALLBACK_SERVER_WRITEABLE ) {
@@ -653,14 +646,17 @@ static int callback_broker_mqtt(struct lws *wsi,
653646 if (ws -> tx_pending != NULL && ws -> tx_len > 0 ) {
654647 int n = lws_write (wsi , ws -> tx_pending + LWS_PRE ,
655648 ws -> tx_len , LWS_WRITE_BINARY );
649+ if (n < (int )ws -> tx_len ) {
650+ WBLOG_ERR (broker , "broker: ws write failed (wsi=%p, "
651+ "n=%d, len=%d)" , (void * )wsi , n , (int )ws -> tx_len );
652+ WOLFMQTT_FREE (ws -> tx_pending );
653+ ws -> tx_pending = NULL ;
654+ ws -> tx_len = 0 ;
655+ return -1 ;
656+ }
656657 WOLFMQTT_FREE (ws -> tx_pending );
657658 ws -> tx_pending = NULL ;
658659 ws -> tx_len = 0 ;
659- if (n < 0 ) {
660- WBLOG_ERR (broker , "broker: ws write failed (wsi=%p)" ,
661- (void * )wsi );
662- return -1 ;
663- }
664660 }
665661 }
666662 else if (reason == LWS_CALLBACK_CLOSED ) {
@@ -804,7 +800,15 @@ static int BrokerWsNetDisconnect(void* context)
804800 }
805801
806802 if (ws -> wsi != NULL && ws -> status > 0 ) {
803+ BrokerClient * * bc_ptr ;
807804 WBLOG_INFO (bc -> broker , "broker: ws disconnect (wsi=%p)" , (void * )ws -> wsi );
805+ /* Clear lws per-session user data so that any later callbacks
806+ * (e.g. LWS_CALLBACK_CLOSED) see NULL and skip processing.
807+ * Without this, the callback would dereference the freed bc. */
808+ bc_ptr = (BrokerClient * * )lws_wsi_user (ws -> wsi );
809+ if (bc_ptr != NULL ) {
810+ * bc_ptr = NULL ;
811+ }
808812 lws_close_reason (ws -> wsi , LWS_CLOSE_STATUS_NORMAL , NULL , 0 );
809813 ws -> wsi = NULL ;
810814 }
0 commit comments