mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 04:37:23 +08:00
125 lines
4.3 KiB
Rust
125 lines
4.3 KiB
Rust
use std::{
|
|
net::{SocketAddr, SocketAddrV4, SocketAddrV6},
|
|
sync::Arc,
|
|
};
|
|
|
|
#[cfg(feature = "quic")]
|
|
use crate::tunnel::quic::QUICTunnelConnector;
|
|
#[cfg(feature = "wireguard")]
|
|
use crate::tunnel::wireguard::{WgConfig, WgTunnelConnector};
|
|
use crate::{
|
|
common::{error::Error, global_ctx::ArcGlobalCtx, network::IPCollector},
|
|
tunnel::{
|
|
check_scheme_and_get_socket_addr, ring::RingTunnelConnector, tcp::TcpTunnelConnector,
|
|
udp::UdpTunnelConnector, FromUrl, IpVersion, TunnelConnector,
|
|
},
|
|
};
|
|
|
|
pub mod direct;
|
|
pub mod manual;
|
|
pub mod udp_hole_punch;
|
|
|
|
async fn set_bind_addr_for_peer_connector(
|
|
connector: &mut (impl TunnelConnector + ?Sized),
|
|
is_ipv4: bool,
|
|
ip_collector: &Arc<IPCollector>,
|
|
) {
|
|
let ips = ip_collector.collect_ip_addrs().await;
|
|
if is_ipv4 {
|
|
let mut bind_addrs = vec![];
|
|
for ipv4 in ips.interface_ipv4s {
|
|
let socket_addr = SocketAddrV4::new(ipv4.parse().unwrap(), 0).into();
|
|
bind_addrs.push(socket_addr);
|
|
}
|
|
connector.set_bind_addrs(bind_addrs);
|
|
} else {
|
|
let mut bind_addrs = vec![];
|
|
for ipv6 in ips.interface_ipv6s {
|
|
let socket_addr = SocketAddrV6::new(ipv6.parse().unwrap(), 0, 0, 0).into();
|
|
bind_addrs.push(socket_addr);
|
|
}
|
|
connector.set_bind_addrs(bind_addrs);
|
|
}
|
|
let _ = connector;
|
|
}
|
|
|
|
pub async fn create_connector_by_url(
|
|
url: &str,
|
|
global_ctx: &ArcGlobalCtx,
|
|
) -> Result<Box<dyn TunnelConnector + 'static>, Error> {
|
|
let url = url::Url::parse(url).map_err(|_| Error::InvalidUrl(url.to_owned()))?;
|
|
match url.scheme() {
|
|
"tcp" => {
|
|
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "tcp")?;
|
|
let mut connector = TcpTunnelConnector::new(url);
|
|
set_bind_addr_for_peer_connector(
|
|
&mut connector,
|
|
dst_addr.is_ipv4(),
|
|
&global_ctx.get_ip_collector(),
|
|
)
|
|
.await;
|
|
return Ok(Box::new(connector));
|
|
}
|
|
"udp" => {
|
|
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "udp")?;
|
|
let mut connector = UdpTunnelConnector::new(url);
|
|
set_bind_addr_for_peer_connector(
|
|
&mut connector,
|
|
dst_addr.is_ipv4(),
|
|
&global_ctx.get_ip_collector(),
|
|
)
|
|
.await;
|
|
return Ok(Box::new(connector));
|
|
}
|
|
"ring" => {
|
|
check_scheme_and_get_socket_addr::<uuid::Uuid>(&url, "ring")?;
|
|
let connector = RingTunnelConnector::new(url);
|
|
return Ok(Box::new(connector));
|
|
}
|
|
#[cfg(feature = "quic")]
|
|
"quic" => {
|
|
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "quic")?;
|
|
let mut connector = QUICTunnelConnector::new(url);
|
|
set_bind_addr_for_peer_connector(
|
|
&mut connector,
|
|
dst_addr.is_ipv4(),
|
|
&global_ctx.get_ip_collector(),
|
|
)
|
|
.await;
|
|
return Ok(Box::new(connector));
|
|
}
|
|
#[cfg(feature = "wireguard")]
|
|
"wg" => {
|
|
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "wg")?;
|
|
let nid = global_ctx.get_network_identity();
|
|
let wg_config = WgConfig::new_from_network_identity(
|
|
&nid.network_name,
|
|
&nid.network_secret.unwrap_or_default(),
|
|
);
|
|
let mut connector = WgTunnelConnector::new(url, wg_config);
|
|
set_bind_addr_for_peer_connector(
|
|
&mut connector,
|
|
dst_addr.is_ipv4(),
|
|
&global_ctx.get_ip_collector(),
|
|
)
|
|
.await;
|
|
return Ok(Box::new(connector));
|
|
}
|
|
#[cfg(feature = "websocket")]
|
|
"ws" | "wss" => {
|
|
let dst_addr = SocketAddr::from_url(url.clone(), IpVersion::Both)?;
|
|
let mut connector = crate::tunnel::websocket::WSTunnelConnector::new(url);
|
|
set_bind_addr_for_peer_connector(
|
|
&mut connector,
|
|
dst_addr.is_ipv4(),
|
|
&global_ctx.get_ip_collector(),
|
|
)
|
|
.await;
|
|
return Ok(Box::new(connector));
|
|
}
|
|
_ => {
|
|
return Err(Error::InvalidUrl(url.into()));
|
|
}
|
|
}
|
|
}
|