mirror of
https://github.com/EasyTier/EasyTier.git
synced 2025-09-27 04:56:07 +08:00
fix net2net kcp proxy
This commit is contained in:
@@ -100,8 +100,8 @@ core_clap:
|
|||||||
en: "do not create TUN device, can use subnet proxy to access node"
|
en: "do not create TUN device, can use subnet proxy to access node"
|
||||||
zh-CN: "不创建TUN设备,可以使用子网代理访问节点"
|
zh-CN: "不创建TUN设备,可以使用子网代理访问节点"
|
||||||
use_smoltcp:
|
use_smoltcp:
|
||||||
en: "enable smoltcp stack for subnet proxy"
|
en: "enable smoltcp stack for subnet proxy and kcp proxy"
|
||||||
zh-CN: "为子网代理启用smoltcp堆栈"
|
zh-CN: "为子网代理和 KCP 代理启用smoltcp堆栈"
|
||||||
manual_routes:
|
manual_routes:
|
||||||
en: "assign routes cidr manually, will disable subnet proxy and wireguard routes propagated from peers. e.g.: 192.168.0.0/16"
|
en: "assign routes cidr manually, will disable subnet proxy and wireguard routes propagated from peers. e.g.: 192.168.0.0/16"
|
||||||
zh-CN: "手动分配路由CIDR,将禁用子网代理和从对等节点传播的wireguard路由。例如:192.168.0.0/16"
|
zh-CN: "手动分配路由CIDR,将禁用子网代理和从对等节点传播的wireguard路由。例如:192.168.0.0/16"
|
||||||
|
@@ -51,14 +51,23 @@ struct Cli {
|
|||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum SubCommand {
|
enum SubCommand {
|
||||||
|
#[command(about = "show peers info")]
|
||||||
Peer(PeerArgs),
|
Peer(PeerArgs),
|
||||||
|
#[command(about = "manage connectors")]
|
||||||
Connector(ConnectorArgs),
|
Connector(ConnectorArgs),
|
||||||
|
#[command(about = "do stun test")]
|
||||||
Stun,
|
Stun,
|
||||||
|
#[command(about = "show route info")]
|
||||||
Route(RouteArgs),
|
Route(RouteArgs),
|
||||||
|
#[command(about = "show global peers info")]
|
||||||
PeerCenter,
|
PeerCenter,
|
||||||
|
#[command(about = "show vpn portal (wireguard) info")]
|
||||||
VpnPortal,
|
VpnPortal,
|
||||||
|
#[command(about = "inspect self easytier-core status")]
|
||||||
Node(NodeArgs),
|
Node(NodeArgs),
|
||||||
|
#[command(about = "manage easytier-core as a system service")]
|
||||||
Service(ServiceArgs),
|
Service(ServiceArgs),
|
||||||
|
#[command(about = "show tcp/kcp proxy status")]
|
||||||
Proxy,
|
Proxy,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +125,9 @@ enum ConnectorSubCommand {
|
|||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum NodeSubCommand {
|
enum NodeSubCommand {
|
||||||
|
#[command(about = "show node info")]
|
||||||
Info,
|
Info,
|
||||||
|
#[command(about = "show node config")]
|
||||||
Config,
|
Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,10 +148,15 @@ struct ServiceArgs {
|
|||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum ServiceSubCommand {
|
enum ServiceSubCommand {
|
||||||
|
#[command(about = "register easytier-core as a system service")]
|
||||||
Install(InstallArgs),
|
Install(InstallArgs),
|
||||||
|
#[command(about = "unregister easytier-core system service")]
|
||||||
Uninstall,
|
Uninstall,
|
||||||
|
#[command(about = "check easytier-core system service status")]
|
||||||
Status,
|
Status,
|
||||||
|
#[command(about = "start easytier-core system service")]
|
||||||
Start,
|
Start,
|
||||||
|
#[command(about = "stop easytier-core system service")]
|
||||||
Stop,
|
Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,13 +171,17 @@ struct InstallArgs {
|
|||||||
#[arg(long, default_value = "false")]
|
#[arg(long, default_value = "false")]
|
||||||
disable_autostart: bool,
|
disable_autostart: bool,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long, help = "path to easytier-core binary")]
|
||||||
core_path: Option<PathBuf>,
|
core_path: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
service_work_dir: Option<PathBuf>,
|
service_work_dir: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
|
#[arg(
|
||||||
|
trailing_var_arg = true,
|
||||||
|
allow_hyphen_values = true,
|
||||||
|
help = "args to pass to easytier-core"
|
||||||
|
)]
|
||||||
core_args: Option<Vec<OsString>>,
|
core_args: Option<Vec<OsString>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,12 +682,22 @@ impl Service {
|
|||||||
environment: None,
|
environment: None,
|
||||||
};
|
};
|
||||||
if self.status()? != ServiceStatus::NotInstalled {
|
if self.status()? != ServiceStatus::NotInstalled {
|
||||||
return Err(anyhow::anyhow!("Service is already installed"));
|
return Err(anyhow::anyhow!(
|
||||||
|
"Service is already installed! Service Name: {}",
|
||||||
|
self.lable
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.service_manager
|
self.service_manager
|
||||||
.install(ctx)
|
.install(ctx.clone())
|
||||||
.map_err(|e| anyhow::anyhow!("failed to install service: {}", e))
|
.map_err(|e| anyhow::anyhow!("failed to install service: {:?}", e))?;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Service installed successfully! Service Name: {}",
|
||||||
|
self.lable
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uninstall(&self) -> Result<(), Error> {
|
pub fn uninstall(&self) -> Result<(), Error> {
|
||||||
@@ -784,7 +814,8 @@ impl Service {
|
|||||||
writeln!(unit_content, "Type=simple")?;
|
writeln!(unit_content, "Type=simple")?;
|
||||||
writeln!(unit_content, "WorkingDirectory={work_dir}")?;
|
writeln!(unit_content, "WorkingDirectory={work_dir}")?;
|
||||||
writeln!(unit_content, "ExecStart={target_app} {args}")?;
|
writeln!(unit_content, "ExecStart={target_app} {args}")?;
|
||||||
writeln!(unit_content, "Restart=Always")?;
|
writeln!(unit_content, "Restart=always")?;
|
||||||
|
writeln!(unit_content, "RestartSec=1")?;
|
||||||
writeln!(unit_content, "LimitNOFILE=infinity")?;
|
writeln!(unit_content, "LimitNOFILE=infinity")?;
|
||||||
writeln!(unit_content)?;
|
writeln!(unit_content)?;
|
||||||
writeln!(unit_content, "[Install]")?;
|
writeln!(unit_content, "[Install]")?;
|
||||||
@@ -1141,6 +1172,8 @@ async fn main() -> Result<(), Error> {
|
|||||||
(e.start_time * 1000) as i64,
|
(e.start_time * 1000) as i64,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
.with_timezone(&chrono::Local)
|
||||||
|
.format("%Y-%m-%d %H:%M:%S")
|
||||||
.to_string(),
|
.to_string(),
|
||||||
state: format!("{:?}", TcpProxyEntryState::try_from(e.state).unwrap()),
|
state: format!("{:?}", TcpProxyEntryState::try_from(e.state).unwrap()),
|
||||||
transport_type: format!(
|
transport_type: format!(
|
||||||
|
@@ -206,9 +206,7 @@ impl NicPacketFilter for TcpProxyForKcpSrc {
|
|||||||
let data = zc_packet.payload();
|
let data = zc_packet.payload();
|
||||||
let ip_packet = Ipv4Packet::new(data).unwrap();
|
let ip_packet = Ipv4Packet::new(data).unwrap();
|
||||||
if ip_packet.get_version() != 4
|
if ip_packet.get_version() != 4
|
||||||
// TODO: how to support net to net kcp proxy?
|
|
||||||
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
||||||
|| !self.check_dst_allow_kcp_input(&ip_packet.get_destination()).await
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -217,15 +215,33 @@ impl NicPacketFilter for TcpProxyForKcpSrc {
|
|||||||
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
|
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
|
||||||
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
|
let is_syn = tcp_packet.get_flags() & TcpFlags::SYN != 0
|
||||||
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
|
&& tcp_packet.get_flags() & TcpFlags::ACK == 0;
|
||||||
if !is_syn
|
if is_syn {
|
||||||
&& !self.0.is_tcp_proxy_connection(SocketAddr::new(
|
// only check dst feature flag when SYN packet
|
||||||
|
if !self
|
||||||
|
.check_dst_allow_kcp_input(&ip_packet.get_destination())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if not syn packet, only allow established connection
|
||||||
|
if !self.0.is_tcp_proxy_connection(SocketAddr::new(
|
||||||
IpAddr::V4(ip_packet.get_source()),
|
IpAddr::V4(ip_packet.get_source()),
|
||||||
tcp_packet.get_source(),
|
tcp_packet.get_source(),
|
||||||
))
|
)) {
|
||||||
{
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(my_ipv4) = self.0.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.0.is_smoltcp_enabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
zc_packet.mut_peer_manager_header().unwrap().to_peer_id = self.0.get_my_peer_id().into();
|
zc_packet.mut_peer_manager_header().unwrap().to_peer_id = self.0.get_my_peer_id().into();
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@@ -2,6 +2,7 @@ use parking_lot::Mutex;
|
|||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{SocketHandle as InnerSocketHandle, SocketSet},
|
iface::{SocketHandle as InnerSocketHandle, SocketSet},
|
||||||
socket::tcp,
|
socket::tcp,
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
@@ -53,6 +54,8 @@ impl SocketAlloctor {
|
|||||||
let tx_buffer = tcp::SocketBuffer::new(vec![0; self.buffer_size.tcp_tx_size]);
|
let tx_buffer = tcp::SocketBuffer::new(vec![0; self.buffer_size.tcp_tx_size]);
|
||||||
let mut tcp = tcp::Socket::new(rx_buffer, tx_buffer);
|
let mut tcp = tcp::Socket::new(rx_buffer, tx_buffer);
|
||||||
tcp.set_nagle_enabled(false);
|
tcp.set_nagle_enabled(false);
|
||||||
|
tcp.set_keep_alive(Some(Duration::from_secs(10)));
|
||||||
|
tcp.set_timeout(Some(Duration::from_secs(60)));
|
||||||
|
|
||||||
tcp
|
tcp
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user