<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ouroboros/src/tools, branch testing</title>
<subtitle>Ouroboros main repository</subtitle>
<id>https://ouroboros.rocks/cgit/ouroboros/atom?h=testing</id>
<link rel='self' href='https://ouroboros.rocks/cgit/ouroboros/atom?h=testing'/>
<link rel='alternate' type='text/html' href='https://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='https://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>tools: Add timeout option to oping</title>
<updated>2026-05-20T06:17:06+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-10T15:29:59+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=3f962298bfcf2fb0c6a30b4f1d9e1423321409cb'/>
<id>urn:sha1:3f962298bfcf2fb0c6a30b4f1d9e1423321409cb</id>
<content type='text'>
Add a -W/--timeout option to override the per-packet recv timeout.
The default is 2000 ms. Raises the receive buffer to 16 KiB so larger
SDUs aren't truncated (useful for fragmentation tests later on).

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>tools: Fix server mutex init in oping</title>
<updated>2026-05-20T06:17:06+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-08T10:34:48+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=86dbd8db9b051c8d1e08071cb8aae180a799427a'/>
<id>urn:sha1:86dbd8db9b051c8d1e08071cb8aae180a799427a</id>
<content type='text'>
The pthread_mutex_init and pthread_mutex_destroy were missing,
resulting in undefined behaviour.

Signed-off-by: Dimitri Staessens &lt;dimitri@ouroboros.rocks&gt;
Signed-off-by: Sander Vrijders &lt;sander@ouroboros.rocks&gt;
</content>
</entry>
<entry>
<title>tools: Use distinct exit codes</title>
<updated>2026-05-20T06:17:04+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-05-01T13:30:40+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=3be3360349ee823531d6c3e53b188a7e8af2b761'/>
<id>urn:sha1:3be3360349ee823531d6c3e53b188a7e8af2b761</id>
<content type='text'>
The tools will now use the following convention:

0 — success

1 — runtime/I/O failure or packet loss

2 — setup failure

oping now uses a SIGALRM to exit on duration tests.

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: Allow direct rbuff between local processes</title>
<updated>2026-02-22T15:02:16+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-02-19T21:03:16+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=c3636005831064e71b03a5f8796a21e89b2a714f'/>
<id>urn:sha1:c3636005831064e71b03a5f8796a21e89b2a714f</id>
<content type='text'>
This allows bypassing the IPCP for local processes that share the same
packet pool, lowering latency between processes to comparable levels
as Unix sockets (RTT in the order of a microsecond).

For local processes, no IPCPs are needed:

 $ irm b prog oping n oping
 $ oping -l
 Ouroboros ping server started.
 New flow 64.
 Received 64 bytes on fd 64.

The direct IPC can be disabled with the DISABLE_DIRECT_IPC build
flag. Note that this is needed for rumba 'local' experiments to
emulate network topologies. Without this flag all processes will just
communicate directly.

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 2026</title>
<updated>2026-02-18T06:54:56+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-02-15T09:21:02+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=0d72b59c2964208ea34ce2322978344d7ff1a223'/>
<id>urn:sha1:0d72b59c2964208ea34ce2322978344d7ff1a223</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>build: Refactor CMake back to in-tree CMakeLists</title>
<updated>2026-02-13T08:22:29+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-02-02T21:50:17+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=3796f6b04b5fce183e5480b57725545cda033f99'/>
<id>urn:sha1:3796f6b04b5fce183e5480b57725545cda033f99</id>
<content type='text'>
This moves the build definitions back to src/ subdirectories
(CMakeLists.txt per component). Configuration and dependencies are
kept out of tree. Configuration options are bundled into cmake/config/
modules. Dependencies are grouped by component (system/, crypt/, eth/,
coverage/, etc.). It now consistently uses target-based commands
(target_include_directories, target_link_libraries) instead of global
include_directories(). Proper PRIVATE/PUBLIC visibility for executable
link libraries. CONFIG_OUROBOROS_DEBUG now properly set based on being
a valid debug config (not just checking the string name).

It also adds OuroborosTargets export for find_package() support and
CMake package config files (OuroborosConfig.cmake) for easier
integration with CMake projects.

The build logic now follows more idiomatic CMake practices with
configuration separated from target definitions.

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 per-user packet pools</title>
<updated>2026-02-13T08:22:28+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-01-26T21:02:50+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=e3dd6d00fe339194328ad884bd9b172dedcf95fc'/>
<id>urn:sha1:e3dd6d00fe339194328ad884bd9b172dedcf95fc</id>
<content type='text'>
The IRMd will now check the user UID and GID for privileged access,
avoiding unprivileged users being able to disrupt all IPC (e.g. by
shm_open the single pool and corrupting its metadata).

