From 3308de49adfdb2a55c646e6b675da998f2c36900 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 28 Sep 2026 19:42:27 +0100 Subject: Remember each sender's secret beside the node's key: no X25519 at restart 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. --- serve/serve.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'serve/serve.c') diff --git a/serve/serve.c b/serve/serve.c index 5309f02..93406fd 100644 --- a/serve/serve.c +++ b/serve/serve.c @@ -2662,6 +2662,9 @@ int main(int argc, char **argv) { for (unsigned i = 0; allowed && i < sender_count; ++i) allowed = pure_link_allow(link_listener, senders[i].name, senders[i].key, error, sizeof(error)); if (allowed && link_idle_ms) pure_link_idle(link_listener, link_idle_ms); + char memo[4096]; + snprintf(memo, sizeof(memo), "%s.links", key_path); /* beside the key the secrets come from */ + allowed = allowed && pure_link_remember(link_listener, memo, error, sizeof(error)); if (!allowed || !pure_link_serve(link_listener, error, sizeof(error))) { fprintf(stderr, "--link-port: %s\n", error); return 2; @@ -2736,11 +2739,12 @@ int main(int argc, char **argv) { ",\"link_packets\":%" PRIu64 ",\"link_records\":%" PRIu64 ",\"link_resent\":%" PRIu64 ",\"link_lost\":%" PRIu64 ",\"link_acknowledged\":%" PRIu64 ",\"link_stored\":%" PRIu64 ",\"listener_packets\":%" PRIu64 ",\"listener_received\":%" PRIu64 ",\"listener_deliveries\":%" PRIu64 - ",\"listener_woken\":%" PRIu64 ",\"listener_swept\":%" PRIu64 ",\"listener_active\":%" PRIu64 "}\n", + ",\"listener_woken\":%" PRIu64 ",\"listener_remembered\":%" PRIu64 ",\"listener_swept\":%" PRIu64 + ",\"listener_active\":%" PRIu64 "}\n", active, retained, accepted, requests, bursts, events, ticks, expired, threads, owned ? "true" : "false", owner.executor.publications, shown, delivered, attempts, owner.executor.answers, groups, grouped, checkpoints, sent.packets, sent.records, sent.resent, sent.lost, sent.acknowledged, sent.stored, - heard.packets, heard.received, heard.deliveries, heard.woken, heard.swept, heard.active); + heard.packets, heard.received, heard.deliveries, heard.woken, heard.remembered, heard.swept, heard.active); free(hosts); free(thread); return 0; -- cgit v1.2.3