node: Fix attempted session state

We shouldn't be marking attempted peers as "connected". We should wait
for the connection to be properly established.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
Alexis Sellier 2023-01-13 15:42:22 +01:00
parent 438ae84304
commit 6d420813f5
No known key found for this signature in database
2 changed files with 55 additions and 21 deletions

View File

@ -520,10 +520,10 @@ where
debug!("Attempted connection to {id} ({addr})"); debug!("Attempted connection to {id} ({addr})");
let persistent = self.config.is_persistent(&id); let persistent = self.config.is_persistent(&id);
let peer = self.sessions.entry(id).or_insert_with(|| { self.sessions
Session::new(id, Link::Outbound, persistent, self.rng.clone(), self.clock) .entry(id)
}); .or_insert_with(|| Session::connecting(id, persistent, self.rng.clone()))
peer.attempted(); .attempted();
} }
pub fn connected(&mut self, remote: NodeId, link: Link) { pub fn connected(&mut self, remote: NodeId, link: Link) {
@ -534,24 +534,22 @@ where
// TODO: How should we deal with multiple peers connecting from the same IP address? // TODO: How should we deal with multiple peers connecting from the same IP address?
if link.is_outbound() { if link.is_outbound() {
if let Some(peer) = self.sessions.get_mut(&remote) { if let Some(peer) = self.sessions.get_mut(&remote) {
if link.is_outbound() { self.reactor.write_all(
self.reactor.write_all( remote,
remote, gossip::handshake(
gossip::handshake( self.clock.as_secs(),
self.clock.as_secs(), &self.storage,
&self.storage, &self.signer,
&self.signer, self.filter.clone(),
self.filter.clone(), &self.config,
&self.config, ),
), );
); peer.to_connected(self.clock);
}
peer.connected(link);
} }
} else { } else {
self.sessions.insert( self.sessions.insert(
remote, remote,
Session::new( Session::connected(
remote, remote,
Link::Inbound, Link::Inbound,
self.config.is_persistent(&remote), self.config.is_persistent(&remote),
@ -568,7 +566,7 @@ where
debug!("Disconnected from {} ({})", remote, reason); debug!("Disconnected from {} ({})", remote, reason);
if let Some(session) = self.sessions.get_mut(&remote) { if let Some(session) = self.sessions.get_mut(&remote) {
session.state = session::State::Disconnected { since }; session.to_disconnected(since);
// Attempt to re-connect to persistent peers. // Attempt to re-connect to persistent peers.
if let Some(address) = self.config.peer(&remote) { if let Some(address) = self.config.peer(&remote) {
@ -887,6 +885,9 @@ where
self.reactor self.reactor
.fetch(*remote, repo, Namespaces::default(), false); .fetch(*remote, repo, Namespaces::default(), false);
} }
(session::State::Connecting { .. }, msg) => {
error!("Received {:?} from connecting peer {}", msg, peer.id);
}
(session::State::Disconnected { .. }, msg) => { (session::State::Disconnected { .. }, msg) => {
debug!("Ignoring {:?} from disconnected peer {}", msg, peer.id); debug!("Ignoring {:?} from disconnected peer {}", msg, peer.id);
} }

View File

@ -29,6 +29,8 @@ pub enum Protocol {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub enum State { pub enum State {
/// Initial state for outgoing connections.
Connecting,
/// Initial state after handshake protocol hand-off. /// Initial state after handshake protocol hand-off.
Connected { Connected {
/// Whether this session was initialized with a [`Message::Initialize`]. /// Whether this session was initialized with a [`Message::Initialize`].
@ -89,7 +91,20 @@ pub struct Session {
} }
impl Session { impl Session {
pub fn new(id: NodeId, link: Link, persistent: bool, rng: Rng, time: LocalTime) -> Self { pub fn connecting(id: NodeId, persistent: bool, rng: Rng) -> Self {
Self {
id,
state: State::Connecting,
link: Link::Outbound,
subscribe: None,
persistent,
last_active: LocalTime::default(),
attempts: 0,
rng,
}
}
pub fn connected(id: NodeId, link: Link, persistent: bool, rng: Rng, time: LocalTime) -> Self {
Self { Self {
id, id,
state: State::Connected { state: State::Connected {
@ -107,6 +122,10 @@ impl Session {
} }
} }
pub fn is_connecting(&self) -> bool {
matches!(self.state, State::Connecting { .. })
}
pub fn is_connected(&self) -> bool { pub fn is_connected(&self) -> bool {
matches!(self.state, State::Connected { .. }) matches!(self.state, State::Connected { .. })
} }
@ -134,8 +153,22 @@ impl Session {
None None
} }
pub fn connected(&mut self, _link: Link) { pub fn to_connected(&mut self, since: LocalTime) {
assert!(
self.is_connecting(),
"Can only transition to 'connected' state from 'connecting' state"
);
self.attempts = 0; self.attempts = 0;
self.state = State::Connected {
initialized: false,
since,
ping: PingState::default(),
protocol: Protocol::default(),
};
}
pub fn to_disconnected(&mut self, since: LocalTime) {
self.state = State::Disconnected { since };
} }
pub fn ping(&mut self, reactor: &mut Reactor) -> Result<(), Error> { pub fn ping(&mut self, reactor: &mut Reactor) -> Result<(), Error> {