5 个版本 (3 个稳定)
1.1.1 | 2024年8月7日 |
---|---|
1.0.0 | 2024年8月7日 |
0.7.1 | 2024年7月14日 |
0.6.1 | 2024年6月2日 |
#333 在 网络编程
每月下载 1,357
在 easytier 中使用
150KB
3.5K SLoC
TUN 接口
这个crate允许创建和使用TUN接口,目标是使其跨平台。
由于原始维护者@meh已不再有兴趣继续维护tun在repo,我们(@ssrlive, @xmh0511)创建了tun2分支仓库并继续积极更新。欢迎任何感兴趣的贡献者。如果您想成为tun2的共同贡献者和发布者,请在issues中与我联系。
对我来说,提交的PR已经很长时间没有审查,无法合并到主分支,也无法发布。这就像一个手术台上长时间未被缝合的病人。这是一种糟糕的经历。我相信很多人都有同样的感受。
使用方法
首先,将以下内容添加到您的 Cargo.toml
[dependencies]
tun2 = "2"
如果您想使用mio/tokio的TUN接口,您需要启用async
功能
[dependencies]
tun2 = { version = "2", features = ["async"] }
示例
以下示例创建和配置一个TUN接口,并开始从中读取数据包。
use std::io::Read;
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let mut config = tun2::Configuration::default();
config
.address((10, 0, 0, 9))
.netmask((255, 255, 255, 0))
.destination((10, 0, 0, 1))
.up();
#[cfg(target_os = "linux")]
config.platform_config(|config| {
// requiring root privilege to acquire complete functions
config.ensure_root_privileges(true);
});
let mut dev = tun2::create(&config)?;
let mut buf = [0; 4096];
loop {
let amount = dev.read(&mut buf)?;
println!("{:?}", &buf[0..amount]);
}
}
平台
支持的平台
- Windows
- Linux
- macOS
- FreeBSD
- Android
- iOS
Linux
您需要加载tun2
模块,并且需要root权限来创建接口。
macOS & FreeBSD
tun2
将根据提供的配置自动设置路由,这类似于以下操作
sudo route -n add -net 10.0.0.0/24 10.0.0.1
iOS
您可以将TUN设备的文件描述符传递给tun2
来创建接口。
以下是一个在iOS上创建TUN设备并将fd
传递给tun2
的示例
// 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)
}
}
}
#[no_mangle]
pub extern "C" fn start_tun(fd: std::os::raw::c_int) {
let mut rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let mut cfg = tun2::Configuration::default();
cfg.raw_fd(fd);
#[cfg(target_os = "ios")]
cfg.platform_config(|p_cfg| {
p_cfg.packet_information(true);
});
let mut tun = tun2::create_as_async(&cfg).unwrap();
let mut framed = tun.into_framed();
while let Some(packet) = framed.next().await {
...
}
});
}
Windows
您需要将与您的架构匹配的wintun.dll文件复制到与可执行文件相同的目录,并以管理员身份运行您的程序。
依赖项
~0.5–12MB
~114K SLoC