mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
Fix: Fixed compilation issue after partially removing the feature flag (#1835)
This commit is contained in:
+12
-8
@@ -155,7 +155,7 @@ bitflags = "2.5"
|
||||
aes-gcm = { version = "0.10.3", optional = true }
|
||||
openssl = { version = "0.10", optional = true, features = ["vendored"] }
|
||||
snow = "0.10.0"
|
||||
x25519-dalek = "2.0"
|
||||
x25519-dalek = { version = "2.0", features = ["static_secrets"] }
|
||||
|
||||
# for cli
|
||||
tabled = "0.16"
|
||||
@@ -185,7 +185,7 @@ smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp.git", rev = "0a926767a6
|
||||
# "socket-tcp-cubic",
|
||||
"async",
|
||||
] }
|
||||
parking_lot = { version = "0.12.0", optional = true }
|
||||
parking_lot = { version = "0.12.0" }
|
||||
|
||||
wildmatch = "2.3.4"
|
||||
|
||||
@@ -199,7 +199,7 @@ service-manager = { git = "https://github.com/EasyTier/service-manager-rs.git",
|
||||
|
||||
zstd = { version = "0.13" }
|
||||
|
||||
kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "94964794caaed5d388463137da59b97499619e5f" }
|
||||
kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "94964794caaed5d388463137da59b97499619e5f", optional = true }
|
||||
|
||||
prost-reflect = { version = "0.14.5", default-features = false, features = [
|
||||
"derive",
|
||||
@@ -215,8 +215,9 @@ hickory-resolver = "0.25.2"
|
||||
hickory-proto = "0.25.2"
|
||||
|
||||
# for magic dns
|
||||
hickory-client = "0.25.2"
|
||||
hickory-server = { version = "0.25.2", features = ["resolver"] }
|
||||
hickory-client = { version = "0.25.2", optional = true }
|
||||
hickory-server = { version = "0.25.2", features = ["resolver"], optional = true }
|
||||
|
||||
derive_builder = "0.20.2"
|
||||
humantime-serde = "1.1.1"
|
||||
multimap = "0.10.1"
|
||||
@@ -318,7 +319,7 @@ tokio-socks = "0.5.2"
|
||||
|
||||
|
||||
[features]
|
||||
default = ["wireguard", "websocket", "smoltcp", "tun", "socks5", "quic"]
|
||||
default = ["wireguard", "websocket", "smoltcp", "tun", "socks5", "kcp", "quic", "magic-dns"]
|
||||
full = [
|
||||
"websocket",
|
||||
"wireguard",
|
||||
@@ -327,9 +328,11 @@ full = [
|
||||
"smoltcp",
|
||||
"tun",
|
||||
"socks5",
|
||||
"magic-dns",
|
||||
]
|
||||
wireguard = ["dep:boringtun", "dep:ring"]
|
||||
quic = ["dep:quinn", "dep:rustls", "dep:rcgen"]
|
||||
kcp = ["dep:kcp-sys"]
|
||||
mimalloc = ["dep:mimalloc"]
|
||||
aes-gcm = ["dep:aes-gcm"]
|
||||
openssl-crypto = ["dep:openssl"]
|
||||
@@ -341,8 +344,9 @@ websocket = [
|
||||
"dep:rustls",
|
||||
"dep:rcgen",
|
||||
]
|
||||
smoltcp = ["dep:smoltcp", "dep:parking_lot"]
|
||||
socks5 = ["dep:smoltcp"]
|
||||
smoltcp = ["dep:smoltcp"]
|
||||
socks5 = ["smoltcp"]
|
||||
jemalloc = ["dep:jemallocator", "dep:jemalloc-sys"]
|
||||
jemalloc-prof = ["jemalloc", "dep:jemalloc-ctl", "jemalloc-ctl/stats", "jemalloc-sys/profiling", "jemalloc-sys/stats"]
|
||||
tracing = ["tokio/tracing", "dep:console-subscriber"]
|
||||
magic-dns = ["dep:hickory-client", "dep:hickory-server"]
|
||||
|
||||
@@ -931,7 +931,6 @@ impl NetworkOptions {
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(feature = "socks5")]
|
||||
for port_forward in self.port_forward.iter() {
|
||||
let example_str = ", example: udp://0.0.0.0:12345/10.126.126.1:12345";
|
||||
|
||||
|
||||
@@ -13,19 +13,9 @@ use kcp_sys::{
|
||||
packet_def::KcpPacket,
|
||||
stream::KcpStream,
|
||||
};
|
||||
use pnet::packet::{
|
||||
ip::IpNextHeaderProtocols,
|
||||
ipv4::Ipv4Packet,
|
||||
tcp::{TcpFlags, TcpPacket},
|
||||
Packet as _,
|
||||
};
|
||||
use pnet::packet::ipv4::Ipv4Packet;
|
||||
use prost::Message;
|
||||
use tokio::{
|
||||
io::{copy_bidirectional, AsyncRead, AsyncWrite},
|
||||
select,
|
||||
task::JoinSet,
|
||||
};
|
||||
use tokio_util::io::InspectReader;
|
||||
use tokio::{select, task::JoinSet};
|
||||
|
||||
use super::{
|
||||
tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy},
|
||||
@@ -37,9 +27,10 @@ use crate::{
|
||||
error::Result,
|
||||
global_ctx::{ArcGlobalCtx, GlobalCtx},
|
||||
},
|
||||
peers::{acl_filter::AclFilter, peer_manager::PeerManager, NicPacketFilter, PeerPacketFilter},
|
||||
gateway::wrapped_proxy::{ProxyAclHandler, TcpProxyForWrappedSrcTrait},
|
||||
peers::{peer_manager::PeerManager, PeerPacketFilter},
|
||||
proto::{
|
||||
acl::{Action, ChainType, Protocol},
|
||||
acl::{ChainType, Protocol},
|
||||
api::instance::{
|
||||
ListTcpProxyEntryRequest, ListTcpProxyEntryResponse, TcpProxyEntry, TcpProxyEntryState,
|
||||
TcpProxyEntryTransportType, TcpProxyRpc,
|
||||
@@ -215,21 +206,14 @@ impl NatDstConnector for NatDstKcpConnector {
|
||||
struct TcpProxyForKcpSrc(Arc<TcpProxy<NatDstKcpConnector>>);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub(crate) trait TcpProxyForKcpSrcTrait: Send + Sync + 'static {
|
||||
type Connector: NatDstConnector;
|
||||
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
|
||||
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc {
|
||||
impl TcpProxyForWrappedSrcTrait for TcpProxyForKcpSrc {
|
||||
type Connector = NatDstKcpConnector;
|
||||
|
||||
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
let Some(peer_manager) = self.0.get_peer_manager() else {
|
||||
return false;
|
||||
};
|
||||
@@ -239,81 +223,6 @@ impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<C: NatDstConnector, T: TcpProxyForKcpSrcTrait<Connector = C>> NicPacketFilter for T {
|
||||
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
|
||||
let ret = self
|
||||
.get_tcp_proxy()
|
||||
.try_process_packet_from_nic(zc_packet)
|
||||
.await;
|
||||
if ret {
|
||||
return true;
|
||||
}
|
||||
|
||||
let data = zc_packet.payload();
|
||||
let ip_packet = Ipv4Packet::new(data).unwrap();
|
||||
if ip_packet.get_version() != 4
|
||||
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if no connection is established, only allow SYN packet
|
||||
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
|
||||
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
|
||||
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
|
||||
if is_syn {
|
||||
// only check dst feature flag when SYN packet
|
||||
if !self
|
||||
.check_dst_allow_kcp_input(&ip_packet.get_destination())
|
||||
.await
|
||||
{
|
||||
tracing::warn!(
|
||||
"{:?} proxy src: dst {} not allow kcp input",
|
||||
self.get_tcp_proxy().get_transport_type(),
|
||||
ip_packet.get_destination()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// if not syn packet, only allow established connection
|
||||
if !self
|
||||
.get_tcp_proxy()
|
||||
.is_tcp_proxy_connection(SocketAddr::new(
|
||||
IpAddr::V4(ip_packet.get_source()),
|
||||
tcp_packet.get_source(),
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(my_ipv4) = self.get_tcp_proxy().get_global_ctx().get_ipv4() {
|
||||
// this is a net-to-net packet, only allow it when smoltcp is enabled
|
||||
// because the syn-ack packet will not be through and handled by the tun device when
|
||||
// the source ip is in the local network
|
||||
if ip_packet.get_source() != my_ipv4.address()
|
||||
&& !self.get_tcp_proxy().is_smoltcp_enabled()
|
||||
{
|
||||
tracing::warn!(
|
||||
"{:?} nat 2 nat packet, src: {} dst: {} not allow kcp input",
|
||||
self.get_tcp_proxy().get_transport_type(),
|
||||
ip_packet.get_source(),
|
||||
ip_packet.get_destination()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let hdr = zc_packet.mut_peer_manager_header().unwrap();
|
||||
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
|
||||
if self.get_tcp_proxy().get_transport_type() == TcpProxyEntryTransportType::Kcp {
|
||||
hdr.set_kcp_src_modified(true);
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KcpProxySrc {
|
||||
kcp_endpoint: Arc<KcpEndpoint>,
|
||||
peer_manager: Arc<PeerManager>,
|
||||
@@ -387,50 +296,6 @@ pub struct KcpProxyDst {
|
||||
tasks: JoinSet<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProxyAclHandler {
|
||||
pub acl_filter: Arc<AclFilter>,
|
||||
pub packet_info: PacketInfo,
|
||||
pub chain_type: ChainType,
|
||||
}
|
||||
|
||||
impl ProxyAclHandler {
|
||||
pub fn handle_packet(&self, buf: &[u8]) -> Result<()> {
|
||||
let mut packet_info = self.packet_info.clone();
|
||||
packet_info.packet_size = buf.len();
|
||||
let ret = self
|
||||
.acl_filter
|
||||
.get_processor()
|
||||
.process_packet(&packet_info, self.chain_type);
|
||||
self.acl_filter.handle_acl_result(
|
||||
&ret,
|
||||
&packet_info,
|
||||
self.chain_type,
|
||||
&self.acl_filter.get_processor(),
|
||||
);
|
||||
if !matches!(ret.action, Action::Allow) {
|
||||
return Err(anyhow::anyhow!("acl denied").into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn copy_bidirection_with_acl(
|
||||
&self,
|
||||
src: impl AsyncRead + AsyncWrite + Unpin,
|
||||
mut dst: impl AsyncRead + AsyncWrite + Unpin,
|
||||
) -> Result<()> {
|
||||
let (src_reader, src_writer) = tokio::io::split(src);
|
||||
let src_reader = InspectReader::new(src_reader, |buf| {
|
||||
let _ = self.handle_packet(buf);
|
||||
});
|
||||
let mut src = tokio::io::join(src_reader, src_writer);
|
||||
|
||||
copy_bidirectional(&mut src, &mut dst).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl KcpProxyDst {
|
||||
pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
|
||||
let mut kcp_endpoint = create_kcp_endpoint();
|
||||
|
||||
@@ -16,8 +16,11 @@ pub mod fast_socks5;
|
||||
#[cfg(feature = "socks5")]
|
||||
pub mod socks5;
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
pub mod kcp_proxy;
|
||||
mod wrapped_proxy;
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
pub mod quic_proxy;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -17,8 +17,8 @@ use crate::common::error::Result;
|
||||
use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtx};
|
||||
use crate::common::join_joinset_background;
|
||||
use crate::defer;
|
||||
use crate::gateway::kcp_proxy::{ProxyAclHandler, TcpProxyForKcpSrcTrait};
|
||||
use crate::gateway::tcp_proxy::{NatDstConnector, NatDstTcpConnector, TcpProxy};
|
||||
use crate::gateway::wrapped_proxy::{ProxyAclHandler, TcpProxyForWrappedSrcTrait};
|
||||
use crate::gateway::CidrSet;
|
||||
use crate::peers::peer_manager::PeerManager;
|
||||
use crate::proto::acl::{ChainType, Protocol};
|
||||
@@ -184,14 +184,14 @@ impl NatDstConnector for NatDstQUICConnector {
|
||||
struct TcpProxyForQUICSrc(Arc<TcpProxy<NatDstQUICConnector>>);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl TcpProxyForKcpSrcTrait for TcpProxyForQUICSrc {
|
||||
impl TcpProxyForWrappedSrcTrait for TcpProxyForQUICSrc {
|
||||
type Connector = NatDstQUICConnector;
|
||||
|
||||
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
let Some(peer_manager) = self.0.get_peer_manager() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -9,9 +9,12 @@ use std::{
|
||||
};
|
||||
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
#[cfg(feature = "kcp")]
|
||||
use kcp_sys::{endpoint::KcpEndpoint, stream::KcpStream};
|
||||
use tokio_util::sync::{CancellationToken, DropGuard};
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
use crate::gateway::kcp_proxy::NatDstKcpConnector;
|
||||
use crate::{
|
||||
common::{
|
||||
config::PortForwardConfig, global_ctx::GlobalCtxEvent, join_joinset_background,
|
||||
@@ -25,7 +28,6 @@ use crate::{
|
||||
util::stream::tcp_connect_with_timeout,
|
||||
},
|
||||
ip_reassembler::IpReassembler,
|
||||
kcp_proxy::NatDstKcpConnector,
|
||||
tokio_smoltcp::{channel_device, BufferSize, Net, NetConfig},
|
||||
},
|
||||
tunnel::{
|
||||
@@ -52,6 +54,7 @@ use crate::{
|
||||
peers::{peer_manager::PeerManager, PeerPacketFilter},
|
||||
};
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
use super::tcp_proxy::NatDstConnector as _;
|
||||
|
||||
enum SocksUdpSocket {
|
||||
@@ -78,6 +81,7 @@ impl SocksUdpSocket {
|
||||
enum SocksTcpStream {
|
||||
Tcp(tokio::net::TcpStream),
|
||||
SmolTcp(super::tokio_smoltcp::TcpStream),
|
||||
#[cfg(feature = "kcp")]
|
||||
Kcp(KcpStream),
|
||||
}
|
||||
|
||||
@@ -92,6 +96,7 @@ impl AsyncRead for SocksTcpStream {
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_read(cx, buf)
|
||||
}
|
||||
#[cfg(feature = "kcp")]
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf),
|
||||
}
|
||||
}
|
||||
@@ -108,6 +113,7 @@ impl AsyncWrite for SocksTcpStream {
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_write(cx, buf)
|
||||
}
|
||||
#[cfg(feature = "kcp")]
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf),
|
||||
}
|
||||
}
|
||||
@@ -119,6 +125,7 @@ impl AsyncWrite for SocksTcpStream {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
#[cfg(feature = "kcp")]
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
}
|
||||
}
|
||||
@@ -130,6 +137,7 @@ impl AsyncWrite for SocksTcpStream {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
#[cfg(feature = "kcp")]
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
}
|
||||
}
|
||||
@@ -211,12 +219,14 @@ impl Drop for SmolTcpConnector {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
struct Socks5KcpConnector {
|
||||
kcp_endpoint: Weak<KcpEndpoint>,
|
||||
peer_mgr: Weak<PeerManager>,
|
||||
src_addr: SocketAddr,
|
||||
}
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
#[async_trait::async_trait]
|
||||
impl AsyncTcpConnector for Socks5KcpConnector {
|
||||
type S = SocksTcpStream;
|
||||
@@ -242,6 +252,7 @@ impl AsyncTcpConnector for Socks5KcpConnector {
|
||||
}
|
||||
|
||||
struct Socks5AutoConnector {
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_endpoint: Option<Weak<KcpEndpoint>>,
|
||||
peer_mgr: Weak<PeerManager>,
|
||||
entries: Socks5EntrySet,
|
||||
@@ -288,6 +299,7 @@ impl AsyncTcpConnector for Socks5AutoConnector {
|
||||
let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&addr.ip()).await;
|
||||
tracing::debug!("dst_allow_kcp: {:?}", dst_allow_kcp);
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
let connector: Box<dyn AsyncTcpConnector<S = SocksTcpStream> + Send> =
|
||||
match (&self.kcp_endpoint, dst_allow_kcp) {
|
||||
(Some(kcp_endpoint), true) => Box::new(Socks5KcpConnector {
|
||||
@@ -301,6 +313,12 @@ impl AsyncTcpConnector for Socks5AutoConnector {
|
||||
current_entry: std::sync::Mutex::new(None),
|
||||
}),
|
||||
};
|
||||
#[cfg(not(feature = "kcp"))]
|
||||
let connector = Box::new(SmolTcpConnector {
|
||||
net: self.smoltcp_net.clone().unwrap(),
|
||||
entries: self.entries.clone(),
|
||||
current_entry: std::sync::Mutex::new(None),
|
||||
});
|
||||
|
||||
let ret = connector.tcp_connect(addr, timeout_s).await;
|
||||
self.inner_connector.lock().replace(Box::new(connector));
|
||||
@@ -490,6 +508,7 @@ pub struct Socks5Server {
|
||||
udp_client_map: Arc<DashMap<UdpClientKey, Arc<UdpClientInfo>>>,
|
||||
udp_forward_task: Arc<DashMap<UdpClientKey, ScopedTask<()>>>,
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_endpoint: Mutex<Option<Weak<KcpEndpoint>>>,
|
||||
|
||||
socks5_enabled: Arc<AtomicBool>,
|
||||
@@ -603,6 +622,7 @@ impl Socks5Server {
|
||||
udp_client_map: Arc::new(DashMap::new()),
|
||||
udp_forward_task: Arc::new(DashMap::new()),
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_endpoint: Mutex::new(None),
|
||||
|
||||
socks5_enabled: Arc::new(AtomicBool::new(false)),
|
||||
@@ -662,9 +682,12 @@ impl Socks5Server {
|
||||
|
||||
pub async fn run(
|
||||
self: &Arc<Self>,
|
||||
kcp_endpoint: Option<Weak<KcpEndpoint>>,
|
||||
#[cfg(feature = "kcp")] kcp_endpoint: Option<Weak<KcpEndpoint>>,
|
||||
) -> Result<(), Error> {
|
||||
*self.kcp_endpoint.lock().await = kcp_endpoint.clone();
|
||||
#[cfg(feature = "kcp")]
|
||||
{
|
||||
*self.kcp_endpoint.lock().await = kcp_endpoint.clone();
|
||||
}
|
||||
if let Some(proxy_url) = self.global_ctx.config.get_socks5_portal() {
|
||||
let bind_addr = format!(
|
||||
"{}:{}",
|
||||
@@ -692,6 +715,7 @@ impl Socks5Server {
|
||||
.as_ref()
|
||||
.map(|net| net.smoltcp_net.clone()),
|
||||
entries: entries.clone(),
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_endpoint: kcp_endpoint.clone(),
|
||||
peer_mgr: peer_manager.clone(),
|
||||
src_addr: addr,
|
||||
@@ -811,6 +835,7 @@ impl Socks5Server {
|
||||
let tasks = Arc::new(std::sync::Mutex::new(JoinSet::new()));
|
||||
join_joinset_background(tasks.clone(), "tcp port forward".to_string());
|
||||
let forward_tasks = tasks;
|
||||
#[cfg(feature = "kcp")]
|
||||
let kcp_endpoint = self.kcp_endpoint.lock().await.clone();
|
||||
let peer_mgr = self.peer_manager.clone();
|
||||
let cancel_token = CancellationToken::new();
|
||||
@@ -843,6 +868,7 @@ impl Socks5Server {
|
||||
);
|
||||
|
||||
let connector = Socks5AutoConnector {
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_endpoint: kcp_endpoint.clone(),
|
||||
peer_mgr: peer_mgr.clone(),
|
||||
entries: entries.clone(),
|
||||
|
||||
@@ -201,6 +201,7 @@ impl ProxyTcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "smoltcp")]
|
||||
type SmolTcpAcceptResult = Result<(tokio_smoltcp::TcpStream, SocketAddr)>;
|
||||
#[cfg(feature = "smoltcp")]
|
||||
struct SmolTcpListener {
|
||||
@@ -331,6 +332,7 @@ pub struct TcpProxy<C: NatDstConnector> {
|
||||
smoltcp_stack_receiver: Arc<Mutex<Option<mpsc::Receiver<ZCPacket>>>>,
|
||||
#[cfg(feature = "smoltcp")]
|
||||
smoltcp_net: Arc<Mutex<Option<Net>>>,
|
||||
#[cfg(feature = "smoltcp")]
|
||||
smoltcp_listener_tx: std::sync::Mutex<Option<mpsc::UnboundedSender<SmolTcpAcceptResult>>>,
|
||||
enable_smoltcp: Arc<AtomicBool>,
|
||||
|
||||
@@ -461,6 +463,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
||||
|
||||
#[cfg(feature = "smoltcp")]
|
||||
smoltcp_net: Arc::new(Mutex::new(None)),
|
||||
#[cfg(feature = "smoltcp")]
|
||||
smoltcp_listener_tx: std::sync::Mutex::new(None),
|
||||
|
||||
enable_smoltcp: Arc::new(AtomicBool::new(true)),
|
||||
@@ -930,6 +933,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
||||
tracing::info!(src = ?src, ?real_dst, ?mapped_dst, old_entry = ?old_val, "tcp syn received");
|
||||
|
||||
// if smoltcp is enabled, add the listener to the net
|
||||
#[cfg(feature = "smoltcp")]
|
||||
if self.is_smoltcp_enabled() {
|
||||
let smoltcp_listener_tx = self.smoltcp_listener_tx.lock().unwrap().clone().unwrap();
|
||||
SmolTcpListener::add_listener(
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
use std::{
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use pnet::packet::{
|
||||
ip::IpNextHeaderProtocols,
|
||||
ipv4::Ipv4Packet,
|
||||
tcp::{TcpFlags, TcpPacket},
|
||||
Packet as _,
|
||||
};
|
||||
use tokio::io::{copy_bidirectional, AsyncRead, AsyncWrite};
|
||||
use tokio_util::io::InspectReader;
|
||||
|
||||
use crate::{
|
||||
common::{acl_processor::PacketInfo, error::Result},
|
||||
gateway::tcp_proxy::{NatDstConnector, TcpProxy},
|
||||
peers::{acl_filter::AclFilter, NicPacketFilter},
|
||||
proto::{
|
||||
acl::{Action, ChainType},
|
||||
api::instance::TcpProxyEntryTransportType,
|
||||
},
|
||||
tunnel::packet_def::ZCPacket,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProxyAclHandler {
|
||||
pub acl_filter: Arc<AclFilter>,
|
||||
pub packet_info: PacketInfo,
|
||||
pub chain_type: ChainType,
|
||||
}
|
||||
|
||||
impl ProxyAclHandler {
|
||||
pub fn handle_packet(&self, buf: &[u8]) -> Result<()> {
|
||||
let mut packet_info = self.packet_info.clone();
|
||||
packet_info.packet_size = buf.len();
|
||||
let ret = self
|
||||
.acl_filter
|
||||
.get_processor()
|
||||
.process_packet(&packet_info, self.chain_type);
|
||||
self.acl_filter.handle_acl_result(
|
||||
&ret,
|
||||
&packet_info,
|
||||
self.chain_type,
|
||||
&self.acl_filter.get_processor(),
|
||||
);
|
||||
if !matches!(ret.action, Action::Allow) {
|
||||
return Err(anyhow::anyhow!("acl denied").into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn copy_bidirection_with_acl(
|
||||
&self,
|
||||
src: impl AsyncRead + AsyncWrite + Unpin,
|
||||
mut dst: impl AsyncRead + AsyncWrite + Unpin,
|
||||
) -> Result<()> {
|
||||
let (src_reader, src_writer) = tokio::io::split(src);
|
||||
let src_reader = InspectReader::new(src_reader, |buf| {
|
||||
let _ = self.handle_packet(buf);
|
||||
});
|
||||
let mut src = tokio::io::join(src_reader, src_writer);
|
||||
|
||||
copy_bidirectional(&mut src, &mut dst).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub(crate) trait TcpProxyForWrappedSrcTrait: Send + Sync + 'static {
|
||||
type Connector: NatDstConnector;
|
||||
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
|
||||
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<C: NatDstConnector, T: TcpProxyForWrappedSrcTrait<Connector = C>> NicPacketFilter for T {
|
||||
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
|
||||
let ret = self
|
||||
.get_tcp_proxy()
|
||||
.try_process_packet_from_nic(zc_packet)
|
||||
.await;
|
||||
if ret {
|
||||
return true;
|
||||
}
|
||||
|
||||
let data = zc_packet.payload();
|
||||
let ip_packet = Ipv4Packet::new(data).unwrap();
|
||||
if ip_packet.get_version() != 4
|
||||
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if no connection is established, only allow SYN packet
|
||||
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
|
||||
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
|
||||
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
|
||||
if is_syn {
|
||||
// only check dst feature flag when SYN packet
|
||||
if !self
|
||||
.check_dst_allow_wrapped_input(&ip_packet.get_destination())
|
||||
.await
|
||||
{
|
||||
tracing::warn!(
|
||||
"{:?} proxy src: dst {} not allow wrapped input",
|
||||
self.get_tcp_proxy().get_transport_type(),
|
||||
ip_packet.get_destination()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// if not syn packet, only allow established connection
|
||||
if !self
|
||||
.get_tcp_proxy()
|
||||
.is_tcp_proxy_connection(SocketAddr::new(
|
||||
IpAddr::V4(ip_packet.get_source()),
|
||||
tcp_packet.get_source(),
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(my_ipv4) = self.get_tcp_proxy().get_global_ctx().get_ipv4() {
|
||||
// this is a net-to-net packet, only allow it when smoltcp is enabled
|
||||
// because the syn-ack packet will not be through and handled by the tun device when
|
||||
// the source ip is in the local network
|
||||
if ip_packet.get_source() != my_ipv4.address()
|
||||
&& !self.get_tcp_proxy().is_smoltcp_enabled()
|
||||
{
|
||||
tracing::warn!(
|
||||
"{:?} nat 2 nat packet, src: {} dst: {} not allow wrapped input",
|
||||
self.get_tcp_proxy().get_transport_type(),
|
||||
ip_packet.get_source(),
|
||||
ip_packet.get_destination()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let hdr = zc_packet.mut_peer_manager_header().unwrap();
|
||||
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
|
||||
if self.get_tcp_proxy().get_transport_type() == TcpProxyEntryTransportType::Kcp {
|
||||
hdr.set_kcp_src_modified(true);
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
// This module is copy and modified from https://github.com/fanyang89/libdns
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub(crate) mod config;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub(crate) mod server;
|
||||
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub mod client_instance;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub mod runner;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub mod server_instance;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub mod system_config;
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, feature = "tun", feature = "magic-dns"))]
|
||||
mod tests;
|
||||
|
||||
pub static MAGIC_DNS_INSTANCE_ADDR: &str = "tcp://127.0.0.1:49813";
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
#[cfg(feature = "tun")]
|
||||
use std::any::Any;
|
||||
use std::collections::HashSet;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Weak};
|
||||
#[cfg(feature = "tun")]
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context;
|
||||
use cidr::{IpCidr, Ipv4Inet};
|
||||
|
||||
use futures::FutureExt;
|
||||
use tokio::sync::{oneshot, Notify};
|
||||
use tokio::{sync::Mutex, task::JoinSet};
|
||||
use tokio::sync::{Mutex, Notify};
|
||||
#[cfg(feature = "tun")]
|
||||
use tokio::{sync::oneshot, task::JoinSet};
|
||||
#[cfg(feature = "magic-dns")]
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::common::acl_processor::AclRuleBuilder;
|
||||
@@ -24,15 +28,19 @@ use crate::connector::manual::{ConnectorManagerRpcService, ManualConnectorManage
|
||||
use crate::connector::tcp_hole_punch::TcpHolePunchConnector;
|
||||
use crate::connector::udp_hole_punch::UdpHolePunchConnector;
|
||||
use crate::gateway::icmp_proxy::IcmpProxy;
|
||||
#[cfg(feature = "kcp")]
|
||||
use crate::gateway::kcp_proxy::{KcpProxyDst, KcpProxyDstRpcService, KcpProxySrc};
|
||||
#[cfg(feature = "quic")]
|
||||
use crate::gateway::quic_proxy::{QUICProxyDst, QUICProxyDstRpcService, QUICProxySrc};
|
||||
use crate::gateway::tcp_proxy::{NatDstTcpConnector, TcpProxy, TcpProxyRpcService};
|
||||
use crate::gateway::udp_proxy::UdpProxy;
|
||||
use crate::peer_center::instance::PeerCenterInstance;
|
||||
use crate::peers::peer_conn::PeerConnId;
|
||||
use crate::peers::peer_manager::{PeerManager, RouteAlgoType};
|
||||
#[cfg(feature = "tun")]
|
||||
use crate::peers::recv_packet_from_chan;
|
||||
use crate::peers::rpc_service::PeerManagerRpcService;
|
||||
use crate::peers::{create_packet_recv_chan, recv_packet_from_chan, PacketRecvChanReceiver};
|
||||
use crate::peers::{create_packet_recv_chan, PacketRecvChanReceiver};
|
||||
use crate::proto::api::config::{
|
||||
ConfigPatchAction, ConfigRpc, GetConfigRequest, GetConfigResponse, PatchConfigRequest,
|
||||
PatchConfigResponse, PortForwardPatch,
|
||||
@@ -53,8 +61,8 @@ use crate::rpc_service::InstanceRpcService;
|
||||
use crate::utils::weak_upgrade;
|
||||
use crate::vpn_portal::{self, VpnPortal};
|
||||
|
||||
use super::dns_server::runner::DnsRunner;
|
||||
use super::dns_server::MAGIC_DNS_FAKE_IP;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
use super::dns_server::{runner::DnsRunner, MAGIC_DNS_FAKE_IP};
|
||||
use super::listeners::ListenerManager;
|
||||
|
||||
#[cfg(feature = "socks5")]
|
||||
@@ -120,35 +128,31 @@ impl IpProxy {
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
type NicCtx = super::virtual_nic::NicCtx;
|
||||
#[cfg(not(feature = "tun"))]
|
||||
struct NicCtx;
|
||||
#[cfg(not(feature = "tun"))]
|
||||
impl NicCtx {
|
||||
pub fn new(
|
||||
_global_ctx: ArcGlobalCtx,
|
||||
_peer_manager: &Arc<PeerManager>,
|
||||
_peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
|
||||
) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub async fn run(&mut self, _ipv4_addr: Ipv4Addr) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic-dns")]
|
||||
struct MagicDnsContainer {
|
||||
dns_runner_task: ScopedTask<()>,
|
||||
dns_runner_cancel_token: CancellationToken,
|
||||
}
|
||||
|
||||
// nic container will be cleared when dhcp ip changed
|
||||
#[cfg(feature = "tun")]
|
||||
pub struct NicCtxContainer {
|
||||
nic_ctx: Option<Box<dyn Any + 'static + Send>>,
|
||||
#[cfg(feature = "magic-dns")]
|
||||
magic_dns: Option<MagicDnsContainer>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
impl NicCtxContainer {
|
||||
#[cfg(not(feature = "magic-dns"))]
|
||||
fn new(nic_ctx: NicCtx) -> Self {
|
||||
Self {
|
||||
nic_ctx: Some(Box::new(nic_ctx)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic-dns")]
|
||||
fn new(nic_ctx: NicCtx, dns_runner: Option<DnsRunner>) -> Self {
|
||||
if let Some(mut dns_runner) = dns_runner {
|
||||
let token = CancellationToken::new();
|
||||
@@ -174,11 +178,13 @@ impl NicCtxContainer {
|
||||
fn new_with_any<T: 'static + Send>(ctx: T) -> Self {
|
||||
Self {
|
||||
nic_ctx: Some(Box::new(ctx)),
|
||||
#[cfg(feature = "magic-dns")]
|
||||
magic_dns: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
type ArcNicCtx = Arc<Mutex<Option<NicCtxContainer>>>;
|
||||
|
||||
pub struct InstanceRpcServerHook {
|
||||
@@ -236,6 +242,7 @@ impl RpcServerHook for InstanceRpcServerHook {
|
||||
#[derive(Clone)]
|
||||
pub struct InstanceConfigPatcher {
|
||||
global_ctx: Weak<GlobalCtx>,
|
||||
#[cfg(feature = "socks5")]
|
||||
socks5_server: Weak<Socks5Server>,
|
||||
peer_manager: Weak<PeerManager>,
|
||||
conn_manager: Weak<ManualConnectorManager>,
|
||||
@@ -313,6 +320,7 @@ impl InstanceConfigPatcher {
|
||||
if port_forwards.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
#[cfg(feature = "socks5")]
|
||||
let Some(socks5_server) = self.socks5_server.upgrade() else {
|
||||
return Err(anyhow::anyhow!("socks5 server not available"));
|
||||
};
|
||||
@@ -326,6 +334,7 @@ impl InstanceConfigPatcher {
|
||||
global_ctx
|
||||
.config
|
||||
.set_port_forwards(current_forwards.clone());
|
||||
#[cfg(feature = "socks5")]
|
||||
socks5_server
|
||||
.reload_port_forwards(¤t_forwards)
|
||||
.await
|
||||
@@ -513,6 +522,7 @@ pub struct Instance {
|
||||
|
||||
id: uuid::Uuid,
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
nic_ctx: ArcNicCtx,
|
||||
|
||||
peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
|
||||
@@ -525,10 +535,14 @@ pub struct Instance {
|
||||
|
||||
ip_proxy: Option<IpProxy>,
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_proxy_src: Option<KcpProxySrc>,
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_proxy_dst: Option<KcpProxyDst>,
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_src: Option<QUICProxySrc>,
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_dst: Option<QUICProxyDst>,
|
||||
|
||||
peer_center: Arc<PeerCenterInstance>,
|
||||
@@ -596,6 +610,7 @@ impl Instance {
|
||||
id,
|
||||
|
||||
peer_packet_receiver: Arc::new(Mutex::new(peer_packet_receiver)),
|
||||
#[cfg(feature = "tun")]
|
||||
nic_ctx: Arc::new(Mutex::new(None)),
|
||||
|
||||
peer_manager,
|
||||
@@ -606,10 +621,14 @@ impl Instance {
|
||||
tcp_hole_puncher: Arc::new(Mutex::new(tcp_hole_puncher)),
|
||||
|
||||
ip_proxy: None,
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_proxy_src: None,
|
||||
#[cfg(feature = "kcp")]
|
||||
kcp_proxy_dst: None,
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_src: None,
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_dst: None,
|
||||
|
||||
peer_center,
|
||||
@@ -639,10 +658,12 @@ impl Instance {
|
||||
}
|
||||
|
||||
// use a mock nic ctx to consume packets.
|
||||
#[cfg(feature = "tun")]
|
||||
async fn clear_nic_ctx(
|
||||
arc_nic_ctx: ArcNicCtx,
|
||||
packet_recv: Arc<Mutex<PacketRecvChanReceiver>>,
|
||||
) {
|
||||
#[cfg(feature = "magic-dns")]
|
||||
if let Some(old_ctx) = arc_nic_ctx.lock().await.take() {
|
||||
if let Some(dns_runner) = old_ctx.magic_dns {
|
||||
dns_runner.dns_runner_cancel_token.cancel();
|
||||
@@ -667,6 +688,7 @@ impl Instance {
|
||||
tracing::debug!("nic ctx cleared.");
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic-dns")]
|
||||
fn create_magic_dns_runner(
|
||||
peer_mgr: Arc<PeerManager>,
|
||||
tun_dev: Option<String>,
|
||||
@@ -686,13 +708,18 @@ impl Instance {
|
||||
Some(runner)
|
||||
}
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
async fn use_new_nic_ctx(
|
||||
arc_nic_ctx: ArcNicCtx,
|
||||
nic_ctx: NicCtx,
|
||||
magic_dns: Option<DnsRunner>,
|
||||
#[cfg(feature = "magic-dns")] magic_dns: Option<DnsRunner>,
|
||||
) {
|
||||
let mut g = arc_nic_ctx.lock().await;
|
||||
*g = Some(NicCtxContainer::new(nic_ctx, magic_dns));
|
||||
*g = Some(NicCtxContainer::new(
|
||||
nic_ctx,
|
||||
#[cfg(feature = "magic-dns")]
|
||||
magic_dns,
|
||||
));
|
||||
tracing::debug!("nic ctx updated.");
|
||||
}
|
||||
|
||||
@@ -701,6 +728,7 @@ impl Instance {
|
||||
use rand::Rng;
|
||||
let peer_manager_c = Arc::downgrade(&self.peer_manager.clone());
|
||||
let global_ctx_c = self.get_global_ctx();
|
||||
#[cfg(feature = "tun")]
|
||||
let nic_ctx = self.nic_ctx.clone();
|
||||
let _peer_packet_receiver = self.peer_packet_receiver.clone();
|
||||
tokio::spawn(async move {
|
||||
@@ -765,6 +793,7 @@ impl Instance {
|
||||
"dhcp start changing ip"
|
||||
);
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
Self::clear_nic_ctx(nic_ctx.clone(), _peer_packet_receiver.clone()).await;
|
||||
|
||||
if let Some(ip) = candidate_ipv4_addr {
|
||||
@@ -776,11 +805,10 @@ impl Instance {
|
||||
continue;
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
target_env = "ohos"
|
||||
)))]
|
||||
#[cfg(all(
|
||||
not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
|
||||
feature = "tun"
|
||||
))]
|
||||
{
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
global_ctx_c.clone(),
|
||||
@@ -798,10 +826,12 @@ impl Instance {
|
||||
global_ctx_c.set_ipv4(None);
|
||||
continue;
|
||||
}
|
||||
#[cfg(feature = "magic-dns")]
|
||||
let ifname = new_nic_ctx.ifname().await;
|
||||
Self::use_new_nic_ctx(
|
||||
nic_ctx.clone(),
|
||||
new_nic_ctx,
|
||||
#[cfg(feature = "magic-dns")]
|
||||
Self::create_magic_dns_runner(peer_manager_c.clone(), ifname, ip),
|
||||
)
|
||||
.await;
|
||||
@@ -819,6 +849,10 @@ impl Instance {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
|
||||
feature = "tun"
|
||||
))]
|
||||
fn check_for_static_ip(&self, first_round_output: oneshot::Sender<Result<(), Error>>) {
|
||||
let ipv4_addr = self.global_ctx.get_ipv4();
|
||||
let ipv6_addr = self.global_ctx.get_ipv6();
|
||||
@@ -862,15 +896,20 @@ impl Instance {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
continue;
|
||||
}
|
||||
let ifname = new_nic_ctx.ifname().await;
|
||||
|
||||
// Create Magic DNS runner only if we have IPv4
|
||||
let dns_runner = if let Some(ipv4) = ipv4_addr {
|
||||
Self::create_magic_dns_runner(peer_manager, ifname, ipv4)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx, dns_runner).await;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
{
|
||||
let ifname = new_nic_ctx.ifname().await;
|
||||
let dns_runner = if let Some(ipv4) = ipv4_addr {
|
||||
Self::create_magic_dns_runner(peer_manager, ifname, ipv4)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx, dns_runner).await;
|
||||
}
|
||||
#[cfg(not(feature = "magic-dns"))]
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await;
|
||||
|
||||
if let Some(output_tx) = output_tx.take() {
|
||||
let _ = output_tx.send(Ok(()));
|
||||
@@ -888,6 +927,7 @@ impl Instance {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
async fn run_quic_dst(&mut self) -> Result<(), Error> {
|
||||
if self.global_ctx.get_flags().disable_quic_input {
|
||||
return Ok(());
|
||||
@@ -911,11 +951,12 @@ impl Instance {
|
||||
self.listener_manager.lock().await.run().await?;
|
||||
self.peer_manager.run().await?;
|
||||
|
||||
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await;
|
||||
#[cfg(feature = "tun")]
|
||||
{
|
||||
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await;
|
||||
|
||||
if !self.global_ctx.config.get_flags().no_tun {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
|
||||
{
|
||||
if !self.global_ctx.config.get_flags().no_tun {
|
||||
let (output_tx, output_rx) = oneshot::channel();
|
||||
self.check_for_static_ip(output_tx);
|
||||
output_rx.await.unwrap()?;
|
||||
@@ -926,24 +967,28 @@ impl Instance {
|
||||
self.check_dhcp_ip_conflict();
|
||||
}
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
if self.global_ctx.get_flags().enable_kcp_proxy {
|
||||
let src_proxy = KcpProxySrc::new(self.get_peer_manager()).await;
|
||||
src_proxy.start().await;
|
||||
self.kcp_proxy_src = Some(src_proxy);
|
||||
}
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
if !self.global_ctx.get_flags().disable_kcp_input {
|
||||
let mut dst_proxy = KcpProxyDst::new(self.get_peer_manager()).await;
|
||||
dst_proxy.start().await;
|
||||
self.kcp_proxy_dst = Some(dst_proxy);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if self.global_ctx.get_flags().enable_quic_proxy {
|
||||
let quic_src = QUICProxySrc::new(self.get_peer_manager()).await;
|
||||
quic_src.start().await;
|
||||
self.quic_proxy_src = Some(quic_src);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if !self.global_ctx.get_flags().disable_quic_input {
|
||||
if let Err(e) = self.run_quic_dst().await {
|
||||
eprintln!(
|
||||
@@ -989,6 +1034,7 @@ impl Instance {
|
||||
#[cfg(feature = "socks5")]
|
||||
self.socks5_server
|
||||
.run(
|
||||
#[cfg(feature = "kcp")]
|
||||
self.kcp_proxy_src
|
||||
.as_ref()
|
||||
.map(|x| Arc::downgrade(&x.get_kcp_endpoint())),
|
||||
@@ -1126,6 +1172,7 @@ impl Instance {
|
||||
#[derive(Clone)]
|
||||
pub struct PortForwardManagerRpcService {
|
||||
global_ctx: Weak<GlobalCtx>,
|
||||
#[cfg(feature = "socks5")]
|
||||
socks5_server: Weak<Socks5Server>,
|
||||
}
|
||||
|
||||
@@ -1146,6 +1193,7 @@ impl Instance {
|
||||
|
||||
PortForwardManagerRpcService {
|
||||
global_ctx: Arc::downgrade(&self.global_ctx),
|
||||
#[cfg(feature = "socks5")]
|
||||
socks5_server: Arc::downgrade(&self.socks5_server),
|
||||
}
|
||||
}
|
||||
@@ -1209,6 +1257,7 @@ impl Instance {
|
||||
pub fn get_config_patcher(&self) -> InstanceConfigPatcher {
|
||||
InstanceConfigPatcher {
|
||||
global_ctx: Arc::downgrade(&self.global_ctx),
|
||||
#[cfg(feature = "socks5")]
|
||||
socks5_server: Arc::downgrade(&self.socks5_server),
|
||||
peer_manager: Arc::downgrade(&self.peer_manager),
|
||||
conn_manager: Arc::downgrade(&self.conn_manager),
|
||||
@@ -1357,6 +1406,7 @@ impl Instance {
|
||||
Arc::new(TcpProxyRpcService::new(ip_proxy.tcp_proxy.clone())),
|
||||
);
|
||||
}
|
||||
#[cfg(feature = "kcp")]
|
||||
if let Some(kcp_proxy) = self.kcp_proxy_src.as_ref() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"kcp_src".to_string(),
|
||||
@@ -1364,6 +1414,7 @@ impl Instance {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "kcp")]
|
||||
if let Some(kcp_proxy) = self.kcp_proxy_dst.as_ref() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"kcp_dst".to_string(),
|
||||
@@ -1371,6 +1422,7 @@ impl Instance {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if let Some(quic_proxy) = self.quic_proxy_src.as_ref() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"quic_src".to_string(),
|
||||
@@ -1378,6 +1430,7 @@ impl Instance {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if let Some(quic_proxy) = self.quic_proxy_dst.as_ref() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"quic_dst".to_string(),
|
||||
@@ -1402,6 +1455,7 @@ impl Instance {
|
||||
self.vpn_portal.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
pub fn get_nic_ctx(&self) -> ArcNicCtx {
|
||||
self.nic_ctx.clone()
|
||||
}
|
||||
@@ -1446,6 +1500,7 @@ impl Instance {
|
||||
|
||||
pub async fn clear_resources(&mut self) {
|
||||
self.peer_manager.clear_resources().await;
|
||||
#[cfg(feature = "tun")]
|
||||
let _ = self.nic_ctx.lock().await.take();
|
||||
}
|
||||
}
|
||||
@@ -1454,8 +1509,10 @@ impl Drop for Instance {
|
||||
fn drop(&mut self) {
|
||||
let my_peer_id = self.peer_manager.my_peer_id();
|
||||
let pm = Arc::downgrade(&self.peer_manager);
|
||||
#[cfg(feature = "tun")]
|
||||
let nic_ctx = self.nic_ctx.clone();
|
||||
tokio::spawn(async move {
|
||||
#[cfg(feature = "tun")]
|
||||
nic_ctx.lock().await.take();
|
||||
if let Some(pm) = pm.upgrade() {
|
||||
pm.clear_resources().await;
|
||||
|
||||
@@ -5,6 +5,7 @@ pub mod acl;
|
||||
pub mod api;
|
||||
pub mod common;
|
||||
pub mod error;
|
||||
#[cfg(feature = "magic-dns")]
|
||||
pub mod magic_dns;
|
||||
pub mod peer_rpc;
|
||||
pub mod web;
|
||||
|
||||
Reference in New Issue
Block a user