mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 02:09:06 +00:00
zero copy tunnel (#55)
make tunnel zero copy, for better performance. remove most of the locks in io path. introduce quic tunnel prepare for encryption
This commit is contained in:
@@ -7,7 +7,9 @@ use tokio::{
|
||||
time::timeout,
|
||||
};
|
||||
|
||||
use crate::{common::PeerId, peers::peer_conn::PeerConnId, rpc as easytier_rpc};
|
||||
use crate::{
|
||||
common::PeerId, peers::zc_peer_conn::PeerConnId, rpc as easytier_rpc, tunnel::TunnelConnector,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
common::{
|
||||
@@ -21,13 +23,13 @@ use crate::{
|
||||
connector_manage_rpc_server::ConnectorManageRpc, Connector, ConnectorStatus,
|
||||
ListConnectorRequest, ManageConnectorRequest,
|
||||
},
|
||||
tunnels::{Tunnel, TunnelConnector},
|
||||
use_global_var,
|
||||
};
|
||||
|
||||
use super::create_connector_by_url;
|
||||
|
||||
type ConnectorMap = Arc<DashMap<String, Box<dyn TunnelConnector + Send + Sync>>>;
|
||||
type MutexConnector = Arc<Mutex<Box<dyn TunnelConnector>>>;
|
||||
type ConnectorMap = Arc<DashMap<String, MutexConnector>>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ReconnResult {
|
||||
@@ -81,12 +83,13 @@ impl ManualConnectorManager {
|
||||
|
||||
pub fn add_connector<T>(&self, connector: T)
|
||||
where
|
||||
T: TunnelConnector + Send + Sync + 'static,
|
||||
T: TunnelConnector + 'static,
|
||||
{
|
||||
log::info!("add_connector: {}", connector.remote_url());
|
||||
self.data
|
||||
.connectors
|
||||
.insert(connector.remote_url().into(), Box::new(connector));
|
||||
self.data.connectors.insert(
|
||||
connector.remote_url().into(),
|
||||
Arc::new(Mutex::new(Box::new(connector))),
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn add_connector_by_url(&self, url: &str) -> Result<(), Error> {
|
||||
@@ -254,7 +257,7 @@ impl ManualConnectorManager {
|
||||
async fn conn_reconnect(
|
||||
data: Arc<ConnectorManagerData>,
|
||||
dead_url: String,
|
||||
connector: Box<dyn TunnelConnector + Send + Sync>,
|
||||
connector: MutexConnector,
|
||||
) -> Result<ReconnResult, Error> {
|
||||
let connector = Arc::new(Mutex::new(Some(connector)));
|
||||
let net_ns = data.net_ns.clone();
|
||||
@@ -269,15 +272,17 @@ impl ManualConnectorManager {
|
||||
let mut locked = connector_clone.lock().await;
|
||||
let conn = locked.as_mut().unwrap();
|
||||
// TODO: should support set v6 here, use url in connector array
|
||||
set_bind_addr_for_peer_connector(conn, true, &ip_collector).await;
|
||||
set_bind_addr_for_peer_connector(conn.lock().await.as_mut(), true, &ip_collector).await;
|
||||
|
||||
data_clone
|
||||
.global_ctx
|
||||
.issue_event(GlobalCtxEvent::Connecting(conn.remote_url().clone()));
|
||||
.issue_event(GlobalCtxEvent::Connecting(
|
||||
conn.lock().await.remote_url().clone(),
|
||||
));
|
||||
|
||||
let _g = net_ns.guard();
|
||||
log::info!("reconnect try connect... conn: {:?}", conn);
|
||||
let tunnel = conn.connect().await?;
|
||||
let tunnel = conn.lock().await.connect().await?;
|
||||
log::info!("reconnect get tunnel succ: {:?}", tunnel);
|
||||
assert_eq!(
|
||||
url_clone,
|
||||
@@ -359,7 +364,7 @@ mod tests {
|
||||
use crate::{
|
||||
peers::tests::create_mock_peer_manager,
|
||||
set_global_var,
|
||||
tunnels::{Tunnel, TunnelError},
|
||||
tunnel::{Tunnel, TunnelError},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@@ -379,7 +384,7 @@ mod tests {
|
||||
}
|
||||
async fn connect(&mut self) -> Result<Box<dyn Tunnel>, TunnelError> {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||
Err(TunnelError::CommonError("fake error".into()))
|
||||
Err(TunnelError::InvalidPacket("fake error".into()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
common::{error::Error, global_ctx::ArcGlobalCtx, network::IPCollector},
|
||||
tunnels::{
|
||||
ring_tunnel::RingTunnelConnector,
|
||||
tcp_tunnel::TcpTunnelConnector,
|
||||
udp_tunnel::UdpTunnelConnector,
|
||||
tunnel::{
|
||||
ring::RingTunnelConnector,
|
||||
tcp::TcpTunnelConnector,
|
||||
udp::UdpTunnelConnector,
|
||||
wireguard::{WgConfig, WgTunnelConnector},
|
||||
TunnelConnector,
|
||||
},
|
||||
@@ -19,7 +19,7 @@ pub mod manual;
|
||||
pub mod udp_hole_punch;
|
||||
|
||||
async fn set_bind_addr_for_peer_connector(
|
||||
connector: &mut impl TunnelConnector,
|
||||
connector: &mut (impl TunnelConnector + ?Sized),
|
||||
is_ipv4: bool,
|
||||
ip_collector: &Arc<IPCollector>,
|
||||
) {
|
||||
@@ -45,7 +45,7 @@ async fn set_bind_addr_for_peer_connector(
|
||||
pub async fn create_connector_by_url(
|
||||
url: &str,
|
||||
global_ctx: &ArcGlobalCtx,
|
||||
) -> Result<Box<dyn TunnelConnector + Send + Sync + 'static>, Error> {
|
||||
) -> Result<Box<dyn TunnelConnector + 'static>, Error> {
|
||||
let url = url::Url::parse(url).map_err(|_| Error::InvalidUrl(url.to_owned()))?;
|
||||
match url.scheme() {
|
||||
"tcp" => {
|
||||
|
||||
@@ -2,20 +2,21 @@ use std::{net::SocketAddr, sync::Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
use rand::{seq::SliceRandom, Rng, SeedableRng};
|
||||
use rand::{seq::SliceRandom, SeedableRng};
|
||||
use tokio::{net::UdpSocket, sync::Mutex, task::JoinSet};
|
||||
use tracing::Instrument;
|
||||
|
||||
use crate::{
|
||||
common::{
|
||||
constants, error::Error, global_ctx::ArcGlobalCtx, join_joinset_background,
|
||||
rkyv_util::encode_to_bytes, stun::StunInfoCollectorTrait, PeerId,
|
||||
stun::StunInfoCollectorTrait, PeerId,
|
||||
},
|
||||
peers::peer_manager::PeerManager,
|
||||
rpc::NatType,
|
||||
tunnels::{
|
||||
tunnel::{
|
||||
common::setup_sokcet2,
|
||||
udp_tunnel::{UdpPacket, UdpTunnelConnector, UdpTunnelListener},
|
||||
packet_def::ZCPacketType,
|
||||
udp::{new_hole_punch_packet, UdpTunnelConnector, UdpTunnelListener},
|
||||
Tunnel, TunnelConnCounter, TunnelListener,
|
||||
},
|
||||
};
|
||||
@@ -149,15 +150,10 @@ impl UdpHolePunchService for UdpHolePunchRpcServer {
|
||||
self.tasks.lock().unwrap().spawn(async move {
|
||||
for _ in 0..10 {
|
||||
tracing::info!(?local_mapped_addr, "sending hole punching packet");
|
||||
// generate a 128 bytes vec with random data
|
||||
let mut rng = rand::rngs::StdRng::from_entropy();
|
||||
let mut buf = vec![0u8; 128];
|
||||
rng.fill(&mut buf[..]);
|
||||
|
||||
let udp_packet = UdpPacket::new_hole_punch_packet(buf);
|
||||
let udp_packet_bytes = encode_to_bytes::<_, 256>(&udp_packet);
|
||||
let udp_packet = new_hole_punch_packet();
|
||||
let _ = socket
|
||||
.send_to(udp_packet_bytes.as_ref(), local_mapped_addr)
|
||||
.send_to(&udp_packet.into_bytes(ZCPacketType::UDP), local_mapped_addr)
|
||||
.await;
|
||||
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user