Skip to content

Commit 20ea6a0

Browse files
lgmugnierEugeny
andauthored
Handle unexpected EOF as expected in session closure (#495)
Fixes: #253 My session was hitting the following error after receiving a `DISCONNECT` message from the client. ``` IO(Custom { kind: UnexpectedEof, error: "early eof" }) ``` On closer inspection (and thanks to the issue), I realized it was coming from the shutdown process of the session. I believe the intention here is to break when we hit eof (read 0 bytes): https://github.com/Eugeny/russh/blob/89fed88265b402e7d505025c42f4e19ab12201f3/russh/src/server/session.rs#L650 but because of this line in the called read function https://github.com/Eugeny/russh/blob/89fed88265b402e7d505025c42f4e19ab12201f3/russh/src/cipher/mod.rs#L254 reading 0 bytes will always be an UnexpectedEOF error. This might be good to fully propagate the error other places in the code, but here it makes sense to catch it and process it as an expected EOF. I kept in the n == 0 check but I doubt we'd ever see that case fire since it would mean that we received an empty ssh message and I'd imagine the reason this loop exists is to make sure we're not missing any actual messages while we wait for everything to shut down. --------- Co-authored-by: Eugene <[email protected]>
1 parent 154f820 commit 20ea6a0

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

russh/src/server/session.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::{HashMap, VecDeque};
2+
use std::io::ErrorKind;
23
use std::sync::Arc;
34

45
use channels::WindowSizeRef;
@@ -647,10 +648,14 @@ impl Session {
647648
if let Some((stream_read, buffer, opening_cipher)) = is_reading.take() {
648649
reading.set(start_reading(stream_read, buffer, opening_cipher));
649650
}
650-
let (n, r, b, opening_cipher) = (&mut reading).await?;
651-
is_reading = Some((r, b, opening_cipher));
652-
if n == 0 {
653-
break;
651+
match (&mut reading).await {
652+
Ok((0, _, _, _)) => break,
653+
Ok((_, r, b, opening_cipher)) => {
654+
is_reading = Some((r, b, opening_cipher));
655+
}
656+
// at this stage of session shutdown, EOF is not unexpected
657+
Err(Error::IO(ref e)) if e.kind() == ErrorKind::UnexpectedEof => break,
658+
Err(e) => return Err(e.into()),
654659
}
655660
}
656661

0 commit comments

Comments
 (0)