mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
port forward (#736)
* support tcp port forward * support udp port forward * command line option for port forward
This commit is contained in:
@@ -7,7 +7,10 @@ use std::{
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{proto::common::CompressionAlgoPb, tunnel::generate_digest_from_str};
|
||||
use crate::{
|
||||
proto::common::{CompressionAlgoPb, PortForwardConfigPb, SocketType},
|
||||
tunnel::generate_digest_from_str,
|
||||
};
|
||||
|
||||
pub type Flags = crate::proto::common::FlagsInConfig;
|
||||
|
||||
@@ -97,6 +100,9 @@ pub trait ConfigLoader: Send + Sync {
|
||||
fn get_socks5_portal(&self) -> Option<url::Url>;
|
||||
fn set_socks5_portal(&self, addr: Option<url::Url>);
|
||||
|
||||
fn get_port_forwards(&self) -> Vec<PortForwardConfig>;
|
||||
fn set_port_forwards(&self, forwards: Vec<PortForwardConfig>);
|
||||
|
||||
fn dump(&self) -> String;
|
||||
}
|
||||
|
||||
@@ -180,6 +186,41 @@ pub struct VpnPortalConfig {
|
||||
pub wireguard_listen: SocketAddr,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
pub struct PortForwardConfig {
|
||||
pub bind_addr: SocketAddr,
|
||||
pub dst_addr: SocketAddr,
|
||||
pub proto: String,
|
||||
}
|
||||
|
||||
impl From<PortForwardConfigPb> for PortForwardConfig {
|
||||
fn from(config: PortForwardConfigPb) -> Self {
|
||||
PortForwardConfig {
|
||||
bind_addr: config.bind_addr.unwrap_or_default().into(),
|
||||
dst_addr: config.dst_addr.unwrap_or_default().into(),
|
||||
proto: match SocketType::try_from(config.socket_type) {
|
||||
Ok(SocketType::Tcp) => "tcp".to_string(),
|
||||
Ok(SocketType::Udp) => "udp".to_string(),
|
||||
_ => "tcp".to_string(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<PortForwardConfigPb> for PortForwardConfig {
|
||||
fn into(self) -> PortForwardConfigPb {
|
||||
PortForwardConfigPb {
|
||||
bind_addr: Some(self.bind_addr.into()),
|
||||
dst_addr: Some(self.dst_addr.into()),
|
||||
socket_type: match self.proto.to_lowercase().as_str() {
|
||||
"tcp" => SocketType::Tcp as i32,
|
||||
"udp" => SocketType::Udp as i32,
|
||||
_ => SocketType::Tcp as i32,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
struct Config {
|
||||
netns: Option<String>,
|
||||
@@ -207,6 +248,8 @@ struct Config {
|
||||
|
||||
socks5_proxy: Option<url::Url>,
|
||||
|
||||
port_forward: Option<Vec<PortForwardConfig>>,
|
||||
|
||||
flags: Option<serde_json::Map<String, serde_json::Value>>,
|
||||
|
||||
#[serde(skip)]
|
||||
@@ -534,6 +577,35 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
self.config.lock().unwrap().exit_nodes = Some(nodes);
|
||||
}
|
||||
|
||||
fn get_routes(&self) -> Option<Vec<cidr::Ipv4Cidr>> {
|
||||
self.config.lock().unwrap().routes.clone()
|
||||
}
|
||||
|
||||
fn set_routes(&self, routes: Option<Vec<cidr::Ipv4Cidr>>) {
|
||||
self.config.lock().unwrap().routes = routes;
|
||||
}
|
||||
|
||||
fn get_socks5_portal(&self) -> Option<url::Url> {
|
||||
self.config.lock().unwrap().socks5_proxy.clone()
|
||||
}
|
||||
|
||||
fn set_socks5_portal(&self, addr: Option<url::Url>) {
|
||||
self.config.lock().unwrap().socks5_proxy = addr;
|
||||
}
|
||||
|
||||
fn get_port_forwards(&self) -> Vec<PortForwardConfig> {
|
||||
self.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.port_forward
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn set_port_forwards(&self, forwards: Vec<PortForwardConfig>) {
|
||||
self.config.lock().unwrap().port_forward = Some(forwards);
|
||||
}
|
||||
|
||||
fn dump(&self) -> String {
|
||||
let default_flags_json = serde_json::to_string(&gen_default_flags()).unwrap();
|
||||
let default_flags_hashmap =
|
||||
@@ -558,22 +630,6 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
config.flags = Some(flag_map);
|
||||
toml::to_string_pretty(&config).unwrap()
|
||||
}
|
||||
|
||||
fn get_routes(&self) -> Option<Vec<cidr::Ipv4Cidr>> {
|
||||
self.config.lock().unwrap().routes.clone()
|
||||
}
|
||||
|
||||
fn set_routes(&self, routes: Option<Vec<cidr::Ipv4Cidr>>) {
|
||||
self.config.lock().unwrap().routes = routes;
|
||||
}
|
||||
|
||||
fn get_socks5_portal(&self) -> Option<url::Url> {
|
||||
self.config.lock().unwrap().socks5_proxy.clone()
|
||||
}
|
||||
|
||||
fn set_socks5_portal(&self, addr: Option<url::Url>) {
|
||||
self.config.lock().unwrap().socks5_proxy = addr;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -614,6 +670,11 @@ dir = "/tmp/easytier"
|
||||
|
||||
[console_logger]
|
||||
level = "warn"
|
||||
|
||||
[[port_forward]]
|
||||
bind_addr = "0.0.0.0:11011"
|
||||
dst_addr = "192.168.94.33:11011"
|
||||
proto = "tcp"
|
||||
"#;
|
||||
let ret = TomlConfigLoader::new_from_str(config_str);
|
||||
if let Err(e) = &ret {
|
||||
@@ -634,6 +695,14 @@ level = "warn"
|
||||
.collect::<Vec<String>>()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
vec![PortForwardConfig {
|
||||
bind_addr: "0.0.0.0:11011".parse().unwrap(),
|
||||
dst_addr: "192.168.94.33:11011".parse().unwrap(),
|
||||
proto: "tcp".to_string(),
|
||||
}],
|
||||
ret.get_port_forwards()
|
||||
);
|
||||
println!("{}", ret.dump());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user