| … | … | @@ -31,8 +31,15 @@ static int on_hello(void *vctx, const swarmd_hello_request_t *req, |
| 31 | 31 | ctx->session->hello = true; |
| 32 | 32 | (*ctx->hellos)++; |
| 33 | 33 | |
| 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); | |
| 36 | 43 | return 0; |
| 37 | 44 | } |
| 38 | 45 |
| … | … | @@ -43,6 +43,11 @@ struct ControlBackend { |
| 43 | 43 | std::function<bool(uint64_t handle, uint32_t slot, uint64_t target, |
| 44 | 44 | const uint8_t *data, size_t len, bool *writable)> send; |
| 45 | 45 | |
| 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 | ||
| 46 | 51 | // Content. The hash is 32 raw bytes on the wire; liboverlay speaks hex, and |
| 47 | 52 | // the conversion belongs on the daemon side of this seam, not in the codec. |
| 48 | 53 | std::function<bool(const std::string &path, uint8_t out_hash[32])> content_hash; |
| … | … | @@ -149,6 +149,8 @@ bool Daemon::start(const char *socket_path, const char *bootstrap, |
| 149 | 149 | return true; |
| 150 | 150 | }; |
| 151 | 151 | |
| 152 | backend.daemon_pubkey = [this](uint8_t out[32]) { memcpy(out, _pubkey, 32); }; | |
| 153 | ||
| 152 | 154 | _control.attach(&_uds, backend); |
| 153 | 155 | |
| 154 | 156 | // Peer lifecycle arrives on the UDX thread. Enqueue only. |
| … | … | @@ -189,6 +191,7 @@ bool Daemon::start(const char *socket_path, const char *bootstrap, |
| 189 | 191 | }); |
| 190 | 192 | |
| 191 | 193 | Ed25519KeyPair kp = NoiseIK::generate_keypair(); |
| 194 | memcpy(_pubkey, kp.public_key, 32); | |
| 192 | 195 | if (bootstrap) { |
| 193 | 196 | const char *bs[1] = { bootstrap }; |
| 194 | 197 | _t.start_dht(kp, bs, 1); |
| … | … | @@ -114,6 +114,8 @@ private: |
| 114 | 114 | |
| 115 | 115 | bool _started = false; |
| 116 | 116 | std::string _socket_path; |
| 117 | // ⚠ Generated per start; see ControlBackend::daemon_pubkey. | |
| 118 | uint8_t _pubkey[32] = { 0 }; | |
| 117 | 119 | }; |
| 118 | 120 | |
| 119 | 121 | } // namespace swarmd |