diff options
Diffstat (limited to 'src/mpu.h')
| -rw-r--r-- | src/mpu.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/mpu.h b/src/mpu.h new file mode 100644 index 0000000..da41a25 --- /dev/null +++ b/src/mpu.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#pragma once + +#include "heap.h" + +#include <netinet/in.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +// +// A two-path UDP tunnel implementation. +// +// The tunnel uses two physical paths to transmit packets to the same destination. +// +// Sent packets are assigned a sequence number and transmitted through one of the +// two paths according to a weighted round-robin scheduler. +// +// On the receiving end, packets are buffered in a reorder buffer and a best effort is made +// to deliver packets in order. +// + +#define MPU_MTU (1500U - 20 - 8) //!< Maximum payload size for traditional IP/UDP headers + +typedef struct { + int sockfd; + float weight; +} mpu_path_t; //!< Physical path for packet transmission + +typedef struct { + uint64_t seq_num; +} mpu_hdr_t; //!< Tunnel packet header + +typedef struct { + uint64_t timestamp; // in milliseconds + uint16_t packet_len; + union { + uint8_t buf[MPU_MTU]; + mpu_hdr_t hdr; + } packet; +} mpu_slot_t; //!< Packet slot for reorder buffer + +typedef struct { + mpu_path_t paths[2]; + + // Weighted round-robin scheduler state + float credits[2]; + uint64_t send_seq_num; + + // Reorder buffer + uint64_t recv_seq_num; + int reorder_window; // in milliseconds + heap_t reorder_heap; +} mpu_ctx_t; + +/// Initialize MPU context with two physical paths +/// Returns 0 on success, -1 on failure (errno is set). +int mpu_init(mpu_ctx_t* ctx, + int sock0, float weight0, + int sock1, float weight1, + int reorder_window, // in milliseconds + size_t reorder_slots); + +/// Send a packet through the tunnel. Packet must not exceed MPU_MTU - sizeof(mpu_hdr_t). +/// Returns 0 on success, -1 on failure (errno is set). +int mpu_send(mpu_ctx_t* ctx, const uint8_t* data, size_t len); + +/// Receive a packet from the tunnel, blocking until one is available. +/// Returns the length of the received data, or -1 on failure (errno is set). +ssize_t mpu_recv(mpu_ctx_t* ctx, uint8_t* data, size_t len); |
