summaryrefslogtreecommitdiffstats
path: root/src/transport/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/mod.rs')
-rw-r--r--src/transport/mod.rs62
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).