summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* irmd: Reject client encap without configured KEXDimitri Staessens36 hours2-0/+51
| | | | | | | | | | | | | A client asking for client-side encapsulation against a server that has no kex= configured left scfg->x.str NULL, crashing the handshake inside strstr(). Client encapsulation decapsulates with the server's configured static key, so a server without the configured key exchange cannot serve the request. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Assign random MAC on ETH poa with loopbackDimitri Staessens36 hours1-0/+24
| | | | | | | | | | | | | | | The loopback has an all-zero MAC, so two PoAs on a loopback receive their own frames and a PoA refuses its own FLOW_REQ, failing the flow with ECONNREFUSED. The shim IPCP didn't have this problem because it ignored requests for names not registered locally (shim-data). The PoA has no "local" name registry, it uses the unicast IPCP's directory (DHT) via IRMd query requests. This fixes the issue by generating a random locally administered MAC on the loopback device. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Fix oftp on OS XDimitri Staessens36 hours1-0/+5
| | | | | Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Update FRCT loss recoveryDimitri Staessens36 hours13-338/+932
| | | | | | | Some more stability fixes in FRCT. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Use capacity queue estimation for mb-ecnDimitri Staessens36 hours24-1078/+3523
| | | | | | | | | | | The mb-ecn algorithm was using rbuff queue depths in packets to mark, but sockets in the poa component report capacity in bytes. The tx rings are now adaptive to block on queuing delay instead of when full to prevent buffer bloat, controllable via fccntl (FLOWSTXQDLY and FLOWGTXQDLY). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Replace shim IPCPs with points of attachmentDimitri Staessens36 hours68-5524/+9712
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Removes the UDP and Ethernet shim IPCPs. The unicast and broadcast IPCPs can now directly attach to a "legacy" socket. We adopt Saltzer's Point-of-Attachment terminology, also advocated in Day's "Patterns in Network Architecture". The "poa" component manages these PoA's with one management thread, one link monitoring thread and one thread per attached point. For Ethernet PoA's the irm connect and enroll can resolve the destination IPCP or Layer name with a broadcast name query over the attached PoAs (first reply wins). UDP PoA's require a destination IP address or FQDN. attach to a local endpoint (required both server and client side): irm ipcp poa attach name a udp 10.0.0.1 irm ipcp poa attach name a udp 10.0.0.1:3435 irm ipcp poa attach name a udp [::1]:3435 irm ipcp poa attach name a eth dev eth0 irm ipcp poa attach name a eth dev eth0 ethertype 0xA000 release a PoA (refused while it carries a flow): irm ipcp poa detach name a udp 10.0.0.1:3435 irm ipcp poa detach name a eth eth0 list an IPCP's PoAs: irm ipcp poa list name a connect to a peer, by name or at an address: irm ipcp connect name b dst a irm ipcp connect name b dst a eth irm ipcp connect name b dst a eth dev eth0 irm ipcp connect name b dst a udp 10.0.0.1:3435 irm ipcp connect name b dst a udp peer.example.com:3435 disconnect by peer name, no address: irm ipcp disconnect name b dst a irm ipcp disconnect name b dst a component mgmt enroll has the same shape as connect: irm ipcp enroll name b layer lr autobind irm ipcp enroll name b layer lr autobind eth dev eth0 irm ipcp enroll name b layer lr autobind udp 10.0.0.1:3435 the IRMd config file attaches PoAs and names peers the same way: udp = [ "10.0.0.1", "10.0.0.1:3436" ] eth = [ "eth0", {dev="eth1", ethertype=0xA007} ] enrol={dst="LAN", eth={dev="eth0"}} conn=[{dst="lan3", eth={}}, {dst="lan4", udp="10.0.0.1:3435"}] Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Immediaty send oping requestDimitri Staessens36 hours1-2/+2
| | | | | | | The oping client was waiting for one interval before sending. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Report write error code in ocbr statsDimitri Staessens36 hours1-6/+17
| | | | | Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Fix irm CLI arg parsingDimitri Staessens36 hours12-37/+97
| | | | | | | | Fixes "irm name list" matching "list" instead of "name" and improves guards against missing (last) arguments. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Make crypt contexts thread-safeDimitri Staessens36 hours4-81/+292
| | | | | | | | | Moves the per-packet EVP context to a thread-local state. Now refuses a security config with -ENOTSUP without supported crypto backend (OpenSSL). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Don't drop DT flows on -EAGAINDimitri Staessens36 hours1-1/+8
| | | | | | | | | The scheduler was dropping DT flows when they were momentarily empty (-EAGAIN). Now it will continue to the next flow and only drop on hard errors. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Clean up pft on flow downDimitri Staessens36 hours1-0/+6
| | | | | | | | | The pft had stale DT entries after a flow goes down until the next lsdb update. The flow descriptors are now purged once the link is declared down. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix next value iteration in DHTDimitri Staessens36 hours2-8/+70
| | | | | | | | There was a bug in the loop where only the last entry was checked. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix FRCT stall under packet lossDimitri Staessens2026-08-031-15/+37
| | | | | | | | | | | | | | | | | A stream flow over a lossy path could block completely with the send window pegged at RQ_SIZE. Fixed not sending the tail loss probe (TLP) when the window was closed. Fixed SACK emission when the window edge and block count remain unchanged. A lost fast retransmit keeps SND_FAST_RXM set. Clear the flag once the slot ages past its own RTO. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix uninitialized qs in acceptorDimitri Staessens2026-08-031-2/+3
| | | | | | | | | The acceptor thread was accepting flows with an uninitialed qosspec, reading garbage. This could cause toggling frct on one end by accident. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Flush fd from pff after disconnectDimitri Staessens2026-08-037-40/+348
| | | | | | | | | | | The flow descriptors were not immediately removed from the routing tables when they were disconnected, so forwarding paths could still use the fd after the IPCP has deallocated the flow. Refactors the tests and adds some for the del_fd function. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Add flow overshoot protection to mb-ecnDimitri Staessens2026-07-2214-80/+873
| | | | | | | | | | | | | | | | | | | | | | | | | | | The ECN marks were the only source of congestion information, and going into congestion collapse (dropping a lot of ECN packets and causing loss of signal) was unrecoverable. The sender's slow-start ramp clock now tracks a measured RTT to avoid overshooting into congestion collapse on the previously fixed (14ms) doubling on long-delay (e.g. 100ms) links. The flow allocator now carries a periodic heartbeat/ack to keep RTT estimates up-to-date. The heartbeat also serves as a congestion collapse detector: consecutive heartbeat losses will go into loss recovery, halving the window and pausing Additive Increase until the path is clear. The DT component now has a max_rtt config parameter that serves as a hint for the layer RTT to optimize slow-start for low-latency networks. These two mechanisms follow TCP, however only during slow start up to the first ECN signal and to recover from a total collapse until the ECN signal returns. MB-ECN is still fully RTT-independent in the AI/PD region. A shorter RTT path will just reach its equal fair share faster than a longer RTT path. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Process DT flows round-robinDimitri Staessens2026-07-221-20/+36
| | | | | | | | | The deadline scheduler kept draining the same flow with fevent() until its queue was empty, so a single greedy flow monopolizes the link. Now it does a per-packet round-robin to ensure each flow is served. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Remove mutex on DT statsHEAD0.24.0masterDimitri Staessens2026-07-191-52/+42
| | | | | | | | | There was a bug where the flow's stat mutex was zero'd while held. Removed the mutex alltogether; use stamp != 0 as the validity guard of the flow stats while reading stats. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Add congestion avoidance unit testsDimitri Staessens2026-07-196-0/+3653
| | | | | | | | | | | | | | | | | | | | | | | | | Cover the shared per-aggregate contexts, the mb-ecn policy and the link capacity estimator. The controller tests pin the invariants of the algorithm: the first mark is reported immediately, the receiver's congestion mean is independent of packet rate and its window adapts to hold a fixed sample count, increase and decrease are invariant under control cadence, a starved sender still cuts and later recovers, signals age out on rate-relative horizons, capacity feedback derives the rate floor and recovery slope with clamps and a staleness fallback, and the pacer bounds the burst after idle. The estimator tests drive synthetic arrival traces: the capacity code survives a round trip within its resolution, hops combine by MIN, busy-period drain measures the link rate, windows extend on slow links, sparse idle observations are tolerated where unsaturated windows are rejected, shaped links measure at the shaped rate, stale windows are discarded, and windows bordering an empty queue can only lower the estimate. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Rework congestion avoidanceDimitri Staessens2026-07-1920-311/+1539
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Congestion avoidance is a property of the layer, orthogonal to ARQ and to flow control: FRCP retransmits and lets the peer pace the sender, per flow, end-to-end; the IPCP paces path aggregates. Each signal means one thing: a loss triggers a retransmission, a mark means congestion, the peer window means a slow receiver. Every flow is paced by the same rate law whatever its QoS, so a greedy raw sender shares a bottleneck fairly with a reliable stream. The unit of control is the (destination address, QoS cube) aggregate: all flows toward that destination share one controller and one rate; a start-time fair-queuing pacer divides the rate across them by deadline instead of blocking the send path, and a new flow rides the aggregate's estimates at its current rate, with no probing of its own. Slow start runs once per aggregate. The congestion signal is a multi-bit magnitude: forwarders mark packets with their standing queue depth, MAX-combined across hops, so a packet carries the deepest queue on its path. The receiver feeds back a time-integral mean over a window that adapts to the flow's byte rate, measuring a slow flow with the same fidelity as a fast one. The sender runs AIMD scaled by elapsed wall-clock time, which makes the steady-state allocation RTT-independent. The PCI gains one byte: the path capacity as a quarter-log2 code. Forwarders estimate their egress rate from busy-period drain and MIN-stamp the byte, the receiver returns the window minimum with its feedback, and the sender scales its rate floor and additive slope to the bottleneck (C / 32). A deep cut implies a backlogged bottleneck and a backlogged bottleneck advertises its capacity, so the scaled floor is live exactly when recovery needs it: the probe heals a halving in seconds at any link rate, and the floor bounds the deepest hole to a factor 32 below the bottleneck. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Raise ocbr server thread pool to 64Dimitri Staessens2026-07-191-1/+1
| | | | | | | 10 threads is not enough to deeply test congestion avoidance. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Fix congestion config from fileDimitri Staessens2026-07-191-1/+1
| | | | | | | The configfile logic was matching "lfa" instead of "mb-ecn". Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Reject rekey without KEX configDimitri Staessens2026-07-193-0/+87
| | | | | | | | A rekey without KEX config should be rejected rather than downgrading to plaintext. Tests added. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Whitespace cleanup in dev and frctDimitri Staessens2026-07-192-11/+21
| | | | | Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Key oftp cleanup on path argumentsDimitri Staessens2026-07-191-5/+9
| | | | | | | | The cleanup guards compared the stream against the stdin/stdout globals, which tripped the clang static analyzer. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Fix oap_test suppression listDimitri Staessens2026-07-191-2/+8
| | | | | | | | he crypto-disabled branch of the test driver referenced two tests that were folded into test_oap_ts_reject_all() and missed newer ones. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix crypt_test without crypto backendDimitri Staessens2026-07-191-0/+8
| | | | | | | | | Creating a context without OpenSSL fails (returns NULL) after adding the key rotation logic (requires HKDF). Assert instead that context creation returns NULL without OpenSSL. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Avoid in-place byteswap in OAP headerDimitri Staessens2026-07-191-3/+3
| | | | | | | | | | gcc 12 -fanalyzer misclassifies kex_len = hton16(kex_len) followed by memcpy(&kex_len) as a read of an uninitialized value. Write the swapped value through the scratch variable like every other field in write_oap_fixed(). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Harden OAP client KEM completionDimitri Staessens2026-07-191-19/+18
| | | | | | | | | | | | | do_client_kex_complete_kem() filled key_buf in the server-encap branch and returned early in the client-encap branch; any other mode value would fall through and memcpy an uninitialized stack buffer into the session key. The client only ever sets the two known modes today, but nothing local enforces that and the server derives its mode from a wire bit. Give each mode an explicit path with no fall-through. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Fix strdup error checks in registryDimitri Staessens2026-07-193-2/+6
| | | | | | | | | | reg_proc_add_name() and reg_prog_add_name() checked the already validated entry pointer instead of the fresh strdup. Found by gcc static analyzer. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix NULL deref in DHT cleanupDimitri Staessens2026-07-191-1/+1
| | | | | | | | | | | | | | The dht_kv_find_node_rsp_msg function steals *contacts and NULLs it on success. When the subsequent msg->val allocation fails in dht_kv_find_value_rsp_msg(), the stolen contacts are freed along with the message, and do_dht_kv_find_value_req() is left with contacts == NULL while n_contacts is still positive: its fail_vals loop then dereferences NULL. Found by clang static analyzer. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix unreachable code in dt_initDimitri Staessens2026-07-191-1/+1
| | | | | | | | With IPCP_FLOW_STATS disabled, the bmp_destroy() in the dt_init() failure handling was unreachable. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Store local names before DHT peeringDimitri Staessens2026-07-081-1/+6
| | | | | | | | | | | A name registered before the DHT had a peer stayed unpublished until it neared its expiry deadline. Make a never-stored local value (t_repl == 0) eligible for replication immediately, and flush replication once when the worker starts so such names are published as soon as the DHT is enrolled. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix DHT bootstrap re-seedingDimitri Staessens2026-07-081-1/+45
| | | | | | | | | | The bootstrap seeder reported success as soon as the query was sent. Only skip seeding once the peer is in a bucket, and return -EAGAIN until it actually appears so the caller keeps retrying rather than assuming bootstrap completed. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Report eth socket egress queue in RIBDimitri Staessens2026-07-081-1/+7
| | | | | | | | Add the raw socket's SIOCOUTQ egress backlog to the eth RIB and relabel the existing FIONREAD RIB entry as ingress. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Minimize ipcpd-eth send bufferDimitri Staessens2026-07-081-6/+13
| | | | | | | | The eth send buffer needs to block quickly so we can mark congestion correctly in the upper layer buffers. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix locking on flow readDimitri Staessens2026-07-081-9/+13
| | | | | | | | | | Reading a deallocated flow could cause an assert on a negative id. The raw-flow path now holds proc.lock across flow_rx_spb rather than dropping it first, and the FRCT loop no longer releases and reacquires the lock on every iteration. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Prefer writers on the proc flow lockDimitri Staessens2026-07-081-4/+18
| | | | | | | | | | FRCT readers hold proc.lock in a rdlock loop and could starve a pending flow accept waiting for the wrlock. Initialise the lock with the writer-nonrecursive kind on Linux with glibc, so writers are not indefinitely delayed. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Clean up on cancelled blocking readDimitri Staessens2026-07-082-4/+20
| | | | | | | | | Cancelling a thread that was blocked in ssm_rbuff_read_b/write_b didn't clean up the n_users reference. If it was in flow_rx_one it didn't unlock the process lock. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Separate rekey replay from epoch conflictDimitri Staessens2026-07-083-16/+42
| | | | | | | | | | | | | keyrot_rekey() treated any re-key attempt against a live epoch (current or previous) the same way, whether the offered root key matched the live one (a replay) or was genuinely different (a conflict). Compare the offered key against the live batch's root and return -EREPLAY for a match, keeping -1/-ECRYPT for an actual conflict, so callers can handle replayed re-keys distinctly from real ones. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Move AUTH test macros to OAP common.hDimitri Staessens2026-07-083-25/+23
| | | | | | | | | | The ML-DSA OAP test defined CLI_AUTH/NO_CLI_AUTH and passed them for the srv_auth parameters of the re-key tests. Rename to the neutral AUTH/NO_AUTH already used by oap_test.c and move the pair to the shared common.h. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Test OAP KEM re-key floorDimitri Staessens2026-07-081-0/+126
| | | | | | | | | Add tests for two client-encap KEM properties the server enforces: reject a client KDF below the server floor, and confirm a re-key forces ephemeral server-encap. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Expand and parametrize OAP testsDimitri Staessens2026-07-084-182/+554
| | | | | | | | | | Parametrize the re-key roundtrips over the full (srv_auth, cli_auth) matrix. Add a KEM re-key axis, request-ID and cleartext-echo tamper tests, and an unsupported cipher/kdf/digest NID cluster guarded by an assertion. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Harden crypto unit testsDimitri Staessens2026-07-083-5/+103
| | | | | | | | | | | | | | Stop the non-OpenSSL runners from masking a real failure as SKIP by only downgrading to SKIP if they passed. Fix a stray call that ran test_kex_dhe_wrong_algo in the skip branch. Fix double free + free of an uninitialised pointer in test_store_add. Test that a KDF- less derive must fail. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Fix OAP re-key header encodeDimitri Staessens2026-07-084-9/+27
| | | | | | | | | | | | | The oap_hdr_encode() function validated its own output by re-decoding with rekey hardcoded false. The case where the client signs a re-key failed its own self-check because the cert is not sent again. Now uses a flag on the encode() to signal the signed re-key without certificate. Also fixes a double free after a failed self-decode check. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Reject re-key to a live epochDimitri Staessens2026-07-082-12/+177
| | | | | | | | A re-key epoch arrives from the peer, so we need to reject duplicates to avoid two batches sharing a wire epoch with different keys. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* build: Fix OpenSSL version check for PQCDimitri Staessens2026-07-089-12/+10
| | | | | | | | | ML-KEM, ML-DSA and SLH-DSA all landed in OpenSSL 3.5.0, not 3.4.0. ML-KEM+ML-DSA and SLH-DSA can be disabled by DISABLE_ML / DISABLE_SLH. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* build: Make re-key watermark configurableDimitri Staessens2026-06-292-51/+8
| | | | | | | | | | KEY_REKEY_WM_CHECK_BITS now controls the watermark check, once per 2^n flow writes (FLOW_WM_CHECK in dev.c). Now the configuration check (check watermark < outstanding packets) is contained in lib.cmake instead of assuming the value of FLOW_WM_CHECK. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Wipe unpacked session key after copyDimitri Staessens2026-06-291-0/+4
| | | | | | | | | | Zeroize the symmetric key in the unpacked IRM message once it has been copied into the crypt context, in both flow__irm_result_des and flow_rekey__irm_result_des, so key material does not linger in the protobuf buffer until it is freed. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>