Skip to content

Commit

Permalink
src/connection: Return error from next_frame Future early
Browse files Browse the repository at this point in the history
> The `frame` future might be _ready_ with an `Error` from the underlying
socket (i.e. here `libp2p-websocket`). Though given that the result of the
`control_command` `Future` is handled first, `on_control_command` is called
despite `frame` having returned an `Error`. `on_control_command` itself may try
to write to the underlying socket, which will panic given that the socket
returned an error earlier via the `frame` `Future`.

Patch to validate suspicion in
libp2p/rust-libp2p#2598.
  • Loading branch information
mxinden committed Aug 1, 2022
1 parent 233199d commit 25e5ee6
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,26 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Connection<T> {

let (stream_command, control_command, frame) = next_item.await;

// Return early in case we hit an error.
let frame = match frame {
Poll::Ready(Some(Err(e))) => {
let e: ConnectionError = e.into();
if e.io_kind() == Some(io::ErrorKind::ConnectionReset) {
log::debug!("{}: connection reset", self.id);
return Err(ConnectionError::Closed);
} else {
log::error!("{}: socket error: {}", self.id, e);
return Err(e);
}
}
Poll::Ready(None) => {
log::debug!("{}: socket eof", self.id);
return Err(ConnectionError::Closed);
}
x @ Poll::Ready(Some(Ok(_))) => x,
x @ Poll::Pending => x,
};

if let Poll::Ready(cmd) = control_command {
self.on_control_command(cmd).await?
}
Expand Down

0 comments on commit 25e5ee6

Please sign in to comment.