<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ouroboros/src/lib/frct.c, branch 0.24.0</title>
<subtitle>Ouroboros main repository</subtitle>
<id>https://ouroboros.rocks/cgit/ouroboros/atom?h=0.24.0</id>
<link rel='self' href='https://ouroboros.rocks/cgit/ouroboros/atom?h=0.24.0'/>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/'/>
<updated>2026-07-19T09:44:35+00:00</updated>
<entry>
<title>lib: Whitespace cleanup in dev and frct</title>
<updated>2026-07-19T09:44:35+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-07-10T15:09:58+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=17263ccd93ba07fb32de12cfd540bd531f23bef2'/>
<id>urn:sha1:17263ccd93ba07fb32de12cfd540bd531f23bef2</id>
<content type='text'>
Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>irmd: Deliver flow re-keying</title>
<updated>2026-06-29T06:32:58+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-06-14T14:16:03+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=fdb50b8256f1038d5bc4f906b41605cacc769bf4'/>
<id>urn:sha1:fdb50b8256f1038d5bc4f906b41605cacc769bf4</id>
<content type='text'>
Re-key each encrypted flow's batch root periodically so a long-lived
flow never exhausts or over-uses a single root. The IRMd re-runs the
OAP exchange with the peer IRMd over the flow-update relay. The
per-flow re-keying state is tracked in the registry (reg_flow).

A re-key delivers one root seed from the OAP exchange. keyrot
immediately HKDF-expands it into 128 node keys (KR_NODES_SZ = 128 × 32
B) and wipes the root. Then each of the 128 node keys is itself a root
→ HKDF-expanded into 64 (2^KEY_NODE_BITS) leaf keys, forked per
direction; each leaf key is the actual AEAD key, good for 2^20 packets
(the low counter bits are its nonce/seq). If the number of keys runs
low, a re-key will be triggered (KEY_REKEY_WATERMARK).

The rekey is signalled out of band to the application. The rbuff ACL
is generalized into a flags word, so an RB_REKEY bit rides alongside
the access RB_RD/RB_WR and FLOWDOWN/FLOWPEER bits. The RD and WR bits
are revised ditching the fcntl historical weirdness. The seed is
pulled via flow_read/flow_write, installed with crypt_rekey(). TX
holds the old epoch until the peer is observed on the new one (or a
grace deadline elapses), promoted from both the read and write paths
so a recv-mostly flow still advances.

Also fix the FLOW_ACCEPT and FLOW_ALLOC handlers, which on a key-buffer
allocation failure returned from inside the cleanup-push region: that
leaked the reply message and skipped both the stack-key scrub and the
cleanup pop.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Send stream FIN in the window</title>
<updated>2026-06-01T05:43:48+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-30T17:50:50+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=9056ba37925b7ecb4b5724633b1b288ed58951bd'/>
<id>urn:sha1:9056ba37925b7ecb4b5724633b1b288ed58951bd</id>
<content type='text'>
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 &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Fix FRCT seqno leak on rxm alloc failure</title>
<updated>2026-06-01T05:43:48+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-30T10:27:58+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=6d787a674797c656c71442767360810457e3d24b'/>
<id>urn:sha1:6d787a674797c656c71442767360810457e3d24b</id>
<content type='text'>
The seqno was committed before calling rxm_arm, whose malloc could
fail and silently leave the seqno without a retransmission entry. None
of the recovery paths (RTO timer, RACK, SACK-driven, NACK-driven) can
repair a slot with NULL rxm, so the gap persists until the receiver's
keepalive marks the flow dead.

This fix splits rxm_arm into rxm_alloc plus rxm_arm (post-state
install). sack_rxm_snd follows the same alloc-then-arm shape.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Add FIN and receive-side linger for msg dealloc</title>
<updated>2026-05-22T06:13:50+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-21T20:49:15+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=5d0cf67a38695ebe65a0506b5c6d6c0d229a3b3e'/>
<id>urn:sha1:5d0cf67a38695ebe65a0506b5c6d6c0d229a3b3e</id>
<content type='text'>
qos_msg flows had no end-of-stream signal: a deallocating sender
relied on the peer's inactivity timers (~30 s) to notice. Worse, the
dealloc-linger path was bugged: a receiver that called flow_dealloc
would stop draining its rx_rb while the peer's tail retransmits kept
arriving. Peer retransmitted into a black hole until its own dealloc
fired, and the whole shutdown stretched takes t_a time.

Generalizes frcti_stream_fin_snd to frcti_fin_snd; for msg mode emit a
FRCT_FIN-only control packet with the FIN seqno boundary in
pci-&gt;ackno. Receiver-side frcti_rcv latches rcv_fin_seen and stores
the boundary on FRCT_FIN-without-DATA.

