aboutsummaryrefslogtreecommitdiffstats
path: root/link/link-protocol.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-30 05:33:14 +0100
committereunhhu <[email protected]>2026-09-30 05:33:14 +0100
commitbaaf955959d4b2187e93e35b64cd3f5b2330a59a (patch)
tree769cb962162a803421cea809a7beea947f58e30c /link/link-protocol.c
parent6b3b1c64328fb6b4932dfb67fd05486182657673 (diff)
downloadpure-baaf955959d4b2187e93e35b64cd3f5b2330a59a.tar.gz
pure-baaf955959d4b2187e93e35b64cd3f5b2330a59a.zip
Try a refused stream again when its try is gone
A sender whose stream the receiver refuses sends one packet of records a wait, and the refusal is over when that packet is acknowledged with no REFUSED. When the try itself went to no one (the receiver started again, as a node upgraded one after the other does, or the path lost it) nothing acknowledged it: the sender took its epoch for lost, began another, and then sent nothing more, still waiting on the try, with no record in flight to probe for. Two nodes of a shared board stayed apart for good after the second one's upgrade. A try declared lost, or dropped with the epoch's flights, now lets the next packet try again. test-link's refused_restarted case: the receiver refuses a stream, is killed while the next try is due and comes back 8 s later with the input; before, nothing was stored in 120 s, now all 200 are by 18.2 s. Streams refused for good send as few packets as before (9 in 90 s).
Diffstat (limited to 'link/link-protocol.c')
-rw-r--r--link/link-protocol.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/link/link-protocol.c b/link/link-protocol.c
index 12f9a24..4fa5aab 100644
--- a/link/link-protocol.c
+++ b/link/link-protocol.c
@@ -521,6 +521,7 @@ static void lose(PureLinkSender *l, Flight *f, uint64_t now, bool by_time) {
f->by_time = by_time;
f->largest_then = l->largest_acked;
++l->counts.lost;
+ if (l->tried == TRYING && f->pn == l->tried_pn) l->tried = 0; /* a refused stream's try, gone: another goes */
for (uint16_t u = 0; u < f->count; ++u) l->counts.resent += carried(l, &f->units[u], f->pn, false, now);
if (f->sent > l->cc.recovery_start) { /* one congestion event per round trip */
if (!l->undo_losses) { /* an episode begins */
@@ -1128,6 +1129,7 @@ static void epoch_lost(PureLinkSender *l) {
}
l->renegotiating = false;
l->pto_count = 0;
+ if (l->tried == TRYING) l->tried = 0; /* its try went with the rest: another goes */
for (size_t k = 0; k < l->flight_count; ++k) {
Flight *f = &l->flights[(l->flight_head + k) & (l->flight_capacity - 1)];
if (!f->done) settle(l, f), f->count = 0;