Tun/Tap interfaces
This crate allows the creation and usage of Tun/Tap interfaces(supporting both Ipv4 and ipv6), aiming to make this cross-platform.
Features:
- Supporting TUN and TAP
- Supporting both IPv4 and IPv6
- Supporting Synchronous and Asynchronous API
- Supports choosing between Tokio and async-io for asynchronous I/O operations.
- All platforms have consistent IP packets(macOS's 4-byte head information can be eliminated)
- Experimentally supporting shutdown for Synchronous version
- Supporting Offload (
TSO
/GSO
) on Linux - Supporting
multi-queue
on Linux - Having a consistent behavior of setting up routes when creating a device
Supported Platforms
Platform | TUN | TAP |
---|---|---|
Windows | ✅ | ✅ |
Linux | ✅ | ✅ |
macOS | ✅ | ⬜ |
FreeBSD | ✅ | ✅ |
Android | ✅ | |
iOS | ✅ | |
Other* | ✅ |
For other Unix-like platforms,You can use raw_fd
Usage
First, add the following to your Cargo.toml
:
[]
# Base sync API (no async runtime)
= "2"
## For async runtime integration
## (choose ONE based on your runtime):
# tokio:
#tun-rs = { version = "2", features = ["async"] }
# async-std, smol, and other
# asynchronous runtimes based on async-io:
#tun-rs = { version = "2", features = ["async_io"] }
Example
The following example creates and configures a TUN interface and reads packets from it synchronously.
use DeviceBuilder;
An example of asynchronously reading packets from an interface
use DeviceBuilder;
async
On Unix, a device can also be directly created using a file descriptor (fd).
use SyncDevice;
More examples are here
Linux
You will need the tun-rs
module to be loaded and root is required to create
interfaces.
TSO
/GSO
and multi-queue
is supported on the Linux platform, enable it via the config
use DeviceBuilder;
use ;
macOS & FreeBSD
tun-rs
will automatically set up a route according to the provided configuration, which does a similar thing like
this:
sudo route -n add -net 10.0.0.0/24 10.0.0.1
iOS
You can pass the file descriptor of the TUN device to tun-rs
to create the interface.
Here is an example to create the TUN device on iOS and pass the fd
to tun-rs
:
// Swift
class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let tunnelNetworkSettings = createTunnelSettings() // Configure TUN address, DNS, mtu, routing...
setTunnelNetworkSettings(tunnelNetworkSettings) { [weak self] error in
// The tunnel of this tunFd is contains `Packet Information` prifix.
let tunFd = self?.packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32
DispatchQueue.global(qos: .default).async {
start_tun(tunFd)
}
completionHandler(nil)
}
}
}
pub extern "C"
Android
// use android.net.VpnService
private void
Windows
Tun:
You need to copy the wintun.dll file which matches your architecture to the same directory as your executable and run your program as administrator.
Tap:
When using the tap network interface, you need to manually install tap-windows that matches your architecture.