<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/research/experiments/019-idle-links/links.c, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-09-29T14:17:40Z</updated>
<entry>
<title>Move M2's node to another machine under load (M3's harness)</title>
<updated>2026-09-29T14:17:40Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T14:17:40Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=088f85ed72b61e879964a4cba6a0c0faa135facb'/>
<id>urn:sha1:088f85ed72b61e879964a4cba6a0c0faa135facb</id>
<content type='text'>
run.py --restart --move runs in namespaces of its own (unshare -rmn: a
network and an /etc/hosts): the devices send to receiver.test, which
names 127.0.0.2; at --kill-at the node is killed, its store, key and
memo copied elsewhere, 127.0.0.2 made unreachable, the name pointed at
127.0.0.3, and the copy started there. The load generator's devices
look for the node again as link/link.c does: after three probes in a
row unanswered, or a send the system said had no way there.
</content>
</entry>
<entry>
<title>Move a link to a new epoch now and then, so keys that leak later open nothing past</title>
<updated>2026-09-29T12:58:06Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T12:57:58Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=9791a1e70979ee4ba832851912f0de20301343a8'/>
<id>urn:sha1:9791a1e70979ee4ba832851912f0de20301343a8</id>
<content type='text'>
A sender offers the public half of a pair made for the next epoch
(OFFER) until the receiver accepts with a half of its own (ACCEPT); their
X25519 and the epoch's secret make the next one's, and the private
halves go. The header's low four bits say a packet's epoch; epoch 0 is
the nodes' static secret, as the keys were. The first epoch is offered in
the run's first packet (it begins with the first answer when the
receiver is not busy), then one an hour or GiB. One who later has both
nodes' keys opens only epoch 0, and no record went there after an epoch
began: test-link tries every packet sent under the static keys, with
epochs a second long, loss, reordering, restarts and replays.

The receiver writes the epoch it accepted in its memo (a place is 256
bytes now), so it goes on without an X25519 when it starts again; one
that forgot is not heard from, and its senders, after 2 s and four
probes unanswered, offer again in epoch 0 with no records until an epoch
begins. Keys of four epochs are tried (accepted, now, before, zero), as
two may share the four bits.

An accept costs an X25519 on each side, 220 µs on this Pi: one of a
sender with records costs a token (256 a second, 8 at once) and the
next packet offers again when there is none; one of a sender with
nothing else to send waits for none, one a second for it. The X25519 is
made after the turn's answers, never between a packet and its answer.
serve's report and M2's generator count keys, X25519s and epochs.
</content>
</entry>
<entry>
<title>Give M2's devices a timer each, and say when the slow records were made</title>
<updated>2026-09-29T12:55:35Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T12:55:35Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=e680e67dc99c33cfaa3152613bddf3742263e385'/>
<id>urn:sha1:e680e67dc99c33cfaa3152613bddf3742263e385</id>
<content type='text'>
The load generator asked all ten thousand senders for their timers every
5 ms: 83 % of its CPU (47 ns a sender, mostly cache misses), and records
were timed from the start of that pass, so the pass (0.75-0.94 ms, longer
as the sender grew) was the floor of every latency it measured. A device
now keeps its sender's next timer, asked again only when the sender is
touched (the only time it changes), and the p50 of M2 falls from 0.8 to
0.4 ms for every version alike. It also says the p50 and p99 of the
records made in each second, and the keys and X25519s its senders made.
</content>
</entry>
<entry>
<title>Find how large a packet the path carries: 1,452 bytes once a probe is acknowledged</title>
<updated>2026-09-29T08:27:49Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T08:27:49Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=f26f5fbd0a487a9a2848f819361b4e6fdd7a9cb1'/>
<id>urn:sha1:f26f5fbd0a487a9a2848f819361b4e6fdd7a9cb1</id>
<content type='text'>
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).
</content>
</entry>
<entry>
<title>Make the load generator's devices real link senders, many on one thread</title>
<updated>2026-09-29T06:22:19Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T06:22:19Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=5dbf6a536627f9a29f7358c547426218aa6f23c1'/>
<id>urn:sha1:5dbf6a536627f9a29f7358c547426218aa6f23c1</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Put the links and the crypto they use in link/, a part of their own</title>
<updated>2026-09-29T06:06:27Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T06:06:27Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=a052b95c8135cdc5f9b91f8efc991cac80fbbe8b'/>
<id>urn:sha1:a052b95c8135cdc5f9b91f8efc991cac80fbbe8b</id>
<content type='text'>
libpure-link.a holds them; pure-serve and the M5 harness link it instead
of naming its source files.
</content>
</entry>
<entry>
<title>Measure a link at rest: 132 bytes against a QUIC connection's 38,106 (094)</title>
<updated>2026-09-28T18:41:08Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T18:41:08Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=63cc9554f2cd93e46d0413a21cbce05014e2f2b3'/>
<id>urn:sha1:63cc9554f2cd93e46d0413a21cbce05014e2f2b3</id>
<content type='text'>
M1 of design 011. A Pure node allows 1,000 to 1,000,000 senders; each
sends one order and, once told it is stored, rests. At rest a link costs
the node 132 bytes (the sender allowed, 73; its number heard, about 60)
and no transport state; with a million the node runs in 139 MB. A quinn
0.11 service holding the same exchange's clients connected at rest costs
38,106 bytes a connection: 289 times as much, past the design's 1/100.
A link at rest takes its next record in 0.56 ms to stored, one X25519 on
the node included; a new QUIC connection takes 1.06 ms and 2.8 times the
receiver's CPU, without storing.

research/experiments/019-idle-links: links.c, many senders written from
serve/link.h's packet format alone (a second implementation), and the
quinn service and clients (quic/, built offline); run.py makes both
measurements.
</content>
</entry>
</feed>
