From 27b20fd4715024035e38db60fc70cf71faa407e2 Mon Sep 17 00:00:00 2001 From: Deuce <shurd@sasktel.net> Date: Fri, 27 Nov 2020 03:38:15 -0500 Subject: [PATCH] "Handle" frames with a data length of zero. These frames were already not allowed in the binkp/1.0 protocol, and it is mentioned in the spec (issued in 2005) as "Some old implementations do send empty frames as the last frame.". It's certainly not allowed now, and any mailer which does it is broken. For zero-length data packets, it will be seen as a frame containing zero data bytes which will also be logged as being after the file if it comes after the file has already been completely transferred. A zero-length command packet will abort with M_ERR, logging an error regarding command number NaN or something like that. This may fix #185 since attempting a recv() of zero bytes and succeeding is the only way I can see for a zero second timeout to have been logged in receving frame data. The software assumed that receiving zero bytes was a timeout, but if that's what you asked for, it's actually success. --- exec/load/binkp.js | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/exec/load/binkp.js b/exec/load/binkp.js index a22780385c..55ba148a19 100644 --- a/exec/load/binkp.js +++ b/exec/load/binkp.js @@ -1096,28 +1096,33 @@ BinkP.prototype.recvFrame = function(timeout) else ret = this.partialFrame; - i = this.recv_buf(this.sock.recv(ret.length - ret.data.length, timeout)); - if (i == null) { - log(LOG_INFO, "Error in recv() of packet data"); - this.sock.close(); - this.sock = undefined; - return undefined; + if (ret.length == 0) { + log(LOG_WARNING, "Remote illegally sent a "+(ret.is_cmd ? 'Command' : 'Data')+" packet with data length of zero. This isn't even allowed in protocol 1.0."); } - if (i.length == 0) { - if (!this.sock.is_connected) { - log(LOG_DEBUG, "Remote host closed socket"); + else { + i = this.recv_buf(this.sock.recv(ret.length - ret.data.length, timeout)); + if (i == null) { + log(LOG_INFO, "Error in recv() of packet data"); this.sock.close(); this.sock = undefined; return undefined; } - else if (timeout) { - log(LOG_WARNING, "Timed out receiving packet data from remote: " + this.remote_addrs); - this.sock.close(); - this.sock = undefined; - return undefined; + if (i.length == 0) { + if (!this.sock.is_connected) { + log(LOG_DEBUG, "Remote host closed socket"); + this.sock.close(); + this.sock = undefined; + return undefined; + } + else if (timeout) { + log(LOG_WARNING, "Timed out receiving packet data from remote: " + this.remote_addrs); + this.sock.close(); + this.sock = undefined; + return undefined; + } } + ret.data += i; } - ret.data += i; if (ret.data.length < ret.length) this.partialFrame = ret; -- GitLab