Skip to content

Commit 3cb80f3

Browse files
authored
Merge pull request #6 from smartethnet/banyc/dev
Refactor network layer, P2P handler, and update dependencies
2 parents 2c462b1 + a8c4ade commit 3cb80f3

44 files changed

Lines changed: 2950 additions & 1949 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 1141 additions & 372 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,34 @@ version = "0.0.1"
44
edition = "2024"
55

66
[dependencies]
7-
serde = { version = "1.0.228", features = ["derive"] }
8-
serde_json = "1.0.145"
9-
bytes = "1.11.0"
10-
anyhow = "1.0.100"
11-
tokio = { version = "1.48.0", features = ["full"] }
12-
tracing = "*"
13-
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
14-
time = "0.3.44"
15-
tun= { version = "0.8.5", features = ["futures-core", "async"] }
16-
async-trait = "0.1.89"
17-
ed25519-dalek = { version = "2.1", features = ["rand_core"] }
18-
rand = "0.9.2"
7+
serde = { version = "1", features = ["derive"] }
8+
serde_json = "1"
9+
bytes = "1"
10+
anyhow = "1"
11+
tokio = { version = "1", features = ["full"] }
12+
tracing = "0.1"
13+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
14+
time = "0.3"
15+
tun= { version = "0.8", features = ["futures-core", "async"] }
16+
async-trait = "0.1"
17+
ed25519-dalek = { version = "2", features = ["rand_core"] }
18+
rand = "0.10"
1919
base64 = "0.22"
2020
aes-gcm = "0.10"
2121
chacha20poly1305 = "0.10"
22-
toml = "0.9.8"
23-
ipnet = "2.10"
24-
clap = { version = "4.5", features = ["derive"] }
25-
ureq = "2.10"
22+
toml = "0.9"
23+
ipnet = "2"
24+
clap = { version = "4", features = ["derive"] }
2625
stunclient = "0.4"
27-
socket2 = "0.6.1"
28-
notify = "7.0"
29-
tokio-util = "0.7.17"
30-
ctrlc2 = "3.7.3"
31-
axum = "0.7"
32-
tower = "0.4"
33-
tower-http = { version = "0.5", features = ["cors"] }
34-
once_cell = "1.20"
26+
socket2 = "0.6"
27+
notify = "8"
28+
tokio-util = "0.7"
29+
ctrlc2 = "3"
30+
axum = "0.8"
31+
tower = "0.5"
32+
tower-http = { version = "0.6", features = ["cors"] }
33+
once_cell = "1"
34+
reqwest = "0.13"
3535

3636
[dev-dependencies]
3737
tokio-test = "0.4"
38-
39-
[[bin]]
40-
name = "server"
41-
path = "src/cmd/server.rs"
42-
43-
[[bin]]
44-
name = "client"
45-
path = "src/cmd/client.rs"
46-
47-
[[example]]
48-
name = "stun_discover"
49-
path = "examples/stun_discover.rs"
50-
51-
[[example]]
52-
name = "tun_reader"
53-
path = "examples/read_async.rs"

examples/read_async.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
//
1313
// 0. You just DO WHAT THE FUCK YOU WANT TO.
1414

15-
use std::thread::{sleep, Builder};
1615
use std::time::Duration;
1716
use tokio::io::AsyncReadExt;
18-
use tokio_util::sync::CancellationToken;
1917
use tun::{AbstractDevice, BoxError};
2018

2119
#[tokio::main]
@@ -45,11 +43,7 @@ async fn main_entry() -> Result<(), BoxError> {
4543
let size = dev.mtu()? as usize + tun::PACKET_INFORMATION_LENGTH;
4644
let mut buf = vec![0; size];
4745
loop {
48-
tokio::select! {
49-
len = dev.read(&mut buf) => {
50-
println!("pkt: {:?}", &buf[..len?]);
51-
}
52-
};
46+
let len = dev.read(&mut buf).await?;
47+
println!("pkt: {:?}", &buf[..len]);
5348
}
54-
Ok(())
55-
}
49+
}
Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//! cargo run --example stun_discover -- --port 51258
1010
//! ```
1111
12-
use rustun::client::p2p::stun::{StunClient, NatType};
12+
use rustun::client::p2p::stun::{NatType, StunClient};
1313
use std::time::Duration;
1414

