Native Support Options for webtor-rs: Platforms, Transports, and TLS Configuration

webtor-rs compiles for native (non-WASM) targets using WebTunnel as the exclusive pluggable transport, backed by Rustls TLS and tokio-tungstenite WebSockets, while omitting WebRTC-based Snowflake support. The library enables Tor connectivity on desktop and server environments through RFC 9298 HTTPS bridges, offering a subset of features optimized for command-line and native async Rust applications.

Native Platform Capabilities Overview

When compiled for native targets, webtor-rs provides a focused feature set distinct from its browser-focused WASM build. The implementation prioritizes WebTunnel bridges for circumventing censorship, leveraging the native tokio runtime for asynchronous I/O.

Native-only features:

Unavailable on native:

  • Snowflake transport (WebRTC-based) explicitly panics when invoked on native platforms (src/snowflake.rs)

Cross-platform features:

Supported Transports on Native Builds

WebTunnel Bridge (Primary Transport)

The WebTunnel implementation serves as the sole pluggable transport for native builds, enabling Tor connections through corporate firewalls and restrictive networks. Located in src/webtunnel.rs, the WebTunnelBridge constructs a TCP connection, performs a Rustls TLS handshake, and initiates an HTTP Upgrade request conforming to RFC 9298.

This transport works identically across native and WASM targets, making it the recommended bridge type for cross-platform applications. The bridge requires a URL and RSA fingerprint, configured through TorClientOptions::webtunnel in src/config.rs.

WebSocket Fallback

For scenarios requiring raw WebSocket channels, native builds utilize tokio-tungstenite as implemented in src/websocket.rs under mod native. The WebSocketStream type opens TLS-protected WebSocket connections and splits the stream into asynchronous read/write halves, functioning as a fallback when bridges require WebSocket negotiation rather than raw TCP.

Snowflake Limitations

Native builds do not support Snowflake. The src/snowflake.rs module contains an explicit stub that panics when invoked on non-WASM targets, with source comments advising developers to use WebTunnel instead. This limitation stems from the WebRTC dependency required by Snowflake, which remains unimplemented for the native target architecture.

Native TLS Implementation

The src/tls.rs module provides the cryptographic foundation for native builds, implementing a TlsStream wrapper around tokio::net::TcpStream using the Rustls library. Key functions include:

  • create_tls_connector – Initializes the TLS configuration
  • wrap_with_tls – Upgrades a TCP stream to encrypted TLS
  • TlsStream::connect – Convenience method for direct TLS connections

All TLS functionality resides behind #[cfg(not(target_arch = "wasm32"))] compile-time guards, ensuring native builds utilize futures-rustls/tokio-rustls while WASM builds use browser crypto APIs.

Core Protocol Features

Circuit Management

The platform-agnostic Tor protocol implementation in src/client.rs, src/circuit.rs, and src/relay.rs compiles unchanged for native targets. This includes circuit creation, stream isolation, and relay selection algorithms. The TorClient orchestrates these components identically across platforms, requiring no platform-specific configuration for circuit operations.

Consensus Fetching

Directory consensus handling in src/directory.rs operates on native builds with one key difference: native platforms always fetch consensus data from the network rather than using embedded snapshots. The WASM build includes a compiled-in cached snapshot for browser environments, while native builds prioritize live directory authorities for up-to-date relay information.

Configuration and Usage Examples

Initializing a Native Client with WebTunnel

use webtor::{TorClient, TorClientOptions};

#[tokio::main]
async fn main() -> webtor::Result<()> {
    // WebTunnel bridge URL and its RSA fingerprint
    let bridge_url = "https://bridge.example.com/secret".to_string();
    let fingerprint = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".to_string();

    // Build options for a native WebTunnel bridge
    let opts = TorClientOptions::webtunnel(bridge_url, fingerprint);
    let client = TorClient::new(opts).await?;

    // Bootstrap the circuit
    client.bootstrap().await?;

    // Perform a GET request through Tor
    let resp = client.get("https://httpbin.org/ip").await?;
    println!("Response: {}", resp.text()?);

    client.close().await;
    Ok(())
}

Key source: TorClientOptions::webtunnel is defined in src/config.rs and wired to the native WebTunnelBridge in src/client.rs.

Establishing Direct TLS Connections

use webtor::tls::TlsStream;

#[tokio::main]
async fn main() -> webtor::Result<()> {
    // Connect directly to example.com on port 443 using native TLS
    let mut stream = TlsStream::connect("example.com", 443, "example.com").await?;
    // Use the stream as AsyncRead/AsyncWrite
    stream.close().await?;
    Ok(())
}

Key source: TlsStream::connect and the TLS wrapper live in src/tls.rs.

Using Native WebSockets

use webtor::websocket::WebSocketStream;

#[tokio::main]
async fn main() -> webtor::Result<()> {
    let ws = WebSocketStream::connect("wss://bridge.example.com/ws").await?;
    // Split the stream, send messages, read responses
    Ok(())
}

Key source: Native implementation in src/websocket.rs under mod native.

Summary

  • WebTunnel is the only supported pluggable transport for native builds of webtor-rs, implemented in src/webtunnel.rs with RFC 9298 HTTPS upgrade support.
  • Native TLS uses the Rustls stack via src/tls.rs, providing TlsStream and connector functions behind #[cfg(not(target_arch = "wasm32"))] guards.
  • WebSocket support relies on tokio-tungstenite in src/websocket.rs, offering TLS-protected WebSocket channels as a transport fallback.
  • Snowflake is unavailable on native targets; the src/snowflake.rs stub panics and directs users to WebTunnel.
  • Core Tor protocols including circuit management, stream isolation, and consensus fetching work identically across native and WASM, though native builds fetch consensus exclusively from the network.

Frequently Asked Questions

Does webtor-rs support Snowflake on native targets?

No. According to the source code in src/snowflake.rs, the native implementation is an intentional stub that panics if invoked. The library explicitly recommends using WebTunnel for native builds instead of the WebRTC-based Snowflake transport.

What TLS library does webtor-rs use for native builds?

Native builds use Rustls as implemented in src/tls.rs. The module provides create_tls_connector, wrap_with_tls, and TlsStream::connect functions that wrap tokio::net::TcpStream with TLS encryption using the futures-rustls/tokio-rustls crates.

How does consensus fetching differ between native and WASM?

On native targets, webtor-rs always fetches directory consensus data from the network via src/directory.rs. WASM builds include an embedded cached snapshot compiled into the binary, while native builds prioritize live directory authorities for the most current relay information.

Can I use webtor-rs without WebTunnel on native platforms?

While you can initialize a TorClient without explicit bridge configuration, direct Tor connections (without bridges) require standard Tor network access. If you need pluggable transport support for censorship circumvention on native platforms, WebTunnel is the only available option, as Snowflake and other WebRTC transports are not implemented.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →