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:
parent
d3f4189324
commit
fe8953ab8b
|
|
@ -119,10 +119,18 @@ pub enum FetchResult {
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// The remote peer sent an invalid announcement timestamp,
|
||||||
|
/// for eg. a timestamp far in the future.
|
||||||
#[error("invalid announcement timestamp: {0}")]
|
#[error("invalid announcement timestamp: {0}")]
|
||||||
InvalidTimestamp(u64),
|
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")]
|
#[error("peer misbehaved")]
|
||||||
Misbehavior,
|
Misbehavior,
|
||||||
|
/// The remote peer timed out.
|
||||||
#[error("peer timed out")]
|
#[error("peer timed out")]
|
||||||
Timeout,
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|
@ -132,6 +140,7 @@ impl Error {
|
||||||
pub fn is_transient(&self) -> bool {
|
pub fn is_transient(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::InvalidTimestamp(_) => false,
|
Self::InvalidTimestamp(_) => false,
|
||||||
|
Self::ProtocolMismatch => true,
|
||||||
Self::Misbehavior => false,
|
Self::Misbehavior => false,
|
||||||
Self::Timeout => true,
|
Self::Timeout => true,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -521,9 +521,11 @@ where
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!(target: "wire", "Invalid gossip message from {id}: {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 {
|
if let Error::UnknownMessageType(t) = e {
|
||||||
let mut leftover = t.to_be_bytes().to_vec();
|
let leftover =
|
||||||
leftover.extend(inbox.unparsed());
|
inbox.unparsed().chain(t.to_be_bytes()).collect::<Vec<_>>();
|
||||||
|
|
||||||
if let Ok(header) =
|
if let Ok(header) =
|
||||||
str::from_utf8(&leftover[..worker::pktline::HEADER_LEN])
|
str::from_utf8(&leftover[..worker::pktline::HEADER_LEN])
|
||||||
|
|
@ -534,6 +536,10 @@ where
|
||||||
"Received possible Git packet-line header `{}` from {id} (protocol mismatch)",
|
"Received possible Git packet-line header `{}` from {id} (protocol mismatch)",
|
||||||
header
|
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());
|
log::debug!(target: "wire", "Dropping read buffer for {id} with {} bytes", inbox.unparsed().count());
|
||||||
}
|
}
|
||||||
self.disconnect(
|
self.disconnect(
|
||||||
fd,
|
fd, // TODO(cloudhead): Include error in reason.
|
||||||
// TODO(cloudhead): Include error in reason.
|
reason,
|
||||||
DisconnectReason::Session(session::Error::Misbehavior),
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue