<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/serve/link.h, 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-29T06:06:27Z</updated>
<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>Send a record whole when it fits a packet, however many pieces it has</title>
<updated>2026-09-29T04:11:01Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T04:11:01Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=41cbb5631fd12dc223738de65246af1a69761bea'/>
<id>urn:sha1:41cbb5631fd12dc223738de65246af1a69761bea</id>
<content type='text'>
A record over a piece (1,000 bytes) went in pieces even when it fit the
packet whole: a record of 1,013 bytes went as two RECORD frames, and the
receiver gathered it the slow way (an allocation, pieces, then onto the
line). A record none of whose pieces went yet now goes whole in a RECORDS
frame whenever it fits what is left of the packet; its pieces are marked
sent together. A record too large for a packet, or one resent after
some of its pieces were lost, still goes in pieces, and a receiver takes
a record whole or in pieces alike.

The transport alone takes 2.85 us a record of 1,013 bytes, not 3.18
(quinn: 3.90). transport.c now checks every record delivered: in order,
once each, its bytes as sent. None was wrong in a network namespace with
1 ms of delay, 3 % loss and 10 % reordering, with records of 61, 1,013
and 16,013 bytes.
</content>
</entry>
<entry>
<title>Send small records in a RECORDS frame: 1 or 2 bytes of framing each, not 19</title>
<updated>2026-09-28T19:12:38Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T19:12:38Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=fd95d3087733f025d5d796e6696c7698aa5d65d2'/>
<id>urn:sha1:fd95d3087733f025d5d796e6696c7698aa5d65d2</id>
<content type='text'>
A RECORD frame carries a number, a size, an offset and a length before
each record's bytes, 19 bytes: a packet held 13.7 records of 61 bytes. A
RECORDS frame (0x06) carries the first record's number and a count, then
whole records whose numbers follow on, each its size as a varint and its
bytes: 17.2 a packet. A piece of a record larger than a piece still goes
in a RECORD frame; a receiver takes both.

The transport alone (research/experiments/019-idle-links/transport.c)
drains 200,000 records of 61 bytes in 11,600 packets instead of 14,600;
per record the link takes 0.217 us and the listener 0.23, 0.447 us in all,
against quinn's 0.43 a message over one stream.
</content>
</entry>
<entry>
<title>Remember each sender's secret beside the node's key: no X25519 at restart</title>
<updated>2026-09-28T18:42:27Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T18:42:27Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=3308de49adfdb2a55c646e6b675da998f2c36900'/>
<id>urn:sha1:3308de49adfdb2a55c646e6b675da998f2c36900</id>
<content type='text'>
A listener lets a quiet sender's secret go with its active state, so a
node started again made one X25519 for every sender that came back (169
us on this Pi, most of a wake's CPU): asymmetric work in proportion to the
links, which design 011 counts as a reason to design again. The secret is
now remembered in a file beside the key (KEY.links, 0600, begun again for
another node's key): a place of 64 bytes a sender in the order allowed,
mapped, so a sender at rest takes no memory for it. A place is the first
28 bytes of the sender's key, a check (FNV-1a of the key and the secret)
and the secret, written secret first and key last; a place whose check
fails is made again. The UDP link checks see a receiver started again
make no X25519.
</content>
</entry>
<entry>
<title>Let a link at rest cost the listener only its allowing</title>
<updated>2026-09-28T18:16:39Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T18:16:39Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=09b754f2490dec5582ba79c9cde55b32bac12bcf'/>
<id>urn:sha1:09b754f2490dec5582ba79c9cde55b32bac12bcf</id>
<content type='text'>
A sender allowed is now a peer of 48 bytes (its key, its key's id, its
sources), found through an index by key id; ids are 32 bits, so keys that
share one are each tried. What a sending peer needs besides (the secret
its key shares with the node's, its runs' keys and addresses, its
streams) is made at its first packet and let go once it has been quiet
for the idle period (--link-idle-ms, 30 s at first) with nothing of it
waiting: the next packet makes it again, one X25519, no handshake. The
listener hands over and answers only the streams and runs that changed,
not every one at each turn. --senders FILE allows senders a line each.

The UDP link checks take their sender from such a file among a thousand
others, let it go after 400 ms of quiet, and see an order after a longer
pause arrive all the same.
</content>
</entry>
<entry>
<title>Link two nodes without a connection over UDP (093, design 011's first stage)</title>
<updated>2026-09-28T16:37:41Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T16:37:41Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=745efcd4f19b59bcfb131df2d127a3387a544e84'/>
<id>urn:sha1:745efcd4f19b59bcfb131df2d127a3387a544e84</id>
<content type='text'>
pure-serve --send OUTPUT=pure://host:port/INPUT sends an output's saved
sends to another node's --link-port with no handshake: the first packet
carries records. Keys come from the two nodes' keys (X25519, HKDF-SHA256,
AES-128-GCM), with a random run in each packet's header so no nonce
repeats across restarts; nothing is stored for them. What lasts is the
apps' own: the sender's outbox and the receiver's heard numbers
(pure_app_heard, new). The sender detects losses as RFC 9002 says, with
NewReno, and trims a send once the receiver says it stored it; the
receiver hands the owner whole records in order, which it applies from
the one after the source's last heard number, stopping at a gap, and
answers how far it stored with every acknowledgment. Stored bytes are
the bytes on the wire: an output and an input of one shape need no JSON.

server_links_udp kills the receiver, the sender, then both (-9) while
four clients buy: every saved order is applied once, with no handshake
(five runs, 10k-11k orders each). server_links_udp_lossy does it again in
a namespace of its own with the link's packets delayed, lost (3 %) and
reordered (10 %) by netem (three runs, 11k-12k orders).
</content>
</entry>
</feed>
