Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ibigbug committed Dec 10, 2023
1 parent b22a749 commit 73cdd52
Show file tree
Hide file tree
Showing 10 changed files with 601 additions and 11 deletions.
121 changes: 121 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions clash_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ tun = { git = "https://github.com/Watfaq/rust-tun.git", rev = "8f7568190f1200d3e
netstack-lwip = { git = "https://github.com/Watfaq/netstack-lwip.git", rev = "2817bf82740e04bbee6b7bf1165f55657a6ed163" }

boringtun = { version = "0.6.0" }
smoltcp = { version = "0.10", default-features = false, features = ["std", "log", "medium-ip", "proto-ipv4", "proto-ipv6", "socket-udp", "socket-tcp"] }


serde = { version = "1.0", features=["derive"] }
serde_yaml = "0.9"
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub mod trojan;
pub mod tun;
pub mod utils;
pub mod vmess;
//pub mod wg;
pub mod wg;

pub mod converters;

Expand Down
14 changes: 14 additions & 0 deletions clash_lib/src/proxy/wg/device.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::{
collections::VecDeque,
sync::{Arc, Mutex},
};

use bytes::Bytes;

use super::events::BusSender;

pub struct VirtualIpDevice {
mtu: usize,
bus_sender: BusSender,
queue: Arc<Mutex<VecDeque<Bytes>>>,
}
108 changes: 108 additions & 0 deletions clash_lib/src/proxy/wg/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use std::sync::{atomic::AtomicU32, Arc};

use bytes::Bytes;
use tracing::error;

/// Layer 7 protocols for ports.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum PortProtocol {
/// TCP
Tcp,
/// UDP
Udp,
}

#[derive(Clone)]
pub struct Bus {
counter: Arc<AtomicU32>,
bus: tokio::sync::broadcast::Sender<(u32, Event)>,
}

impl Bus {
pub fn new() -> Self {
let (tx, _) = tokio::sync::broadcast::channel(1024);
Self {
counter: Arc::new(AtomicU32::new(0)),
bus: tx,
}
}

pub fn new_endpoint(&self) -> BusEndpoint {
let id = self
.counter
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);

let tx = self.bus.clone();
let rx = self.bus.subscribe();

let tx = BusSender { id, tx };
BusEndpoint { id, tx, rx }
}
}

pub struct BusEndpoint {
id: u32,
tx: BusSender,
rx: tokio::sync::broadcast::Receiver<(u32, Event)>,
}

impl BusEndpoint {
/// Sends the event on the bus. Note that the messages sent by this endpoint won't reach itself.
pub fn send(&self, event: Event) {
self.tx.send(event)
}

/// Returns the unique sequential ID of this endpoint.
pub fn id(&self) -> u32 {
self.id
}

/// Awaits the next `Event` on the bus to be read.
pub async fn recv(&mut self) -> Event {
loop {
match self.rx.recv().await {
Ok((id, event)) => {
if id == self.id {
// If the event was sent by this endpoint, it is skipped
continue;
} else {
return event;
}
}
Err(_) => {
error!("Failed to read event bus from endpoint #{}", self.id);
return futures::future::pending().await;
}
}
}
}

/// Creates a new sender for this endpoint that can be cloned.
pub fn sender(&self) -> BusSender {
self.tx.clone()
}
}

/// Events that go on the bus between the local server, smoltcp, and WireGuard.
#[derive(Debug, Clone)]
pub enum Event {
InboundInternetPacket(PortProtocol, Bytes),
/// IP packet to be sent through the WireGuard tunnel as crafted by the virtual device.
OutboundInternetPacket(Bytes),
}

#[derive(Clone)]
pub struct BusSender {
id: u32,
tx: tokio::sync::broadcast::Sender<(u32, Event)>,
}

impl BusSender {
/// Sends the event on the bus. Note that the messages sent by this endpoint won't reach itself.
pub fn send(&self, event: Event) {
match self.tx.send((self.id, event)) {
Ok(_) => {}
Err(_) => error!("Failed to send event to bus from endpoint #{}", self.id),
}
}
}
22 changes: 12 additions & 10 deletions clash_lib/src/proxy/wg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ use std::{
};

use crate::{
app::{dispatcher::BoxedChainedStream, dns::ThreadSafeDNSResolver},
app::{
dispatcher::{BoxedChainedDatagram, BoxedChainedStream},
dns::ThreadSafeDNSResolver,
},
session::{Session, SocksAddr},
};

use super::{
AnyOutboundDatagram, AnyOutboundHandler, AnyStream, CommonOption, OutboundHandler, OutboundType,
};
use super::{AnyOutboundHandler, AnyStream, CommonOption, OutboundHandler, OutboundType};

use async_trait::async_trait;
pub use netstack_lwip as netstack;

mod device;
mod events;
mod stack;
mod wireguard;

pub struct Opts {
pub name: String,
pub common_opts: CommonOption,
Expand All @@ -34,15 +40,11 @@ pub struct Opts {

pub struct Handler {
opts: Opts,

device: boringtun::device::Device,
}

impl Handler {
pub fn new(opts: Opts) -> AnyOutboundHandler {
let device_cfg = boringtun::device::DeviceConfig::default();
let device = boringtun::device::Device::new("utun", device_cfg).unwrap();
Arc::new(Self { opts, device })
Arc::new(Self { opts })
}
}

Expand Down Expand Up @@ -88,7 +90,7 @@ impl OutboundHandler for Handler {
&self,
sess: &Session,
resolver: ThreadSafeDNSResolver,
) -> io::Result<AnyOutboundDatagram> {
) -> io::Result<BoxedChainedDatagram> {
todo!()
}
}
Loading

0 comments on commit 73cdd52

Please sign in to comment.