node: Make sure we bound peer message inboxes

This commit is contained in:
cloudhead 2024-05-03 17:03:05 +02:00
parent e8f2f88bf6
commit f212dbb2ee
No known key found for this signature in database
2 changed files with 15 additions and 1 deletions

View File

@ -67,6 +67,11 @@ impl<D: wire::Decode> Deserializer<D> {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.unparsed.is_empty() self.unparsed.is_empty()
} }
/// Return the size of the unparsed data.
pub fn len(&self) -> usize {
self.unparsed.len()
}
} }
impl<D: wire::Decode> io::Write for Deserializer<D> { impl<D: wire::Decode> io::Write for Deserializer<D> {

View File

@ -53,6 +53,9 @@ pub const DEFAULT_CONNECTION_TIMEOUT: time::Duration = time::Duration::from_secs
/// Default time to wait when dialing a connection, before the remote is considered unreachable. /// Default time to wait when dialing a connection, before the remote is considered unreachable.
pub const DEFAULT_DIAL_TIMEOUT: time::Duration = time::Duration::from_secs(6); pub const DEFAULT_DIAL_TIMEOUT: time::Duration = time::Duration::from_secs(6);
/// Maximum size of a peer inbox, in bytes.
pub const MAX_INBOX_SIZE: usize = 1024 * 1024 * 2;
/// Control message used internally between workers, users, and the service. /// Control message used internally between workers, users, and the service.
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Debug)] #[derive(Debug)]
@ -699,6 +702,12 @@ where
.. ..
}) = self.peers.get_mut(&id) }) = self.peers.get_mut(&id)
{ {
if inbox.len() + data.len() > MAX_INBOX_SIZE {
log::error!(target: "wire", "Maximum inbox size ({MAX_INBOX_SIZE}) reached for peer {nid}");
log::error!(target: "wire", "Unable to process messages fast enough for peer {nid}; disconnecting..");
self.disconnect(id, DisconnectReason::Session(session::Error::Misbehavior));
return;
}
inbox.input(&data); inbox.input(&data);
loop { loop {
@ -781,7 +790,7 @@ where
log::error!(target: "wire", "Invalid gossip message from {nid}: {e}"); log::error!(target: "wire", "Invalid gossip message from {nid}: {e}");
if !inbox.is_empty() { if !inbox.is_empty() {
log::debug!(target: "wire", "Dropping read buffer for {nid} with {} bytes", inbox.unparsed().count()); log::debug!(target: "wire", "Dropping read buffer for {nid} with {} bytes", inbox.len());
} }
self.disconnect( self.disconnect(
id, id,