From 4fdcfa5bee2ca9709d53e4c5fdd2a684da63f2b0 Mon Sep 17 00:00:00 2001 From: asxalex Date: Tue, 28 Jan 2025 15:47:24 +0800 Subject: [PATCH] is mtu's bug --- .cargo/config.toml | 3 + Cargo.lock | 17 ++- Cargo.toml | 3 +- Makefile | 10 +- src/bin/sdlan/main.rs | 10 +- src/lib.rs | 10 +- src/network/async_main.rs | 15 ++- src/network/device.rs | 4 +- src/network/ipv6.rs | 2 +- src/network/node.rs | 37 ++++--- src/network/packet.rs | 224 +++++++++++++++++++------------------- src/network/tun_linux.rs | 10 +- 12 files changed, 198 insertions(+), 147 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 7d7cf07..46cf537 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ [target.x86_64-unknown-linux-musl] linker = "x86_64-linux-musl-gcc" + +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" diff --git a/Cargo.lock b/Cargo.lock index 6c915fe..1b6cc3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -1374,6 +1374,18 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rolling-file" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "time", + "tracing", + "tracing-appender", + "tracing-subscriber", +] + [[package]] name = "rolling-file" version = "0.1.0" @@ -1454,6 +1466,7 @@ dependencies = [ "prost", "prost-build", "rand", + "rolling-file 0.1.0", "rsa", "sdlan-sn-rs", "structopt", @@ -1476,7 +1489,7 @@ dependencies = [ "once_cell", "prost", "rand", - "rolling-file", + "rolling-file 0.1.0 (git+ssh://git@git.asxalex.pw/rust/rolling-file.git)", "rsa", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index b72956e..b5aac34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,9 +23,10 @@ structopt = "0.3.26" tokio = { version = "1.38.0", features = ["full"] } tokio-util = "0.7.11" tracing = "0.1.40" +rolling-file = { path = "../rolling-file" } [target.'cfg(windows)'.dependencies] wintun = "0.4.0" [features] -tap = [] +tun = [] diff --git a/Makefile b/Makefile index d9a3921..e937f3a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,15 @@ self: - RUSTFLAGS="-L ." cargo build --features "tap" --release + RUSTFLAGS="-L ." cargo build --release linux: - RUSTFLAGS="-L ." cargo build --features "tap" --release --target x86_64-unknown-linux-musl + RUSTFLAGS="-L ." cargo build --release --target x86_64-unknown-linux-musl + +aarch64: + RUSTFLAGS="-L ." cargo build --release --target aarch64-unknown-linux-gnu + linux-tun: - RUSTFLAGS="-L ." cargo build --release + RUSTFLAGS="-L ." cargo build --features "tun" --release win: cargo build --release diff --git a/src/bin/sdlan/main.rs b/src/bin/sdlan/main.rs index ba11294..4acd821 100644 --- a/src/bin/sdlan/main.rs +++ b/src/bin/sdlan/main.rs @@ -11,7 +11,15 @@ use structopt::StructOpt; #[tokio::main] async fn main() { - let _guard = log::init_log(); + let _guard = rolling_file::new_log( + "./.output", + 7, + rolling_file::PeriodGap::Daily, + tracing::Level::DEBUG, + true, + true, + ); + // let _guard = log::init_log(); let cmd = CommandLineInput::from_args(); diff --git a/src/lib.rs b/src/lib.rs index b7591dd..e20c12b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,15 @@ pub async fn run_sdlan( init_arp(); - if let Err(e) = init_edge(&args.token, node_conf, args.tos, start_stop_sender).await { + if let Err(e) = init_edge( + &args.token, + node_conf, + args.tos, + start_stop_sender, + args.mtu, + ) + .await + { panic!("failed to init edge: {:?}", e); } let _ = sender.send(true); diff --git a/src/network/async_main.rs b/src/network/async_main.rs index 823df2d..043a583 100644 --- a/src/network/async_main.rs +++ b/src/network/async_main.rs @@ -61,7 +61,7 @@ async fn handle_tcp_message(msg: SdlanTcp) { }; let ip = ip_to_string(&dev.net_addr); - debug!("aes key is {:?}, ip is {}/{}", aes, ip, dev.net_bit_len,); + // debug!("aes key is {:?}, ip is {}/{}", aes, ip, dev.net_bit_len,); println!("assigned ip: {}", ip); edge.device_config .ip @@ -636,25 +636,32 @@ async fn find_peer_destination(eee: &'static Node, dst_mac: Mac) -> (SdlanSock, } let mut is_p2p = false; let result: SdlanSock; - if let Some(dst) = eee.known_peers.get_peer(&dst_mac) { + let mut need_delete_from_known_peers = false; + if let Some(dst) = eee.known_peers.peers.get_mut(&dst_mac) { let now = get_current_timestamp(); if now - dst.last_p2p.load(Ordering::Relaxed) >= ((dst.timeout / 2) as u64) { // too much time elapsed since we saw the peer, need to register again error!("last p2p is too old, deleting from known_peers"); - eee.known_peers.delete_peer_with_mac(&dst_mac); + need_delete_from_known_peers = true; + // eee.known_peers.delete_peer_with_mac(&dst_mac); + debug!("deleted from known"); result = eee.config.super_nodes [eee.config.super_node_index.load(Ordering::Relaxed) as usize] .deepcopy(); } else { // dst.last_seen.store(now, Ordering::Relaxed); is_p2p = true; - result = dst.sock.read().unwrap().deepcopy(); + result = dst.sock.deepcopy(); } } else { result = eee.config.super_nodes [eee.config.super_node_index.load(Ordering::Relaxed) as usize] .deepcopy(); } + + if need_delete_from_known_peers { + eee.known_peers.delete_peer_with_mac(&dst_mac); + } // println!("find peer_destination: {}", is_p2p); if !is_p2p { debug!("check_query_peer_info"); diff --git a/src/network/device.rs b/src/network/device.rs index ecfc695..a388639 100644 --- a/src/network/device.rs +++ b/src/network/device.rs @@ -7,16 +7,18 @@ use tracing::debug; use crate::utils::generate_mac_address; pub struct DeviceConfig { + pub mtu: u32, pub mac: RwLock, pub ip: IpSubnet, } impl DeviceConfig { - pub fn new() -> Self { + pub fn new(mtu: u32) -> Self { let mac = generate_mac_address(); println!("self mac: {}", mac_to_string(&mac)); debug!("self mac: {}", mac_to_string(&mac)); DeviceConfig { + mtu, mac: RwLock::new(mac), ip: IpSubnet::new(0, 0), } diff --git a/src/network/ipv6.rs b/src/network/ipv6.rs index 5f4d974..f11dd4e 100644 --- a/src/network/ipv6.rs +++ b/src/network/ipv6.rs @@ -76,7 +76,7 @@ pub fn get_current_ipv6() -> Option { } IpAddr::V6(ipv6) => { if ipv6.octets()[0] & 0x70 == 0x20 { - println!("got global ip: {}", ipv6); + // println!("got global ip: {}", ipv6); return Some(ipv6); } } diff --git a/src/network/node.rs b/src/network/node.rs index dd7b861..679e0a7 100644 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -35,6 +35,7 @@ pub async fn init_edge( node_conf: NodeConfig, tos: u32, start_stop: Sender, + mtu: u32, ) -> Result<()> { let _ = PidRecorder::new(".pid"); @@ -75,6 +76,7 @@ pub async fn init_edge( privatekey, tcp_pong.clone(), start_stop, + mtu, ); do_init_edge(edge)?; @@ -247,8 +249,9 @@ impl Node { private: RsaPrivateKey, tcp_pong: Arc, start_stop: Sender, + mtu: u32, ) -> Self { - let mode = if cfg!(feature = "tap") { + let mode = if cfg!(not(feature = "tun")) { Mode::Tap } else { Mode::Tun @@ -265,7 +268,7 @@ impl Node { nat_type: Mutex::new(NatType::Blocked), - device_config: DeviceConfig::new(), + device_config: DeviceConfig::new(mtu), device: new_iface("dev", mode), authorized: AtomicBool::new(false), @@ -463,7 +466,7 @@ impl Node { attr: msgattr as u32, cookie, }; - println!("==> sending probe request: {:?}", probe); + // println!("==> sending probe request: {:?}", probe); let (tx, rx) = oneshot::channel(); self.cookie_match.insert(cookie, tx); @@ -494,7 +497,7 @@ impl Node { } pub struct PeerMap { - pub peers: DashMap>, + pub peers: DashMap, } #[allow(unused)] @@ -505,33 +508,37 @@ impl PeerMap { } } - pub fn get_peer(&self, ip: &Mac) -> Option> { - if let Some(v) = self.peers.get(ip) { + /* + pub fn get_peer(&self, mac: &Mac) -> Option> { + if let Some(v) = self.peers.get(mac) { Some(v.clone()) } else { None } } + */ pub fn clear(&self) { self.peers.clear(); } pub fn get_peer_by_sock(&self, sock: &SdlanSock) -> Option> { + /* for s in self.peers.iter() { let m = s.sock.read().unwrap(); if is_sdlan_sock_equal(&m, sock) { return Some(s.value().clone()); } } + */ None } - pub fn delete_peer_with_mac(&self, mac: &Mac) -> Option<(Mac, Arc)> { + pub fn delete_peer_with_mac(&self, mac: &Mac) -> Option<(Mac, EdgePeer)> { self.peers.remove(mac) } - pub fn insert_peer(&self, mac: Mac, p: Arc) { + pub fn insert_peer(&self, mac: Mac, p: EdgePeer) { self.peers.insert(mac, p); } } @@ -609,12 +616,12 @@ pub struct EdgePeer { // pub mac: Mac, pub dev_addr: IpSubnet, - pub nat_type: RwLock, + pub nat_type: NatType, // 对端对外开放的ip和端口信息 - pub sock: RwLock, + pub sock: SdlanSock, // peer's ipv6 info - pub _v6_info: RwLock>, + pub _v6_info: Option, pub timeout: u8, @@ -653,18 +660,18 @@ impl EdgePeer { Self { // mac, dev_addr: IpSubnet::new(net_addr, net_bit_len), - sock: RwLock::new(sock.deepcopy()), - _v6_info: RwLock::new(v6_info), + sock: sock.deepcopy(), + _v6_info: v6_info, timeout: REGISTER_SUPER_INTERVAL as u8, last_p2p: AtomicU64::new(0), last_seen: AtomicU64::new(0), _last_valid_timestamp: AtomicU64::new(now), last_sent_query: AtomicU64::new(0), - nat_type: RwLock::new(NatType::Invalid), + nat_type: NatType::Invalid, } } pub fn get_nat_type(&self) -> NatType { - *self.nat_type.read().unwrap() + self.nat_type } } diff --git a/src/network/packet.rs b/src/network/packet.rs index fa32965..e742721 100644 --- a/src/network/packet.rs +++ b/src/network/packet.rs @@ -124,15 +124,18 @@ pub async fn handle_packet(eee: &'static Node, addr: SocketAddr, buf: &[u8]) -> ); } if data.is_p2p { - check_peer_registration_needed( - eee, - !data.is_p2p, - src_mac, - NatType::NoNat, - &None, - &from_sock, - ) - .await; + let from_sock = from_sock.deepcopy(); + tokio::spawn(async move { + check_peer_registration_needed( + eee, + !data.is_p2p, + src_mac, + NatType::NoNat, + &None, + &from_sock, + ) + .await; + }); } handle_tun_packet(eee, &from_sock, !data.is_p2p, data).await; } @@ -284,16 +287,19 @@ pub async fn handle_packet_peer_info( if dst_mac == NULL_MAC { // pong from sn } else { - match eee.pending_peers.get_peer(&dst_mac) { - Some(edgeinfo) => { + let pending = eee.pending_peers.peers.get_mut(&dst_mac); + match pending { + Some(mut v) => { let sock = SdlanSock { family: AF_INET, port: v4.port as u16, v4: v4_u32, v6: [0; 16], }; - *(edgeinfo.nat_type.write().unwrap()) = remote_nat; - *(edgeinfo.sock.write().unwrap()) = sock.deepcopy(); + v.nat_type = remote_nat; + v.sock = sock.deepcopy(); + // v.sock = sock.deepcopy(); + info!( "Rx PEERINFO for {}: is at {}", mac_to_string(&dst_mac), @@ -304,8 +310,6 @@ pub async fn handle_packet_peer_info( v6_info = Some(V6Info { port: v6_port, v6 }) } send_register(eee, remote_nat, &sock, dst_mac, &v6_info).await; - - // register_with_local_peers(eee).await; } None => { debug!("Rx PEERINFO unknown peer: {}", mac_to_string(&dst_mac)); @@ -544,26 +548,28 @@ pub async fn check_peer_registration_needed( _v6_info: &Option, peer_sock: &SdlanSock, ) { - let mut p = eee.known_peers.get_peer(&src_mac); - if let None = p { - p = eee.known_peers.get_peer_by_sock(peer_sock); - if let Some(ref k) = p { - eee.known_peers.insert_peer(src_mac, k.clone()); - } - } + let mut p = eee.known_peers.peers.get(&src_mac); + let last_seen; + let now; match p { None => { debug!("check peer registration needed, not found in known peers"); let _ = register_with_new_peer(eee, from_sn, src_mac, _v6_info, remote_nat, peer_sock) .await; + return; // unimplemented!(); } Some(k) => { - let mut ipv4_to_ipv6 = false; - let now = get_current_timestamp(); + // let mut ipv4_to_ipv6 = false; + now = get_current_timestamp(); if !from_sn { k.last_p2p.store(now, Ordering::Relaxed); } + let origin_family = k.sock.family; + if origin_family != peer_sock.family { + return; + } + /* if peer_sock.family == AF_INET6 && k.sock.read().unwrap().family == AF_INET { println!("changing to ipv6"); *k.sock.write().unwrap() = peer_sock.deepcopy(); @@ -571,14 +577,15 @@ pub async fn check_peer_registration_needed( } else { println!("already is ipv6"); } - let last_seen = k.last_seen.load(Ordering::Relaxed); + */ + last_seen = k.last_seen.load(Ordering::Relaxed); // more than 3 seconds - if now - last_seen > 3 { - check_known_peer_sock_change(eee, from_sn, src_mac, peer_sock, now, ipv4_to_ipv6) - .await; - } } } + + if now - last_seen > 300 { + check_known_peer_sock_change(eee, from_sn, src_mac, peer_sock, now, false).await; + } } async fn check_known_peer_sock_change( @@ -594,30 +601,38 @@ async fn check_known_peer_sock_change( if is_multi_broadcast(&mac) { return; } - match eee.known_peers.get_peer(&mac) { + let mut delete_from_known_peers = false; + let remote_nat; + match eee.known_peers.peers.get_mut(&mac) { Some(p) => { - if !ipv4_to_ipv6 && !is_sdlan_sock_equal(&p.sock.read().unwrap(), peersock) { + if !ipv4_to_ipv6 && !is_sdlan_sock_equal(&p.sock, peersock) { if !from_sn { info!( "peer changed: {}: {} -> {}", mac_to_string(&mac), - &p.sock.read().unwrap().to_string(), + &p.sock.to_string(), peersock.to_string() ); - eee.known_peers.delete_peer_with_mac(&mac); - error!("known peers is deleted"); - let remote_nat = p.get_nat_type(); - register_with_new_peer(eee, from_sn, mac, &None, remote_nat, peersock).await; + delete_from_known_peers = true; + remote_nat = p.get_nat_type(); } else { // from sn, sn could see a different sock with us, just ignore it + return; } } else { p.last_seen.store(when, Ordering::Relaxed); + return; // from sn, sn could see a different sock with us, just ignore it } } None => return, } + + if delete_from_known_peers { + eee.known_peers.delete_peer_with_mac(&mac); + error!("known peers is deleted"); + register_with_new_peer(eee, from_sn, mac, &None, remote_nat, peersock).await; + } } async fn register_with_new_peer( @@ -630,25 +645,21 @@ async fn register_with_new_peer( peersock: &SdlanSock, ) { let now = get_current_timestamp(); - let mut scan = eee.pending_peers.get_peer(&mac); - if let None = scan { - // such ip not found in pending - let temp = Arc::new(EdgePeer::new( - // mac, - 0, - eee.device_config.get_net_bit(), - peersock, - &None, - now, - )); + let entry = eee.pending_peers.peers.entry(mac); + let mut new_created = false; + + let mut scan = entry.or_insert_with(|| { + new_created = true; + let temp = EdgePeer::new(0, eee.device_config.get_net_bit(), peersock, &None, now); + temp + }); + + if new_created { debug!( "===> new pending {} => {}", mac_to_string(&mac), peersock.to_string(), ); - eee.pending_peers.insert_peer(mac, temp.clone()); - scan = Some(temp); - debug!("Pending size: {}", eee.pending_peers.peers.len()); if from_sn { // should send register to peer @@ -690,14 +701,11 @@ async fn register_with_new_peer( } register_with_local_peers(eee).await; } else { - if let Some(ref s) = scan { - *(s.sock.write().unwrap()) = peersock.deepcopy(); - } - } - if let Some(s) = scan { - s.last_seen - .store(get_current_timestamp(), Ordering::Relaxed); + scan.sock = peersock.deepcopy(); } + + scan.last_seen + .store(get_current_timestamp(), Ordering::Relaxed); } async fn register_with_local_peers(eee: &'static Node) { @@ -1024,10 +1032,9 @@ async fn send_register_ack(eee: &Node, orig_sender: &SdlanSock, reg: &SdlRegiste } fn peer_set_p2p_confirmed(eee: &Node, src_mac: Mac, sender_sock: &SdlanSock) { - let mut scan = eee.pending_peers.get_peer(&src_mac); - if let None = scan { - scan = eee.pending_peers.get_peer_by_sock(sender_sock); - } + // let mut scan = eee.pending_peers.get_peer(&src_mac); + let scan = eee.pending_peers.peers.remove(&src_mac); + if let None = scan { error!( "failed to find sender in pending peer: {}", @@ -1035,30 +1042,17 @@ fn peer_set_p2p_confirmed(eee: &Node, src_mac: Mac, sender_sock: &SdlanSock) { ); return; } + let (_, scan) = scan.unwrap(); - let mut scan = scan.unwrap(); - eee.pending_peers.delete_peer_with_mac(&src_mac); - match eee.known_peers.get_peer(&src_mac) { - Some(scantmp) => { - eee.known_peers.delete_peer_with_mac(&src_mac); - scan = scantmp; - // set the remote peer sock - *scan.sock.write().unwrap() = sender_sock.deepcopy(); - // scan.mac = src_mac; - /* - scan.dev_addr.net_addr.store(&src_mac, Ordering::Relaxed); - scan.dev_addr - .net_bit_len - .store(eee.device_config.get_net_bit(), Ordering::Relaxed); - */ - } - None => { - *(scan.sock.write().unwrap()) = sender_sock.deepcopy(); - } + { + let entry = eee.known_peers.peers.entry(src_mac); + let mut scan2 = entry.or_insert(scan); + scan2.sock = sender_sock.deepcopy(); + + let now = get_current_timestamp(); + scan2.last_p2p.store(now, Ordering::Relaxed); + scan2.last_seen.store(now, Ordering::Relaxed); } - let now = get_current_timestamp(); - scan.last_p2p.store(now, Ordering::Relaxed); - scan.last_seen.store(now, Ordering::Relaxed); let mac_string = mac_to_string(&src_mac); let sock_string = sender_sock.to_string(); @@ -1066,45 +1060,47 @@ fn peer_set_p2p_confirmed(eee: &Node, src_mac: Mac, sender_sock: &SdlanSock) { "P2P connection established: {} [{}]", &mac_string, &sock_string, ); - eee.known_peers.insert_peer(src_mac, scan); + // eee.known_peers.insert_peer(src_mac, scan); debug!("==> new peer: {} -> {}", &mac_string, &sock_string,); } pub async fn check_query_peer_info(eee: &'static Node, mac: Mac) { let scan: Arc; let now = get_current_timestamp(); - match eee.pending_peers.get_peer(&mac) { - None => { - let sock = SdlanSock { - family: AF_INET, - port: 0, - v4: [0; 4], - v6: [0; 16], - }; - let peer = Arc::new(EdgePeer::new( - // mac, - 0, - eee.device_config.get_net_bit(), - &sock, - &None, - now, - )); - debug!("insert peer {} to pending", mac_to_string(&mac)); - eee.pending_peers.insert_peer(mac, peer.clone()); - scan = peer; - } - Some(s) => { - scan = s; + + let last_sent_query; + let mut need_send_query = false; + { + let entry = eee.pending_peers.peers.entry(mac); + + let sock = SdlanSock { + family: AF_INET, + port: 0, + v4: [0; 4], + v6: [0; 16], + }; + let peer = EdgePeer::new( + // mac, + 0, + eee.device_config.get_net_bit(), + &sock, + &None, + now, + ); + debug!("insert peer {} to pending", mac_to_string(&mac)); + let val = entry.or_insert(peer); + last_sent_query = val.last_sent_query.load(Ordering::Relaxed); + if now - last_sent_query > (REGISTER_INTERVAL as u64) { + need_send_query = true; + val.last_sent_query.store(now, Ordering::Relaxed); } } + debug!( - "now={}, last_sent_query={}, REGISTER_INTERVAL={}, scan={:?}", - now, - scan.last_sent_query.load(Ordering::Relaxed), - REGISTER_INTERVAL, - scan, + "now={}, last_sent_query={}, REGISTER_INTERVAL={}", + now, last_sent_query, REGISTER_INTERVAL, ); - if now - scan.last_sent_query.load(Ordering::Relaxed) > (REGISTER_INTERVAL as u64) { + if need_send_query { /* send_register( eee, @@ -1115,9 +1111,7 @@ pub async fn check_query_peer_info(eee: &'static Node, mac: Mac) { */ debug!("sending query for {}", mac_to_string(&mac)); register_with_local_peers(eee).await; - if let Ok(()) = send_query_peer(eee, mac).await { - scan.last_sent_query.store(now, Ordering::Relaxed); - } + send_query_peer(eee, mac).await; } } diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index 98e2c22..a6df79a 100644 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -116,7 +116,7 @@ impl Iface { let ip = ip_to_string(&ip); let netbit = ip_to_string(&net_bit_len_to_mask(netbit)); - if cfg!(feature = "tap") { + if cfg!(not(feature = "tun")) { println!("set tap device"); let mac = device_config.get_mac(); let res = Command::new("ifconfig") @@ -130,6 +130,8 @@ impl Iface { "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] )) + .arg("mtu") + .arg(format!("{}", device_config.mtu)) .arg("up") .output(); match res { @@ -147,6 +149,8 @@ impl Iface { .arg(ip) .arg("netmask") .arg(&netbit) + .arg("mtu") + .arg(format!("{}", device_config.mtu)) .arg("up") .output(); match res { @@ -169,7 +173,7 @@ impl Iface { } } -#[cfg(feature = "tap")] +#[cfg(not(feature = "tun"))] impl TunTapPacketHandler for Iface { async fn handle_packet_from_net(&self, data: &[u8], _: &[u8]) -> std::io::Result<()> { // debug!("in tap mode, got data: {:?}", data); @@ -221,7 +225,7 @@ impl TunTapPacketHandler for Iface { } } -#[cfg(not(feature = "tap"))] +#[cfg(feature = "tun")] impl TunTapPacketHandler for Iface { async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()> { debug!("in tun mode");