Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session.set_tcp_stream #4

Closed
0xdeafbeef opened this issue Jan 21, 2020 · 10 comments
Closed

session.set_tcp_stream #4

0xdeafbeef opened this issue Jan 21, 2020 · 10 comments

Comments

@0xdeafbeef
Copy link

async-ssh2::Session::set_tcp_stream
Why not to use tokio::net::TcpStream instead of std::net::TcpStream?

@spebern
Copy link
Owner

spebern commented Jan 21, 2020

ssh2-rs expects a std::net::TcpStream so I need that anyway. I want the interface to be as close as possible to the ssh2-rs crate.

What would be the benefit for using tokio::net::TcpStream here?

I am sure that the way I introduced async within the file aio.rs can be improved. Initially I also planned to support async-std, but I haven't found a way to get that to work just yet.

@0xdeafbeef
Copy link
Author

Function wouldn't block on initialization of tcp connection. Sometimes it takes several minutes, if there troubles with network

@spebern
Copy link
Owner

spebern commented Jan 23, 2020

The connect is handled by the libssh2 c library which only needs a file descriptor which can be obtained from std::net:TcpStream. There is no synchronous connect call.

@spebern
Copy link
Owner

spebern commented Jan 23, 2020

Ok, I got what you mean, I forgot that the stream is created with a synchronous connect method. I'll change that.

@wez
Copy link

wez commented Jan 25, 2020

My suggestion for this is to submit a PR to ssh2 that:

  • Replaces set_tcp_stream with a method that has a signature:
#[cfg(unix)]
pub fn set_tcp_stream<S: AsRawFd>(&mut self, stream: S) {}

#[cfg(windows)]
pub fn set_tcp_stream<S: AsRawSocket>(&mut self, stream: S) {}

Initially I was thinking that IntoRawFd would be ideal, but the tokio TcpStream doesn't implement that. So I think we'll need to own a Box<AsRawFd> or Box<AsRawSocket> instead of owning TcpStream; this way we can own either the standard stream or the tokio stream or the async-std stream, or a stream obtained through some other means.

Then I think we need to change the tcp_stream method to return Option<RawFd> (unix) or Option<RawSocket> (windows).

@spebern
Copy link
Owner

spebern commented Jan 26, 2020

I think the windows version will only work as soon as tokio and async-std upgrade to mio 0.7, because 0.6 does not give access to as_raw_socket. Tokio plans to update with the release of 0.3 which is planned in february.

@oleid
Copy link
Contributor

oleid commented May 8, 2020

On that matter, I'm trying to figure out how to use this library in the context of socks proxys. From what I've read about the C library, one would need to connect to the SOCKS proxy externally, then create a socket for the communication, pipe the communication to that socket and pass the other end of the socket to the C library. Obviously, this won't work at the moment here.

tokio_socks::tcp::Socks5Stream::connect(socks_addr, target_addr).await? yields a stream object and you can even extract the corresponding TcpStream. But I it would work to extract that raw socket and pass that to the C library.

@spebern
Copy link
Owner

spebern commented May 8, 2020

@0xd34b33f I ported the library to use smol so it should work with both tokio and async std so async connecting should now be possible:

use async_ssh2::Session;
use std::net::TcpStream;
use smol::Async;

#[tokio::main]
async fn main() {
    let stream = Async::<TcpStream>::connect("127.0.0.1:22").await.unwrap();
    let mut sess = async_ssh2::Session::new().unwrap();
    sess.set_tcp_stream(stream).unwrap();
}

@oleid
Copy link
Contributor

oleid commented May 9, 2020

That is amazing! With sticnarf/tokio-socks#18 you can now easily wire-up this library to tokio-socks as follows:

use async_ssh2::Session;
use tokio_socks::{tcp::Socks5Stream};

fn main() -> Result<(), Box<dyn std::error::Error>> {

    smol::run( async {
        let stream = Socks5Stream::connect("localhost:33712", "10.101.120.23:22").await?.into_inner().?;
        let mut sess = async_ssh2::Session::new()?;
        sess.set_tcp_stream(stream)?;
    })
}

@spebern
Copy link
Owner

spebern commented May 9, 2020

That's really nice to hear! I think I'll publish a beta soon on crates.io.

@spebern spebern closed this as completed May 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants