I've a very simple program that creates a tun device, splits it, and writes to the write half. The write succeeds, but when I attempt to call flush it panics. Here's my sample:
#![deny(clippy::all)]
#![warn(clippy::pedantic)]
use tokio::io::AsyncWriteExt;
use std::os::fd::AsRawFd;
use tokio_tun::Tun;
use std::net::Ipv4Addr;
#[tokio::main]
async fn main() -> () {
let tun = Tun::builder()
.name("foo")
.tap(false)
.packet_info(false)
.up()
.address(Ipv4Addr::new(10, 0, 0, 1))
.destination(Ipv4Addr::new(10, 1, 0, 1))
.broadcast(Ipv4Addr::BROADCAST)
.netmask(Ipv4Addr::new(255, 255, 255, 0))
.try_build()
.unwrap();
println!("tun created, name: {}, fd: {}", tun.name(), tun.as_raw_fd());
let (_reader, mut writer) = tokio::io::split(tun);
// Just a basic ICMP request packet
let packet = [
69, 0, 0, 84, 0, 0, 64, 0, 64, 1, 38, 166, 10, 1, 0, 2, 10, 0, 0, 1,
0, 0, 102, 216, 0, 7, 5, 26, 197, 176, 29, 101, 0, 0, 0, 0, 238, 29, 4,
0, 0, 0, 0, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55];
writer.write_all(&packet).await.unwrap();
writer.flush().await.unwrap();
}
When I invoke this small program with root privs via the following command, I generate a stack trace:
$ cargo b && sudo RUST_BACKTRACE=full ./target/debug/pinger-tokio
$ cargo b && sudo RUST_BACKTRACE=full ./target/debug/pinger-tokio
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
tun created, name: foo, fd: 9
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }', src/main.rs:36:26
stack backtrace:
0: 0x559179961511 - std::backtrace_rs::backtrace::libunwind::trace::h66dc1c6acf794faa
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x559179961511 - std::backtrace_rs::backtrace::trace_unsynchronized::ha80d20099a67f790
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x559179961511 - std::sys_common::backtrace::_print_fmt::h7b959d43f35f16d4
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:65:5
3: 0x559179961511 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hdaa196410d9ee0b9
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:44:22
4: 0x559179982cef - core::fmt::rt::Argument::fmt::h0ddfbbe8be3f80d0
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/fmt/rt.rs:138:9
5: 0x559179982cef - core::fmt::write::h66b3c629f3d623e4
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/fmt/mod.rs:1094:21
6: 0x55917995e927 - std::io::Write::write_fmt::hb6d80fba4115e0c2
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/io/mod.rs:1714:15
7: 0x559179961325 - std::sys_common::backtrace::_print::h1a49cfb0cf3cce17
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:47:5
8: 0x559179961325 - std::sys_common::backtrace::print::hca95c2d0055e42a2
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:34:9
9: 0x559179962853 - std::panicking::default_hook::{{closure}}::hc03c01c56bca600c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:269:22
10: 0x5591799625e4 - std::panicking::default_hook::hb2cb5315b6634f1c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:288:9
11: 0x559179962dd9 - std::panicking::rust_panic_with_hook::h75cd912a39a34e8a
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:705:13
12: 0x559179962cd7 - std::panicking::begin_panic_handler::{{closure}}::h1498b46f7849e167
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:597:13
13: 0x559179961976 - std::sys_common::backtrace::__rust_end_short_backtrace::hd36a39b27b98086b
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:151:18
14: 0x559179962a22 - rust_begin_unwind
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:593:5
15: 0x559179875273 - core::panicking::panic_fmt::h98ef273141454c23
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:67:14
16: 0x559179875743 - core::result::unwrap_failed::h26e7d1a596cddd61
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/result.rs:1651:5
17: 0x55917987a2cd - core::result::Result<T,E>::unwrap::hfba736a1f516fc32
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/result.rs:1076:23
18: 0x55917987d0b2 - pinger_tokio::main::{{closure}}::hb4c29fabc0e0a84c
at /home/rjw/pinger-tokio/src/main.rs:36:5
19: 0x559179876674 - tokio::runtime::park::CachedParkThread::block_on::{{closure}}::hc2102838ad1ff373
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/park.rs:282:63
20: 0x5591798764a5 - tokio::runtime::coop::with_budget::h7bd2944232a4b354
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/coop.rs:107:5
21: 0x5591798764a5 - tokio::runtime::coop::budget::h35f9a719fa4c7073
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/coop.rs:73:5
22: 0x5591798764a5 - tokio::runtime::park::CachedParkThread::block_on::hdd97a7aecde53be4
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/park.rs:282:31
23: 0x55917987c2e5 - tokio::runtime::context::blocking::BlockingRegionGuard::block_on::h8bcad03ed3746a7a
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context/blocking.rs:66:9
24: 0x55917987c056 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}::hdc0db8febb28906c
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/multi_thread/mod.rs:87:13
25: 0x55917987b8fc - tokio::runtime::context::runtime::enter_runtime::h83da395e19220ae7
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context/runtime.rs:65:16
26: 0x55917987c011 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::h0b01f4b37ea5a961
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/multi_thread/mod.rs:86:9
27: 0x5591798767cb - tokio::runtime::runtime::Runtime::block_on::hc28efc14991c6fd4
at /home/rjw/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/runtime.rs:349:45
28: 0x55917987a9fd - pinger_tokio::main::h5657d9d59fbfb77f
at /home/rjw/pinger-tokio/src/main.rs:36:5
29: 0x55917987719b - core::ops::function::FnOnce::call_once::h9646c2d630b860c2
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:250:5
30: 0x55917987c5de - std::sys_common::backtrace::__rust_begin_short_backtrace::h574604846fa0a270
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:135:18
31: 0x559179877a11 - std::rt::lang_start::{{closure}}::he00ac19dd4a14f13
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:166:18
32: 0x55917995b3eb - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h87e9a912d8a0de33
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:284:13
33: 0x55917995b3eb - std::panicking::try::do_call::ha8d57d42181c12cf
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
34: 0x55917995b3eb - std::panicking::try::h2fdb2d19c253437c
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
35: 0x55917995b3eb - std::panic::catch_unwind::h9fe5959d2e133449
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
36: 0x55917995b3eb - std::rt::lang_start_internal::{{closure}}::ha072eb7bbeaa0b6a
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:48
37: 0x55917995b3eb - std::panicking::try::do_call::h983dae29f79ed5db
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
38: 0x55917995b3eb - std::panicking::try::h15014751f4b412ba
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
39: 0x55917995b3eb - std::panic::catch_unwind::hf837426183b1055f
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
40: 0x55917995b3eb - std::rt::lang_start_internal::h2bbe0b58b2b89a9f
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:20
41: 0x5591798779ea - std::rt::lang_start::hf6639bc367ab8881
at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:165:17
42: 0x55917987aaae - main
43: 0x7f4c90c900d0 - <unknown>
44: 0x7f4c90c90189 - __libc_start_main
45: 0x559179875a45 - _start
46: 0x0 - <unknown>
I'd like to note that if I use async-tun, I can write to the Tun device fine. The difference may be in the tokio::split vs. Tun.writer() calls, I'm not sure. Thought, it appears this is not the case, as changing the sample program above to forego calling tokio::io::split and instead just writing and flushing the Tun device directly produces the same result. e.g.,
// Just a basic ICMP request packet
let packet = [
69, 0, 0, 84, 0, 0, 64, 0, 64, 1, 38, 166, 10, 1, 0, 2, 10, 0, 0, 1,
0, 0, 102, 216, 0, 7, 5, 26, 197, 176, 29, 101, 0, 0, 0, 0, 238, 29, 4,
0, 0, 0, 0, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55];
tun.write_all(&packet).await.unwrap();
tun.flush().await.unwrap();
I should also note my platform info:
$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home: /home/rjw/.rustup
installed toolchains
--------------------
stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu
active toolchain
----------------
stable-x86_64-unknown-linux-gnu (default)
rustc 1.72.1 (d5c2e9c34 2023-09-13)
$ uname -a Linux angband 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
As you can see, I am running on Ubuntu under WSL. I'm not sure this is relevant but, one never knows.