mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
Follows config key no_delay and mode in ss-libev
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user