Pure-Rust asynchronous SSH library, both client and server

#72 Bug within `Channel::send_data` causes send loop to exit if window_size reaches 0

Opened by jgrund on March 8, 2022
jgrund on March 8, 2022

Channel::send_data will exit prematurely if the window_size sent by the server reaches 0. This happens within the following bit of code:

            let sendable = self.window_size.min(self.max_packet_size) as usize;
            debug!("sendable {:?}", sendable);
            let mut c = CryptoVec::new_zeroed(sendable);
            let n = data.read(&mut c[..]).await?;
            total += n;
            c.resize(n);
            self.window_size -= n as u32;
            self.send_data_packet(ext, c).await?;
            if n == 0 {
                break;
            } else if self.window_size > 0 {
                continue;
            }

If window_size hits 0, a zero sized buffer is passed to data.read. This in turn causes data.read to return 0. Here’s a link explaining why: https://docs.rs/tokio/1.17.0/tokio/io/trait.AsyncReadExt.html#return

Since we do not account for a zero sized buffer, we exit the loop prematurely and do not send all data to the server.

We should instead check if we are at zero window size and loop again so we can wait for window adjustment and continue.