Follows config key no_delay and mode in ss-libev

This commit is contained in:
zonyitoo
2019-01-01 02:32:20 +08:00
parent 09c622ba8e
commit db04bdb36d
11 changed files with 148 additions and 37 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "shadowsocks-rust"
version = "1.7.0-alpha.19"
version = "1.7.0-alpha.20"
authors = ["Y. T. CHUNG <zonyitoo@gmail.com>"]
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
repository = "https://github.com/zonyitoo/shadowsocks-rust"

View File

@@ -25,7 +25,7 @@ use futures::Future;
use log::{LevelFilter, Record};
use tokio::runtime::Runtime;
use shadowsocks::{plugin::PluginConfig, run_local, Config, ConfigType, ServerAddr, ServerConfig};
use shadowsocks::{plugin::PluginConfig, run_local, Config, ConfigType, Mode, ServerAddr, ServerConfig};
fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> {
if without_time {
@@ -136,6 +136,12 @@ fn main() {
.takes_value(true)
.help("Server address in SIP002 URL"),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.get_matches();
let mut log_builder = Builder::new();
@@ -250,7 +256,17 @@ fn main() {
return;
}
config.enable_udp |= matches.is_present("ENABLE_UDP");
if matches.is_present("ENABLE_UDP") {
if config.mode.enable_tcp() {
config.mode = Mode::TcpAndUdp;
} else {
config.mode = Mode::UdpOnly;
}
}
if matches.is_present("NO_DELAY") {
config.no_delay = true;
}
if let Some(p) = matches.value_of("PLUGIN") {
let plugin = PluginConfig {

View File

@@ -27,7 +27,7 @@ use futures::Future;
use log::{LevelFilter, Record};
use tokio::runtime::Runtime;
use shadowsocks::{plugin::PluginConfig, run_server, Config, ConfigType, ServerAddr, ServerConfig};
use shadowsocks::{plugin::PluginConfig, run_server, Config, ConfigType, Mode, ServerAddr, ServerConfig};
fn log_time(fmt: &mut Formatter, without_time: bool, record: &Record) -> io::Result<()> {
if without_time {
@@ -125,6 +125,12 @@ fn main() {
.long("log-without-time")
.help("Disable time in log"),
)
.arg(
Arg::with_name("NO_DELAY")
.long("no-delay")
.takes_value(false)
.help("Set no-delay option for socket"),
)
.get_matches();
let mut log_builder = Builder::new();
@@ -220,7 +226,17 @@ fn main() {
return;
}
config.enable_udp |= matches.is_present("ENABLE_UDP");
if matches.is_present("ENABLE_UDP") {
if config.mode.enable_tcp() {
config.mode = Mode::TcpAndUdp;
} else {
config.mode = Mode::UdpOnly;
}
}
if matches.is_present("NO_DELAY") {
config.no_delay = true;
}
if let Some(p) = matches.value_of("PLUGIN") {
let plugin = PluginConfig {

View File

@@ -86,8 +86,6 @@ struct SSConfig {
#[serde(skip_serializing_if = "Option::is_none")]
plugin_opts: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
enable_udp: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
timeout: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
udp_timeout: Option<u64>,
@@ -99,6 +97,10 @@ struct SSConfig {
dns: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
remote_dns: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
mode: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
no_delay: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug)]
@@ -472,15 +474,63 @@ pub enum ConfigType {
Server,
}
/// Server mode
#[derive(Clone, Copy, Debug)]
pub enum Mode {
TcpOnly,
TcpAndUdp,
UdpOnly,
}
impl Mode {
pub fn enable_udp(&self) -> bool {
match *self {
Mode::UdpOnly | Mode::TcpAndUdp => true,
_ => false,
}
}
pub fn enable_tcp(&self) -> bool {
match *self {
Mode::TcpOnly | Mode::TcpAndUdp => true,
_ => false,
}
}
}
impl fmt::Display for Mode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Mode::TcpOnly => f.write_str("tcp_only"),
Mode::TcpAndUdp => f.write_str("tcp_and_udp"),
Mode::UdpOnly => f.write_str("udp_only"),
}
}
}
impl FromStr for Mode {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"tcp_only" => Ok(Mode::TcpOnly),
"tcp_and_udp" => Ok(Mode::TcpAndUdp),
"udp_only" => Ok(Mode::UdpOnly),
_ => Err(()),
}
}
}
/// Configuration
#[derive(Clone, Debug)]
pub struct Config {
pub server: Vec<ServerConfig>,
pub local: Option<ClientConfig>,
pub enable_udp: bool,
pub forbidden_ip: HashSet<IpAddr>,
pub dns: Option<String>,
pub remote_dns: Option<SocketAddr>,
pub mode: Mode,
pub no_delay: bool,
}
impl Default for Config {
@@ -544,10 +594,11 @@ impl Config {
Config {
server: Vec::new(),
local: None,
enable_udp: false,
forbidden_ip: HashSet::new(),
dns: None,
remote_dns: None,
mode: Mode::TcpOnly,
no_delay: false,
}
}
@@ -730,9 +781,24 @@ impl Config {
}
}
// UDP switch
if let Some(enable) = config.enable_udp {
nconfig.enable_udp = enable;
// Mode
if let Some(m) = config.mode {
match m.parse::<Mode>() {
Ok(xm) => nconfig.mode = xm,
Err(..) => {
let e = Error::new(
ErrorKind::Malformed,
"malformed `mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`",
None,
);
return Err(e);
}
}
}
// TCP nodelay
if let Some(b) = config.no_delay {
nconfig.no_delay = b;
}
Ok(nconfig)
@@ -853,8 +919,10 @@ impl fmt::Display for Config {
}
}
if self.enable_udp {
jconf.enable_udp = Some(true);
jconf.mode = Some(self.mode.to_string());
if self.no_delay {
jconf.no_delay = Some(self.no_delay);
}
if !self.forbidden_ip.is_empty() {

View File

@@ -110,7 +110,7 @@ extern crate url;
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
pub use self::{
config::{ClientConfig, Config, ConfigType, ServerAddr, ServerConfig},
config::{ClientConfig, Config, ConfigType, Mode, ServerAddr, ServerConfig},
relay::{dns::run as run_dns, local::run as run_local, server::run as run_server, tcprelay::client::Socks5Client},
};

View File

@@ -39,7 +39,7 @@ pub fn run(config: Config) -> impl Future<Item = (), Error = io::Error> + Send {
let mut context = Context::new(config);
if context.config().enable_udp {
if context.config().mode.enable_udp() {
// Clone config here, because the config for TCP relay will be modified
// after plugins started
let udp_context = SharedContext::new(context.clone());

View File

@@ -39,7 +39,7 @@ pub fn run(config: Config) -> impl Future<Item = (), Error = io::Error> + Send {
let mut vf = Vec::new();
if context.config().enable_udp {
if context.config().mode.enable_udp() {
// Clone config here, because the config for TCP relay will be modified
// after plugins started
let udp_context = SharedContext::new(context.clone());
@@ -50,14 +50,16 @@ pub fn run(config: Config) -> impl Future<Item = (), Error = io::Error> + Send {
vf.push(boxed_future(udp_fut));
}
// Hold it here, kill all plugins when `tokio::run` is finished
let plugins = launch_plugin(context.config_mut(), PluginMode::Server).expect("Failed to launch plugins");
let mon = ::monitor::monitor_signal(plugins);
if context.config().mode.enable_tcp() {
// Hold it here, kill all plugins when `tokio::run` is finished
let plugins = launch_plugin(context.config_mut(), PluginMode::Server).expect("Failed to launch plugins");
let mon = ::monitor::monitor_signal(plugins);
let tcp_fut = run_tcp(SharedContext::new(context));
let tcp_fut = run_tcp(SharedContext::new(context));
vf.push(boxed_future(mon));
vf.push(boxed_future(tcp_fut));
vf.push(boxed_future(mon));
vf.push(boxed_future(tcp_fut));
}
futures_unordered(vf).into_future().then(|res| -> io::Result<()> {
match res {

View File

@@ -148,13 +148,22 @@ fn handle_socks5_client(
let addr = header.address;
match header.command {
socks5::Command::TcpConnect => {
debug!("CONNECT {}", addr);
let fut =
handle_socks5_connect(context, (r, w), cloned_client_addr, addr.clone(), conf).map_err(move |err| {
error!("CONNECT {} failed with error: {}", addr, err);
err
});
boxed_future(fut)
let enable_tcp = context.config().mode.enable_tcp();
if enable_tcp {
debug!("CONNECT {}", addr);
let fut = handle_socks5_connect(context, (r, w), cloned_client_addr, addr.clone(), conf)
.map_err(move |err| {
error!("CONNECT {} failed with error: {}", addr, err);
err
});
boxed_future(fut)
} else {
warn!("CONNECT is not enabled");
let fut = TcpResponseHeader::new(socks5::Reply::CommandNotSupported, addr)
.write_to(w)
.map(|_| ());
boxed_future(fut)
}
}
socks5::Command::TcpBind => {
warn!("BIND is not supported");
@@ -176,7 +185,7 @@ fn handle_socks5_client(
boxed_future(fut)
} else {
warn!("UDP Associate is not enabled");
warn!("UDP ASSOCIATE is not enabled");
let fut = TcpResponseHeader::new(socks5::Reply::CommandNotSupported, addr)
.write_to(w)
.map(|_| ());
@@ -208,7 +217,7 @@ pub fn run(context: SharedContext) -> impl Future<Item = (), Error = io::Error>
info!("ShadowSocks TCP Listening on {}", local_addr);
let udp_conf = UdpConfig {
enable_udp: context.config().enable_udp,
enable_udp: context.config().mode.enable_udp(),
client_addr: local_addr,
};

View File

@@ -29,7 +29,7 @@ const CONFIG: &'static str = r#"{
"password": "abc",
"timeout": 20,
"method": "aes-256-gcm",
"enable_udp": true
"mode": "tcp_and_udp"
}"#;
#[test]

View File

@@ -16,7 +16,7 @@ use tokio::runtime::current_thread::Runtime;
use tokio_io::io::{flush, read_to_end, write_all};
use shadowsocks::{
config::{Config, ServerConfig},
config::{Config, Mode, ServerConfig},
crypto::CipherType,
relay::{socks5::Address, tcprelay::client::Socks5Client},
run_local,
@@ -49,7 +49,7 @@ impl Socks5TestServer {
let mut cfg = Config::new();
cfg.local = Some(local_addr);
cfg.server = vec![ServerConfig::basic(svr_addr, pwd.to_owned(), method)];
cfg.enable_udp = enable_udp;
cfg.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
cfg
},
}

View File

@@ -21,7 +21,7 @@ use tokio::runtime::current_thread::Runtime;
use tokio_io::io::read_to_end;
use shadowsocks::{
config::{Config, ServerConfig},
config::{Config, Mode, ServerConfig},
crypto::CipherType,
relay::{
socks5::{Address, UdpAssociateHeader},
@@ -48,7 +48,7 @@ fn get_config() -> Config {
PASSWORD.to_owned(),
METHOD,
)];
cfg.enable_udp = true;
cfg.mode = Mode::UdpOnly;
cfg
}