diff options
| author | tv <tv@krebsco.de> | 2026-10-27 01:31:58 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-27 01:31:58 +0100 |
| commit | 4cdece6d0f8e25ac154c3fd0f30bca604b08c16a (patch) | |
| tree | 10a6aab1793d1c4fd0bd53c16b600f1adf986cb9 /src/transport/mod.rs | |
| parent | 5fd686dcd8ddfbdf276c044e5acf03f744e03193 (diff) | |
add identity layer
Diffstat (limited to 'src/transport/mod.rs')
| -rw-r--r-- | src/transport/mod.rs | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/src/transport/mod.rs b/src/transport/mod.rs index 29c48d6..52db406 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -12,6 +12,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; pub(crate) use crate::document::replica::Epoch; pub(crate) mod firewall; +pub(crate) mod identity; pub(crate) mod mycelium; #[cfg(test)] pub(crate) mod sim; @@ -137,6 +138,31 @@ pub(crate) enum ParsedMessage { Ping(Keepalive), Pong(Keepalive), Blob(BlobMessage), + /// Asks the recipient who it is, saying who the sender is (`transport::identity`). + Who(IdentityProof), + /// Answers a WHO. + Me(IdentityProof), +} + +/// A node's proof that it holds the key of its node ID (`identity`), sending from its +/// transport address to the recipient's: a signature over both addresses +/// (`transport::identity::signed`). WHO and ME end at the identity layer; the rest of +/// the node never sees them. +#[derive(Clone, Serialize, Deserialize)] +pub(crate) struct IdentityProof { + /// The sender's public node key. + #[serde(with = "crate::transport::wire::codec::bytes32")] + pub(crate) key: [u8; 32], + #[serde(with = "crate::transport::wire::codec::bytes64")] + pub(crate) signature: [u8; 64], +} + +impl std::fmt::Debug for IdentityProof { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("IdentityProof") + .field("key", &Hex(&self.key)) + .finish_non_exhaustive() + } } /// Content-addressed bytes that any node holding them can serve, in chunks @@ -237,6 +263,8 @@ pub(crate) enum MessageKind { Ping, Pong, Blob, + Who, + Me, } impl ParsedMessage { @@ -248,28 +276,23 @@ impl ParsedMessage { ParsedMessage::Ping(_) => MessageKind::Ping, ParsedMessage::Pong(_) => MessageKind::Pong, ParsedMessage::Blob(_) => MessageKind::Blob, + ParsedMessage::Who(_) => MessageKind::Who, + ParsedMessage::Me(_) => MessageKind::Me, } } - /// Every message carries the sender's epoch. - pub(crate) fn epoch(&self) -> Epoch { - match self { - ParsedMessage::Hello(hello) => hello.epoch, - ParsedMessage::HelloReply(reply) => reply.epoch, - ParsedMessage::Sync(envelope) => envelope.epoch, - ParsedMessage::Ping(keepalive) | ParsedMessage::Pong(keepalive) => keepalive.epoch, - ParsedMessage::Blob(blob) => blob.epoch, - } - } - - /// `SyncEnvelope::epoch_seq`, as every message carries it. - pub(crate) fn epoch_seq(&self) -> u32 { + /// The sender's epoch and `SyncEnvelope::epoch_seq`, as every message carries them + /// but WHO and ME (which the node never sees). + pub(crate) fn epoch_stamp(&self) -> Option<(Epoch, u32)> { match self { - ParsedMessage::Hello(hello) => hello.epoch_seq, - ParsedMessage::HelloReply(reply) => reply.epoch_seq, - ParsedMessage::Sync(envelope) => envelope.epoch_seq, - ParsedMessage::Ping(keepalive) | ParsedMessage::Pong(keepalive) => keepalive.epoch_seq, - ParsedMessage::Blob(blob) => blob.epoch_seq, + ParsedMessage::Hello(hello) => Some((hello.epoch, hello.epoch_seq)), + ParsedMessage::HelloReply(reply) => Some((reply.epoch, reply.epoch_seq)), + ParsedMessage::Sync(envelope) => Some((envelope.epoch, envelope.epoch_seq)), + ParsedMessage::Ping(keepalive) | ParsedMessage::Pong(keepalive) => { + Some((keepalive.epoch, keepalive.epoch_seq)) + } + ParsedMessage::Blob(blob) => Some((blob.epoch, blob.epoch_seq)), + ParsedMessage::Who(_) | ParsedMessage::Me(_) => None, } } } @@ -472,6 +495,9 @@ impl std::fmt::Debug for SyncPayload { #[derive(Clone, Debug)] pub(crate) struct EncodedMessage { pub(crate) peer: String, + /// Where the transport sends it: `peer` itself for a transport whose identities are + /// addresses, the peer's address under the identity layer (`transport::identity`). + pub(crate) address: String, pub(crate) body: bytes::Bytes, pub(crate) kind: MessageKind, /// Bytes the message takes on the wire (without the transport's own framing). |
