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:
- WebTunnel transport via HTTPS with RFC 9298 Upgrade (
src/webtunnel.rs) - Native TLS stack using Rustls (
src/tls.rs) - WebSocket client via
tokio-tungstenite(src/websocket.rs)
Unavailable on native:
- Snowflake transport (WebRTC-based) explicitly panics when invoked on native platforms (
src/snowflake.rs)
Cross-platform features:
- Circuit creation, stream isolation, and relay selection (
src/client.rs,src/circuit.rs) - Consensus directory fetching (
src/directory.rs) - Platform-agnostic time utilities (
src/time.rs)
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 configurationwrap_with_tls– Upgrades a TCP stream to encrypted TLSTlsStream::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.rswith RFC 9298 HTTPS upgrade support. - Native TLS uses the Rustls stack via
src/tls.rs, providingTlsStreamand connector functions behind#[cfg(not(target_arch = "wasm32"))]guards. - WebSocket support relies on
tokio-tungsteniteinsrc/websocket.rs, offering TLS-protected WebSocket channels as a transport fallback. - Snowflake is unavailable on native targets; the
src/snowflake.rsstub 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →