summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* lib: Fix RTO update on timeoutDimitri Staessens2022-04-033-12/+9
| | | | | | | | | | | | | This fixes the RTO doubling on timeout according to Karn/Partridge. Exponentially increasing RTO when it times out (e.g. doubling) fixes the problem that a sudden increase in real RTT starves the sRTT updates by never getting out of backoff as retransmitted packets can't update RTT. Added an parameter to make it less aggressive, default is doubling. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Remove timerwheel from instanceDimitri Staessens2022-04-031-2/+0
| | | | | | | | There was an unused struct timerwheel * lingering in the application instance. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* build: Update copyright to 2022Dimitri Staessens2022-04-03165-165/+165
| | | | | | | Growing pains. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix delayed ACK under high loadDimitri Staessens2022-04-031-3/+9
| | | | | | | | | | The delayed ACK was wrongly measuring the delay against the receiver activity instead of the sender activity. Also fixed receiver activity not being updated for non-data packets (and duplicates and other dropped traffic). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Add support for Linux RTT estimatorDimitri Staessens2022-04-033-2/+13
| | | | | | | | | | | | | This adds the option to use the Round-Trip-Time (RTT) estimation algorithm as it is implemented in the TCP implementation in Linux. It looks like it outperforms the TCP default algorithm, so I enabled this one by default. Also adds the option to change the RTO timeout calculation to include more (or less) than 4 times the mdev (specified as a power of 2. Left the default value to 2 (so, 4 mdevs), but 3 (8 mdevs) gives better results in my tests. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix fqueue_next handling of deallocated flowsDimitri Staessens2022-04-012-3/+8
| | | | | | | | | If a flow was deallocated while there were still unprocessed events in an fqueue, it would cause a SEGV in fqueue_next because it was not checking the validity of the returned flow descriptor. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix timing of delayed ACKsDimitri Staessens2022-04-012-7/+26
| | | | | | | | | | Delayed ACKs are now sent after twice the internal tick time. Fixes initial ACK record (rcv_cr.seqno) being uninitialized (0) when the first ACK was to be sent. Adds some FRCT metrics for number of received delayed (bare) ACKs and the RTT estimator. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Use struct portevent internallyDimitri Staessens2022-03-302-22/+26
| | | | | | | | The fqueues were relying on the fact that the portevent were two integers. This cleans that up a bit. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix use-after-free of recv_msgDimitri Staessens2022-03-301-10/+7
| | | | | | | The protobuf message was free'd before usage in flow_init. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Fix SEGV in oping with missing param valuesDimitri Staessens2022-03-301-12/+18
| | | | | | | If not passed a value for the last parameter, oping would SEGV. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix unidirectional FRCT traffic handlingDimitri Staessens2022-03-302-9/+9
| | | | | | | | | | | | | Unidirectional traffic has one of the peers only send bare FRCT packets. These never set a DRF, since they have no sequence number. At the receiver, all these ACKs and window updates were always dropped as the receiver connection record was timed out. Also fixes a SEGV if flow control kicks in (passing NULL timeout to pthread_cond_timedwait). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Move incoming FRCT handling to own threadDimitri Staessens2022-03-301-24/+67
| | | | | | | | | | | | | | | | The application will now handle incoming FRCT packets even if the application never reads data from the flow (for instance servers). To do this, it reserves an fset_t (id 0). When an FRCT-enabled flow is created, it is automatically added to this fset. An rx thread will listen for incoming events and perform necessary actions on the flow if needed. If the FRCT flow is added to another user fset, it will be handled by that user fset (and if the flow is removed from a user fset, it will be re-added to the set with id 0 to be handled by the rx_flow thread. The flow monitoring is handled by the same thread, replacing the previous monitoring thread. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Iterate over monitored flowsDimitri Staessens2022-03-301-49/+49
| | | | | | | | | | Now the instance keeps all flows for an application in a linked list to easily iterate over all allocated flows, which is needed by the keepalive monitoring. This is more efficient that tracking min and max fd. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Remove flows list from fsetDimitri Staessens2022-03-301-62/+2
| | | | | | | We don't need to iterate fsets anymore since the removal of fset_keepalive. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix filtering encrypted packetsDimitri Staessens2022-03-302-54/+54
| | | | | | | | | | | | The frcti_filter was reading raw data from the buffers, causing the frcti_rcv to operate directly on encrypted packets. It decrypt and filter for invalid packets. I moved the function from frct to the fqueue implementation and renamed it fqueue_filter as it filters fqueues. Should be extended to filter out keepalives on non-FRCT flows, as these will now still cause spurious wakeups. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Move flow monitoring to its own threadDimitri Staessens2022-03-301-174/+130
| | | | | | | | | This adds a monitoring thread to handle flow keepalive management in the application and removes the thread interruptions to schedule FRCT calls within the regular IPC calls. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Add np1_flow_read and np1_flow_write callsDimitri Staessens2022-03-308-30/+119
| | | | | | | | | | | | | | | | Reading/writing to (N + 1)-flows from the IPCP was using a raw QoS flow to bypass some functions in the ipcp_flow_read call. But this call was broken for keepalive packets. Fixing the ipcp_flow_read call for (N - 1) flows causes the IPCPs to drop 0-byte keepalive packets coming from (N + 1) client flows. >From now on, there is a dedicated call for (N + 1) reads/writes from the IPCPs that's more efficient and cleaner. The (N + 1) flow internal QoS is now also defaulted to a qos_np1 qosspec, instead of tampering with the qosspec requested by the (N + 1) client. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Add rbuff support for FLOWPEER stateDimitri Staessens2022-03-302-15/+32
| | | | | | | | This allows setting the FLOWPEER state on a flow to signal a peer is unresponsive. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Move timerwheel processing to its own threadDimitri Staessens2022-03-303-27/+34
| | | | | | | | | | | | | | | This is the first step moving away from scheduling the FRCT and flow monitoring functions as part of the IPC calls (flow_read / flow_write / fevent) and towards the more scalable (and far less complicated) implementation to take care of these functions in separate threads. If a process creates the first flow that requires FRCT, it will spin up a thread to process events on the timerwheel (retransmissions and delayed ACKs). This single thread lives until the last flow with FRCT is deallocated. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Create FRCT instance when initializing flowDimitri Staessens2022-03-301-59/+46
| | | | | | | | The creation of FRCT instances (if needed) is now part of flow_init() call instead of an addition after the flow is initialized. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Refactor writing to rbuffDimitri Staessens2022-03-301-69/+57
| | | | | | | | Writing valid packets to the rbuff (add crc check, encrypt) is now extracted into a function. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Remove prog name and pid from instanceDimitri Staessens2022-03-301-25/+10
| | | | | | | | Prog name is not used anymore, probably a remnant from the early days, when we were passing rina_name_t tuples all over the place. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Refactor reading packet from rbuffDimitri Staessens2022-03-3011-80/+97
| | | | | | | | | | | | Reading packets from the rbuff and checking their validity (non-zero size, pass crc check, pass decryption) is now extracted into a function. Also adds a function to get the length of an sdu_du_buff instead of subtracting the tail and head pointers. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Notify once for packets in new fsetDimitri Staessens2022-03-301-4/+1
| | | | | | | | The fset add function was notifying for each packet already stored in the rx rbuff, which isn't needed. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Support --quiet option for oping serverDimitri Staessens2022-03-302-2/+6
| | | | | | | | The oping server will not print receiving packets when the --quiet (-Q) flag is passed, like the client. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Non-configurable delayed acks in FRCPDimitri Staessens2022-03-304-30/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It doesn't really make sense to manually and one-sidedly configure the timeout of delayed acknowledgements, as setting it too high upsets the peer's sRTT estimates. Even worse, it also causes a lot of spurious retransmissions if it exceeds the sRTT mean deviation calculated by the receiver. Compensating on bare acknowledgment for the ack delay could improve the RTT estimate deviation, but not the spurious retransmissions if it was set too high. This sets the delayed ack to wait for a single RTT mean deviation. Probably needs more tweaking to further reduce differences between the RTT estimates at the sender and receiver, e.g. compensate the RTT estimate for delayed acks, or increase the RTO to add 8 mdevs to sRTT instead of 4. However, it looks like the mdev estimate is the trickiest one to get to sync, not the RTT average. Linux reduces the sample weight for mdev from 1/4 to 1/32 in some cases, will give that a shot some day too to see if that further align sRTT estimates. In any case, this patch already improves things a lot. Also fixes a bug where the sender was sending acknowlegments on the first packets in flight for the 0 sequence number. The receiver activity was measured in seconds but compared to a timeout value in nanoseconds. There's still a lot of spurious retransmissions that start after actual packet loss occurs, I'm still investigating what causes it. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Expose flow control metrics to RIB0.19.1Dimitri Staessens2022-03-162-14/+48
| | | | | | | | | | This exposes some additional metrics relating to FRCT / Flow control: the number of duplicate packets received, number of packets received out of the flow control window and / or reordering queue, and the number of rendez-vous messages sent. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix retransmission schedulingDimitri Staessens2022-03-161-72/+60
| | | | | | | | | | | | | There still were a couple of bugs in the timerwheel. If the future schedule was coinciding with the slot currently being processed (i.e. exactly RXMQ_SLOTS in the future), the list_add_tail caused an infinite loop. Another bug was causing the slots at higher levels to be processed too soon. Retransmissions should now schedule correctly. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix buffer allocation when retransmitting0.19.0Dimitri Staessens2022-03-115-18/+50
| | | | | | | | | | | | | | | The timerwheel was retransmitting packets and the error check for negative values of the rbuff allocation was instead checking for non-zero values, causing a buffer allocation to succeed but the program to continue down the unhappy path leaving that packet stuck in the buffer unattended. Also fixes wrongly scheduled retransmissions that cause packet storms. FRCP is much more stable now. Still needs some work for high bandwidth-delay products (fast-retransmit). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix memcpy with NULL in piggyback APIDimitri Staessens2022-03-084-9/+17
| | | | | | | | If there is no piggyback data, memcpy was passed a NULL pointer in memcpy(buf, NULL, 0) calls, which is undefined behaviour. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Refactor kad_req_createDimitri Staessens2022-03-081-20/+25
| | | | | | | A small refactor of the kad_req_create function's cleanup code. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipdpd: Pass MPL to application at flow_allocationDimitri Staessens2022-03-0817-24/+88
| | | | | | | | | | | | The maximum packet lifetime (MPL) is a property of the flow that needs to be passed to the reliable transmission protocol (FRCP) for its correct operation. Previously, the value of MPL was set fixed as one of the (fixed) Delta-t parameters. This patch makes the MPL a property of the layer, and it can now be set per layer-type at build time. This is a step towards a proper MPL estimator in the flow allocator. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Pass Delta-t params to frcti_create()Dimitri Staessens2022-03-082-9/+9
| | | | | | | | | The parameters were set directly from the build configs. A first step to making FRCP configurable at runtime, is to pass the parameters to the frcti_create() function. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix RTT estimator invocation in FRCTDimitri Staessens2022-03-031-1/+1
| | | | | | | The notorious off-by-one hit again. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix underflow in keepalive timerDimitri Staessens2022-03-031-1/+1
| | | | | | | If the keepalive would underflow if set to 1-3 ms. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Flag all flows down as the IRMd exitsDimitri Staessens2022-03-034-14/+28
| | | | | | | | | | | | | | On exit of the IRMd all flows will now be flagged as down, so external applications will not hang anymore. Note: reads keep work from flows that are down until there are no more remaining packets in the buffer, but no more packets can be written. When the RIB is used, the external application may exit a bit later than the IRMd, so I added a brief sleep before the IRMd tries to remove the fuse main directory. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Fix lock reversal in timerwheelDimitri Staessens2022-03-031-5/+0
| | | | | | | | | There was a lock reversal in the timerwheel. There still is a thorough revision needed of the locking in dev.c after the FRCP logic is completed and tuned. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd, ipcp: Remove socket option in acceptloopDimitri Staessens2022-03-032-14/+3
| | | | | | | | | | | | | We cancel the thread, so the SO_RCVTIMEO is not needed anymore (it dated from when we checked the state every so often. The address sanitizer is complaining about the the cleanup handlers in the acceptloops after the thread gets cancelled in the read(). I've tried to resolve it, but no avail. Pretty convinced it's a false-positive, so ASan will ignore these functions for now. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Cleanup RIB mount nameDimitri Staessens2022-03-031-1/+3
| | | | | | | | | | IPCPs would call rib_fini() twice, once after cleaning up their managed RIB, and once again for the program-generic RIB, which is not initialized for IPCPs. rib_fini() checked if the mount name was valid, but it didn't unset it after execution. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Check return value of rib_initDimitri Staessens2022-03-031-1/+6
| | | | | | | The rib_init return value wasn't checked. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Encrypt bare FRCP messages on encrypted flowsDimitri Staessens2022-03-033-44/+29
| | | | | | | | Bare FRCP messages (ACKs without data, Rendez-vous packets) were not encrypted on encrypted flows, causing the receiver to fail decryption. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Make flow liveness timeout configurableDimitri Staessens2022-03-037-31/+70
| | | | | | | | | 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 <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Fix return value on error in ocbrDimitri Staessens2022-03-031-3/+8
| | | | | | | The ocbr tool was returning 0 on error. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* tools: Fix signed/unsigned mismatch in irm_enrollDimitri Staessens2022-03-031-31/+30
| | | | | | | The irm_list_ipcps function can return negative values. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Remove dead code in timerwheelDimitri Staessens2022-03-031-6/+0
| | | | | | | The checked condition can't happen. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* irmd: Fix memory leak of ret_msgDimitri Staessens2022-03-032-2/+2
| | | | | | | | The ret_msg variable can leak in the main loop of the irmd in this failure path. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix some unchecked return valuesDimitri Staessens2022-03-034-24/+45
| | | | | | | Fixes some unchecked and wrongly checked return values. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Add initial flow liveness monitoringDimitri Staessens2022-02-243-23/+163
| | | | | | | | | | | | | | | | | | This adds flow liveness monitoring for flows, with a fixed timeout of 120s. I will make it configurable at flow allocation later on (timeout needs to be communicated to the peer). If one peer dies, or doesn't call any IPC calls (flow_write/flow_read/fevent) it will stop sending keepalives and the other peer's read/writes will error on an -EFLOWDOWN after the timeout expires. Packets without a payload (0 length packets) are interpreted as keepalive packets for the flow. They can be sent from any application, but they will not trigger a message read at the receiver side (0 as a return value on flow_read indicates a previous partial read has completed at exactly the buffer size). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* lib: Maintain a list of flows in flow_setDimitri Staessens2022-02-241-26/+99
| | | | | | | | | The flow_set will now keep a list of the flows in the set, this makes it more efficient to iterate over the flows. Extending the public API for fset_t with an iterator will also be useful. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
* ipcpd: Fix potential double unlock in ethDimitri Staessens2022-02-211-23/+15
| | | | | | | | | When handling management frames, there was a cancellation point after the unlock, which would cause the cleanup handler to attempt a double unlock if the thread was cancelled at that point. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>