summaryrefslogtreecommitdiffstats
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/firewall.rs12
-rw-r--r--src/transport/mod.rs30
-rw-r--r--src/transport/traffic.rs12
-rw-r--r--src/transport/wire.rs28
4 files changed, 73 insertions, 9 deletions
diff --git a/src/transport/firewall.rs b/src/transport/firewall.rs
index df82aa7..3036b11 100644
--- a/src/transport/firewall.rs
+++ b/src/transport/firewall.rs
@@ -72,6 +72,18 @@ impl Transport for FirewallTransport {
self.inner.delivery_limit()
}
+ fn local_addresses(&self) -> Vec<String> {
+ self.inner.local_addresses()
+ }
+
+ fn addresses_of(&self, peer: &str) -> Vec<String> {
+ self.inner.addresses_of(peer)
+ }
+
+ fn learn_addresses(&self, peer: &str, addresses: &[String]) {
+ self.inner.learn_addresses(peer, addresses)
+ }
+
async fn resolve_seed(&self, seed: &str) -> Result<String> {
self.inner.resolve_seed(seed).await
}
diff --git a/src/transport/mod.rs b/src/transport/mod.rs
index 61b1f4b..29c48d6 100644
--- a/src/transport/mod.rs
+++ b/src/transport/mod.rs
@@ -297,10 +297,18 @@ pub(crate) struct HelloRequest {
pub(crate) handshake: u32,
}
+/// A peer a HELLO_REPLY lists: who it is, and where the sender reaches it.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub(crate) struct ListedPeer {
+ pub(crate) id: String,
+ /// As `Transport::addresses_of` gives them; hints for the recipient.
+ pub(crate) addresses: Vec<String>,
+}
+
#[derive(Clone, Serialize, Deserialize)]
pub(crate) struct HelloReply {
pub(crate) swarm_id: String,
- pub(crate) peers: Vec<String>,
+ pub(crate) peers: Vec<ListedPeer>,
#[serde(with = "crate::transport::wire::codec::epoch")]
pub(crate) epoch: Epoch,
/// See `SyncEnvelope::epoch_seq`.
@@ -490,6 +498,26 @@ pub(crate) trait Transport: Send + Sync {
/// a message sent is delivered or lost for good.
fn delivery_limit(&self) -> std::time::Duration;
+ /// Where this node can be reached, as addresses other nodes can use: published in
+ /// the member list (`swarm::members`). By default its identity, for a transport
+ /// whose identities are addresses (Mycelium: a public key).
+ fn local_addresses(&self) -> Vec<String> {
+ vec![self.local_id().to_owned()]
+ }
+
+ /// Where `peer` can be reached, as far as this node knows: passed on to others (in
+ /// a HELLO_REPLY). By default its identity, as for `local_addresses`.
+ fn addresses_of(&self, peer: &str) -> Vec<String> {
+ vec![peer.to_owned()]
+ }
+
+ /// Where others say `peer` can be reached (the member list, a HELLO_REPLY): hints,
+ /// to be checked before they are relied on. By default nothing to learn, as for
+ /// `local_addresses`.
+ fn learn_addresses(&self, peer: &str, addresses: &[String]) {
+ let _ = (peer, addresses);
+ }
+
/// Resolves a seed (anything that leads to a node, e.g. an address) to that node's
/// identity, as `local_id` gives it on that node.
async fn resolve_seed(&self, seed: &str) -> Result<String>;
diff --git a/src/transport/traffic.rs b/src/transport/traffic.rs
index f9b8289..c27f0d7 100644
--- a/src/transport/traffic.rs
+++ b/src/transport/traffic.rs
@@ -145,6 +145,18 @@ impl Transport for CountingTransport {
self.inner.delivery_limit()
}
+ fn local_addresses(&self) -> Vec<String> {
+ self.inner.local_addresses()
+ }
+
+ fn addresses_of(&self, peer: &str) -> Vec<String> {
+ self.inner.addresses_of(peer)
+ }
+
+ fn learn_addresses(&self, peer: &str, addresses: &[String]) {
+ self.inner.learn_addresses(peer, addresses)
+ }
+
async fn resolve_seed(&self, seed: &str) -> Result<String> {
self.inner.resolve_seed(seed).await
}
diff --git a/src/transport/wire.rs b/src/transport/wire.rs
index 009380f..ceeaf87 100644
--- a/src/transport/wire.rs
+++ b/src/transport/wire.rs
@@ -14,7 +14,7 @@ use super::{MessageKind, ParsedMessage};
/// The wire format's version, the first byte of every payload. Bump it with every change
/// to a message type or a codec (`golden_bytes` fails then).
-pub(crate) const VERSION: u8 = 3;
+pub(crate) const VERSION: u8 = 4;
/// What the second byte of a payload says.
fn tag(kind: MessageKind) -> u8 {
@@ -300,7 +300,7 @@ mod tests {
use crate::document::replica::Epoch;
use crate::transport::{
BlobBody, BlobId, BlobMessage, HeadsSummary, HelloReply, HelloRequest, Keepalive,
- MAX_LISTED_HEADS,
+ ListedPeer, MAX_LISTED_HEADS,
};
use automerge::ChangeHash;
@@ -330,7 +330,10 @@ mod tests {
let reply = ParsedMessage::HelloReply(HelloReply {
swarm_id: "swarm".into(),
- peers: vec!["p".into()],
+ peers: vec![ListedPeer {
+ id: "p".into(),
+ addresses: vec!["a".into()],
+ }],
epoch,
epoch_seq: 1,
auth: Vec::new(),
@@ -342,7 +345,13 @@ mod tests {
let ParsedMessage::HelloReply(decoded) = decode(&encode(&reply).unwrap()).unwrap() else {
panic!("not a HELLO_REPLY");
};
- assert_eq!(decoded.peers, vec!["p".to_owned()]);
+ assert_eq!(
+ decoded.peers,
+ vec![ListedPeer {
+ id: "p".into(),
+ addresses: vec!["a".into()],
+ }]
+ );
assert_eq!(decoded.away_ms, Some(5));
assert_eq!(decoded.sender_run_id, [6; 16]);
}
@@ -438,12 +447,15 @@ mod tests {
});
assert_eq!(
hex(&encode(&hello).unwrap()),
- format!("030097a5737761726d{epoch_hex}01c403010203c3{}07", run("04"))
+ format!("040097a5737761726d{epoch_hex}01c403010203c3{}07", run("04"))
);
let reply = ParsedMessage::HelloReply(HelloReply {
swarm_id: "swarm".into(),
- peers: vec!["p".into()],
+ peers: vec![ListedPeer {
+ id: "p".into(),
+ addresses: vec!["a".into()],
+ }],
epoch,
epoch_seq: 1,
auth: Vec::new(),
@@ -455,7 +467,7 @@ mod tests {
assert_eq!(
hex(&encode(&reply).unwrap()),
format!(
- "030199a5737761726d91a170{epoch_hex}01c400c2{}05{}",
+ "040199a5737761726d9192a17091a161{epoch_hex}01c400c2{}05{}",
run("04"),
run("06")
)
@@ -470,7 +482,7 @@ mod tests {
});
assert_eq!(
hex(&encode(&ping).unwrap()),
- format!("0303959290c400{epoch_hex}01c3c2")
+ format!("0403959290c400{epoch_hex}01c3c2")
);
}
}