<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ouroboros/src/tools/oftp, branch be</title>
<subtitle>Ouroboros main repository</subtitle>
<id>http://133.ip-51-38-114.eu/cgit/ouroboros/atom?h=be</id>
<link rel='self' href='http://133.ip-51-38-114.eu/cgit/ouroboros/atom?h=be'/>
<link rel='alternate' type='text/html' href='http://133.ip-51-38-114.eu/cgit/ouroboros/'/>
<updated>2026-05-20T06:17:07+00:00</updated>
<entry>
<title>lib: Update FRCP implementation</title>
<updated>2026-05-20T06:17:07+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-10T17:06:21+00:00</published>
<link rel='alternate' type='text/html' href='http://133.ip-51-38-114.eu/cgit/ouroboros/commit/?id=63d3aa9ab8d8b0b6d8a10362e112a431dcb5b4e9'/>
<id>urn:sha1:63d3aa9ab8d8b0b6d8a10362e112a431dcb5b4e9</id>
<content type='text'>
The Flow and Retransmission Control Protocol (FRCP) runs end-to-end
between two peers over a flow. It provides reliability, in-order
delivery, flow control, and liveness. Note that congestion avoidance
is orthogonal to FRCP and handled in the IPCP.

A fixed 16-octet header, network byte order, is prefixed to every FRCP
packet:

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |             flags             |              hcs              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            window                             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            seqno                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            ackno                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     payload (variable) ...
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

hcs is a CRC-16-CCITT-FALSE checksum over the PCI (and the stream
extension when present), verified before any flag-driven dispatch.  A
single packet can simultaneously carry DATA + ACK + FC + RXM by OR-ing
flag bits. An optional CRC trailer covers the body on DATA when qs.ber
== 0, and on every SACK packet; an optional AEAD wrap (per-flow keys)
sits outermost.

Flag bits (MSB-first; bits 13..15 reserved, MUST be zero):

    +------+--------+--------+----------------------------------------+
    | Bit  | Mask   | Name   | Meaning                                |
    +------+--------+--------+----------------------------------------+
    |   0  | 0x8000 | DATA   | Carries caller payload                 |
    |   1  | 0x4000 | DRF    | Start of a fresh data run              |
    |   2  | 0x2000 | ACK    | ackno field valid                      |
    |   3  | 0x1000 | NACK   | Pre-DRF nudge (seqno informational)    |
    |   4  | 0x0800 | FC     | window field valid (rwe advertisement) |
    |   5  | 0x0400 | RDVS   | Rendezvous probe (window-closed)       |
    |   6  | 0x0200 | FFGM   | First Fragment of a multi-fragment SDU |
    |   7  | 0x0100 | LFGM   | Last Fragment of a multi-fragment SDU  |
    |   8  | 0x0080 | RXM    | Retransmission                         |
    |   9  | 0x0040 | SACK   | Block list follows in payload          |
    |  10  | 0x0020 | RTTP   | RTT probe / echo (payload follows)     |
    |  11  | 0x0010 | KA     | Keepalive                              |
    |  12  | 0x0008 | FIN    | End of stream marker                   |
    | 13-15|   --   |   --   | Reserved (MUST be zero)                |
    +------+--------+--------+----------------------------------------+

(FFGM, LFGM) encodes the fragment role of a DATA packet (SCTP-style
B/E): 11=SOLE, 10=FIRST, 00=MID, 01=LAST. Each fragment carries its
own seqno; Retransmission recovers fragments individually, reassembly
runs at consume time. In stream mode FFGM/LFGM are unused; per-byte
position is carried by the stream extension below and end-of-stream is
signalled by FIN on a 0-byte DATA packet.

SACK payload (FRCT_ACK | FRCT_FC | FRCT_SACK):

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           n_blocks            |        padding (2 octets)     |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                           start[0]                            |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            end[0]                             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        ... n_blocks pairs total ...

Each block describes a *present* (received) range strictly above the
cumulative ACK in the PCI ackno. D-SACK (RFC 2883) is signalled
in-band as block[0] - no flag bit, no extra framing - and consumed by
the RACK reo_wnd_mult scaler (RFC 8985 sec. 7.2).

RTTP payload (FRCT_RTTP only; 24 octets):

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          probe_id                             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          echo_id                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                  nonce (16 octets, echoed verbatim)           +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Stream PCI extension (in_order == STREAM only; 8 octets after the base
PCI on every DATA packet):

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            start                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                             end                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

start, end are monotonic 32-bit byte offsets; end - start equals the
on-wire payload length. Stream mode is negotiated at flow allocation;
the extension is present iff stream mode is in use, never on a
per-packet basis.

Service modes are an orthogonal (in_order, loss, ber) vector selected
at flow_alloc; the cubes above map to the axes:

    +----------------+---------+------+-----+-----------------------+
    | Cube           | in_order| loss | ber | Engaged               |
    +----------------+---------+------+-----+-----------------------+
    | qos_raw        |    0    |   1  |   1 | Raw passthrough       |
    | qos_raw_safe   |    0    |   1  |   0 | Raw + CRC trailer     |
    | qos_rt         |    1    |   1  |   1 | FRCP, no FRTX, no CRC |
    | qos_rt_safe    |    1    |   1  |   0 | FRCP, no FRTX, CRC    |
    | qos_msg        |    1    |   0  |   0 | FRCP + FRTX           |
    | qos_stream     |    2    |   0  |   0 | FRCP + FRTX, stream   |
    +----------------+---------+------+-----+-----------------------+

in_order=0 sends raw datagrams with no PCI (UDP-equivalent);
in_order=1 engages FRCP with SDU framing; in_order=2 (stream) requires
loss=0 and is rejected otherwise. loss=0 engages the FRTX retransmit
machinery. ber=0 appends the CRC-32 trailer; QOS_DISABLE_CRC at build
time forces ber=1 for development. Encryption is a separate per-flow
attribute layered as an AEAD wrap outside the FRCP packet.

Heritage: delta-t (Watson 1981) supplies timer-based connection
management - no SYN/FIN handshake, the DRF marker, the t_mpl / t_a /
t_r timers. RINA (Day 2008) supplies the unified flow_alloc(name, qos,
...) primitive and the orthogonal QoS-cube axes.  Loss detection
follows TCP/QUIC practice (RFCs 2018, 2883, 6582, 6298, 8985); RTT
probing is nonce-authenticated like QUIC PATH_CHALLENGE.

Adds oftp, a minimal file-transfer tool over an FRCP stream flow. The
client reads from stdin or --in FILE and writes through a
flow_alloc(qos_stream); the server (--listen) calls flow_accept and
writes to stdout or --out FILE. Both sides compute a CRC-64/NVMe over
the bytes they handle and print the result. The server rejects flows
whose negotiated qs.in_order != STREAM.

Two FRCP knobs are exposed via env vars on either side:
  OFTP_FRCT_RTO_MIN         fccntl FRCTSRTOMIN  (ns)
  OFTP_FRCT_STREAM_RING_SZ  fccntl FRCTSRRINGSZ (octets)

The ocbr_client gains an OCBR_QOS env var to pick the cube the client
uses for flow_alloc; recognised values are raw, safe, rt, rt_safe,
msg, stream. Unknown values fall back to raw with a warning on
stderr. Without the env set behaviour is unchanged.

Removes the deprecated lib/timerwheel.c

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