OverviewFilesCommitsIssuesDocsReleasesPeers

hyperswarm-peer commits / af54824

swarmd: HELLO answered with two zeroes and a comment saying someone else would fill them
res->client_id = 0; // filled by the caller, which knows it memset(res->daemon_pubkey, 0, 32); // no transport attached yet Nobody filled them, and the transport was attached. §5 of the design says the HELLO reply carries {client_id, daemon_pubkey}; §7 item 4 says client ids exist so a client can suppress its OWN echo once messages carry an origin. A client that cannot learn its own id cannot tell its own traffic from a peer's, and a zeroed key tells it nothing about which daemon it reached. Control already had the client id in its dispatch context. The daemon's key is now kept when the keypair is made and handed over through the backend. ⚠ That key identifies this RUN of the daemon, not this machine: it is generated per start. A stored seed is §7 item 5 and is not built — so the value is truthful and not yet stable, and this commit does not pretend otherwise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
af54824882c08da7e714f9bf56a8d02c50887d79
by plankatron <fleeky@gmail.com> · 2026-09-10T22:07:35.000Z

Changed files (4) +19 -2

swarmd/src/control.cpp +9 -2
……@@ -31,8 +31,15 @@ static int on_hello(void *vctx, const swarmd_hello_request_t *req,
3131 ctx->session->hello = true;
3232 (*ctx->hellos)++;
3333
34 res->client_id = 0; // filled by the caller, which knows it
35 memset(res->daemon_pubkey, 0, 32); // no transport attached yet
34 // ⛔ THESE ARE WHAT HELLO IS FOR. §5 says the reply carries {client_id,
35 // daemon_pubkey}; §7 item 4 says client ids exist so a client can suppress
36 // its OWN echo once messages carry an origin. Both were zero — a placeholder
37 // with a comment saying someone else would fill it, and nobody did. A client
38 // that cannot learn its own id cannot tell its own traffic from a peer's,
39 // and a zeroed key tells it nothing about which daemon it reached.
40 res->client_id = *ctx->client_id;
41 memset(res->daemon_pubkey, 0, 32);
42 if (ctx->backend->daemon_pubkey) ctx->backend->daemon_pubkey(res->daemon_pubkey);
3643 return 0;
3744}
3845
swarmd/src/control.h +5 -0
……@@ -43,6 +43,11 @@ struct ControlBackend {
4343 std::function<bool(uint64_t handle, uint32_t slot, uint64_t target,
4444 const uint8_t *data, size_t len, bool *writable)> send;
4545
46 // The daemon's own transport key, for HELLO. ⚠ It is generated per start
47 // today — a stored seed is §7 item 5 and is not built — so it identifies
48 // this RUN of the daemon, not this machine.
49 std::function<void(uint8_t out[32])> daemon_pubkey;
50
4651 // Content. The hash is 32 raw bytes on the wire; liboverlay speaks hex, and
4752 // the conversion belongs on the daemon side of this seam, not in the codec.
4853 std::function<bool(const std::string &path, uint8_t out_hash[32])> content_hash;
swarmd/src/daemon.cpp +3 -0
……@@ -149,6 +149,8 @@ bool Daemon::start(const char *socket_path, const char *bootstrap,
149149 return true;
150150 };
151151
152 backend.daemon_pubkey = [this](uint8_t out[32]) { memcpy(out, _pubkey, 32); };
153
152154 _control.attach(&_uds, backend);
153155
154156 // Peer lifecycle arrives on the UDX thread. Enqueue only.
……@@ -189,6 +191,7 @@ bool Daemon::start(const char *socket_path, const char *bootstrap,
189191 });
190192
191193 Ed25519KeyPair kp = NoiseIK::generate_keypair();
194 memcpy(_pubkey, kp.public_key, 32);
192195 if (bootstrap) {
193196 const char *bs[1] = { bootstrap };
194197 _t.start_dht(kp, bs, 1);
swarmd/src/daemon.h +2 -0
……@@ -114,6 +114,8 @@ private:
114114
115115 bool _started = false;
116116 std::string _socket_path;
117 // ⚠ Generated per start; see ControlBackend::daemon_pubkey.
118 uint8_t _pubkey[32] = { 0 };
117119};
118120
119121} // namespace swarmd