diff --git a/src/bin/local.rs b/src/bin/local.rs index bae9b72e57b4..ecd489e26ca0 100644 --- a/src/bin/local.rs +++ b/src/bin/local.rs @@ -204,8 +204,8 @@ fn main() { if let Some(p) = matches.value_of("PLUGIN") { let plugin = PluginConfig { plugin: p.to_owned(), - plugin_opt: matches.value_of("PLUGIN_OPT").map(ToOwned::to_owned), - plugin_arg: None, + plugin_opts: matches.value_of("PLUGIN_OPT").map(ToOwned::to_owned), + plugin_args: Vec::new(), }; sc.set_plugin(plugin); diff --git a/src/bin/server.rs b/src/bin/server.rs index c9adb010a5b0..087dfa8754c4 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -110,8 +110,8 @@ fn main() { if let Some(p) = matches.value_of("PLUGIN") { let plugin = PluginConfig { plugin: p.to_owned(), - plugin_opt: matches.value_of("PLUGIN_OPT").map(ToOwned::to_owned), - plugin_arg: None, + plugin_opts: matches.value_of("PLUGIN_OPT").map(ToOwned::to_owned), + plugin_args: Vec::new(), }; sc.set_plugin(plugin); diff --git a/src/config.rs b/src/config.rs index ac2e476ddfa7..bdb387c95313 100644 --- a/src/config.rs +++ b/src/config.rs @@ -98,7 +98,7 @@ struct SSConfig { #[serde(skip_serializing_if = "Option::is_none")] plugin_opts: Option, #[serde(skip_serializing_if = "Option::is_none")] - plugin_arg: Option, + plugin_args: Option>, #[serde(skip_serializing_if = "Option::is_none")] timeout: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -130,6 +130,8 @@ struct SSServerExtConfig { #[serde(skip_serializing_if = "Option::is_none")] plugin_opts: Option, #[serde(skip_serializing_if = "Option::is_none")] + plugin_args: Option>, + #[serde(skip_serializing_if = "Option::is_none")] timeout: Option, } @@ -345,7 +347,7 @@ impl ServerConfig { let mut url = format!("ss://{}@{}", encoded_user_info, self.addr()); if let Some(c) = self.plugin() { let mut plugin = c.plugin.clone(); - if let Some(ref opt) = c.plugin_opt { + if let Some(ref opt) = c.plugin_opts { plugin += ";"; plugin += opt; } @@ -423,8 +425,8 @@ impl ServerConfig { Some(p) => { plugin = Some(PluginConfig { plugin: p.to_owned(), - plugin_opt: vsp.next().map(ToOwned::to_owned), - plugin_arg: None, + plugin_opts: vsp.next().map(ToOwned::to_owned), + plugin_args: Vec::new(), // SIP002 doesn't have arguments for plugins }) } } @@ -1212,8 +1214,8 @@ impl Config { None => None, Some(plugin) => Some(PluginConfig { plugin, - plugin_opt: config.plugin_opts, - plugin_arg: config.plugin_arg, + plugin_opts: config.plugin_opts, + plugin_args: config.plugin_args.unwrap_or_default(), }), }; @@ -1260,8 +1262,8 @@ impl Config { None => None, Some(p) => Some(PluginConfig { plugin: p, - plugin_opt: svr.plugin_opts, - plugin_arg: None, + plugin_opts: svr.plugin_opts, + plugin_args: svr.plugin_args.unwrap_or_default(), }), }; @@ -1495,8 +1497,14 @@ impl fmt::Display for Config { jconf.method = Some(svr.method().to_string()); jconf.password = Some(svr.password().to_string()); jconf.plugin = svr.plugin().map(|p| p.plugin.to_string()); - jconf.plugin_opts = svr.plugin().and_then(|p| p.plugin_opt.clone()); - jconf.plugin_arg = svr.plugin().and_then(|p| p.plugin_arg.clone()); + jconf.plugin_opts = svr.plugin().and_then(|p| p.plugin_opts.clone()); + jconf.plugin_args = svr.plugin().and_then(|p| { + if p.plugin_args.is_empty() { + None + } else { + Some(p.plugin_args.clone()) + } + }); jconf.timeout = svr.timeout().map(|t| t.as_secs()); } _ => { @@ -1515,7 +1523,14 @@ impl fmt::Display for Config { password: svr.password().to_string(), method: svr.method().to_string(), plugin: svr.plugin().map(|p| p.plugin.to_string()), - plugin_opts: svr.plugin().and_then(|p| p.plugin_opt.clone()), + plugin_opts: svr.plugin().and_then(|p| p.plugin_opts.clone()), + plugin_args: svr.plugin().and_then(|p| { + if p.plugin_args.is_empty() { + None + } else { + Some(p.plugin_args.clone()) + } + }), timeout: svr.timeout().map(|t| t.as_secs()), }); } diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index c13885ae8bb7..2355dab60f30 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -34,8 +34,8 @@ mod ss_plugin; #[derive(Debug, Clone)] pub struct PluginConfig { pub plugin: String, - pub plugin_opt: Option, - pub plugin_arg: Option, + pub plugin_opts: Option, + pub plugin_args: Vec, } /// Mode of Plugin diff --git a/src/plugin/obfs_proxy.rs b/src/plugin/obfs_proxy.rs index c7ea46ff05d8..1d50b40a494e 100644 --- a/src/plugin/obfs_proxy.rs +++ b/src/plugin/obfs_proxy.rs @@ -34,7 +34,7 @@ pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr .arg("--data-dir") .arg(format!("/tmp/{}_{}_{}", plugin.plugin, remote, local)); // FIXME: Not compatible in Windows - if let Some(ref opt) = plugin.plugin_opt { + if let Some(ref opt) = plugin.plugin_opts { cmd.args(opt.split(' ')); } @@ -51,5 +51,9 @@ pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr .arg(remote.to_string()), }; + if !plugin.plugin_args.is_empty() { + cmd.args(&plugin.plugin_args); + } + cmd } diff --git a/src/plugin/ss_plugin.rs b/src/plugin/ss_plugin.rs index 00b56bf9cc73..c6a2f21c932d 100644 --- a/src/plugin/ss_plugin.rs +++ b/src/plugin/ss_plugin.rs @@ -6,9 +6,10 @@ use tokio::process::Command; pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr, _mode: PluginMode) -> Command { trace!( - "Starting plugin \"{}\", opt: {:?} remote: {}, local: {}", + "Starting plugin \"{}\", opt: {:?}, arg: {:?}, remote: {}, local: {}", plugin.plugin, - plugin.plugin_opt, + plugin.plugin_opts, + plugin.plugin_args, remote, local ); @@ -21,12 +22,12 @@ pub fn plugin_cmd(plugin: &PluginConfig, remote: &ServerAddr, local: &SocketAddr .stdin(Stdio::null()) .kill_on_drop(true); - if let Some(ref opt) = plugin.plugin_opt { + if let Some(ref opt) = plugin.plugin_opts { cmd.env("SS_PLUGIN_OPTIONS", opt); } - if let Some(ref arg) = plugin.plugin_arg { - cmd.arg(arg); + if !plugin.plugin_args.is_empty() { + cmd.args(&plugin.plugin_args); } cmd diff --git a/src/relay/manager.rs b/src/relay/manager.rs index e76abe038dfc..64d14124aeaf 100644 --- a/src/relay/manager.rs +++ b/src/relay/manager.rs @@ -48,7 +48,7 @@ mod protocol { #[serde(skip_serializing_if = "Option::is_none")] pub plugin: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub plugin_opt: Option, + pub plugin_opts: Option, #[serde(skip_serializing_if = "Option::is_none")] pub mode: Option, } @@ -444,8 +444,8 @@ impl ManagerService { match p.plugin { Some(pp) => Some(PluginConfig { plugin: pp, - plugin_opt: p.plugin_opt, - plugin_arg: None, + plugin_opts: p.plugin_opts, + plugin_args: Vec::new(), }), None => None, }, @@ -519,7 +519,7 @@ impl ManagerService { password: svr_cfg.password().to_string(), no_delay: None, plugin: None, - plugin_opt: None, + plugin_opts: None, mode: None, };