Add new dependencies and implement TUN interface initialization
- Updated Cargo.toml to include `etherparse` and enable async feature for `tun-rs`. - Added `ip_match_network` function in network module for IP matching. - Implemented TUN interface initialization in `tun.rs`. - Enhanced client handling in `client.rs` to support new features and improved message handling. - Refactored router messages to use a structured `VpnPacket`. - Updated settings for spell checking in VSCode.
This commit is contained in:
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"etherparse",
|
||||||
|
"nodelay",
|
||||||
|
"xvpn"
|
||||||
|
]
|
||||||
|
}
|
||||||
124
Cargo.lock
generated
124
Cargo.lock
generated
@@ -67,6 +67,36 @@ version = "1.0.102"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-channel"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-task"
|
||||||
|
version = "4.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-waker"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@@ -85,6 +115,19 @@ version = "2.11.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blocking"
|
||||||
|
version = "1.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
|
||||||
|
dependencies = [
|
||||||
|
"async-channel",
|
||||||
|
"async-task",
|
||||||
|
"futures-io",
|
||||||
|
"futures-lite",
|
||||||
|
"piper",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.20.2"
|
version = "3.20.2"
|
||||||
@@ -205,6 +248,15 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "concurrent-queue"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@@ -221,6 +273,12 @@ version = "0.8.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.35"
|
version = "0.8.35"
|
||||||
@@ -246,6 +304,36 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "etherparse"
|
||||||
|
version = "0.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b119b9796ff800751a220394b8b3613f26dd30c48f254f6837e64c464872d1c7"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "5.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener-strategy"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
@@ -285,6 +373,22 @@ version = "0.3.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-lite"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
@@ -623,6 +727,12 @@ version = "1.70.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
@@ -635,6 +745,17 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "piper"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"fastrand",
|
||||||
|
"futures-io",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.37"
|
version = "0.2.37"
|
||||||
@@ -927,6 +1048,7 @@ version = "2.8.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5aed038a26d2b6a7906a62b3d0c42fb77541b0a695b9c2b9489a0c25c093ce8b"
|
checksum = "5aed038a26d2b6a7906a62b3d0c42fb77541b0a695b9c2b9489a0c25c093ce8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"blocking",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"c2rust-bitfields",
|
"c2rust-bitfields",
|
||||||
@@ -940,6 +1062,7 @@ dependencies = [
|
|||||||
"nix 0.31.1",
|
"nix 0.31.1",
|
||||||
"route_manager",
|
"route_manager",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
|
"tokio",
|
||||||
"widestring",
|
"widestring",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
"winreg",
|
"winreg",
|
||||||
@@ -1469,6 +1592,7 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
"etherparse",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -22,5 +22,6 @@ anyhow = "1.0.102"
|
|||||||
uuid = { version = "1.21.0", features = ["v4", "serde"] }
|
uuid = { version = "1.21.0", features = ["v4", "serde"] }
|
||||||
ipnet = { version = "2.11.0", features = ["serde"] }
|
ipnet = { version = "2.11.0", features = ["serde"] }
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
tun-rs = "2.8.2"
|
tun-rs = { version = "2.8.2", features = ["async"] }
|
||||||
chrono = "0.4.44"
|
chrono = "0.4.44"
|
||||||
|
etherparse = "0.19.0"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::net::IpAddr;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use chrono::Utc;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use ipnet::Ipv4Net;
|
use ipnet::Ipv4Net;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -11,7 +10,21 @@ use tokio::{
|
|||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::router::{CLIENT_REGISTER_TIMEOUT, CliRegMessages, RouterMessages, SERVER_PACKET_SIZE};
|
use crate::{
|
||||||
|
network::ip_match_network,
|
||||||
|
router::{CLIENT_REGISTER_TIMEOUT, CliRegMessages, RouterMessages, SERVER_PACKET_SIZE},
|
||||||
|
tun::inti_tun_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ClientStaTistic {
|
||||||
|
pub last_keep_alive: Option<chrono::DateTime<Utc>>,
|
||||||
|
pub keep_alive_count: usize,
|
||||||
|
pub total_data_received: usize,
|
||||||
|
pub total_data_sent: usize,
|
||||||
|
pub last_data_received: Option<chrono::DateTime<Utc>>,
|
||||||
|
pub last_data_sent: Option<chrono::DateTime<Utc>>,
|
||||||
|
pub latency_ms: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Args)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Args)]
|
||||||
pub struct ClientCfg {
|
pub struct ClientCfg {
|
||||||
@@ -19,9 +32,9 @@ pub struct ClientCfg {
|
|||||||
#[arg(long, short)]
|
#[arg(long, short)]
|
||||||
pub server: String,
|
pub server: String,
|
||||||
|
|
||||||
/// The local interface IP address (example: 10.8.0.2).
|
/// The local interface IP address (example: 10.8.0.2/32).
|
||||||
#[arg(long = "interface-ip")]
|
#[arg(long = "interface-ip")]
|
||||||
pub interface_ip: IpAddr,
|
pub interface_ip: Ipv4Net,
|
||||||
|
|
||||||
/// The local interface name.
|
/// The local interface name.
|
||||||
#[arg(long = "interface-name", default_value = "xvpn0")]
|
#[arg(long = "interface-name", default_value = "xvpn0")]
|
||||||
@@ -31,6 +44,10 @@ pub struct ClientCfg {
|
|||||||
/// Example: --local-route 1.1.1.1/32,10.0.0.0/24
|
/// Example: --local-route 1.1.1.1/32,10.0.0.0/24
|
||||||
#[arg(long = "local-route", visible_alias = "lr", value_delimiter = ',')]
|
#[arg(long = "local-route", visible_alias = "lr", value_delimiter = ',')]
|
||||||
pub local_routes: Vec<Ipv4Net>,
|
pub local_routes: Vec<Ipv4Net>,
|
||||||
|
/// MTU for the TUN interface.
|
||||||
|
/// If not specified, the default MTU of the system will be used.
|
||||||
|
#[arg(long = "mtu", default_value = "1400")]
|
||||||
|
pub mtu: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(config: ClientCfg) -> Result<()> {
|
pub async fn start(config: ClientCfg) -> Result<()> {
|
||||||
@@ -41,27 +58,51 @@ pub async fn start(config: ClientCfg) -> Result<()> {
|
|||||||
let (mut rx, mut tx) = stream.into_split();
|
let (mut rx, mut tx) = stream.into_split();
|
||||||
// let client_stream = ClientStream::new(tx);
|
// let client_stream = ClientStream::new(tx);
|
||||||
|
|
||||||
let mut buf = vec![0u8; SERVER_PACKET_SIZE];
|
let mut vpn_buf = vec![0u8; SERVER_PACKET_SIZE];
|
||||||
register_client(&mut rx, &mut tx, config, &mut buf).await?;
|
let mut tun_buf = vec![0u8; config.mtu as usize];
|
||||||
|
register_client(&mut rx, &mut tx, &config, &mut vpn_buf).await?;
|
||||||
|
let tun_device = inti_tun_interface(&config).await?;
|
||||||
|
|
||||||
println!("Client registration successful. Entering main loop to receive messages from router...");
|
println!("Client registration successful. Entering main loop to receive messages from router...");
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
msg = rx.read(&mut buf) => {
|
msg = rx.read(&mut vpn_buf) => {
|
||||||
match msg {
|
match msg {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
println!("Connection to router closed by peer.");
|
println!("Connection to router closed by peer.");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
println!("Received {} bytes from router: {:?}", n, RouterMessages::from_slice(&buf[..n]));
|
match RouterMessages::from_slice(&vpn_buf[..n]){
|
||||||
|
RouterMessages::KeepAlive(timestamp) => {
|
||||||
|
println!("Received keep-alive message from router with timestamp: {}, delta {} ms", timestamp, (Utc::now().timestamp_micros() - timestamp).abs() as f64 / 1000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => println!("Received message from router: {:?}", RouterMessages::from_slice(&vpn_buf[..n]))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error reading from router: {}", e);
|
eprintln!("Error reading from router: {}", e);
|
||||||
return Err(anyhow::anyhow!(format!("Error reading from router: {}", e)));
|
return Err(anyhow::anyhow!(format!("Error reading from router: {}", e)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
data = tun_device.recv(&mut tun_buf) => {
|
||||||
|
match data {
|
||||||
|
Ok(n) => {
|
||||||
|
let packet = etherparse::Ipv4HeaderSlice::from_slice(&tun_buf[..n])?;
|
||||||
|
let src = packet.source_addr();
|
||||||
|
match ip_match_network(src, &config.local_routes).await {
|
||||||
|
Some(net) => println!("Source IP {} matches local route {}", src, net),
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error reading from TUN interface: {}", e);
|
||||||
|
return Err(anyhow::anyhow!(format!("Error reading from TUN interface: {}", e)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +112,10 @@ pub async fn start(config: ClientCfg) -> Result<()> {
|
|||||||
pub async fn register_client(
|
pub async fn register_client(
|
||||||
rx: &mut OwnedReadHalf,
|
rx: &mut OwnedReadHalf,
|
||||||
tx: &mut OwnedWriteHalf,
|
tx: &mut OwnedWriteHalf,
|
||||||
config: ClientCfg,
|
config: &ClientCfg,
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let register_msg = RouterMessages::CliReg(CliRegMessages::Reg(config));
|
let register_msg = RouterMessages::CliReg(CliRegMessages::Reg(config.clone()));
|
||||||
let mut client_registration_timeout =
|
let mut client_registration_timeout =
|
||||||
tokio::time::interval_at(Instant::now() + CLIENT_REGISTER_TIMEOUT, CLIENT_REGISTER_TIMEOUT);
|
tokio::time::interval_at(Instant::now() + CLIENT_REGISTER_TIMEOUT, CLIENT_REGISTER_TIMEOUT);
|
||||||
tx.write_all(®ister_msg.to_bytes()).await?;
|
tx.write_all(®ister_msg.to_bytes()).await?;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod network;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
|
pub mod tun;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ impl Display for OpModes {
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
// Check if some commanline or check if config file.
|
// Check if some commandline or check if config file.
|
||||||
let commandline = if env::args().nth(1).is_some() {
|
let commandline = if env::args().nth(1).is_some() {
|
||||||
Cli::parse()
|
Cli::parse()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
11
src/network.rs
Normal file
11
src/network.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use ipnet::Ipv4Net;
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
|
pub async fn ip_match_network(ip: Ipv4Addr, networks: &[Ipv4Net]) -> Option<Ipv4Net> {
|
||||||
|
for net in networks {
|
||||||
|
if net.contains(&ip) {
|
||||||
|
return Some(*net);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
@@ -27,16 +27,23 @@ pub trait ReceiverTrait {}
|
|||||||
pub enum RouterMessages {
|
pub enum RouterMessages {
|
||||||
CliReg(CliRegMessages),
|
CliReg(CliRegMessages),
|
||||||
KeepAlive(i64),
|
KeepAlive(i64),
|
||||||
Data(Vec<u8>),
|
Data(VpnPacket),
|
||||||
Quit(String),
|
Quit(String),
|
||||||
Uknown(String),
|
Unknown(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct VpnPacket {
|
||||||
|
pub src_uuid: Uuid,
|
||||||
|
pub dst_uuid: Uuid,
|
||||||
|
pub payload: Vec<u8>,
|
||||||
}
|
}
|
||||||
impl RouterMessages {
|
impl RouterMessages {
|
||||||
pub fn to_bytes(&self) -> Vec<u8> {
|
pub fn to_bytes(&self) -> Vec<u8> {
|
||||||
serde_json::to_vec(self).expect("Unable to serialize RouteMessages")
|
serde_json::to_vec(self).expect("Unable to serialize RouteMessages")
|
||||||
}
|
}
|
||||||
pub fn from_slice(slice: &[u8]) -> Self {
|
pub fn from_slice(slice: &[u8]) -> Self {
|
||||||
serde_json::from_slice(slice).unwrap_or(RouterMessages::Uknown(
|
serde_json::from_slice(slice).unwrap_or(RouterMessages::Unknown(
|
||||||
String::from_utf8(slice.to_vec()).unwrap_or_else(|b| format!("Invalid UTF-8: {:?}", b.as_bytes())),
|
String::from_utf8(slice.to_vec()).unwrap_or_else(|b| format!("Invalid UTF-8: {:?}", b.as_bytes())),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -47,7 +54,7 @@ pub enum CliRegMessages {
|
|||||||
Reg(ClientCfg),
|
Reg(ClientCfg),
|
||||||
RegOk(Uuid),
|
RegOk(Uuid),
|
||||||
RegFailed(String),
|
RegFailed(String),
|
||||||
Uknown(String),
|
Unknown(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliRegMessages {
|
impl CliRegMessages {
|
||||||
@@ -55,7 +62,7 @@ impl CliRegMessages {
|
|||||||
serde_json::to_vec(self).expect("Unable to serialize RegisterMessages")
|
serde_json::to_vec(self).expect("Unable to serialize RegisterMessages")
|
||||||
}
|
}
|
||||||
pub fn from_slice(slice: &[u8]) -> Self {
|
pub fn from_slice(slice: &[u8]) -> Self {
|
||||||
serde_json::from_slice(slice).unwrap_or(CliRegMessages::Uknown(
|
serde_json::from_slice(slice).unwrap_or(CliRegMessages::Unknown(
|
||||||
String::from_utf8(slice.to_vec()).unwrap_or_else(|b| format!("Invalid UTF-8: {:?}", b.as_bytes())),
|
String::from_utf8(slice.to_vec()).unwrap_or_else(|b| format!("Invalid UTF-8: {:?}", b.as_bytes())),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -202,7 +209,6 @@ pub async fn handle_client(router: Router, stream: TcpStream) -> Result<()> {
|
|||||||
|
|
||||||
_= keep_alive_tick.tick() => {
|
_= keep_alive_tick.tick() => {
|
||||||
// Send keep-alive message to the client
|
// Send keep-alive message to the client
|
||||||
println!("Sent keep-alive message to client");
|
|
||||||
vpn_client.send(RouterMessages::KeepAlive(Utc::now().timestamp_micros())).await?;
|
vpn_client.send(RouterMessages::KeepAlive(Utc::now().timestamp_micros())).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/tun.rs
Normal file
29
src/tun.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use tun_rs::{AsyncDevice, DeviceBuilder};
|
||||||
|
|
||||||
|
use crate::client::ClientCfg;
|
||||||
|
|
||||||
|
pub async fn inti_tun_interface(config: &ClientCfg) -> Result<AsyncDevice> {
|
||||||
|
println!(
|
||||||
|
"Initializing TUN interface with name: {}, IP: {}/{}, MTU: {}",
|
||||||
|
config.interface_name,
|
||||||
|
config.interface_ip.addr(),
|
||||||
|
config.interface_ip.netmask(),
|
||||||
|
config.mtu
|
||||||
|
);
|
||||||
|
let device = match DeviceBuilder::new()
|
||||||
|
.name(&config.interface_name)
|
||||||
|
.ipv4(config.interface_ip.addr(), config.interface_ip.netmask(), None)
|
||||||
|
.mtu(config.mtu)
|
||||||
|
.build_async()
|
||||||
|
{
|
||||||
|
Ok(dev) => dev,
|
||||||
|
Err(e) => {
|
||||||
|
let msg = format!("Failed to create TUN interface: {:#}", e);
|
||||||
|
eprintln!("{}", msg);
|
||||||
|
return Err(anyhow::anyhow!(msg));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(device)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user