summaryrefslogtreecommitdiff
path: root/src/mpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mpu.h')
-rw-r--r--src/mpu.h71
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);