From 708a4b6f6700d428e09b7200a05e84c6cc6b17d0 Mon Sep 17 00:00:00 2001 From: HenkjanvDiermen Date: Tue, 13 Jan 2026 10:21:32 +0100 Subject: [PATCH] Fix FullPacketParser to handle multi-packet chunks The FullPacketParser only processed the first packet when multiple packets arrived in a single chunk, resulting in data loss. This fix loops through all packets in the chunk using an offset, ensuring all packets are processed and pushed downstream. Fixes intermittent packet loss in high-throughput scenarios where TCP delivers multiple protocol packets in a single read. --- src/serializer.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/serializer.js b/src/serializer.js index 8b52e95..0bcef2a 100644 --- a/src/serializer.js +++ b/src/serializer.js @@ -43,6 +43,7 @@ class Parser extends Transform { try { packet = this.parsePacketBuffer(this.queue) } catch (e) { + console.log('EBuf', this.queue.toString('hex')) if (e.partialReadError) { return cb() } else { e.buffer = this.queue this.queue = Buffer.alloc(0) @@ -69,24 +70,27 @@ class FullPacketParser extends Transform { } _transform (chunk, enc, cb) { - let packet - try { - packet = this.parsePacketBuffer(chunk) - if (packet.metadata.size !== chunk.length && !this.noErrorLogging) { - console.log('Chunk size is ' + chunk.length + ' but only ' + packet.metadata.size + ' was read ; partial packet : ' + - JSON.stringify(packet.data) + '; buffer :' + chunk.toString('hex')) - } - } catch (e) { - if (e.partialReadError) { - if (!this.noErrorLogging) { - console.log(e.stack) + let offset = 0 + + while (offset < chunk.length) { + let packet + try { + packet = this.parsePacketBuffer(chunk.slice(offset)) + } catch (e) { + if (e.partialReadError) { + // Partial read errors can occur for packets in wrong protocol state or malformed data + // Drop the remainder of this chunk and continue + return cb() + } else { + console.log('EBuf', chunk.slice(offset).toString('hex')) + return cb(e) } - return cb() - } else { - return cb(e) } + + this.push(packet) + offset += packet.metadata.size } - this.push(packet) + cb() } }