<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ouroboros/doc/man/flow_read.3, branch be</title>
<subtitle>Ouroboros main repository</subtitle>
<id>http://www.ouroboros.rocks/cgit/ouroboros/atom?h=be</id>
<link rel='self' href='http://www.ouroboros.rocks/cgit/ouroboros/atom?h=be'/>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/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://www.ouroboros.rocks/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>
<entry>
<title>build: Update licenses to 2024</title>
<updated>2024-01-13T09:20:14+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2024-01-05T08:07:30+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=8742a31bf672c5bc087601ec39ab1feb206d2446'/>
<id>urn:sha1:8742a31bf672c5bc087601ec39ab1feb206d2446</id>
<content type='text'>
Slow but steady.

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: Make flow liveness timeout configurable</title>
<updated>2022-03-03T11:00:54+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2022-02-25T16:34:29+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=f5d642a06f9c1a58197313b32f6b213a152e446f'/>
<id>urn:sha1:f5d642a06f9c1a58197313b32f6b213a152e446f</id>
<content type='text'>
The qosspec_t now has a timeout value that sets the timeout value of
the flow. Flows with a peer that has timed out will now return
-EFLOWPEER on flow_read() or flow_write().

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>build: Update email addresses</title>
<updated>2021-01-03T10:57:05+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2021-01-02T06:24:35+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=fa2ca608aa06c98c080edf80c00d39d6d90e4d3a'/>
<id>urn:sha1:fa2ca608aa06c98c080edf80c00d39d6d90e4d3a</id>
<content type='text'>
The ugent email addresses are shut down, updated to Ouroboros mail
addresses.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>build: Update copyright to 2021</title>
<updated>2021-01-03T10:56:28+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2021-01-02T06:24:34+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=505703bcd8cf33279f89c414b008e393cb04522f'/>
<id>urn:sha1:505703bcd8cf33279f89c414b008e393cb04522f</id>
<content type='text'>
Happy New Year, Ouroboros!

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: Return number of written bytes on flow_write</title>
<updated>2020-03-15T13:30:58+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2020-03-14T16:52:06+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=51d8f69fb152ae5a47151c2f132fd4263ec3d144'/>
<id>urn:sha1:51d8f69fb152ae5a47151c2f132fd4263ec3d144</id>
<content type='text'>
This is more in line with the write() system call and prepares for
partial writes. Partial writes are disabled by default (and not yet
implemented).

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>build: Update copyright to 2020</title>
<updated>2020-01-02T14:07:36+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2020-01-01T08:48:07+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=435a91165a3c1f8ca715b22ee2c2361d9bd853dd'/>
<id>urn:sha1:435a91165a3c1f8ca715b22ee2c2361d9bd853dd</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>doc: Update documentation to new website URL</title>
<updated>2019-03-18T10:09:32+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2019-03-16T18:06:27+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=33c6b76a80189dd92f0fa2d579b1a0b9ca69127c'/>
<id>urn:sha1:33c6b76a80189dd92f0fa2d579b1a0b9ca69127c</id>
<content type='text'>
The documentation and package point to the imec site, which is now
moved to ouroboros.rocks

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>build: Update copyright to 2019</title>
<updated>2019-02-05T08:58:08+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri.staessens@ugent.be</email>
</author>
<published>2019-02-04T15:37:21+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=5dd086aa679e3e05d20ef6a19f3fefbe46ffe40e'/>
<id>urn:sha1:5dd086aa679e3e05d20ef6a19f3fefbe46ffe40e</id>
<content type='text'>
Updates the copyright notice in all sources to 2019.

Signed-off-by: Dimitri Staessens &lt;dimitri.staessens@ugent.be&gt;
Signed-off-by: Sander Vrijders &lt;sander.vrijders@ugent.be&gt;
</content>
</entry>
<entry>
<title>lib: Allow disabling partial read</title>
<updated>2018-03-19T09:29:21+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri.staessens@ugent.be</email>
</author>
<published>2018-03-17T13:55:46+00:00</published>
<link rel='alternate' type='text/html' href='http://www.ouroboros.rocks/cgit/ouroboros/commit/?id=4230103ff633904c69cc18d861bf42781f57bb64'/>
<id>urn:sha1:4230103ff633904c69cc18d861bf42781f57bb64</id>
<content type='text'>
This allows disabling partial reads. It adds a flag FLOWFRNOPART that
disables partial reads. Partial read is different from partial
delivery (FRCTFPARTIAL), which allows delivery of fragments of an
incomplete packet and thus potentially corrupted data. FLOWFRNOPART
will never deliver corrupted data (unless FRCTFPARTIAL is also set).
If FLOWFRNOPART is set and the buffer provided to flow_read is too
small for the SDU, that SDU will be discarded and -EMSGSIZE is
returned;

Signed-off-by: Dimitri Staessens &lt;dimitri.staessens@ugent.be&gt;
Signed-off-by: Sander Vrijders &lt;sander.vrijders@ugent.be&gt;
</content>
</entry>
</feed>
