Help in using tokio_native_tls TlsConnector

Hi

When trying to use tokio_native_tls' TlsConnector (https://docs.rs/tokio-native-tls/0.1.0/tokio_native_tls/struct.TlsConnector.html), I encountered an error stating that it requires 3 arguments but I only provided 2. Am I missing the "self" argument since the arguments required are self, domain and stream.

use futures::executor::block_on;
use tokio_native_tls::{ TlsConnector };

async fn async_main()
{
	let tcp_stream = async_std::net::TcpStream::connect("127.0.0.1:4444").await;

	match tcp_stream
	{
		Ok(working_stream) =>
		{
			let tokio_tls_connector = TlsConnector::connect("127.0.0.1:4444",working_stream);
                        //expected 3 arguments, supplied 2
		}

		Err(error) =>
		{
			panic!("cannot establish TCP stream {}",error);
		}
	}
}

fn main() {
   async_std::task::block_on(async_main());
}

You need to first create a native_tls::TlsConnector then use tokio_tls_connector::TlsConnector::from(connector).connect("127.0.0.1:4444", working_stream).

Hi @bjorn3

Thanks for the quick feedback, I will give it a try.

Hi @bjorn3

I tried the following and encountered different errors.

let tcp_stream = tokio::net::TcpStream::connect("127.0.0.1:4444").await;

	match tcp_stream
	{
		Ok(working_stream) =>
		{
			let mut native_tls_builder = native_tls::TlsConnector::builder();
			native_tls_builder.danger_accept_invalid_certs(true);
			native_tls_builder.danger_accept_invalid_hostnames(true);
			native_tls_builder.use_sni(false);

			let native_tls_connector = native_tls_builder.build().unwrap();

			let tokio_tls_connector = tokio_native_tls::TlsConnector::from(native_tls_connector).connect("127.0.0.1:4444",working_stream);
             //ERROR temporary value dropped while borrowed
             //consider using a `let` binding to create a longer lived value
		}

		Err(error) =>
		{
			panic!("cannot establish TCP stream {}",error);
		}
	}

I was not sure what that error means, so based on what I read online (Borrowed value does not live long enough), I tried the following and it compiles but I got a runtime error.

			let tokio_tls_connector = tokio_native_tls::TlsConnector::from(native_tls_connector);
			let tls_connector = tokio_tls_connector.connect("127.0.0.1:4444",working_stream);
             //thread 'main' panicked at 'there is no reactor running, must be called from the context of Tokio runtime'

How should I troubleshoot this?

You need to run in the context of a tokio runtime. If you have the macros tokio feature enabled you can use the following:

#[tokio::main]
async fn main() {
    // my code here
}

I strongly recommend not trying to mix async-std and Tokio.

1 Like

Hi @bjorn3

I tried your suggestion and also removed the async_std code that alice suggested and my code now looks like this

extern crate tokio_native_tls;
extern crate native_tls;
extern crate tokio;

use tokio_native_tls::{ TlsConnector };
use tokio::net::*;

#[tokio::main]
async fn initiate_tls()
{
	let tcp_stream = tokio::net::TcpStream::connect("127.0.0.1:4444").await;

	match tcp_stream
	{
		Ok(working_stream) =>
		{
			let mut native_tls_builder = native_tls::TlsConnector::builder();
			native_tls_builder.danger_accept_invalid_certs(true);
			native_tls_builder.danger_accept_invalid_hostnames(true);
			native_tls_builder.use_sni(false);

			let native_tls_connector = native_tls_builder.build().unwrap();

			let tokio_tls_connector = tokio_native_tls::TlsConnector::from(native_tls_connector);
			let tls_connector = tokio_tls_connector.connect("127.0.0.1:4444",working_stream);
		}

		Err(error) =>
		{
			panic!("cannot establish TCP stream {}",error);
		}
	}
}

fn main() {
    initiate_tls();
}

I observed on Wireshark that the TLS handshake will not happen (only saw the TCP handshake) and the ncat listener showed

Ncat: Failed SSL connection from 127.0.0.1: error:00000000:lib(0):func(0):reason(0)

If #[tokio::main] was removed, there will be no TCP connection established at all.

When you mentioned the macros feature, do you mean what was configued in the dependencies section of Cargo.toml? This was what I put in the file.

tokio = { version = "0.2", features = ["full"] }

The idea is to do

#[tokio::main]
async fn main() {
    initiate_tls().await;
}

async fn initiate_tls() {
    // ...
}

Hi @bjorn3

I tried your suggestion but I still don't see the TLS handshake, only saw the TCP connection.

async fn initiate_tls()
{
	let tcp_stream = tokio::net::TcpStream::connect("127.0.0.1:4444").await;

	match tcp_stream
	{
		Ok(working_stream) =>
		{
			let mut native_tls_builder = native_tls::TlsConnector::builder();
			native_tls_builder.danger_accept_invalid_certs(true);
			native_tls_builder.danger_accept_invalid_hostnames(true);
			native_tls_builder.use_sni(false);

			let native_tls_connector = native_tls_builder.build().unwrap();

			let tokio_tls_connector = tokio_native_tls::TlsConnector::from(native_tls_connector);
			let tls_connector = tokio_tls_connector.connect("127.0.0.1:4444",working_stream);
		}

		Err(error) =>
		{
			panic!("cannot establish TCP stream {}",error);
		}
	}
}

#[tokio::main]
async fn main()
{
    initiate_tls().await;
}

You are missing an .await on the result of .connect(). Futures only run when you wait for them. Otherwise they do nothing.

Thanks for the prompt reply @bjorn3. That resolved this issue.