aboutsummaryrefslogtreecommitdiffstats
path: root/link
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 07:44:50 +0100
committereunhhu <[email protected]>2026-09-29 07:44:50 +0100
commit6a72b5c8164ceb73994ab231a075cfb0ad1d7192 (patch)
tree9769d2d41a82f6b07adf07d4ab27906e6a53e7be /link
parented123556cf1c10369959fa96e1262050db63f7ce (diff)
downloadpure-6a72b5c8164ceb73994ab231a075cfb0ad1d7192.tar.gz
pure-6a72b5c8164ceb73994ab231a075cfb0ad1d7192.zip
Measure a link on a path of loss, reordering and a bottleneck (M6 harness)
020-lossy-paths/run.py runs each case in an unprivileged namespace: a 50 Mbit/s tbf bottleneck under netem's delay, jitter and loss, both ways. A link may send without UDP GSO (pure_link_gso), as netem takes a burst as one packet; quinn the same (QUIC_GSO=0). transport.c and the quinn harness give the records handed over in each 100 ms, and at a steady rate the time each took; TCP CUBIC flows run beside them.
Diffstat (limited to 'link')
-rw-r--r--link/link.c6
-rw-r--r--link/link.h4
2 files changed, 8 insertions, 2 deletions
diff --git a/link/link.c b/link/link.c
index 0588633..449ea60 100644
--- a/link/link.c
+++ b/link/link.c
@@ -112,7 +112,7 @@ struct PureLink {
size_t burst_size;
unsigned burst_count;
uint64_t burst_pn[BURST];
- bool gso;
+ bool gso, no_gso;
};
PureLink *pure_link_open(const char *url, const char *source, uint32_t shape, const PureSealKey *own,
@@ -148,6 +148,8 @@ PureLink *pure_link_open(const char *url, const char *source, uint32_t shape, co
return l;
}
+void pure_link_gso(PureLink *l, bool on) { l->no_gso = !on; }
+
void pure_link_peer(PureLink *l, const unsigned char peer[PURE_SEAL_KEY]) {
l->peered = true;
l->keyed = pure_link_sender_peer(l->sender, peer);
@@ -279,7 +281,7 @@ bool pure_link_start(PureLink *l, void (*notify)(void *), void *context, char *e
setsockopt(l->fd, SOL_SOCKET, SO_RCVBUF, &buffer, sizeof(buffer));
}
int segment = DATAGRAM;
- l->gso = ok && !setsockopt(l->fd, SOL_UDP, UDP_SEGMENT, &segment, sizeof(segment));
+ l->gso = ok && !l->no_gso && !setsockopt(l->fd, SOL_UDP, UDP_SEGMENT, &segment, sizeof(segment));
ok = ok && l->keyed && (l->burst = malloc((size_t)BURST * DATAGRAM)) && (l->taking = malloc(sizeof(*l->taking))) &&
(l->wake = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC)) >= 0;
l->notify = notify;
diff --git a/link/link.h b/link/link.h
index 5237262..afe1430 100644
--- a/link/link.h
+++ b/link/link.h
@@ -22,6 +22,10 @@ bool pure_link_queue(PureLink *, uint64_t seq, const unsigned char *bytes, size_
uint64_t pure_link_queued(PureLink *);
/* The last number the receiver saved; any thread. */
uint64_t pure_link_delivered(PureLink *);
+/* Packets go in bursts with UDP GSO where the system has it (at first);
+ * off, each in a call of its own: for a path whose queues take a burst as
+ * one packet (netem does). Before pure_link_start. */
+void pure_link_gso(PureLink *, bool on);
/* Send on a thread of the link's own, calling notify when more was saved. */
bool pure_link_start(PureLink *, void (*notify)(void *), void *context, char *error, size_t size);
void pure_link_counts(PureLink *, PureLinkCounts *);