1515
#[derive(clap::Parser, Debug)]
@@ -19,15 +19,15 @@ struct Args {
1919
/// Local UDP port to bind (0 for automatic)
2020
#[arg(short, long, default_value = "0")]
2121
port: u16,
22-
22+
2323
/// Custom STUN server (can be specified multiple times)
2424
#[arg(short, long)]
2525
stun_server: Vec<String>,
26-
26+
2727
/// Request timeout in seconds
2828
#[arg(short, long, default_value = "5")]
2929
timeout: u64,
30-
30+
3131
/// Enable verbose logging
3232
#[arg(short, long)]
3333
verbose: bool,
@@ -37,16 +37,14 @@ struct Args {
3737
async fn main() {
3838
use clap::Parser;
3939
let args = Args::parse();
40-
40+
4141
// Setup logging
4242
let log_level = if args.verbose { "debug" } else { "info" };
43-
tracing_subscriber::fmt()
44-
.with_env_filter(log_level)
45-
.init();
46-
43+
tracing_subscriber::fmt().with_env_filter(log_level).init();
44+
4745
println!("🔍 STUN Discovery Tool");
4846
println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
49-
47+
5048
// Create STUN client
5149
let stun_client = if args.stun_server.is_empty() {
5250
println!("📡 Using default Google STUN servers");
@@ -55,35 +53,42 @@ async fn main() {
5553
println!("📡 Using custom STUN servers: {:?}", args.stun_server);
5654
StunClient::with_servers(args.stun_server)
5755
};
58-
56+
5957
let stun_client = stun_client.with_timeout(Duration::from_secs(args.timeout));
60-
61-
println!("🔌 Local port: {}", if args.port == 0 { "auto".to_string() } else { args.port.to_string() });
58+
59+
println!(
60+
"🔌 Local port: {}",
61+
if args.port == 0 {
62+
"auto".to_string()
63+
} else {
64+
args.port.to_string()
65+
}
66+
);
6267
println!();
63-
68+
6469
// Perform discovery
6570
println!("⏳ Discovering public address...");
6671
match stun_client.discover(args.port).await {
6772
Ok(result) => {
6873
println!("✅ STUN Discovery Successful!\n");
69-
74+
7075
println!("📍 Results:");
7176
println!(" Local Address: {}", result.local_addr);
7277
println!(" Public Address: {}", result.public_addr());
7378
println!(" Public IP: {}", result.public_ip);
7479
println!(" Public Port: {}", result.public_port);
7580
println!();
76-
81+
7782
println!("🌐 NAT Information:");
7883
println!(" Type: {:?}", result.nat_type);
7984
println!(" Description: {}", result.nat_type.description());
8085
println!();
81-
86+
8287
// Show P2P compatibility
8388
println!("🔗 P2P Compatibility:");
8489
show_p2p_compatibility(&result.nat_type);
8590
println!();
86-
91+
8792
// Recommendations
8893
println!("💡 Recommendations:");
8994
match result.nat_type {
@@ -117,7 +122,7 @@ async fn main() {
117122
}
118123
}
119124
Err(e) => {
120-
eprintln!("❌ STUN Discovery Failed: {}", e);
125+
eprintln!("❌ STUN Discovery Failed: {e}");
121126
eprintln!();
122127
eprintln!("Possible reasons:");
123128
eprintln!(" - No internet connection");
@@ -137,7 +142,7 @@ fn show_p2p_compatibility(nat_type: &NatType) {
137142
("Port-Restricted", NatType::PortRestricted),
138143
("Symmetric NAT", NatType::Symmetric),
139144
];
140-
145+
141146
println!(" Success rates with different peer NAT types:");
142147
for (name, peer_nat) in &scenarios {
143148
let rate = nat_type.hole_punch_success_rate(peer_nat);
@@ -146,4 +151,3 @@ fn show_p2p_compatibility(nat_type: &NatType) {
146151
println!(" {:18} {:3}% {}", name, percentage, bar);
147152
}
148153
}
149-

src/bin/client.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use rustun::client::main;
2+
3+
#[tokio::main]
4+
async fn main() -> anyhow::Result<()> {
5+
main::run_client().await
6+
}

src/bin/server.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use rustun::server::main;
2+
3+
#[tokio::main]
4+
async fn main() -> anyhow::Result<()> {
5+
main::run_server().await
6+
}

src/client/http/cache.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Status cache management
22
3-
use std::sync::Arc;
4-
use tokio::sync::RwLock;
53
use super::models::StatusResponse;
4+
use std::sync::Arc;
5+
use std::sync::RwLock;
66

77
/// Global status cache (shared between HTTP server and event loop)
88
static STATUS_CACHE: once_cell::sync::Lazy<Arc<RwLock<Option<StatusResponse>>>> =
@@ -14,14 +14,13 @@ pub fn get_cache() -> Arc<RwLock<Option<StatusResponse>>> {
1414
}
1515

1616
/// Update the status cache (called from event loop)
17-
pub async fn update(status: StatusResponse) {
18-
let mut cache = STATUS_CACHE.write().await;
17+
pub fn update(status: StatusResponse) {
18+
let mut cache = STATUS_CACHE.write().unwrap();
1919
*cache = Some(status);
2020
}
2121

2222
/// Get the current cached status
23-
pub async fn get() -> Option<StatusResponse> {
24-
let cache = STATUS_CACHE.read().await;
23+
pub fn get() -> Option<StatusResponse> {
24+
let cache = STATUS_CACHE.read().unwrap();
2525
cache.clone()
2626
}
27-

src/client/http/handlers.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
//! HTTP request handlers
22
3-
use axum::{
4-
extract::State,
5-
http::StatusCode,
6-
response::Json,
7-
};
8-
use serde_json;
9-
use super::models::StatusResponse;
103
use super::cache::get_cache;
4+
use super::models::StatusResponse;
5+
use axum::{extract::State, http::StatusCode, response::Json};
6+
use serde_json;
117

128
/// Shared state for the HTTP server
139
#[derive(Clone)]
1410
pub struct AppState {
15-
status_cache: std::sync::Arc<tokio::sync::RwLock<Option<StatusResponse>>>,
11+
status_cache: std::sync::Arc<std::sync::RwLock<Option<StatusResponse>>>,
1612
}
1713

1814
impl AppState {
@@ -32,13 +28,10 @@ pub async fn health() -> Json<serde_json::Value> {
3228
}
3329

3430
/// Status endpoint handler
35-
pub async fn status(
36-
State(state): State<AppState>,
37-
) -> Result<Json<StatusResponse>, StatusCode> {
38-
let cache = state.status_cache.read().await;
31+
pub async fn status(State(state): State<AppState>) -> Result<Json<StatusResponse>, StatusCode> {
32+
let cache = state.status_cache.read().unwrap();
3933
match cache.as_ref() {
4034
Some(status) => Ok(Json(status.clone())),
4135
None => Err(StatusCode::SERVICE_UNAVAILABLE),
4236
}
4337
}
44-

src/client/http/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
pub mod models;
21
pub mod cache;
32
mod handlers;
3+
pub mod models;
44
pub mod server;
55

66
// Re-export commonly used types
7-
pub use models::*;
7+
pub use models::*;

src/client/http/models.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,3 @@ pub struct ClusterPeerInfo {
9292
pub last_active: u64,
9393
pub status: String, // "online", "warning", "inactive", "offline"
9494
}
95-

0 commit comments

Comments
 (0)