Skip to content

Commit

Permalink
Merge pull request #89 from HsuJv/v0_4_5
Browse files Browse the repository at this point in the history
Version 0.4.5
  • Loading branch information
HsuJv authored Nov 17, 2023
2 parents 40daa4f + c875b05 commit be05260
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssh-rs"
version = "0.4.4"
version = "0.4.5"
edition = "2021"
authors = [
"Gao Xiang Kang <[email protected]>",
Expand Down
4 changes: 4 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v0.4.5 (2023-11-17)
1. Fix the high cpu usage caused by non_block tcp
2. Fix the failuer of version agreement if the server sends more than one lines

v0.4.4 (2023-11-15)
1. Remove some debug print
2. Fix the panic when connect to non-ssh servers
Expand Down
50 changes: 43 additions & 7 deletions src/config/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,58 @@ impl Default for SshVersion {
}
}

/// <https://www.rfc-editor.org/rfc/rfc4253#section-4.2>

// When the connection has been established, both sides MUST send an
// identification string. This identification string MUST be

// SSH-protoversion-softwareversion SP comments CR LF

// Since the protocol being defined in this set of documents is version
// 2.0, the 'protoversion' MUST be "2.0". The 'comments' string is
// OPTIONAL. If the 'comments' string is included, a 'space' character
// (denoted above as SP, ASCII 32) MUST separate the 'softwareversion'
// and 'comments' strings. The identification MUST be terminated by a
// single Carriage Return (CR) and a single Line Feed (LF) character
// (ASCII 13 and 10, respectively).
fn read_version<S>(stream: &mut S, tm: Option<Duration>) -> SshResult<Vec<u8>>
where
S: Read,
{
let mut buf = vec![0; 128];
let timeout = Timeout::new(tm);
let mut ch = vec![0; 1];
const LF: u8 = 0xa;
let crlf = vec![0xd, 0xa];
let mut outbuf = vec![];
let mut timeout = Timeout::new(tm);
loop {
match stream.read(&mut buf) {
match stream.read(&mut ch) {
Ok(i) => {
// MY TO DO: To Skip the other lines
buf.truncate(i);
return Ok(buf);
if 0 == i {
// eof got, return
return Ok(outbuf);
}

outbuf.extend_from_slice(&ch);

if LF == ch[0] && outbuf.len() > 1 && outbuf.ends_with(&crlf) {
// The server MAY send other lines of data before sending the version
// string. Each line SHOULD be terminated by a Carriage Return and Line
// Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
// in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients
// MUST be able to process such lines. Such lines MAY be silently
// ignored, or MAY be displayed to the client user.
if outbuf.len() < 4 || &outbuf[0..4] != SSH_MAGIC {
// skip other lines
// and start read for another line
outbuf.clear();
continue;
}
return Ok(outbuf);
}
}
Err(e) => {
if let std::io::ErrorKind::WouldBlock = e.kind() {
timeout.test()?;
timeout.till_next_tick()?;
continue;
} else {
return Err(e.into());
Expand Down
2 changes: 1 addition & 1 deletion src/constant.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// The client version
pub(crate) const CLIENT_VERSION: &str = "SSH-2.0-SSH_RS-0.4.4";
pub(crate) const CLIENT_VERSION: &str = "SSH-2.0-SSH_RS-0.4.5";
pub(crate) const SSH_MAGIC: &[u8] = b"SSH-";

/// The constant strings that used for ssh communication
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Dependencies
//! ```toml
//! ssh-rs = "0.4.4"
//! ssh-rs = "0.4.5"
//! ```
//!
//!Rust implementation of ssh2.0 client.
Expand Down
4 changes: 2 additions & 2 deletions src/model/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ where
}
Err(e) => {
if let std::io::ErrorKind::WouldBlock = e.kind() {
timeout.test()?;
timeout.till_next_tick()?;
continue;
} else {
return Err(e.into());
Expand Down Expand Up @@ -117,7 +117,7 @@ where
}
Err(e) => {
if let std::io::ErrorKind::WouldBlock = e.kind() {
timeout.test()?;
timeout.till_next_tick()?;
continue;
} else {
return Err(e.into());
Expand Down
21 changes: 20 additions & 1 deletion src/model/timeout.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
use crate::{SshError, SshResult};
use std::time::{Duration, Instant};

#[cfg(not(target_arch = "wasm32"))]
const NANOS_PER_SEC: u64 = 1_000_000_000;

pub(crate) struct Timeout {
instant: Instant,
timeout: Option<Duration>,
wait_tick: u64,
}

impl Timeout {
pub fn new(timeout: Option<Duration>) -> Self {
Timeout {
instant: Instant::now(),
timeout,
wait_tick: 1,
}
}

fn wait(&mut self) -> u64 {
#[cfg(not(target_arch = "wasm32"))]
{
let sleep_time = Duration::from_nanos(self.wait_tick);
std::thread::sleep(sleep_time);
if self.wait_tick < NANOS_PER_SEC {
self.wait_tick <<= 1;
}
}
self.wait_tick
}

pub fn test(&self) -> SshResult<()> {
pub fn till_next_tick(&mut self) -> SshResult<()> {
if let Some(t) = self.timeout {
if self.instant.elapsed() > t {
tracing::error!("time out.");
Err(SshError::TimeoutError)
} else {
self.wait();
Ok(())
}
} else {
self.wait();
Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.4
0.4.5

0 comments on commit be05260

Please sign in to comment.