early return on partial packet ack

This commit is contained in:
Patricio Whittingslow
2025-10-29 18:06:38 -03:00
parent 46137bbbec
commit 71cf99dcb8
2 changed files with 20 additions and 9 deletions
+15 -6
View File
@@ -161,12 +161,13 @@ func (rtx *ringTx) RecvACK(ack Value) error {
} }
// lastAckedPkt stores last fully acked packet. // lastAckedPkt stores last fully acked packet.
var lastAckedPkt *ringidx var lastAckedPkt *ringidx
var partialPkt *ringidx
for i := 0; i < len(rtx.packets); i++ { for i := 0; i < len(rtx.packets); i++ {
pkt := &rtx.packets[i] pkt := &rtx.packets[i]
if !pkt.sent() || ack.LessThanEq(pkt.seq) { if !pkt.sent() || ack.LessThanEq(pkt.seq) {
continue continue
} }
endseq := Add(pkt.seq, pkt.size) endseq := pkt.endSeq()
isFullyAcked := endseq.LessThanEq(ack) isFullyAcked := endseq.LessThanEq(ack)
isPartialAcked := ack.InRange(pkt.seq, endseq) isPartialAcked := ack.InRange(pkt.seq, endseq)
isLast := lastAckedPkt == nil || lastAckedPkt.seq.LessThanEq(pkt.seq) isLast := lastAckedPkt == nil || lastAckedPkt.seq.LessThanEq(pkt.seq)
@@ -186,10 +187,10 @@ func (rtx *ringTx) RecvACK(ack Value) error {
pkt.markRcvd() pkt.markRcvd()
} else if !isPartialAcked { } else if !isPartialAcked {
panic("unreachable") panic("unreachable")
} } else {
if isPartialAcked { // Is partial acked.
if lastAckedPkt != nil && lastAckedPkt.seq.LessThan(pkt.seq) { if partialPkt != nil {
panic("unreachable") panic("unreachable") // can't have two partially acked packets.
} }
acked := int(ack - pkt.seq) acked := int(ack - pkt.seq)
pring := rtx.ring(pkt.off, pkt.end) pring := rtx.ring(pkt.off, pkt.end)
@@ -202,8 +203,12 @@ func (rtx *ringTx) RecvACK(ack Value) error {
pkt.seq = ack pkt.seq = ack
pkt.size = pkt.size - Size(acked) pkt.size = pkt.size - Size(acked)
rtx.sentoff = off rtx.sentoff = off
partialPkt = pkt
} }
} }
if partialPkt != nil {
return nil
}
if lastAckedPkt != nil { if lastAckedPkt != nil {
rtx.sentoff = lastAckedPkt.end rtx.sentoff = lastAckedPkt.end
lastAckedPkt.markRcvd() lastAckedPkt.markRcvd()
@@ -317,7 +322,7 @@ func (rtx *ringTx) endSeq() (Value, bool) {
return 0, false return 0, false
} }
last := rtx.pkt(pkt) last := rtx.pkt(pkt)
return Add(last.seq, last.size), true return last.endSeq(), true
} }
func (rtx *ringTx) lastSeq() (Value, bool) { func (rtx *ringTx) lastSeq() (Value, bool) {
pkt := rtx.lastPkt() pkt := rtx.lastPkt()
@@ -352,3 +357,7 @@ func (pkt *ringidx) markRcvd() {
// pkt.end = 0 // pkt.end = 0
// pkt.off = 0 // pkt.off = 0
} }
func (pkt *ringidx) endSeq() Value {
return Add(pkt.seq, pkt.size)
}
+5 -3
View File
@@ -16,9 +16,11 @@ func TestTxQueue_multipacket(t *testing.T) {
const maxWriteSize = mtu / maxWrites const maxWriteSize = mtu / maxWrites
var rtx ringTx var rtx ringTx
internalbuff := make([]byte, mtu) internalbuff := make([]byte, mtu)
rng := rand.New(rand.NewSource(1)) rng := rand.New(rand.NewSource(3))
var wbuf, rbuf [mtu]byte var wbuf, rbuf [mtu]byte
for itest := 0; itest < 32; itest++ { for itest := 0; itest < 32; itest++ {
// rng.Seed(int64(itest))
println(itest)
err := rtx.Reset(internalbuff, maxPkts, iss) err := rtx.Reset(internalbuff, maxPkts, iss)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -67,7 +69,7 @@ func TestTxQueue_multipacket(t *testing.T) {
for acked < roff { for acked < roff {
maxToack := min(roff-acked, maxWriteSize) maxToack := min(roff-acked, maxWriteSize)
toack := rng.Intn(maxToack) + 1 toack := rng.Intn(maxToack) + 1
t.Log("\n", rtx.string()) // t.Log("\n", rtx.string())
err = rtx.RecvACK(iss + Value(acked+toack)) err = rtx.RecvACK(iss + Value(acked+toack))
testQueueSanity(t, &rtx) testQueueSanity(t, &rtx)
if err != nil { if err != nil {
@@ -347,7 +349,7 @@ func (rx *ringTx) string() string {
wrapZone = &zones[i] wrapZone = &zones[i]
} }
} }
var currentZone *zone var currentZone *zone = wrapZone
var lastPrintedZone *zone var lastPrintedZone *zone
var l1, l2 bytes.Buffer var l1, l2 bytes.Buffer
changes := 0 changes := 0