Changes to be committed:

modified:   Cargo.lock
	modified:   Cargo.toml
	modified:   src/main.rs
	new file:   src/tcp_client.rs
	new file:   src/tcp_server.rs
This commit is contained in:
Michael Wain 2024-08-12 03:54:49 +03:00
parent 8f5bc39232
commit 4fc9ccb860
5 changed files with 244 additions and 5 deletions

16
Cargo.lock generated
View File

@ -275,6 +275,21 @@ dependencies = [
"libc",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -793,6 +808,7 @@ dependencies = [
"block-modes",
"block-padding",
"clap",
"crossbeam-channel",
"ctrlc",
"ctrlc2",
"env_logger",

View File

@ -27,4 +27,5 @@ log = "0.4.20"
futures = "0.3.30"
tun2 = "2.0.5"
packet = "0.1.4"
ctrlc2 = "3.5"
ctrlc2 = "3.5"
crossbeam-channel = "0.5.13"

View File

@ -8,8 +8,10 @@ use tun::platform::Device;
use serde_derive::Serialize;
use serde_derive::Deserialize;
mod client;
mod server;
//mod client;
//mod server;
mod tcp_client;
mod tcp_server;
#[derive(Serialize, Deserialize)]
struct VpnPacket {
@ -43,11 +45,11 @@ async fn main() {
let is_server_mode = matches.value_of("mode").unwrap() == "server";
// "192.168.0.4:8879"
if is_server_mode {
server::server_mode().await;
tcp_server::server_mode().await;
} else {
if let Some(vpn_server_ip) = matches.value_of("vpn-server") {
let server_address = format!("{}:8879", vpn_server_ip);
client::client_mode(server_address).await;
tcp_client::client_mode(server_address).await;
} else {
eprintln!("Error: For client mode, you shall provide the '--vpn-server' argument.");
}

111
src/tcp_client.rs Normal file
View File

@ -0,0 +1,111 @@
use crossbeam_channel::{unbounded, Receiver};
use tokio::{io::AsyncWriteExt, net::{TcpListener, TcpSocket, TcpStream}, sync::{mpsc, Mutex}};
use tokio::task::JoinSet;
use packet::{builder::Builder, icmp, ip, Packet};
use std::io::{Read, Write};
use tun2::BoxError;
use log::{error, info, LevelFilter};
use std::sync::Arc;
use std::net::SocketAddr;
use std::collections::HashMap;
use std::process::Command;
fn configure_routes() {
let ip_output = Command::new("ip")
.arg("addr")
.arg("add")
.arg("10.8.0.2/24")
.arg("dev")
.arg("tun0")
.output()
.expect("Failed to execute IP command");
if !ip_output.status.success() {
eprintln!("Failed to set IP: {}", String::from_utf8_lossy(&ip_output.stderr));
return;
}
let link_output = Command::new("ip")
.arg("link")
.arg("set")
.arg("up")
.arg("dev")
.arg("tun0")
.output()
.expect("Failed to execute IP LINK command");
if !link_output.status.success() {
eprintln!("Failed to set link up: {}", String::from_utf8_lossy(&link_output.stderr));
return;
}
let route_output = Command::new("ip")
.arg("route")
.arg("add")
.arg("0.0.0.0/0")
.arg("via")
.arg("10.8.0.1")
.arg("dev")
.arg("tun0")
.output()
.expect("Failed to execute IP ROUTE command");
if !route_output.status.success() {
eprintln!("Failed to set route: {}", String::from_utf8_lossy(&route_output.stderr));
}
}
pub async fn client_mode(remote_addr: String) {
info!("Starting client...");
let mut config = tun2::Configuration::default();
config.address("10.8.0.2");
config.netmask("128.0.0.0");
config.destination("0.0.0.0");
config.name("tun0");
config.up();
#[cfg(target_os = "linux")]
config.platform_config(|config| {
config.packet_information(true);
});
let dev = tun2::create(&config).unwrap();
let (mut dev_reader, mut dev_writer) = dev.split();
#[cfg(target_os = "linux")]
configure_routes();
let socket = TcpStream::connect(&remote_addr).await.unwrap();
let (mut sock_reader, mut sock_writer) = socket.into_split();
let (tx, rx) = unbounded::<Vec<u8>>();
let (dx, mx) = unbounded::<Vec<u8>>();
tokio::spawn(async move {
while let Ok(bytes) = rx.recv() {
dev_writer.write(&bytes).unwrap();
}
});
tokio::spawn(async move {
let mut buf = vec![0; 2048];
while let Ok(n) = dev_reader.read(&mut buf) {
dx.send(buf[..n].to_vec()).unwrap();
}
});
tokio::spawn(async move {
let mut buf = vec![0; 2048];
loop {
let n = sock_reader.try_read(&mut buf).unwrap();
tx.send(buf[..n].to_vec()).unwrap();
}
});
loop {
if let Ok(bytes) = mx.recv() {
sock_writer.write(&bytes).await.unwrap();
}
}
}

109
src/tcp_server.rs Normal file
View File

@ -0,0 +1,109 @@
use crossbeam_channel::{unbounded, Receiver};
use tokio::{io::AsyncWriteExt, net::{TcpListener, TcpSocket, TcpStream}, sync::{mpsc, Mutex}};
use tokio::task::JoinSet;
use packet::{builder::Builder, icmp, ip, Packet};
use std::io::{Read, Write};
use tun2::BoxError;
use log::{error, info, LevelFilter};
use std::sync::Arc;
use std::net::SocketAddr;
use std::collections::HashMap;
pub async fn server_mode() {
info!("Starting server...");
let mut config = tun2::Configuration::default();
config.address("10.8.0.1");
config.tun_name("tun0");
config.up();
#[cfg(target_os = "linux")]
config.platform_config(|config| {
config.packet_information(true);
});
let dev = tun2::create(&config).unwrap();
let (mut dev_reader, mut dev_writer) = dev.split();
let (tx, rx) = unbounded::<Vec<u8>>();
let (dx, mx) = unbounded::<Vec<u8>>();
tokio::spawn(async move {
while let Ok(bytes) = rx.recv() {
dev_writer.write(&bytes).unwrap();
}
});
tokio::spawn(async move {
let mut buf = vec![0; 2048];
while let Ok(n) = dev_reader.read(&mut buf) {
dx.send(buf[..n].to_vec()).unwrap();
}
});
let listener = TcpListener::bind("192.168.0.5:8879".parse::<SocketAddr>().unwrap()).await.unwrap();
loop {
let (mut socket, _) = listener.accept().await.unwrap();
let (mut sock_reader, mut sock_writer) = socket.into_split();
let thread_tx = tx.clone();
let thread_mx = mx.clone();
tokio::spawn(async move {
loop {
if let Ok(bytes) = thread_mx.recv() {
sock_writer.write(&bytes).await.unwrap();
}
}
});
tokio::spawn(async move {
let mut buf = vec![0; 2048];
loop {
let n = sock_reader.try_read(&mut buf).unwrap();
thread_tx.send(buf[..n].to_vec()).unwrap();
}
});
}
/* let mut set = JoinSet::new();
set.spawn(async move {
let mut buf = [0; 4096];
loop {
let size = reader.read(&mut buf)?;
let pkt = &buf[..size];
use std::io::{Error, ErrorKind::Other};
let m = clients_getter.lock().await;
match m.get(&"10.0.8.2") {
Some(&ref sock) => { sock.send(&pkt).await.unwrap(); info!("Wrote to sock") },
None => { error!("There's no client!") }
};
drop(m);
()
}
#[allow(unreachable_code)]
Ok::<(), std::io::Error>(())
});
set.spawn(async move {
let mut buf = [0; 4096];
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 {}
Ok(())*/
}