Fix comment on the FRCT flags.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Allow up to two TLPs per recovery episode</title>
<updated>2026-05-22T06:13:50+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-21T20:23:01+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=3ad96a09df9dfd8e63e494887f7ef5bc07f244b5'/>
<id>urn:sha1:3ad96a09df9dfd8e63e494887f7ef5bc07f244b5</id>
<content type='text'>
RFC 8985 §7.3 permits up to two tail loss probes before falling back
to RTO. Previously FRCP allowed exactly one TLP per episode, making
tail-loss recovery dependent on a successful first probe; if that
probe was lost the sender fell straight to slow RTO with exponential
backoff.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Further align FRCP with TCP RFCs</title>
<updated>2026-05-22T06:13:50+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-21T19:42:57+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=6a8b532870cf8c642adb1b7554691cadb8be5257'/>
<id>urn:sha1:6a8b532870cf8c642adb1b7554691cadb8be5257</id>
<content type='text'>
Only the HoL slot retransmits on RTO; non-HoL slots defer and rely on
SACK/RACK fast-rxm for recovery. Matches RFC 6298 §5.4 + RFC 8985 §3
and Linux tcp_retransmit_skb(head, 1). Eliminates the spurious-RTO
storm where ~50-66% of retransmits arrived as duplicates at the peer.

Co-fixes for three latent state-machine bugs that the previous
spurious-retx mask was hiding:

  - recovery_enter: seal recovery_high at the false→true edge only
    (RFC 6582 §3.2). Previously extended on every gap-SACK, which
    trapped the sender in NewReno indefinitely once any cum-ACK fell
    behind the moving recovery_high.

  - rtt_sample_eligible: drop the in_recovery super-gate. Karn at the
    per-slot SND_RTX|SND_TLP level is already correct (matches Linux).

  - rxm_due defer interval: use base RTO, not rto&lt;&lt;rto_mul. Inheriting
    HoL's backoff parked deferred slots tens of seconds in the future.

Bring RACK reorder-window scaling into RFC 8985 §7.2 compliance:
reo_wnd_mult widens at most once per RTT, gated via a srtt-elapsed
check in reo_wnd_on_dsack.

Stat refactor for clearer attribution: rename rxm_snd → rxm_rto (now
RTO-driven sends only), add rxm_nack and rxm_due_defer, split rxm_rcv
into total FRCT_RXM arrivals and rxm_dup_rcv (duplicates). Expose
rx/tx ring queue depths as RIB stats.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Set a timeout on FRCT control packets</title>
<updated>2026-05-22T06:13:50+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-20T07:23:07+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=3cde856b4b68b5d6bbb9d6bb2d1b995f0babe109'/>
<id>urn:sha1:3cde856b4b68b5d6bbb9d6bb2d1b995f0babe109</id>
<content type='text'>
Time out frct_tx for control packets at 250us so a full tx ring cannot
stall the timer wheel (and with it KA, TLP, RXM fires). DATA frames
(fresh, RXM, TLP, FIN) keep blocking - dropping them would lose
recovery progress.

Add inact_drop, drf_rebase, rq_released, tlp_snd, sdu_snd_alloc,
sdu_snd_tx, sdu_sole, rxm_tx_dead, and per-type tx_drop counters.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Add tail loss probe (TLP) to FRCP</title>
<updated>2026-05-22T06:13:50+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-20T16:15:10+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=40cc98c427186a54ddf27fbd10763d7457fffb30'/>
<id>urn:sha1:40cc98c427186a54ddf27fbd10763d7457fffb30</id>
<content type='text'>
The previous bugfixes that fixed a false-positive inactivity timer
check unmasked the need for the tail loss probe (TLP) to quickly
recover from loss of the HoL.

When the sender finishes its app data with packets still inflight,
RACK fast-rxm cannot fire (no ACK arrives), pre-DRF NACK is gated on
rcv_cr.inact, and rto_mul climbs into seconds before the next RXM fire
— recv-side deadline expires first.

This adds the RFC 8985 §7.2 TLP: PTO = 2*SRTT + max_ack_delay (t_a),
capped by the HoL slot's current RTO deadline. Probe fires from
frcti_snd and after frcti_ack_rcv; per §7.3 at most one TLP per
recovery episode, tracked via tlp_high_seq. On fire, re-emit HoL via
fast_rxm_send and hand off to RTO — no PTO self re-arm. A new SND_TLP
slot flag is Karn-skipped for RTT sampling, cleared by RTO retransmit
or NACK-driven fast-rxm, and clears rto_mul on its TLP-ACK (rto_mul
carries no CC meaning in FRCP). Also caps MAX_RTO_MUL at 8 instead of
20.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>lib: Fix underrun in activity timer</title>
<updated>2026-05-22T06:13:33+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-20T11:09:20+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=ac994f2456681bada8371d6cb379467313acddfa'/>
<id>urn:sha1:ac994f2456681bada8371d6cb379467313acddfa</id>
<content type='text'>
The inactivity timers are updated under rdlock with atomics on the
time stamp. Inactivity is measured by comparison between the act stamp
against the thread's own current time (now_ns). A different thread
could already have updated the act stamp, causing undderun in the
signed comparison and causing a false-positive on the inactive test.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
</feed>
