node: Don't penalize peer for protocol mismatch

Instead of returning a non-transient disconnect reason, return
a transient one, since protocol mismatches can happen.
This commit is contained in:
Alexis Sellier 2023-03-23 14:08:12 +01:00 committed by Alexis Sellier
parent d3f4189324
commit fe8953ab8b
No known key found for this signature in database
2 changed files with 19 additions and 5 deletions

View File

@ -119,10 +119,18 @@ pub enum FetchResult {
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// The remote peer sent an invalid announcement timestamp,
/// for eg. a timestamp far in the future.
#[error("invalid announcement timestamp: {0}")]
InvalidTimestamp(u64),
/// The remote peer sent git protocol messages while we were expecting
/// gossip messages. Or vice-versa.
#[error("protocol mismatch")]
ProtocolMismatch,
/// The remote peer did something that violates the protocol rules.
#[error("peer misbehaved")]
Misbehavior,
/// The remote peer timed out.
#[error("peer timed out")]
Timeout,
}
@ -132,6 +140,7 @@ impl Error {
pub fn is_transient(&self) -> bool {
match self {
Self::InvalidTimestamp(_) => false,
Self::ProtocolMismatch => true,
Self::Misbehavior => false,
Self::Timeout => true,
}

View File

@ -521,9 +521,11 @@ where
Err(e) => {
log::error!(target: "wire", "Invalid gossip message from {id}: {e}");
let mut reason =
DisconnectReason::Session(session::Error::Misbehavior);
if let Error::UnknownMessageType(t) = e {
let mut leftover = t.to_be_bytes().to_vec();
leftover.extend(inbox.unparsed());
let leftover =
inbox.unparsed().chain(t.to_be_bytes()).collect::<Vec<_>>();
if let Ok(header) =
str::from_utf8(&leftover[..worker::pktline::HEADER_LEN])
@ -534,6 +536,10 @@ where
"Received possible Git packet-line header `{}` from {id} (protocol mismatch)",
header
);
// In case of protocol mismatch, don't penalize the peer.
reason = DisconnectReason::Session(
session::Error::ProtocolMismatch,
);
}
}
}
@ -542,9 +548,8 @@ where
log::debug!(target: "wire", "Dropping read buffer for {id} with {} bytes", inbox.unparsed().count());
}
self.disconnect(
fd,
// TODO(cloudhead): Include error in reason.
DisconnectReason::Session(session::Error::Misbehavior),
fd, // TODO(cloudhead): Include error in reason.
reason,
);
break;
}