mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
@@ -134,25 +134,25 @@ impl FakeTcpTunnelListener {
|
||||
IpAddr::V6(ip) => (None, Some(ip)),
|
||||
};
|
||||
|
||||
let ret = self
|
||||
.stack_map
|
||||
.entry(interface_name.to_string())
|
||||
.or_insert_with(|| {
|
||||
let tun = create_tun(interface_name, None, local_socket_addr);
|
||||
let ret = match self.stack_map.entry(interface_name.to_string()) {
|
||||
dashmap::Entry::Occupied(entry) => entry.get().clone(),
|
||||
dashmap::Entry::Vacant(entry) => {
|
||||
let tun = create_tun(interface_name, None, local_socket_addr)?;
|
||||
tracing::info!(
|
||||
?local_socket_addr,
|
||||
"create new stack with interface_name: {:?}",
|
||||
interface_name
|
||||
);
|
||||
// TODO: Get local MAC address of the interface
|
||||
Arc::new(Mutex::new(stack::Stack::new(
|
||||
let stack = Arc::new(Mutex::new(stack::Stack::new(
|
||||
tun,
|
||||
local_ip.unwrap_or(Ipv4Addr::UNSPECIFIED),
|
||||
local_ip6,
|
||||
accept_result.mac,
|
||||
)))
|
||||
})
|
||||
.clone();
|
||||
)));
|
||||
entry.insert(stack.clone());
|
||||
stack
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
@@ -314,7 +314,7 @@ impl crate::tunnel::TunnelConnector for FakeTcpTunnelConnector {
|
||||
IpAddr::V6(ip) => (None, Some(ip)),
|
||||
};
|
||||
|
||||
let tun = create_tun(&interface_name, Some(remote_addr), local_addr);
|
||||
let tun = create_tun(&interface_name, Some(remote_addr), local_addr)?;
|
||||
let local_ip = local_ip.unwrap_or("0.0.0.0".parse().unwrap());
|
||||
let mut stack = stack::Stack::new(tun, local_ip, local_ip6, mac);
|
||||
let driver_type = stack.driver_type();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pub mod pnet;
|
||||
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use std::{io, net::SocketAddr, sync::Arc};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
@@ -10,19 +10,19 @@ cfg_if::cfg_if! {
|
||||
interface_name: &str,
|
||||
src_addr: Option<SocketAddr>,
|
||||
dst_addr: SocketAddr,
|
||||
) -> Arc<dyn super::stack::Tun> {
|
||||
) -> io::Result<Arc<dyn super::stack::Tun>> {
|
||||
match linux_bpf::LinuxBpfTun::new(interface_name, src_addr, dst_addr) {
|
||||
Ok(tun) => Arc::new(tun),
|
||||
Ok(tun) => Ok(Arc::new(tun)),
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
?e,
|
||||
interface_name,
|
||||
"LinuxBpfTun init failed, falling back to PnetTun"
|
||||
);
|
||||
Arc::new(pnet::PnetTun::new(
|
||||
Ok(Arc::new(pnet::PnetTun::new(
|
||||
interface_name,
|
||||
pnet::create_packet_filter(src_addr, dst_addr),
|
||||
))
|
||||
)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,19 +33,19 @@ cfg_if::cfg_if! {
|
||||
interface_name: &str,
|
||||
src_addr: Option<SocketAddr>,
|
||||
dst_addr: SocketAddr,
|
||||
) -> Arc<dyn super::stack::Tun> {
|
||||
) -> io::Result<Arc<dyn super::stack::Tun>> {
|
||||
match macos_bpf::MacosBpfTun::new(interface_name, src_addr, dst_addr) {
|
||||
Ok(tun) => Arc::new(tun),
|
||||
Ok(tun) => Ok(Arc::new(tun)),
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
?e,
|
||||
interface_name,
|
||||
"MacosBpfTun init failed, falling back to PnetTun"
|
||||
);
|
||||
Arc::new(pnet::PnetTun::new(
|
||||
Ok(Arc::new(pnet::PnetTun::new(
|
||||
interface_name,
|
||||
pnet::create_packet_filter(src_addr, dst_addr),
|
||||
))
|
||||
)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,19 +56,19 @@ cfg_if::cfg_if! {
|
||||
_interface_name: &str,
|
||||
_src_addr: Option<SocketAddr>,
|
||||
local_addr: SocketAddr,
|
||||
) -> Arc<dyn super::stack::Tun> {
|
||||
) -> io::Result<Arc<dyn super::stack::Tun>> {
|
||||
match windivert::WinDivertTun::new(local_addr) {
|
||||
Ok(tun) => Arc::new(tun),
|
||||
Ok(tun) => Ok(Arc::new(tun)),
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
?e,
|
||||
?local_addr,
|
||||
"WinDivertTun init failed, falling back to PnetTun"
|
||||
);
|
||||
Arc::new(pnet::PnetTun::new(
|
||||
Ok(Arc::new(pnet::PnetTun::new(
|
||||
local_addr.to_string().as_str(),
|
||||
pnet::create_packet_filter(None, local_addr),
|
||||
))
|
||||
)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,11 +77,11 @@ cfg_if::cfg_if! {
|
||||
interface_name: &str,
|
||||
src_addr: Option<SocketAddr>,
|
||||
dst_addr: SocketAddr,
|
||||
) -> Arc<dyn super::stack::Tun> {
|
||||
Arc::new(pnet::PnetTun::new(
|
||||
) -> io::Result<Arc<dyn super::stack::Tun>> {
|
||||
Ok(Arc::new(pnet::PnetTun::new(
|
||||
interface_name,
|
||||
pnet::create_packet_filter(src_addr, dst_addr),
|
||||
))
|
||||
)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
io,
|
||||
net::{IpAddr, SocketAddr},
|
||||
sync::{
|
||||
atomic::{AtomicU32, Ordering},
|
||||
@@ -145,14 +146,11 @@ struct InterfaceWorker {
|
||||
}
|
||||
|
||||
impl InterfaceWorker {
|
||||
fn new(interface: NetworkInterface) -> Arc<Self> {
|
||||
fn new(interface: NetworkInterface) -> io::Result<Arc<Self>> {
|
||||
let (tx, mut rx) = match datalink::channel(&interface, Default::default()) {
|
||||
Ok(pnet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
|
||||
Ok(_) => panic!("Unhandled channel type"),
|
||||
Err(e) => panic!(
|
||||
"An error occurred when creating the datalink channel: {}",
|
||||
e
|
||||
),
|
||||
Ok(_) => return Err(io::Error::other("Unhandled channel type")),
|
||||
Err(e) => return Err(io::Error::other(e)),
|
||||
};
|
||||
|
||||
let subscribers = Arc::new(DashMap::<u32, Subscriber>::new());
|
||||
@@ -187,10 +185,10 @@ impl InterfaceWorker {
|
||||
}
|
||||
});
|
||||
|
||||
Arc::new(Self {
|
||||
Ok(Arc::new(Self {
|
||||
tx: Mutex::new(tx),
|
||||
subscribers,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn subscribe(&self, filter: PacketFilter, sender: tokio::sync::mpsc::Sender<Vec<u8>>) -> u32 {
|
||||
@@ -207,13 +205,13 @@ impl InterfaceWorker {
|
||||
|
||||
static INTERFACE_MANAGERS: Lazy<DashMap<String, Weak<InterfaceWorker>>> = Lazy::new(DashMap::new);
|
||||
|
||||
fn get_or_create_worker(interface_name: &str) -> Arc<InterfaceWorker> {
|
||||
fn get_or_create_worker(interface_name: &str) -> io::Result<Arc<InterfaceWorker>> {
|
||||
// Check if we have an active worker
|
||||
if let Some(worker) = INTERFACE_MANAGERS
|
||||
.get(interface_name)
|
||||
.and_then(|w| w.upgrade())
|
||||
{
|
||||
return worker;
|
||||
return Ok(worker);
|
||||
}
|
||||
|
||||
// Need to create new worker.
|
||||
@@ -229,9 +227,9 @@ fn get_or_create_worker(interface_name: &str) -> Arc<InterfaceWorker> {
|
||||
.find(|iface| iface.name == interface_name)
|
||||
.expect("Network interface not found");
|
||||
|
||||
let worker = InterfaceWorker::new(interface);
|
||||
let worker = InterfaceWorker::new(interface)?;
|
||||
INTERFACE_MANAGERS.insert(interface_name.to_string(), Arc::downgrade(&worker));
|
||||
worker
|
||||
Ok(worker)
|
||||
}
|
||||
|
||||
pub struct PnetTun {
|
||||
@@ -241,17 +239,17 @@ pub struct PnetTun {
|
||||
}
|
||||
|
||||
impl PnetTun {
|
||||
pub fn new(interface_name: &str, filter: PacketFilter) -> Self {
|
||||
pub fn new(interface_name: &str, filter: PacketFilter) -> io::Result<Self> {
|
||||
tracing::debug!(interface_name, "Creating new PnetTun");
|
||||
let worker = get_or_create_worker(interface_name);
|
||||
let worker = get_or_create_worker(interface_name)?;
|
||||
let (tx, rx) = tokio::sync::mpsc::channel(1024);
|
||||
let id = worker.subscribe(filter, tx);
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
worker,
|
||||
subscription_id: id,
|
||||
recv_queue: Mutex::new(rx),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user