-
-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Double ACK causes Block transfer to send duplicate messages #391
Comments
did you tried running your repro with "DEBUG=*" to get more internal details? |
From my own investigations, the second "chain" of blocks seems to be caused by this call to The following diff fixes the issue for the application I'm working on: diff --git a/lib/agent.ts b/lib/agent.ts
index 10ade18..5569690 100644
--- a/lib/agent.ts
+++ b/lib/agent.ts
@@ -234,6 +234,11 @@ class Agent extends EventEmitter {
req._packet.messageId = this._nextMessageId()
this._msgIdToReq.set(req._packet.messageId, req)
segmentedSender.receiveACK(block1)
+ } else if (segmentedSender.isPreviousACK(block1)) {
+ // The received ACK is a response to a previous messageId.
+ // This can happen if a block transmission is retried
+ // and the server ACKs both messages.
+ return
} else {
segmentedSender.resendPreviousPacket()
diff --git a/lib/segmentation.ts b/lib/segmentation.ts
index 488d650..1f33e51 100644
--- a/lib/segmentation.ts
+++ b/lib/segmentation.ts
@@ -62,6 +62,10 @@ export class SegmentedTransmission {
return retBlockState.num === this.blockState.num// && packet.code == "2.31"
}
+ isPreviousACK (retBlockState: Block): boolean {
+ return retBlockState.num < this.blockState.num
+ }
+
resendPreviousPacket (): void {
if (this.resendCount < 5) {
this.currentByte = this.lastByte I'm not sure One could also argue that the server is misconfigured, and should not ACK blocks that have already been received. I couldn't find any info on what behavior is correct in the RFC. |
Description
This is a bug which has been observed in crowded network conditions when doing large block transfers. It happens with a node-coap client (using Agent) when the server ACKs a block N after the client already sent a retransmission. Both the original ACK and the ACK of the retransmission will cause the client to send block N+1.
Reproduction
Below is a reproduction of the bug. The server will not send the ACK of block 5 until it received the retransmission of block 5, then it sends both. Note that the same behavior can happen while the original ACK is in flight which is the case we originally observed.
client.js:
server.js:
Output from server when running repro:
Notice that every message beyond 5 is sent twice.
The text was updated successfully, but these errors were encountered: