diff --git a/examples/tun2.rs b/examples/tun2.rs index 1df739f..d802de8 100644 --- a/examples/tun2.rs +++ b/examples/tun2.rs @@ -18,6 +18,15 @@ //! route add 1.2.3.4 mask 255.255.255.255 10.0.0.1 metric 100 # Windows //! sudo route add 1.2.3.4/32 10.0.0.1 # macOS //! ``` +//! +//! In Windows, the route of `0.0.0.0` will be added to your tun interface automatically, +//! it will cause all traffic to be routed to it. So you can't access the Internet anymore. +//! To solve this problem, you must delete the route of `0.0.0.0` with the following command: +//! ``` +//! route delete 0.0.0.0 mask 0.0.0.0 10.0.0.1 # Windows +//! ``` +//! Then the traffic will be routed to your physical network card. +//! //! Now you can test it with `nc 1.2.3.4 any_port` or `nc -u 1.2.3.4 any_port`. //! You can watch the echo information in the `nc` console. //! ``` @@ -71,62 +80,78 @@ async fn main() -> Result<(), Box> { let netmask = Ipv4Addr::new(255, 255, 255, 0); let gateway = Ipv4Addr::new(10, 0, 0, 1); - let mut config = tun2::Configuration::default(); - config.address(ipv4).netmask(netmask).mtu(MTU).up(); - config.destination(gateway); + let mut tun_config = tun2::Configuration::default(); + tun_config.address(ipv4).netmask(netmask).mtu(MTU).up(); + tun_config.destination(gateway); #[cfg(target_os = "linux")] - config.platform_config(|config| { - config.ensure_root_privileges(true); + tun_config.platform_config(|p_cfg| { + p_cfg.ensure_root_privileges(true); }); #[cfg(target_os = "windows")] - config.platform_config(|config| { - config.device_guid(Some(12324323423423434234_u128)); + tun_config.platform_config(|p_cfg| { + p_cfg.device_guid(Some(12324323423423434234_u128)); }); let mut ipstack_config = ipstack::IpStackConfig::default(); ipstack_config.mtu(MTU); - let mut ip_stack = ipstack::IpStack::new(ipstack_config, tun2::create_as_async(&config)?); + let mut ip_stack = ipstack::IpStack::new(ipstack_config, tun2::create_as_async(&tun_config)?); let server_addr = args.server_addr; + let count = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); + let serial_number = std::sync::atomic::AtomicUsize::new(0); + loop { + let count = count.clone(); + let number = serial_number.fetch_add(1, std::sync::atomic::Ordering::Relaxed); match ip_stack.accept().await? { IpStackStream::Tcp(mut tcp) => { let mut s = match TcpStream::connect(server_addr).await { Ok(s) => s, Err(e) => { - println!("connect TCP server failed \"{}\"", e); + log::info!("connect TCP server failed \"{}\"", e); continue; } }; - println!("==== New TCP connection ===="); + let c = count.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + 1; + let number1 = number; + log::info!("#{number1} TCP connecting, session count {c}"); tokio::spawn(async move { - let _ = tokio::io::copy_bidirectional(&mut tcp, &mut s).await; - println!("====== end tcp connection ======"); + if let Err(err) = tokio::io::copy_bidirectional(&mut tcp, &mut s).await { + log::error!("#{number1} TCP error: {}", err); + } + let c = count.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) - 1; + log::info!("#{number1} TCP closed, session count {c}"); }); } IpStackStream::Udp(mut udp) => { let mut s = match UdpStream::connect(server_addr).await { Ok(s) => s, Err(e) => { - println!("connect UDP server failed \"{}\"", e); + log::info!("connect UDP server failed \"{}\"", e); continue; } }; - println!("==== New UDP connection ===="); + let c = count.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + 1; + let number2 = number; + log::info!("#{number2} UDP connecting, session count {c}"); tokio::spawn(async move { - let _ = tokio::io::copy_bidirectional(&mut udp, &mut s).await; - println!("==== end UDP connection ===="); + if let Err(err) = tokio::io::copy_bidirectional(&mut udp, &mut s).await { + log::error!("#{number2} UDP error: {}", err); + } + let c = count.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) - 1; + log::info!("#{number2} UDP closed, session count {c}"); }); } IpStackStream::UnknownTransport(u) => { + let n = number; if u.src_addr().is_ipv4() && u.ip_protocol() == IpNumber::ICMP { let (icmp_header, req_payload) = Icmpv4Header::from_slice(u.payload())?; if let etherparse::Icmpv4Type::EchoRequest(req) = icmp_header.icmp_type { - println!("ICMPv4 echo"); + log::info!("#{n} ICMPv4 echo"); let echo = IcmpEchoHeader { id: req.id, seq: req.seq, @@ -137,15 +162,15 @@ async fn main() -> Result<(), Box> { payload.extend_from_slice(req_payload); u.send(payload)?; } else { - println!("ICMPv4"); + log::info!("#{n} ICMPv4"); } continue; } - println!("unknown transport - Ip Protocol {:?}", u.ip_protocol()); + log::info!("#{n} unknown transport - Ip Protocol {:?}", u.ip_protocol()); continue; } IpStackStream::UnknownNetwork(pkt) => { - println!("unknown transport - {} bytes", pkt.len()); + log::info!("#{number} unknown transport - {} bytes", pkt.len()); continue; } };