"acl" is available in ext-config "servers" & "locals"

The "acl" in "servers" & "locals" will have higher priority than the
global "acl" in configuration.

fix #1042
This commit is contained in:
zonyitoo
2022-12-10 17:49:43 +08:00
parent 8b1e4c566f
commit 8953210907
13 changed files with 253 additions and 103 deletions
+4 -4
View File
@@ -7,7 +7,7 @@ use clap::{Arg, ArgAction, Command, ValueHint};
use qrcode::{types::Color, QrCode};
use shadowsocks_service::{
config::{Config, ConfigType},
config::{Config, ConfigType, ServerInstanceConfig},
shadowsocks::config::ServerConfig,
};
@@ -48,12 +48,12 @@ fn encode(filename: &str, need_qrcode: bool) {
let config = Config::load_from_file(filename, ConfigType::Server).unwrap();
for svr in config.server {
let encoded = svr.to_url();
let encoded = svr.config.to_url();
println!("{}", encoded);
if need_qrcode {
let encoded = svr.to_qrcode_url();
let encoded = svr.config.to_qrcode_url();
print_qrcode(&encoded);
}
}
@@ -63,7 +63,7 @@ fn decode(encoded: &str, need_qrcode: bool) {
let svrconfig = ServerConfig::from_url(encoded).unwrap();
let mut config = Config::new(ConfigType::Server);
config.server.push(svrconfig);
config.server.push(ServerInstanceConfig::with_server_config(svrconfig));
println!("{}", config);
+139 -25
View File
@@ -66,14 +66,7 @@ use serde::{Deserialize, Serialize};
use shadowsocks::relay::socks5::Address;
use shadowsocks::{
config::{
ManagerAddr,
Mode,
ReplayAttackPolicy,
ServerAddr,
ServerConfig,
ServerUser,
ServerUserManager,
ServerWeight,
ManagerAddr, Mode, ReplayAttackPolicy, ServerAddr, ServerConfig, ServerUser, ServerUserManager, ServerWeight,
},
crypto::CipherKind,
plugin::PluginConfig,
@@ -272,6 +265,9 @@ struct SSLocalExtConfig {
#[cfg(feature = "local")]
#[serde(skip_serializing_if = "Option::is_none")]
socks5_auth_config_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
acl: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
@@ -322,6 +318,9 @@ struct SSServerExtConfig {
tcp_weight: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
udp_weight: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
acl: Option<String>,
}
/// Server config type
@@ -1032,13 +1031,45 @@ pub enum LocalFlowStatAddress {
TcpStreamAddr(SocketAddr),
}
/// Server instance config
#[derive(Debug, Clone)]
pub struct ServerInstanceConfig {
/// Server's config
pub config: ServerConfig,
/// Server's private ACL, set to `None` will use the global `AccessControl`
pub acl: Option<AccessControl>,
}
impl ServerInstanceConfig {
/// Create with `ServerConfig`
pub fn with_server_config(config: ServerConfig) -> ServerInstanceConfig {
ServerInstanceConfig { config, acl: None }
}
}
/// Local instance config
#[derive(Debug, Clone)]
pub struct LocalInstanceConfig {
/// Local server's config
pub config: LocalConfig,
/// Server's private ACL, set to `None` will use the global `AccessControl`
pub acl: Option<AccessControl>,
}
impl LocalInstanceConfig {
/// Create with `LocalConfig`
pub fn with_local_config(config: LocalConfig) -> LocalInstanceConfig {
LocalInstanceConfig { config, acl: None }
}
}
/// Configuration
#[derive(Clone, Debug)]
pub struct Config {
/// Remote ShadowSocks server configurations
pub server: Vec<ServerConfig>,
pub server: Vec<ServerInstanceConfig>,
/// Local server configuration
pub local: Vec<LocalConfig>,
pub local: Vec<LocalInstanceConfig>,
/// DNS configuration, uses system-wide DNS configuration by default
///
@@ -1106,7 +1137,9 @@ pub struct Config {
/// Maximum number of UDP Associations, default is unconfigured
pub udp_max_associations: Option<usize>,
/// ACL configuration
/// ACL configuration (Global)
///
/// Could be overwritten by servers/locals' private `acl`
pub acl: Option<AccessControl>,
/// Flow statistic report Unix socket path (only for Android)
@@ -1325,7 +1358,13 @@ impl Config {
}
},
};
nconfig.local.push(local_config);
let local_instance = LocalInstanceConfig {
config: local_config,
acl: None,
};
nconfig.local.push(local_instance);
}
// Ext locals
@@ -1491,7 +1530,27 @@ impl Config {
local_config.socks5_auth = Socks5AuthConfig::load_from_file(&socks5_auth_config_path)?;
}
nconfig.local.push(local_config);
let mut local_instance = LocalInstanceConfig {
config: local_config,
acl: None,
};
if let Some(acl_path) = local.acl {
let acl = match AccessControl::load_from_file(&acl_path) {
Ok(acl) => acl,
Err(err) => {
let err = Error::new(
ErrorKind::Invalid,
"acl loading failed",
Some(format!("file {}, error: {}", acl_path, err)),
);
return Err(err);
}
};
local_instance.acl = Some(acl);
}
nconfig.local.push(local_instance);
}
}
}
@@ -1564,7 +1623,12 @@ impl Config {
nsvr.set_timeout(timeout);
}
nconfig.server.push(nsvr);
let server_instance = ServerInstanceConfig {
config: nsvr,
acl: None,
};
nconfig.server.push(server_instance);
}
(None, None, None, Some(_)) if config_type.is_manager() => {
// Set the default method for manager
@@ -1711,7 +1775,27 @@ impl Config {
nsvr.set_weight(weight);
}
nconfig.server.push(nsvr);
let mut server_instance = ServerInstanceConfig {
config: nsvr,
acl: None,
};
if let Some(acl_path) = svr.acl {
let acl = match AccessControl::load_from_file(&acl_path) {
Ok(acl) => acl,
Err(err) => {
let err = Error::new(
ErrorKind::Invalid,
"acl loading failed",
Some(format!("file {}, error: {}", acl_path, err)),
);
return Err(err);
}
};
server_instance.acl = Some(acl);
}
nconfig.server.push(server_instance);
}
}
@@ -1719,7 +1803,8 @@ impl Config {
if let Some(timeout) = config.timeout {
let timeout = Duration::from_secs(timeout);
// Set as a default timeout
for svr in &mut nconfig.server {
for inst in &mut nconfig.server {
let svr = &mut inst.config;
if svr.timeout().is_none() {
svr.set_timeout(timeout);
}
@@ -2029,7 +2114,9 @@ impl Config {
/// Check if there are any plugin are enabled with servers
pub fn has_server_plugins(&self) -> bool {
for server in &self.server {
for inst in &self.server {
let server = &inst.config;
if server.plugin().is_some() {
return true;
}
@@ -2050,7 +2137,7 @@ impl Config {
}
for local_config in &self.local {
local_config.check_integrity()?;
local_config.config.check_integrity()?;
}
// Balancer related checks
@@ -2087,7 +2174,9 @@ impl Config {
return Err(err);
}
for server in &self.server {
for inst in &self.server {
let server = &inst.config;
// Plugin shouldn't be an empty string
if let Some(plugin) = server.plugin() {
if plugin.plugin.trim().is_empty() {
@@ -2157,8 +2246,9 @@ impl fmt::Display for Config {
// Locals
if !self.local.is_empty() {
if self.local.len() == 1 && self.local[0].is_basic() {
let local = &self.local[0];
if self.local.len() == 1 && self.local[0].config.is_basic() {
let local_instance = &self.local[0];
let local = &local_instance.config;
if let Some(ref a) = local.addr {
jconf.local_address = Some(match a {
ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),
@@ -2169,12 +2259,20 @@ impl fmt::Display for Config {
ServerAddr::DomainName(.., port) => *port,
});
}
if local.protocol != ProtocolType::Socks {
jconf.protocol = Some(local.protocol.as_str().to_owned());
}
// ACL
if let Some(ref acl) = local_instance.acl {
jconf.acl = Some(acl.file_path().to_str().unwrap().to_owned());
}
} else {
let mut jlocals = Vec::with_capacity(self.local.len());
for local in &self.local {
for local_instance in &self.local {
let local = &local_instance.config;
let jlocal = SSLocalExtConfig {
local_address: local.addr.as_ref().map(|a| match a {
ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),
@@ -2275,6 +2373,11 @@ impl fmt::Display for Config {
#[cfg(feature = "local")]
socks5_auth_config_path: None,
acl: local_instance
.acl
.as_ref()
.and_then(|a| a.file_path().to_str().map(ToOwned::to_owned)),
};
jlocals.push(jlocal);
}
@@ -2286,8 +2389,9 @@ impl fmt::Display for Config {
match self.server.len() {
0 => {}
// For 1 server, uses standard configure format
1 if self.server[0].is_basic() => {
let svr = &self.server[0];
1 if self.server[0].config.is_basic() => {
let inst = &self.server[0];
let svr = &inst.config;
jconf.server = Some(match *svr.addr() {
ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),
@@ -2314,12 +2418,18 @@ impl fmt::Display for Config {
});
jconf.timeout = svr.timeout().map(|t| t.as_secs());
jconf.mode = Some(svr.mode().to_string());
if let Some(ref acl) = inst.acl {
jconf.acl = Some(acl.file_path().to_str().unwrap().to_owned());
}
}
// For >1 servers, uses extended multiple server format
_ => {
let mut vsvr = Vec::new();
for svr in &self.server {
for inst in &self.server {
let svr = &inst.config;
vsvr.push(SSServerExtConfig {
server: match *svr.addr() {
ServerAddr::SocketAddr(ref sa) => sa.ip().to_string(),
@@ -2369,6 +2479,10 @@ impl fmt::Display for Config {
} else {
None
},
acl: inst
.acl
.as_ref()
.and_then(|a| a.file_path().to_str().map(ToOwned::to_owned)),
});
}
@@ -19,20 +19,21 @@ use tokio::sync::Mutex;
use crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat};
/// Local Service Context
#[derive(Clone)]
pub struct ServiceContext {
context: SharedContext,
connect_opts: ConnectOpts,
accept_opts: AcceptOpts,
// Access Control
acl: Option<AccessControl>,
acl: Option<Arc<AccessControl>>,
// Flow statistic report
flow_stat: Arc<FlowStat>,
// For DNS relay's ACL domain name reverse lookup -- whether the IP shall be forwarded
#[cfg(feature = "local-dns")]
reverse_lookup_cache: Mutex<LruCache<IpAddr, bool>>,
reverse_lookup_cache: Arc<Mutex<LruCache<IpAddr, bool>>>,
}
impl Default for ServiceContext {
@@ -51,10 +52,10 @@ impl ServiceContext {
acl: None,
flow_stat: Arc::new(FlowStat::new()),
#[cfg(feature = "local-dns")]
reverse_lookup_cache: Mutex::new(LruCache::with_expiry_duration_and_capacity(
reverse_lookup_cache: Arc::new(Mutex::new(LruCache::with_expiry_duration_and_capacity(
Duration::from_secs(3 * 24 * 60 * 60),
10240, // XXX: It should be enough for a normal user.
)),
))),
}
}
@@ -89,13 +90,13 @@ impl ServiceContext {
}
/// Set Access Control List
pub fn set_acl(&mut self, acl: AccessControl) {
pub fn set_acl(&mut self, acl: Arc<AccessControl>) {
self.acl = Some(acl);
}
/// Get Access Control List reference
pub fn acl(&self) -> Option<&AccessControl> {
self.acl.as_ref()
self.acl.as_deref()
}
/// Get cloned flow statistic
+23 -8
View File
@@ -109,7 +109,9 @@ pub async fn create(config: Config) -> io::Result<Server> {
// Warning for Stream Ciphers
#[cfg(feature = "stream-cipher")]
for server in config.server.iter() {
for inst in config.server.iter() {
let server = &inst.config;
if server.method().is_stream() {
log::warn!("stream cipher {} for server {} have inherent weaknesses (see discussion in https://github.com/shadowsocks/shadowsocks-org/issues/36). \
DO NOT USE. It will be removed in the future.", server.method(), server.addr());
@@ -124,6 +126,8 @@ pub async fn create(config: Config) -> io::Result<Server> {
}
}
// Global ServiceContext template
// Each Local instance will hold a copy of its fields
let mut context = ServiceContext::new();
let mut connect_opts = ConnectOpts {
@@ -165,15 +169,13 @@ pub async fn create(config: Config) -> io::Result<Server> {
}
if let Some(acl) = config.acl {
context.set_acl(acl);
context.set_acl(Arc::new(acl));
}
context.set_security_config(&config.security);
assert!(!config.local.is_empty(), "no valid local server configuration");
let context = Arc::new(context);
let mut vfut = Vec::new();
// Create a service balancer for choosing between multiple servers
@@ -181,10 +183,11 @@ pub async fn create(config: Config) -> io::Result<Server> {
let mut mode = Mode::TcpOnly;
for local in &config.local {
mode = mode.merge(local.mode);
mode = mode.merge(local.config.mode);
}
let mut balancer_builder = PingBalancerBuilder::new(context.clone(), mode);
// Load balancer will hold an individual ServiceContext
let mut balancer_builder = PingBalancerBuilder::new(Arc::new(context.clone()), mode);
// max_server_rtt have to be set before add_server
if let Some(rtt) = config.balancer.max_server_rtt {
@@ -200,7 +203,7 @@ pub async fn create(config: Config) -> io::Result<Server> {
}
for server in config.server {
balancer_builder.add_server(server);
balancer_builder.add_server(server.config);
}
balancer_builder.build().await?
@@ -214,7 +217,19 @@ pub async fn create(config: Config) -> io::Result<Server> {
vfut.push(ServerHandle(tokio::spawn(report_fut)));
}
for local_config in config.local {
for local_instance in config.local {
let local_config = local_instance.config;
// Clone from global ServiceContext instance
// It will shares Shadowsocks' global context, and FlowStat, DNS reverse cache
let mut context = context.clone();
// Private ACL
if let Some(acl) = local_instance.acl {
context.set_acl(Arc::new(acl))
}
let context = Arc::new(context);
let balancer = balancer.clone();
match local_config.protocol {
@@ -81,8 +81,8 @@ pub async fn run(config: Config) -> io::Result<()> {
manager.set_acl(Arc::new(acl));
}
for svr_cfg in config.server {
manager.add_server(svr_cfg).await;
for svr_inst in config.server {
manager.add_server(svr_inst.config).await;
}
manager.run().await
@@ -11,22 +11,12 @@ use shadowsocks::{
crypto::CipherKind,
dns_resolver::DnsResolver,
manager::protocol::{
self,
AddRequest,
AddResponse,
ErrorResponse,
ListResponse,
ManagerRequest,
PingResponse,
RemoveRequest,
RemoveResponse,
ServerUserConfig,
StatRequest,
self, AddRequest, AddResponse, ErrorResponse, ListResponse, ManagerRequest, PingResponse, RemoveRequest,
RemoveResponse, ServerUserConfig, StatRequest,
},
net::{AcceptOpts, ConnectOpts},
plugin::PluginConfig,
ManagerListener,
ServerAddr,
ManagerListener, ServerAddr,
};
use tokio::{sync::Mutex, task::JoinHandle};
@@ -332,7 +322,7 @@ impl Manager {
use tokio::process::Command;
use crate::config::{Config, ConfigType};
use crate::config::{Config, ConfigType, ServerInstanceConfig};
// Lock the map first incase there are multiple requests to create one server instance
let mut servers = self.servers.lock().await;
@@ -351,8 +341,13 @@ impl Manager {
let config_file_path = self.server_config_path(port);
let pid_path = self.server_pid_path(port);
let server_instance = ServerInstanceConfig {
config: svr_cfg.clone(),
acl: None, // Set with --acl command line argument
};
let mut config = Config::new(ConfigType::Server);
config.server.push(svr_cfg.clone());
config.server.push(server_instance);
trace!("created standalone server with config {:?}", config);
@@ -618,7 +613,7 @@ impl Manager {
continue;
}
let svr_cfg = config.server[0].clone();
let svr_cfg = config.server[0].config.clone();
vac.insert(ServerInstance {
mode: ServerInstanceMode::Standalone { flow_stat: *flow },
@@ -13,6 +13,7 @@ use shadowsocks::{
use crate::{acl::AccessControl, config::SecurityConfig, net::FlowStat};
/// Server Service Context
#[derive(Clone)]
pub struct ServiceContext {
context: SharedContext,
connect_opts: ConnectOpts,
+12 -4
View File
@@ -41,7 +41,9 @@ pub async fn run(config: Config) -> io::Result<()> {
// Warning for Stream Ciphers
#[cfg(feature = "stream-cipher")]
for server in config.server.iter() {
for inst in config.server.iter() {
let server = &inst.config;
if server.method().is_stream() {
log::warn!("stream cipher {} for server {} have inherent weaknesses (see discussion in https://github.com/shadowsocks/shadowsocks-org/issues/36). \
DO NOT USE. It will be removed in the future.", server.method(), server.addr());
@@ -93,7 +95,8 @@ pub async fn run(config: Config) -> io::Result<()> {
let acl = config.acl.map(Arc::new);
for svr_cfg in config.server {
for inst in config.server {
let svr_cfg = inst.config;
let mut server = Server::new(svr_cfg);
if let Some(ref r) = resolver {
@@ -113,8 +116,13 @@ pub async fn run(config: Config) -> io::Result<()> {
server.set_manager_addr(m.addr.clone());
}
if let Some(ref acl) = acl {
server.set_acl(acl.clone());
match inst.acl {
Some(acl) => server.set_acl(Arc::new(acl)),
None => {
if let Some(ref acl) = acl {
server.set_acl(acl.clone());
}
}
}
if config.ipv6_first {
+9 -7
View File
@@ -13,7 +13,10 @@ use shadowsocks_service::config::RedirType;
use shadowsocks_service::shadowsocks::relay::socks5::Address;
use shadowsocks_service::{
acl::AccessControl,
config::{read_variable_field_value, Config, ConfigType, LocalConfig, ProtocolType},
config::{
read_variable_field_value, Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType,
ServerInstanceConfig,
},
create_local,
local::loadbalancing::PingBalancer,
shadowsocks::{
@@ -27,8 +30,7 @@ use shadowsocks_service::{
use crate::logging;
use crate::{
config::{Config as ServiceConfig, RuntimeMode},
monitor,
vparser,
monitor, vparser,
};
#[cfg(feature = "local-dns")]
@@ -571,11 +573,11 @@ pub fn main(matches: &ArgMatches) -> ExitCode {
sc.set_plugin(plugin);
}
config.server.push(sc);
config.server.push(ServerInstanceConfig::with_server_config(sc));
}
if let Some(svr_addr) = matches.get_one::<ServerConfig>("URL").cloned() {
config.server.push(svr_addr);
config.server.push(ServerInstanceConfig::with_server_config(svr_addr));
}
#[cfg(feature = "local-flow-stat")]
@@ -710,7 +712,7 @@ pub fn main(matches: &ArgMatches) -> ExitCode {
local_config.mode = Mode::TcpAndUdp;
}
config.local.push(local_config);
config.local.push(LocalInstanceConfig::with_local_config(local_config));
}
if matches.get_flag("TCP_NO_DELAY") {
@@ -888,7 +890,7 @@ fn launch_reload_server_task(config_path: PathBuf, balancer: PingBalancer) {
}
};
let servers = config.server;
let servers: Vec<ServerConfig> = config.server.into_iter().map(|s| s.config).collect();
info!("auto-reload {} with {} servers", config_path.display(), servers.len());
if let Err(err) = balancer.reset_servers(servers).await {
+3 -4
View File
@@ -9,7 +9,7 @@ use tokio::{self, runtime::Builder};
use shadowsocks_service::{
acl::AccessControl,
config::{read_variable_field_value, Config, ConfigType, ManagerConfig},
config::{read_variable_field_value, Config, ConfigType, ManagerConfig, ServerInstanceConfig},
run_server,
shadowsocks::{
config::{ManagerAddr, Mode, ServerAddr, ServerConfig},
@@ -22,8 +22,7 @@ use shadowsocks_service::{
use crate::logging;
use crate::{
config::{Config as ServiceConfig, RuntimeMode},
monitor,
vparser,
monitor, vparser,
};
/// Defines command line options
@@ -369,7 +368,7 @@ pub fn main(matches: &ArgMatches) -> ExitCode {
sc.set_mode(Mode::TcpAndUdp);
}
config.server.push(sc);
config.server.push(ServerInstanceConfig::with_server_config(sc));
}
if matches.get_flag("TCP_NO_DELAY") {
+14 -7
View File
@@ -11,10 +11,9 @@ use tokio::{
};
use shadowsocks_service::{
config::{Config, ConfigType, LocalConfig, ProtocolType},
config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},
local::socks::client::Socks4TcpClient,
run_local,
run_server,
run_local, run_server,
shadowsocks::{
config::{ServerAddr, ServerConfig},
crypto::CipherKind,
@@ -40,16 +39,24 @@ impl Socks4TestServer {
local_addr,
svr_config: {
let mut cfg = Config::new(ConfigType::Server);
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
svr_addr,
pwd.to_owned(),
method,
))];
cfg
},
cli_config: {
let mut cfg = Config::new(ConfigType::Local);
cfg.local = vec![LocalConfig::new_with_addr(
cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(
ServerAddr::from(local_addr),
ProtocolType::Socks,
)];
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
))];
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
svr_addr,
pwd.to_owned(),
method,
))];
cfg
},
}
+18 -9
View File
@@ -11,10 +11,9 @@ use tokio::{
};
use shadowsocks_service::{
config::{Config, ConfigType, LocalConfig, ProtocolType},
config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},
local::socks::client::socks5::Socks5TcpClient,
run_local,
run_server,
run_local, run_server,
shadowsocks::{
config::{Mode, ServerAddr, ServerConfig},
crypto::CipherKind,
@@ -41,18 +40,28 @@ impl Socks5TestServer {
local_addr,
svr_config: {
let mut cfg = Config::new(ConfigType::Server);
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
cfg.server[0].set_mode(if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly });
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
svr_addr,
pwd.to_owned(),
method,
))];
cfg.server[0]
.config
.set_mode(if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly });
cfg
},
cli_config: {
let mut cfg = Config::new(ConfigType::Local);
cfg.local = vec![LocalConfig::new_with_addr(
cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(
ServerAddr::from(local_addr),
ProtocolType::Socks,
)];
cfg.local[0].mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
))];
cfg.local[0].config.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
svr_addr,
pwd.to_owned(),
method,
))];
cfg
},
}
+10 -11
View File
@@ -7,10 +7,9 @@ use log::debug;
use tokio::time::{self, Duration};
use shadowsocks_service::{
config::{Config, ConfigType, LocalConfig, ProtocolType},
config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},
local::socks::client::socks5::Socks5UdpClient,
run_local,
run_server,
run_local, run_server,
shadowsocks::{config::Mode, crypto::CipherKind, relay::socks5::Address, ServerConfig},
};
@@ -24,27 +23,27 @@ const METHOD: CipherKind = CipherKind::AES_128_GCM;
fn get_svr_config() -> Config {
let mut cfg = Config::new(ConfigType::Server);
cfg.server = vec![ServerConfig::new(
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
SERVER_ADDR.parse::<SocketAddr>().unwrap(),
PASSWORD.to_owned(),
METHOD,
)];
cfg.server[0].set_mode(Mode::TcpAndUdp);
))];
cfg.server[0].config.set_mode(Mode::TcpAndUdp);
cfg
}
fn get_cli_config() -> Config {
let mut cfg = Config::new(ConfigType::Local);
cfg.local = vec![LocalConfig::new_with_addr(
cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(
LOCAL_ADDR.parse().unwrap(),
ProtocolType::Socks,
)];
cfg.local[0].mode = Mode::TcpAndUdp;
cfg.server = vec![ServerConfig::new(
))];
cfg.local[0].config.mode = Mode::TcpAndUdp;
cfg.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
SERVER_ADDR.parse::<SocketAddr>().unwrap(),
PASSWORD.to_owned(),
METHOD,
)];
))];
cfg
}