Changes to be committed:

modified:   Cargo.lock
	modified:   Cargo.toml
	modified:   src/client.rs
	modified:   src/server.rs
This commit is contained in:
Michael Wain 2024-08-11 20:25:37 +03:00
parent 6ce51c0679
commit b2f09f1de2
4 changed files with 211 additions and 123 deletions

119
Cargo.lock generated
View File

@ -217,6 +217,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.2.5" version = "0.2.5"
@ -295,7 +301,17 @@ version = "3.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345"
dependencies = [ dependencies = [
"nix", "nix 0.28.0",
"windows-sys 0.52.0",
]
[[package]]
name = "ctrlc2"
version = "3.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76b9bdf0b3623a4c37b654b319624bae363b94c4e27c22db8d48a61c6d74234f"
dependencies = [
"nix 0.28.0",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -459,6 +475,15 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hwaddr"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e414433a9e4338f4e87fa29d0670c883a5e73e7955c45f4a49130c0aa992c85b"
dependencies = [
"phf",
]
[[package]] [[package]]
name = "inout" name = "inout"
version = "0.1.3" version = "0.1.3"
@ -474,6 +499,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c" checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c"
[[package]]
name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.155"
@ -541,7 +572,19 @@ checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"cfg-if", "cfg-if",
"cfg_aliases", "cfg_aliases 0.1.1",
"libc",
]
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases 0.2.1",
"libc", "libc",
] ]
@ -560,6 +603,18 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "packet"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c136c7ad0619ed4f88894aecf66ad86c80683e7b5d707996e6a3a7e0e3916944"
dependencies = [
"bitflags 1.3.2",
"byteorder",
"hwaddr",
"thiserror",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.3" version = "0.12.3"
@ -583,6 +638,24 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.14" version = "0.2.14"
@ -721,16 +794,19 @@ dependencies = [
"block-padding", "block-padding",
"clap", "clap",
"ctrlc", "ctrlc",
"ctrlc2",
"env_logger", "env_logger",
"futures", "futures",
"generic-array", "generic-array",
"log", "log",
"packet",
"rand", "rand",
"serde", "serde",
"serde_derive", "serde_derive",
"socket2 0.4.10", "socket2 0.4.10",
"tokio", "tokio",
"tun", "tun",
"tun2",
] ]
[[package]] [[package]]
@ -768,6 +844,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.9"
@ -914,7 +996,25 @@ dependencies = [
"libc", "libc",
"log", "log",
"thiserror", "thiserror",
"wintun", "wintun 0.3.2",
]
[[package]]
name = "tun2"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50ff242bea1c5ceb9b6aa4918cf340a6c157e1328a2389c5353cf91049d8cf17"
dependencies = [
"bytes",
"cfg-if",
"ipnet",
"libc",
"libloading",
"log",
"nix 0.29.0",
"thiserror",
"windows-sys 0.52.0",
"wintun 0.5.0",
] ]
[[package]] [[package]]
@ -1165,6 +1265,19 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "wintun"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b196f9328341b035820c54beebca487823e2e20a5977f284f2af2a0ee8f04400"
dependencies = [
"c2rust-bitfields",
"libloading",
"log",
"thiserror",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.35" version = "0.7.35"

View File

@ -25,3 +25,6 @@ socket2 = "0.4"
env_logger = "0.9" env_logger = "0.9"
log = "0.4.20" log = "0.4.20"
futures = "0.3.30" futures = "0.3.30"
tun2 = "2.0.5"
packet = "0.1.4"
ctrlc2 = "3.5"

View File

@ -1,12 +1,15 @@
use tokio::{net::UdpSocket, sync::{mpsc, Mutex}};
use std::{borrow::{Borrow, BorrowMut}, future::IntoFuture, io::{self, Read, Write}, net::SocketAddr, sync::Arc, thread, time};
use std::process::Command; use std::process::Command;
use clap::{App, Arg}; use clap::{App, Arg};
use env_logger::Builder; use env_logger::Builder;
use tokio::{net::UdpSocket, sync::{mpsc, Mutex}};
use tokio::task::JoinSet;
use std::io::{self, Read, Write};
use std::sync::mpsc::Receiver;
use tun2::BoxError;
use log::{error, info, LevelFilter}; use log::{error, info, LevelFilter};
use tun::platform::Device; use std::sync::Arc;
use serde_derive::Serialize; use std::net::SocketAddr;
use serde_derive::Deserialize; use std::collections::HashMap;
fn configure_routes() { fn configure_routes() {
let ip_output = Command::new("ip") let ip_output = Command::new("ip")
@ -56,7 +59,7 @@ fn configure_routes() {
pub async fn client_mode(remote_addr: &str) -> io::Result<()> { pub async fn client_mode(remote_addr: &str) -> io::Result<()> {
info!("Starting client..."); info!("Starting client...");
let mut config = tun::Configuration::default(); let mut config = tun2::Configuration::default();
config.address("10.8.0.2"); config.address("10.8.0.2");
config.netmask("128.0.0.0"); config.netmask("128.0.0.0");
config.destination("0.0.0.0"); config.destination("0.0.0.0");
@ -68,65 +71,57 @@ pub async fn client_mode(remote_addr: &str) -> io::Result<()> {
config.packet_information(true); config.packet_information(true);
}); });
let tun_device = Arc::new(Mutex::new(tun::create(&config).unwrap())); let dev = tun2::create(&config)?;
let (mut reader, mut writer) = dev.split();
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
configure_routes(); configure_routes();
let sock = Arc::new(Mutex::new(UdpSocket::bind("0.0.0.0:59611").await?)); let sock = UdpSocket::bind("0.0.0.0:59611").await?;
let r = Arc::new(sock);
let s = r.clone();
let (tx, mut rx) = mpsc::channel::<Vec<u8>>(1_000);
let sock_main = sock.clone(); let mut set = JoinSet::new();
let sock_main_instance = sock_main.lock().await;
sock_main_instance.connect(remote_addr).await?;
let tun_device_clone = tun_device.clone(); set.spawn(async move {
let sock_clone = sock.clone(); let mut buf = [0; 4096];
tokio::spawn(async move {
let mut buf = [0; 1024];
let mut tun = tun_device_clone.lock().await;
let sock = sock_clone.lock().await;
loop { loop {
let len = match sock.recv(&mut buf).await { match reader.read(&mut buf) {
Err(error) => { Ok(size) => {
error!("Problem with reading from socket: {error:?}"); let pkt = &buf[..size];
0 use std::io::{Error, ErrorKind::Other};
}, tx.send(pkt.to_vec()).await.unwrap();
Ok(l) => l, info!("Wrote to sock");
};
if len <= 0 { continue; }
info!("{:?} bytes received from socket", len);
let len = match tun.write(&buf) {
Ok(l) => l,
Err(error) => {
error!("Problem with writing to tun: {error:?}");
0
} }
}; Err(error) => error!("Error with reading from tun")
}
info!("{:?} bytes sent to tun", len); ()
} }
}); });
let tun_device_clone_second = tun_device.clone(); set.spawn(async move {
let mut buf = [0; 1024]; while let Some(bytes) = rx.recv().await {
let mut tun = tun_device_clone_second.lock().await; let len = s.send(&bytes).await.unwrap();
loop { println!("{:?} bytes sent", len);
let len = match tun.read(&mut buf) {
Ok(l) => l,
Err(error) => {
error!("Problem with reading from tun: {error:?}");
0
},
};
if len <= 0 { continue; }
info!("{:?} bytes received from tun", len);
let len = sock_main_instance.send(&buf).await?;
info!("{:?} bytes sent to socket", len);
} }
});
set.spawn(async move {
let mut buf = [0; 1024];
loop {
match r.recv_from(&mut buf).await {
Ok((len, addr)) => {
println!("{:?} bytes received from {:?}", len, addr);
writer.write_all(&buf[..len]);
info!("Wrote to tun");
}
Err(error) => error!("Error with reading from sock")
};
}
});
while let Some(res) = set.join_next().await {}
Ok(())
} }

View File

@ -1,20 +1,19 @@
use tokio::{net::UdpSocket, sync::{mpsc, Mutex}}; use tokio::{net::UdpSocket, sync::{mpsc, Mutex}};
use tokio::task::JoinSet; use tokio::task::JoinSet;
use std::{borrow::{Borrow, BorrowMut}, future::IntoFuture, io::{self, Read, Write}, net::{SocketAddr, Ipv4Addr, IpAddr}, sync::{Arc}, thread, time}; use packet::{builder::Builder, icmp, ip, Packet};
use std::process::Command; use std::io::{Read, Write};
use clap::{App, Arg}; use std::sync::mpsc::Receiver;
use env_logger::Builder; use tun2::BoxError;
use log::{error, info, LevelFilter}; use log::{error, info, LevelFilter};
use tun::platform::Device; use std::sync::Arc;
use serde_derive::Serialize; use std::net::SocketAddr;
use serde_derive::Deserialize;
//use packet::{builder::Builder, icmp, ip, Packet};
use std::collections::HashMap; use std::collections::HashMap;
pub async fn server_mode() {
pub async fn server_mode() -> Result<(), BoxError> {
info!("Starting server..."); info!("Starting server...");
let mut config = tun::Configuration::default(); let mut config = tun2::Configuration::default();
config.address("10.8.0.1"); config.address("10.8.0.1");
config.name("tun0"); config.name("tun0");
config.up(); config.up();
@ -24,78 +23,56 @@ pub async fn server_mode() {
config.packet_information(true); config.packet_information(true);
}); });
let tun_receiver = Arc::new(Mutex::new(tun::create(&config).unwrap())); let dev = tun2::create(&config)?;
let tun_sender = tun_receiver.clone(); let (mut reader, mut writer) = dev.split();
let clients_inserter = Arc::new(Mutex::new(HashMap::new())); let clients_inserter = Arc::new(Mutex::new(HashMap::<&str, UdpSocket>::new()));
let clients_getter = clients_inserter.clone(); let clients_getter = clients_inserter.clone();
let receiver_sock = Arc::new(match UdpSocket::bind("192.168.0.5:8879".parse::<SocketAddr>().unwrap()).await { let receiver_sock = Arc::new(match UdpSocket::bind("192.168.0.5:8879".parse::<SocketAddr>().unwrap()).await {
Ok(s) => s, Ok(s) => s,
Err(_error) => panic!("Cannot bind to address") Err(_error) => panic!("Cannot bind to address")
}); });
let sender_sock = receiver_sock.clone();
let (tx, mut rx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);
let (mx, mut dx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);
let mut set = JoinSet::new(); let mut set = JoinSet::new();
// tun 2 socket
set.spawn(async move { set.spawn(async move {
while let Some((bytes, addr)) = rx.recv().await { let mut buf = [0; 4096];
let len = sender_sock.send_to(&bytes, &addr).await.unwrap();
info!("{:?} bytes sent to socket", len);
}
});
// socket 2 tun
set.spawn(async move {
while let Some((bytes, addr)) = dx.recv().await {
let mut m = clients_inserter.lock().await;
m.insert("10.0.8.2", addr);
let mut ltun = tun_sender.lock().await;
let len = match ltun.write(&bytes) {
Ok(l) => l,
Err(error) => {
error!("Failed to write to tun!");
0
}
};
info!("{:?} bytes sent to tun", len);
}
});
// socket 2 tun
set.spawn(async move {
let mut buf = [0; 1024];
while let Ok((len, addr)) = receiver_sock.recv_from(&mut buf).await {
info!("{:?} bytes received from {:?}", len, addr);
mx.send((buf[..len].to_vec(), addr)).await.unwrap();
}
});
// tun 2 socket
set.spawn(async move {
let mut buf = [0; 1024];
let mut ltun: tokio::sync::MutexGuard<Device> = tun_receiver.lock().await;
loop { loop {
let len = match ltun.read(&mut buf) { let size = reader.read(&mut buf)?;
Ok(l) => l, let pkt = &buf[..size];
Err(error) => { use std::io::{Error, ErrorKind::Other};
error!("Problem with reading from tun: {error:?}"); //tx.send(pkt.to_vec()).map_err(|e| Error::new(Other, e))?;
0
}
};
info!("{:?} bytes received from tun", len);
let m = clients_getter.lock().await; let m = clients_getter.lock().await;
match m.get(&"10.0.8.2") { match m.get(&"10.0.8.2") {
Some(&addr) => tx.send((buf[..len].to_vec(), addr)).await.unwrap(), Some(&ref sock) => { sock.send(&pkt).await.unwrap(); info!("Wrote to sock") },
None => error!("There's no client!") None => { error!("There's no client!") }
};
drop(m);
()
}
#[allow(unreachable_code)]
Ok::<(), std::io::Error>(())
});
set.spawn(async move {
let mut buf = [0; 1024];
loop {
if let Ok((len, addr)) = receiver_sock.recv_from(&mut buf).await {
let mut m = clients_inserter.lock().await;
if !m.contains_key(&"10.0.8.2") {
let cl = UdpSocket::bind("0.0.0.0:59611").await?;
cl.connect(addr).await?;
m.insert("10.0.8.2", cl);
}
drop(m);
writer.write_all(&buf[..len])?;
info!("Wrote to tun");
} }
} }
}); });
while let Some(res) = set.join_next().await {} while let Some(res) = set.join_next().await {}
Ok(())
} }