Non-privileged users are now limited to a PUP (per-user pool) for
sending/receiving packets. It is still created by the IRMd, but owned
by the user (uid) with 600 permissions. It does not add additional
copies for local IPC between their own processes (i.e. over the local
IPCP), but packets between processes owned by a different user or
destined over the network (other IPCPs) will incur a copy when
crossing the PUP / PUP or the PUP / GSPP boundary.

Privileged users and users in the ouroboros group still have direct
access to the GSPP (globally shared private pool) for packet transfer
that will avoid additional copies when processing packets between
processes owned by different users and to the network.

This aligns the security model with UNIX trust domains defined by UID
and GID by leveraging file permission on the pools in shared memory.

┌─────────────────────────────────────────────────────────────┐
│ Source Pool    │ Dest Pool      │ Operation    │ Copies     │
├─────────────────────────────────────────────────────────────┤
│ GSPP           │ GSPP           │ Zero-copy    │ 0          │
│ PUP.uid        │ PUP.uid        │ Zero-copy    │ 0          │
│ PUP.uid1       │ PUP.uid2       │ memcpy()     │ 1          │
│ PUP.uid        │ GSPP           │ memcpy()     │ 1          │
│ GSPP           │ PUP.uid        │ memcpy()     │ 1          │
└─────────────────────────────────────────────────────────────┘

This also renames the struct ai ("application instance") in dev.c to
struct proc (process).

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 post-quantum cryptography support</title>
<updated>2026-01-19T07:29:29+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2026-01-07T15:44:34+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=60b04305d70614580b4f883c0a147507edef3779'/>
<id>urn:sha1:60b04305d70614580b4f883c0a147507edef3779</id>
<content type='text'>
This adds initial support for runtime-configurable encryption and
post-quantum Key Encapsulation Mechanisms (KEMs) and authentication
(ML-DSA).

Supported key exchange algorithms:

  ECDH: prime256v1, secp384r1, secp521r1, X25519, X448
  Finite Field DH: ffdhe2048, ffdhe3072, ffdhe4096
  ML-KEM (FIPS 203): ML-KEM-512, ML-KEM-768, ML-KEM-1024
  Hybrid KEMs: X25519MLKEM768, X448MLKEM1024

Supported ciphers:
  AEAD: aes-128-gcm, aes-192-gcm, aes-256-gcm, chacha20-poly1305
  CTR: aes-128-ctr, aes-192-ctr, aes-256-ctr

Supported HKDFs:
  sha256, sha384, sha512, sha3-256, sha3-384, sha3-512,
  blake2b512, blake2s256

Supported Digests for DSA:
  sha256, sha384, sha512, sha3-256, sha3-384, sha3-512,
  blake2b512, blake2s256

PQC support requires OpenSSL 3.4.0+ and is detected automatically via
CMake. A DISABLE_PQC option allows building without PQC even when
available.

KEMs differ from traditional DH in that they require asymmetric roles:
one party encapsulates to the other's public key. This creates a
coordination problem during simultaneous reconnection attempts. The
kem_mode configuration parameter resolves this by pre-assigning roles:

  kem_mode=server  # Server encapsulates (1-RTT, full forward secrecy)
  kem_mode=client  # Client encapsulates (0-RTT, cached server key)

The enc.conf file format supports:

  kex=&lt;algorithm&gt;      # Key exchange algorithm
  cipher=&lt;algorithm&gt;   # Symmetric cipher
  kdf=&lt;KDF&gt;            # Key derivation function
  digest=&lt;digest&gt;      # Digest for DSA
  kem_mode=&lt;mode&gt;      # Server (default) or client
  none                 # Disable encryption

The OAP protocol is extended to negotiate algorithms and exchange KEX
data. All KEX messages are signed using existing authentication
infrastructure for integrity and replay protection.

Tests are split into base and _pqc variants to handle conditional PQC
compilation (kex_test.c/kex_test_pqc.c, oap_test.c/oap_test_pqc.c).

Bumped minimum required OpenSSL version for encryption to 3.0
(required for HKDF API). 1.1.1 is long time EOL.

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: Refactor CMake modules</title>
<updated>2026-01-07T09:00:06+00:00</updated>
<author>
<name>Dimitri Staessens</name>
<email>dimitri@ouroboros.rocks</email>
</author>
<published>2025-12-23T10:59:45+00:00</published>
<link rel='alternate' type='text/html' href='https://ouroboros.rocks/cgit/ouroboros/commit/?id=48c294105f5123dc876fbad199ec1e0166d82a18'/>
<id>urn:sha1:48c294105f5123dc876fbad199ec1e0166d82a18</id>
<content type='text'>
This moves the CMake build logic out of the source tree and splits it
up into a more modular form. The tests now have a CMakeLists.txt file
in their respective source directory.

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