diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-05-30 19:50:50 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-06-01 07:43:48 +0200 |
| commit | 9056ba37925b7ecb4b5724633b1b288ed58951bd (patch) | |
| tree | 4b4b5cb5ac7237b95dce8171d29e540e4e5118e5 /src/lib | |
| parent | 8ca71e4d4b62c05110a73c20a6aa28fa86a6fa53 (diff) | |
| download | ouroboros-9056ba37925b7ecb4b5724633b1b288ed58951bd.tar.gz ouroboros-9056ba37925b7ecb4b5724633b1b288ed58951bd.zip | |
lib: Send stream FIN in the windowbe
The stream FIN was not gated on the flow control window, potentially
causing a seqno overrun if the windows was full.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/frct.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/lib/frct.c b/src/lib/frct.c index cf1b60e2..3077df65 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -3789,6 +3789,15 @@ static int frcti_snd(struct frcti * frcti, return 0; } +/* Stream FIN is armed for rxm; needs to be in window. */ +static __inline__ bool stream_fin_blocked(struct frcti * frcti) +{ + if (!frcti->stream) + return false; + + return !before(frcti->snd_cr.seqno, frcti->snd_cr.lwe + RQ_SIZE); +} + /* * Stream: 0-byte FRCT_FIN DATA so peer's flow_read returns 0 at this * byte. Msg: control packet with FRCT_FIN flag, snd_cr.seqno carried @@ -3806,6 +3815,13 @@ static void frcti_fin_snd(struct frcti * frcti) pthread_rwlock_wrlock(&frcti->lock); already = frcti->snd_fin_sent; + + /* Defer before committing snd_fin_sent; linger loop retries. */ + if (!already && stream_fin_blocked(frcti)) { + pthread_rwlock_unlock(&frcti->lock); + return; + } + frcti->snd_fin_sent = true; fin_seqno = frcti->snd_cr.seqno; |
