node: Add support for multiple address types
Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
parent
92f17d71c3
commit
b78bbc4ecc
|
|
@ -2,6 +2,7 @@
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::{collections::VecDeque, fmt, io, net, net::IpAddr};
|
use std::{collections::VecDeque, fmt, io, net, net::IpAddr};
|
||||||
|
|
||||||
|
use ed25519_consensus::VerificationKey;
|
||||||
use fastrand::Rng;
|
use fastrand::Rng;
|
||||||
use git_url::Url;
|
use git_url::Url;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
@ -27,6 +28,14 @@ pub type Routing = HashMap<ProjId, HashSet<PeerId>>;
|
||||||
/// Seconds since epoch.
|
/// Seconds since epoch.
|
||||||
pub type Timestamp = u64;
|
pub type Timestamp = u64;
|
||||||
|
|
||||||
|
/// Peer public protocol address.
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub enum Address {
|
||||||
|
Tor { key: VerificationKey, port: u16 },
|
||||||
|
Tcp { addr: net::SocketAddr },
|
||||||
|
Dns { host: String, port: u16 },
|
||||||
|
}
|
||||||
|
|
||||||
pub const NETWORK_MAGIC: u32 = 0x819b43d9;
|
pub const NETWORK_MAGIC: u32 = 0x819b43d9;
|
||||||
pub const DEFAULT_PORT: u16 = 8776;
|
pub const DEFAULT_PORT: u16 = 8776;
|
||||||
pub const PROTOCOL_VERSION: u32 = 1;
|
pub const PROTOCOL_VERSION: u32 = 1;
|
||||||
|
|
@ -62,6 +71,7 @@ pub enum Message {
|
||||||
Hello {
|
Hello {
|
||||||
timestamp: Timestamp,
|
timestamp: Timestamp,
|
||||||
version: u32,
|
version: u32,
|
||||||
|
addrs: Vec<Address>,
|
||||||
git: Url,
|
git: Url,
|
||||||
},
|
},
|
||||||
/// Get node addresses from a peer.
|
/// Get node addresses from a peer.
|
||||||
|
|
@ -91,10 +101,11 @@ impl From<Message> for Envelope {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
pub fn hello(timestamp: Timestamp, git: Url) -> Self {
|
pub fn hello(timestamp: Timestamp, addrs: Vec<Address>, git: Url) -> Self {
|
||||||
Self::Hello {
|
Self::Hello {
|
||||||
timestamp,
|
timestamp,
|
||||||
version: PROTOCOL_VERSION,
|
version: PROTOCOL_VERSION,
|
||||||
|
addrs,
|
||||||
git,
|
git,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +170,8 @@ pub struct Config {
|
||||||
pub remote_tracking: RemoteTracking,
|
pub remote_tracking: RemoteTracking,
|
||||||
/// Whether or not our node should relay inventories.
|
/// Whether or not our node should relay inventories.
|
||||||
pub relay: bool,
|
pub relay: bool,
|
||||||
|
/// List of addresses to listen on for protocol connections.
|
||||||
|
pub listen: Vec<Address>,
|
||||||
/// Our Git URL for fetching projects.
|
/// Our Git URL for fetching projects.
|
||||||
pub git_url: Url,
|
pub git_url: Url,
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +183,7 @@ impl Default for Config {
|
||||||
project_tracking: ProjectTracking::default(),
|
project_tracking: ProjectTracking::default(),
|
||||||
remote_tracking: RemoteTracking::default(),
|
remote_tracking: RemoteTracking::default(),
|
||||||
relay: true,
|
relay: true,
|
||||||
|
listen: vec![],
|
||||||
git_url: Url::default(),
|
git_url: Url::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -504,7 +518,11 @@ where
|
||||||
self.context.write_all(
|
self.context.write_all(
|
||||||
peer.addr,
|
peer.addr,
|
||||||
[
|
[
|
||||||
Message::hello(self.context.timestamp(), git),
|
Message::hello(
|
||||||
|
self.context.timestamp(),
|
||||||
|
self.context.config.listen.clone(),
|
||||||
|
git,
|
||||||
|
),
|
||||||
Message::get_inventory([]),
|
Message::get_inventory([]),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
@ -818,7 +836,12 @@ enum PeerState {
|
||||||
#[default]
|
#[default]
|
||||||
Initial,
|
Initial,
|
||||||
/// State after successful handshake.
|
/// State after successful handshake.
|
||||||
Negotiated { since: LocalTime, git: Url },
|
Negotiated {
|
||||||
|
since: LocalTime,
|
||||||
|
/// Addresses this peer is reachable on.
|
||||||
|
addrs: Vec<Address>,
|
||||||
|
git: Url,
|
||||||
|
},
|
||||||
/// When a peer is disconnected.
|
/// When a peer is disconnected.
|
||||||
Disconnected { since: LocalTime },
|
Disconnected { since: LocalTime },
|
||||||
}
|
}
|
||||||
|
|
@ -896,6 +919,7 @@ impl Peer {
|
||||||
Message::Hello {
|
Message::Hello {
|
||||||
timestamp,
|
timestamp,
|
||||||
version,
|
version,
|
||||||
|
addrs,
|
||||||
git,
|
git,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -913,7 +937,10 @@ impl Peer {
|
||||||
let git = ctx.config.git_url.clone();
|
let git = ctx.config.git_url.clone();
|
||||||
ctx.write_all(
|
ctx.write_all(
|
||||||
self.addr,
|
self.addr,
|
||||||
[Message::hello(now, git), Message::get_inventory([])],
|
[
|
||||||
|
Message::hello(now, ctx.config.listen.clone(), git),
|
||||||
|
Message::get_inventory([]),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Nb. we don't set the peer timestamp here, since it is going to be
|
// Nb. we don't set the peer timestamp here, since it is going to be
|
||||||
|
|
@ -921,6 +948,7 @@ impl Peer {
|
||||||
// mean that messages received right after the handshake could be ignored.
|
// mean that messages received right after the handshake could be ignored.
|
||||||
self.state = PeerState::Negotiated {
|
self.state = PeerState::Negotiated {
|
||||||
since: ctx.clock.local_time(),
|
since: ctx.clock.local_time(),
|
||||||
|
addrs,
|
||||||
git,
|
git,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,14 @@ where
|
||||||
|
|
||||||
self.initialize();
|
self.initialize();
|
||||||
self.protocol.connected(*remote, &local, Link::Inbound);
|
self.protocol.connected(*remote, &local, Link::Inbound);
|
||||||
self.receive(remote, Message::hello(self.local_time().as_secs(), git));
|
self.receive(
|
||||||
|
remote,
|
||||||
|
Message::hello(
|
||||||
|
self.local_time().as_secs(),
|
||||||
|
vec![Address::Tcp { addr: *remote }],
|
||||||
|
git,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
let mut msgs = self.messages(remote);
|
let mut msgs = self.messages(remote);
|
||||||
msgs.find(|m| matches!(m, Message::Hello { .. }))
|
msgs.find(|m| matches!(m, Message::Hello { .. }))
|
||||||
|
|
@ -161,7 +168,14 @@ where
|
||||||
.expect("`get-inventory` is sent");
|
.expect("`get-inventory` is sent");
|
||||||
|
|
||||||
let git = peer.config().git_url.clone();
|
let git = peer.config().git_url.clone();
|
||||||
self.receive(&remote, Message::hello(self.local_time().as_secs(), git));
|
self.receive(
|
||||||
|
&remote,
|
||||||
|
Message::hello(
|
||||||
|
self.local_time().as_secs(),
|
||||||
|
peer.config().listen.clone(),
|
||||||
|
git,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drain outgoing messages sent from this peer to the remote address.
|
/// Drain outgoing messages sent from this peer to the remote address.
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ fn test_handshake_invalid_timestamp() {
|
||||||
alice.connected(bob.addr(), &local, Link::Inbound);
|
alice.connected(bob.addr(), &local, Link::Inbound);
|
||||||
alice.receive(
|
alice.receive(
|
||||||
&bob.addr(),
|
&bob.addr(),
|
||||||
Message::hello(alice.timestamp() - time_delta, bob.git_url()),
|
Message::hello(alice.timestamp() - time_delta, vec![], bob.git_url()),
|
||||||
);
|
);
|
||||||
assert_matches!(alice.outbox().next(), Some(Io::Disconnect(addr, _)) if addr == bob.addr());
|
assert_matches!(alice.outbox().next(), Some(Io::Disconnect(addr, _)) if addr == bob.addr());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue