aboutsummaryrefslogtreecommitdiffstats
path: root/link
Commit message (Collapse)AuthorAgeFilesLines
* Pace a link's packets, and keep Reno's pace by time as well as by ↵eunhhu2026-09-291-0/+30
| | | | | | | | | | | | | | | | acknowledgments Packets go at the window an RTT, a quarter more (twice in slow start), up to 2 ms of it at once (10 to 256 datagrams, RFC 9002 7.7); the sender says when the next may go. The Reno-friendly estimate grows by the acknowledgments (RFC 9438) or by time (RFC 8312), whichever is ahead, so a link its app holds back to a few records a second does not fall behind it. In the M6 simulator (RTT 100 ms, 5% loss, 50 records a second) the median time a record takes falls from 134 to 51-71 ms and the p99 from about 900 to 290-350 ms; a backlog with 1% loss at RTT 20 ms goes at 8.3 Mbit/s. The transport's CPU a record is unchanged.
* Find how large a packet the path carries: 1,452 bytes once a probe is ↵eunhhu2026-09-294-40/+114
| | | | | | | | | | | | | | | acknowledged A link starts at 1,200 bytes; once an RTT is known it sends a PING padded to 1,452 (DPLPMTUD, RFC 8899), alone and with the don't-fragment bit, and uses that size once it is acknowledged. A probe lost is no congestion; it is tried again a second on, three times, then ten minutes on. GSO is asked for each burst (a control message), not the socket, so a packet sent alone is never cut. CUBIC counts in the datagram. On loopback packets fall by 19-27%; the CPU a record falls 13% at 1 KiB and 7% at 16 KiB; in the simulator of a 50 Mbit/s path with 1% loss the goodput rises from 6.1 to 7.0 Mbit/s (5%: 2.3 to 3.0).
* Send a record in parts cut where a packet is full, not 1000-byte pieceseunhhu2026-09-292-129/+246
| | | | | | | | | A record that does not fit what is left of a packet goes in part when at least 64 bytes fit; its parts keep their cuts, so what a packet carried is whole parts. The receiver keeps the spans it had of a record, and a record coming in order from its start fills the line's tail with no allocation. Packets fall by 8% for 1 KiB records and 10% for 16 KiB; the CPU a record is the same at 61 B and 1 KiB and 5% less at 16 KiB.
* Measure a link on a path of loss, reordering and a bottleneck (M6 harness)eunhhu2026-09-292-2/+8
| | | | | | | | | 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.
* Wait for late packets, undo what they cost, and grow as CUBICeunhhu2026-09-292-12/+145
| | | | | | | | | | | | | | | A packet called lost stays known a while; acknowledged after all, it came late: what it carried counts as received, the reordering awaited grows (later packets acknowledged, and time past the RTT, as RACK), and an episode of congestion events whose losses all came late is undone. The window grows only when it was used (RFC 9002 7.8), and congestion avoidance is CUBIC (RFC 9438), as quinn's. In a path of 50 Mbit/s whose packets reorder by up to 5 ms, with no loss, a link carried 1.5 Mbit/s at an RTT of 20 ms and 10 at 100 ms; now 43.6 and 40.1, as without reordering (research/experiments/020-lossy-paths, virtual time). With 1% random loss: 4.9 to 6.1 at 20 ms, 1.0 to 1.3 at 100 ms. The transport's CPU a record is unchanged.
* Make the load generator's devices real link senders, many on one threadeunhhu2026-09-292-4/+17
| | | | | | | | | | links.c was a second implementation of the packet format; each device is now a PureLinkSender on a socket of its own, keyed with a secret made outside (pure_link_sender_shared: a key kept elsewhere, or a test's many). M1 (1k, 10k) and M2 (10k, kill -9) pass with it: no silent step, caught up in 0.2 s, every order applied once; the slowest store after the restart is now the sender's 1 s wait for a word of the save (STORED_WAIT), where the old devices tried again after 200 ms.
* Keep a link's two sides as state alone, the sockets and threads aparteunhhu2026-09-295-1541/+2033
| | | | | | | | | | | | link/link-protocol.h is the protocol with no socket, thread or clock of its own: packets and time in, packets out. link/link.h carries it over UDP as before. A sender starts small (8 flights, 16 records, a 4 KiB ring) so one thread can hold many. The transport's CPU a record is the same within 2% (five rounds each way, 61 B to 16 KiB). test-link runs both sides through a network of its own: loss, packets held back and doubled, failed saves, an idle sweep, and both sides starting again, every record applied once as sent.
* Let links know nothing of the core: the host names inputs and shapeseunhhu2026-09-292-91/+67
| | | | | | A sender takes its messages' shape, and a listener asks its host which input a stream goes to. The core gives the shape (pure_module_shape); link/ now builds without the core's headers.
* Put the links and the crypto they use in link/, a part of their owneunhhu2026-09-297-0/+2578
libpure-link.a holds them; pure-serve and the M5 harness link it instead of naming its source files.