mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
allow setting mode independently for every locals and servers
ref #452 - adding `mode` in `locals` and `servers` extended format` redir and tunnel supports customizing UDP binding address by `udp_addr` BREAKING CHANGES: - `sslocal` and `ssserver` command line option `-u` and `-U` can only control mode of command line specified local or server instance`
This commit is contained in:
@@ -17,10 +17,10 @@ use shadowsocks_service::config::RedirType;
|
||||
use shadowsocks_service::shadowsocks::relay::socks5::Address;
|
||||
use shadowsocks_service::{
|
||||
acl::AccessControl,
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, ProtocolType},
|
||||
run_local,
|
||||
shadowsocks::{
|
||||
config::{ServerAddr, ServerConfig},
|
||||
config::{Mode, ServerAddr, ServerConfig},
|
||||
crypto::v1::{available_ciphers, CipherKind},
|
||||
plugin::PluginConfig,
|
||||
},
|
||||
@@ -40,12 +40,11 @@ fn main() {
|
||||
(version: VERSION)
|
||||
(about: "A fast tunnel proxy that helps you bypass firewalls.")
|
||||
|
||||
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
|
||||
(@arg TCP_AND_UDP: -U "Server mode TCP_AND_UDP")
|
||||
|
||||
(@arg CONFIG: -c --config +takes_value required_unless_all(&["LOCAL_ADDR", "SERVER_CONFIG"]) "Shadowsocks configuration file (https://shadowsocks.org/en/config/quick-guide.html)")
|
||||
|
||||
(@arg LOCAL_ADDR: -b --("local-addr") +takes_value {validator::validate_server_addr} "Local address, listen only to this address if specified")
|
||||
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] requires[LOCAL_ADDR] "Server mode UDP_ONLY")
|
||||
(@arg TCP_AND_UDP: -U requires[LOCAL_ADDR] "Server mode TCP_AND_UDP")
|
||||
|
||||
(@arg SERVER_ADDR: -s --("server-addr") +takes_value {validator::validate_server_addr} requires[PASSWORD ENCRYPT_METHOD] "Server address")
|
||||
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR] "Server's password")
|
||||
@@ -324,18 +323,17 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("UDP_ONLY") {
|
||||
local_config.mode = Mode::UdpOnly;
|
||||
}
|
||||
|
||||
if matches.is_present("TCP_AND_UDP") {
|
||||
local_config.mode = Mode::TcpAndUdp;
|
||||
}
|
||||
|
||||
config.local.push(local_config);
|
||||
}
|
||||
|
||||
// override the config's mode if UDP_ONLY is set
|
||||
if matches.is_present("UDP_ONLY") {
|
||||
config.mode = Mode::UdpOnly;
|
||||
}
|
||||
|
||||
if matches.is_present("TCP_AND_UDP") {
|
||||
config.mode = Mode::TcpAndUdp;
|
||||
}
|
||||
|
||||
if matches.is_present("NO_DELAY") {
|
||||
config.no_delay = true;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ use tokio::{self, runtime::Builder};
|
||||
|
||||
use shadowsocks_service::{
|
||||
acl::AccessControl,
|
||||
config::{Config, ConfigType, ManagerConfig, ManagerServerHost, Mode},
|
||||
config::{Config, ConfigType, ManagerConfig, ManagerServerHost},
|
||||
run_manager,
|
||||
shadowsocks::{
|
||||
config::ManagerAddr,
|
||||
config::{ManagerAddr, Mode},
|
||||
crypto::v1::{available_ciphers, CipherKind},
|
||||
},
|
||||
};
|
||||
@@ -138,16 +138,17 @@ fn main() {
|
||||
config.local_addr = Some(bind_addr);
|
||||
}
|
||||
|
||||
// Overrides
|
||||
if matches.is_present("UDP_ONLY") {
|
||||
if config.mode.enable_tcp() {
|
||||
config.mode = Mode::TcpAndUdp;
|
||||
} else {
|
||||
config.mode = Mode::UdpOnly;
|
||||
if let Some(ref mut m) = config.manager {
|
||||
m.mode = m.mode.merge(Mode::UdpOnly);
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("TCP_AND_UDP") {
|
||||
config.mode = Mode::TcpAndUdp;
|
||||
if let Some(ref mut m) = config.manager {
|
||||
m.mode = Mode::TcpAndUdp;
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("NO_DELAY") {
|
||||
|
||||
@@ -16,10 +16,10 @@ use tokio::{self, runtime::Builder};
|
||||
|
||||
use shadowsocks_service::{
|
||||
acl::AccessControl,
|
||||
config::{Config, ConfigType, ManagerConfig, Mode},
|
||||
config::{Config, ConfigType, ManagerConfig},
|
||||
run_server,
|
||||
shadowsocks::{
|
||||
config::{ManagerAddr, ServerAddr, ServerConfig},
|
||||
config::{ManagerAddr, Mode, ServerAddr, ServerConfig},
|
||||
crypto::v1::{available_ciphers, CipherKind},
|
||||
plugin::PluginConfig,
|
||||
},
|
||||
@@ -40,9 +40,6 @@ fn main() {
|
||||
(version: VERSION)
|
||||
(about: "A fast tunnel proxy that helps you bypass firewalls.")
|
||||
|
||||
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] "Server mode UDP_ONLY")
|
||||
(@arg TCP_AND_UDP: -U "Server mode TCP_AND_UDP")
|
||||
|
||||
(@arg CONFIG: -c --config +takes_value required_unless("SERVER_ADDR") "Shadowsocks configuration file (https://shadowsocks.org/en/config/quick-guide.html)")
|
||||
|
||||
(@arg BIND_ADDR: -b --("bind-addr") +takes_value {validator::validate_ip_addr} "Bind address, outbound socket will bind this address")
|
||||
@@ -51,6 +48,8 @@ fn main() {
|
||||
(@arg PASSWORD: -k --password +takes_value requires[SERVER_ADDR] "Server's password")
|
||||
(@arg ENCRYPT_METHOD: -m --("encrypt-method") +takes_value requires[SERVER_ADDR] possible_values(available_ciphers()) +next_line_help "Server's encryption method")
|
||||
(@arg TIMEOUT: --timeout +takes_value {validator::validate_u64} requires[SERVER_ADDR] "Server's timeout seconds for TCP relay")
|
||||
(@arg UDP_ONLY: -u conflicts_with[TCP_AND_UDP] requires[SERVER_ADDR] "Server mode UDP_ONLY")
|
||||
(@arg TCP_AND_UDP: -U requires[SERVER_ADDR] "Server mode TCP_AND_UDP")
|
||||
|
||||
(@arg PLUGIN: --plugin +takes_value requires[SERVER_ADDR] "SIP003 (https://shadowsocks.org/en/spec/Plugin.html) plugin")
|
||||
(@arg PLUGIN_OPT: --("plugin-opts") +takes_value requires[PLUGIN] "Set SIP003 plugin options")
|
||||
@@ -168,6 +167,14 @@ fn main() {
|
||||
sc.set_plugin(plugin);
|
||||
}
|
||||
|
||||
if matches.is_present("UDP_ONLY") {
|
||||
sc.set_mode(sc.mode().merge(Mode::UdpOnly));
|
||||
}
|
||||
|
||||
if matches.is_present("TCP_AND_UDP") {
|
||||
sc.set_mode(Mode::TcpAndUdp);
|
||||
}
|
||||
|
||||
config.server.push(sc);
|
||||
}
|
||||
|
||||
@@ -176,18 +183,6 @@ fn main() {
|
||||
config.local_addr = Some(bind_addr);
|
||||
}
|
||||
|
||||
if matches.is_present("UDP_ONLY") {
|
||||
if config.mode.enable_tcp() {
|
||||
config.mode = Mode::TcpAndUdp;
|
||||
} else {
|
||||
config.mode = Mode::UdpOnly;
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("TCP_AND_UDP") {
|
||||
config.mode = Mode::TcpAndUdp;
|
||||
}
|
||||
|
||||
if matches.is_present("NO_DELAY") {
|
||||
config.no_delay = true;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[cfg(any(feature = "local-tunnel", feature = "local-dns"))]
|
||||
use shadowsocks::relay::socks5::Address;
|
||||
use shadowsocks::{
|
||||
config::{ManagerAddr, ServerAddr, ServerConfig},
|
||||
config::{ManagerAddr, Mode, ServerAddr, ServerConfig},
|
||||
crypto::v1::CipherKind,
|
||||
plugin::PluginConfig,
|
||||
};
|
||||
@@ -132,6 +132,9 @@ struct SSLocalExtConfig {
|
||||
local_address: Option<String>,
|
||||
local_port: u16,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
mode: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
local_udp_address: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -202,6 +205,8 @@ struct SSServerExtConfig {
|
||||
remarks: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
mode: Option<String>,
|
||||
}
|
||||
|
||||
/// Server config type
|
||||
@@ -234,47 +239,6 @@ impl ConfigType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Server mode
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Mode {
|
||||
TcpOnly,
|
||||
TcpAndUdp,
|
||||
UdpOnly,
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
pub fn enable_udp(self) -> bool {
|
||||
matches!(self, Mode::UdpOnly | Mode::TcpAndUdp)
|
||||
}
|
||||
|
||||
pub fn enable_tcp(self) -> bool {
|
||||
matches!(self, Mode::TcpOnly | Mode::TcpAndUdp)
|
||||
}
|
||||
}
|
||||
|
||||
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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "local-redir")] {
|
||||
use strum::IntoEnumIterator;
|
||||
@@ -502,6 +466,8 @@ pub struct ManagerConfig {
|
||||
///
|
||||
/// Note: Outbound address is defined in Config.local_addr
|
||||
pub server_host: ManagerServerHost,
|
||||
/// Server's mode
|
||||
pub mode: Mode,
|
||||
}
|
||||
|
||||
impl ManagerConfig {
|
||||
@@ -512,6 +478,7 @@ impl ManagerConfig {
|
||||
method: None,
|
||||
timeout: None,
|
||||
server_host: ManagerServerHost::default(),
|
||||
mode: Mode::TcpOnly,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -597,6 +564,10 @@ pub struct LocalConfig {
|
||||
pub addr: ServerAddr,
|
||||
pub protocol: ProtocolType,
|
||||
|
||||
/// Mode
|
||||
/// Uses global `mode` if not specified
|
||||
pub mode: Mode,
|
||||
|
||||
/// UDP server bind address. Uses `addr` if not specified
|
||||
///
|
||||
/// Resolving Android's issue: [shadowsocks/shadowsocks-android#2571](https://github.com/shadowsocks/shadowsocks-android/issues/2571)
|
||||
@@ -631,6 +602,8 @@ impl LocalConfig {
|
||||
LocalConfig {
|
||||
addr,
|
||||
protocol,
|
||||
|
||||
mode: Mode::TcpOnly,
|
||||
udp_addr: None,
|
||||
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
@@ -767,8 +740,6 @@ pub struct Config {
|
||||
/// Manager's configuration
|
||||
pub manager: Option<ManagerConfig>,
|
||||
|
||||
/// Server mode, `tcp_only`, `tcp_and_udp`, and `udp_only`
|
||||
pub mode: Mode,
|
||||
/// Config is for Client or Server
|
||||
pub config_type: ConfigType,
|
||||
|
||||
@@ -872,7 +843,6 @@ impl Config {
|
||||
|
||||
manager: None,
|
||||
|
||||
mode: Mode::TcpOnly,
|
||||
config_type,
|
||||
|
||||
udp_timeout: None,
|
||||
@@ -919,6 +889,22 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
// Mode
|
||||
let mut global_mode = Mode::TcpOnly;
|
||||
if let Some(m) = config.mode {
|
||||
match m.parse::<Mode>() {
|
||||
Ok(xm) => global_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match config_type {
|
||||
ConfigType::Local => {
|
||||
// Standard config
|
||||
@@ -985,6 +971,19 @@ impl Config {
|
||||
local_config.udp_addr = Some(local_udp_addr);
|
||||
}
|
||||
|
||||
match local.mode {
|
||||
Some(mode) => match mode.parse::<Mode>() {
|
||||
Ok(mode) => local_config.mode = mode,
|
||||
Err(..) => {
|
||||
let err = Error::new(ErrorKind::Malformed, "invalid `mode`", None);
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
local_config.mode = global_mode;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
if let Some(forward_address) = local.forward_address {
|
||||
let forward_port = match local.forward_port {
|
||||
@@ -1076,53 +1075,6 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
// match config.local_address {
|
||||
// Some(la) => {
|
||||
// let local_port = if config_type.is_local() {
|
||||
// let local_port = config.local_port.unwrap_or(0);
|
||||
// if local_port == 0 {
|
||||
// let err = Error::new(ErrorKind::MissingField, "missing `local_port`", None);
|
||||
// return Err(err);
|
||||
// }
|
||||
// local_port
|
||||
// } else if config_type.is_server() || config_type.is_manager() {
|
||||
// // server's local_port is ignored
|
||||
// 0
|
||||
// } else {
|
||||
// config.local_port.unwrap_or(0)
|
||||
// };
|
||||
|
||||
// let local_addr = match la.parse::<IpAddr>() {
|
||||
// Ok(ip) => ServerAddr::from(SocketAddr::new(ip, local_port)),
|
||||
// Err(..) => {
|
||||
// // treated as domain
|
||||
// ServerAddr::from((la, local_port))
|
||||
// }
|
||||
// };
|
||||
// nconfig.local_addr = Some(local_addr);
|
||||
// }
|
||||
// None => {
|
||||
// if config_type.is_local() && config.local_port.is_some() {
|
||||
// // Implementation note: This is not implemented like libev which will choose IPv6 or IPv6 LoopBack address
|
||||
// // by checking all its remote servers if all of them supports IPv6.
|
||||
// let ip = if config.ipv6_first.unwrap_or(false) {
|
||||
// Ipv6Addr::LOCALHOST.into()
|
||||
// } else {
|
||||
// Ipv4Addr::LOCALHOST.into()
|
||||
// };
|
||||
|
||||
// let local_port = config.local_port.unwrap_or(0);
|
||||
// if local_port == 0 {
|
||||
// let err = Error::new(ErrorKind::MissingField, "`local_port` shouldn't be 0", None);
|
||||
// return Err(err);
|
||||
// }
|
||||
|
||||
// let local_addr = ServerAddr::from(SocketAddr::new(ip, local_port));
|
||||
// nconfig.local_addr = Some(local_addr);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// Standard config
|
||||
// Server
|
||||
match (config.server, config.server_port, config.password, config.method) {
|
||||
@@ -1148,6 +1100,7 @@ impl Config {
|
||||
};
|
||||
|
||||
let mut nsvr = ServerConfig::new(addr, pwd, method);
|
||||
nsvr.set_mode(global_mode);
|
||||
|
||||
if let Some(p) = config.plugin {
|
||||
// SIP008 allows "plugin" to be an empty string
|
||||
@@ -1212,6 +1165,17 @@ impl Config {
|
||||
|
||||
let mut nsvr = ServerConfig::new(addr, svr.password, method);
|
||||
|
||||
match svr.mode {
|
||||
Some(mode) => match mode.parse::<Mode>() {
|
||||
Ok(mode) => nsvr.set_mode(mode),
|
||||
Err(..) => {
|
||||
let err = Error::new(ErrorKind::Malformed, "invalid `mode`", None);
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
None => nsvr.set_mode(global_mode),
|
||||
}
|
||||
|
||||
if let Some(p) = svr.plugin {
|
||||
// SIP008 allows "plugin" to be an empty string
|
||||
// Empty string implies "no plugin"
|
||||
@@ -1273,7 +1237,8 @@ impl Config {
|
||||
}
|
||||
};
|
||||
|
||||
let manager_config = ManagerConfig::new(manager);
|
||||
let mut manager_config = ManagerConfig::new(manager);
|
||||
manager_config.mode = global_mode;
|
||||
nconfig.manager = Some(manager_config);
|
||||
}
|
||||
|
||||
@@ -1304,21 +1269,6 @@ impl Config {
|
||||
};
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -1608,6 +1558,7 @@ impl fmt::Display for Config {
|
||||
ServerAddr::DomainName(.., port) => *port,
|
||||
}),
|
||||
},
|
||||
mode: Some(local.mode.to_string()),
|
||||
protocol: match local.protocol {
|
||||
ProtocolType::Socks => None,
|
||||
p => Some(p.as_str().to_owned()),
|
||||
@@ -1710,6 +1661,7 @@ impl fmt::Display for Config {
|
||||
}
|
||||
});
|
||||
jconf.timeout = svr.timeout().map(|t| t.as_secs());
|
||||
jconf.mode = Some(svr.mode().to_string());
|
||||
}
|
||||
// For >1 servers, uses extended multiple server format
|
||||
_ => {
|
||||
@@ -1740,6 +1692,7 @@ impl fmt::Display for Config {
|
||||
timeout: svr.timeout().map(|t| t.as_secs()),
|
||||
remarks: svr.remarks().map(ToOwned::to_owned),
|
||||
id: svr.id().map(ToOwned::to_owned),
|
||||
mode: Some(svr.mode().to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1761,9 +1714,11 @@ impl fmt::Display for Config {
|
||||
#[cfg(unix)]
|
||||
ManagerAddr::UnixSocketAddr(..) => None,
|
||||
};
|
||||
}
|
||||
|
||||
jconf.mode = Some(self.mode.to_string());
|
||||
if jconf.mode.is_none() {
|
||||
jconf.mode = Some(m.mode.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if self.no_delay {
|
||||
jconf.no_delay = Some(self.no_delay);
|
||||
|
||||
@@ -41,8 +41,9 @@ pub async fn build_dns_resolver(dns: DnsConfig, ipv6_first: bool, connect_opts:
|
||||
},
|
||||
#[cfg(feature = "local-dns")]
|
||||
DnsConfig::LocalDns(ns) => {
|
||||
use crate::{config::Mode, local::dns::dns_resolver::DnsResolver as LocalDnsResolver};
|
||||
use crate::local::dns::dns_resolver::DnsResolver as LocalDnsResolver;
|
||||
use log::trace;
|
||||
use shadowsocks::config::Mode;
|
||||
|
||||
trace!("initializing direct DNS resolver for {}", ns);
|
||||
|
||||
|
||||
@@ -8,14 +8,12 @@ use std::{
|
||||
use async_trait::async_trait;
|
||||
use futures::future;
|
||||
use log::{debug, trace};
|
||||
use shadowsocks::{dns_resolver::DnsResolve, net::ConnectOpts};
|
||||
use shadowsocks::{config::Mode, dns_resolver::DnsResolve, net::ConnectOpts};
|
||||
use trust_dns_resolver::proto::{
|
||||
op::{Message, Query},
|
||||
rr::{DNSClass, Name, RData, RecordType},
|
||||
};
|
||||
|
||||
use crate::config::Mode;
|
||||
|
||||
use super::{client_cache::DnsClientCache, config::NameServerAddr};
|
||||
|
||||
pub struct DnsResolver {
|
||||
|
||||
@@ -16,6 +16,7 @@ use futures::future::{self, Either};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use rand::{thread_rng, Rng};
|
||||
use shadowsocks::{
|
||||
config::Mode,
|
||||
lookup_then,
|
||||
net::{TcpListener, UdpSocket as ShadowUdpSocket},
|
||||
relay::{udprelay::MAXIMUM_UDP_PAYLOAD_SIZE, Address},
|
||||
@@ -33,7 +34,6 @@ use trust_dns_resolver::proto::{
|
||||
|
||||
use crate::{
|
||||
acl::AccessControl,
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use byte_string::ByteStr;
|
||||
use futures::future::{self, AbortHandle};
|
||||
use log::{debug, info, trace};
|
||||
use shadowsocks::{
|
||||
config::Mode,
|
||||
relay::{
|
||||
socks5::Address,
|
||||
tcprelay::proxy_stream::ProxyClientStream,
|
||||
@@ -28,7 +29,7 @@ use tokio::{
|
||||
time,
|
||||
};
|
||||
|
||||
use crate::{config::Mode, local::context::ServiceContext};
|
||||
use crate::local::context::ServiceContext;
|
||||
|
||||
use super::{
|
||||
server_data::ServerIdent,
|
||||
|
||||
@@ -11,6 +11,7 @@ use futures::{
|
||||
};
|
||||
use log::{error, trace, warn};
|
||||
use shadowsocks::{
|
||||
config::Mode,
|
||||
net::{AcceptOpts, ConnectOpts},
|
||||
plugin::{Plugin, PluginMode},
|
||||
};
|
||||
@@ -104,17 +105,16 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
|
||||
// Check if any of the local servers enable TCP connections
|
||||
|
||||
let mode = config.mode;
|
||||
let enable_tcp = config.local.iter().any(|local_config| match local_config.protocol {
|
||||
ProtocolType::Socks => mode.enable_tcp(),
|
||||
ProtocolType::Socks => local_config.mode.enable_tcp(),
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
ProtocolType::Tunnel => mode.enable_tcp(),
|
||||
ProtocolType::Tunnel => local_config.mode.enable_tcp(),
|
||||
#[cfg(feature = "local-http")]
|
||||
ProtocolType::Http => true,
|
||||
#[cfg(feature = "local-redir")]
|
||||
ProtocolType::Redir => mode.enable_tcp(),
|
||||
ProtocolType::Redir => local_config.mode.enable_tcp(),
|
||||
#[cfg(feature = "local-dns")]
|
||||
ProtocolType::Dns => mode.enable_tcp(),
|
||||
ProtocolType::Dns => local_config.mode.enable_tcp(),
|
||||
});
|
||||
|
||||
if enable_tcp {
|
||||
@@ -169,7 +169,13 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
//
|
||||
// XXX: This have to be called after allocating plugins' addresses
|
||||
let balancer = {
|
||||
let mut balancer_builder = PingBalancerBuilder::new(context.clone(), config.mode);
|
||||
let mut mode = Mode::TcpOnly;
|
||||
|
||||
for local in &config.local {
|
||||
mode = mode.merge(local.mode);
|
||||
}
|
||||
|
||||
let mut balancer_builder = PingBalancerBuilder::new(context.clone(), mode);
|
||||
for server in config.server {
|
||||
balancer_builder.add_server(ServerIdent::new(server));
|
||||
}
|
||||
@@ -179,21 +185,6 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
balancer
|
||||
};
|
||||
|
||||
// #[cfg(feature = "local-dns")]
|
||||
// if matches!(config.local_protocol, ProtocolType::Dns) || config.dns_bind_addr.is_some() {
|
||||
// use self::dns::Dns;
|
||||
|
||||
// let local_addr = config.local_dns_addr.expect("missing local_dns_addr");
|
||||
// let remote_addr = config.remote_dns_addr.expect("missing remote_dns_addr");
|
||||
|
||||
// let bind_addr = config.dns_bind_addr.as_ref().unwrap_or_else(|| &client_config);
|
||||
|
||||
// let mut server = Dns::with_context(context.clone(), local_addr, remote_addr);
|
||||
// server.set_mode(config.mode);
|
||||
|
||||
// vfut.push(server.run(bind_addr, balancer.clone()).boxed());
|
||||
// }
|
||||
|
||||
#[cfg(feature = "local-flow-stat")]
|
||||
if let Some(stat_path) = config.stat_path {
|
||||
// For Android's flow statistic
|
||||
@@ -211,7 +202,7 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
use self::socks::Socks;
|
||||
|
||||
let mut server = Socks::with_context(context.clone());
|
||||
server.set_mode(config.mode);
|
||||
server.set_mode(local_config.mode);
|
||||
|
||||
if let Some(c) = config.udp_max_associations {
|
||||
server.set_udp_capacity(c);
|
||||
@@ -242,12 +233,13 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
if let Some(d) = config.udp_timeout {
|
||||
server.set_udp_expiry_duration(d);
|
||||
}
|
||||
server.set_mode(config.mode);
|
||||
server.set_mode(local_config.mode);
|
||||
if config.no_delay {
|
||||
server.set_nodelay(true);
|
||||
}
|
||||
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
let udp_addr = local_config.udp_addr.unwrap_or_else(|| client_addr.clone());
|
||||
vfut.push(async move { server.run(&client_addr, &udp_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-http")]
|
||||
ProtocolType::Http => {
|
||||
@@ -267,14 +259,15 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
if let Some(d) = config.udp_timeout {
|
||||
server.set_udp_expiry_duration(d);
|
||||
}
|
||||
server.set_mode(config.mode);
|
||||
server.set_mode(local_config.mode);
|
||||
if config.no_delay {
|
||||
server.set_nodelay(true);
|
||||
}
|
||||
server.set_tcp_redir(local_config.tcp_redir);
|
||||
server.set_udp_redir(local_config.udp_redir);
|
||||
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
let udp_addr = local_config.udp_addr.unwrap_or_else(|| client_addr.clone());
|
||||
vfut.push(async move { server.run(&client_addr, &udp_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-dns")]
|
||||
ProtocolType::Dns => {
|
||||
@@ -286,7 +279,7 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
|
||||
Dns::with_context(context.clone(), local_addr.clone(), remote_addr.clone())
|
||||
};
|
||||
server.set_mode(config.mode);
|
||||
server.set_mode(local_config.mode);
|
||||
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use shadowsocks::ServerAddr;
|
||||
use shadowsocks::{config::Mode, ServerAddr};
|
||||
|
||||
use crate::{
|
||||
config::{Mode, RedirType},
|
||||
config::RedirType,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
@@ -74,15 +74,15 @@ impl Redir {
|
||||
}
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, tcp_addr: &ServerAddr, udp_addr: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
vfut.push(self.run_tcp_tunnel(client_config, balancer.clone()).boxed());
|
||||
vfut.push(self.run_tcp_tunnel(tcp_addr, balancer.clone()).boxed());
|
||||
}
|
||||
|
||||
if self.mode.enable_udp() {
|
||||
vfut.push(self.run_udp_tunnel(client_config, balancer).boxed());
|
||||
vfut.push(self.run_udp_tunnel(udp_addr, balancer).boxed());
|
||||
}
|
||||
|
||||
let (res, ..) = future::select_all(vfut).await;
|
||||
|
||||
@@ -4,13 +4,10 @@ use std::{io, net::SocketAddr, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use log::{error, info};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, ServerAddr};
|
||||
use shadowsocks::{config::Mode, lookup_then, net::TcpListener as ShadowTcpListener, ServerAddr};
|
||||
use tokio::{net::TcpStream, time};
|
||||
|
||||
use crate::{
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
use crate::local::{context::ServiceContext, loadbalancing::PingBalancer};
|
||||
|
||||
#[cfg(feature = "local-socks4")]
|
||||
use self::socks4::Socks4TcpHandler;
|
||||
|
||||
@@ -7,19 +7,17 @@ use std::{
|
||||
};
|
||||
|
||||
use log::{debug, trace, warn};
|
||||
use shadowsocks::config::Mode;
|
||||
use tokio::{
|
||||
io::{AsyncWriteExt, BufReader},
|
||||
net::TcpStream,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::Mode,
|
||||
local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
net::AutoProxyClientStream,
|
||||
utils::establish_tcp_tunnel,
|
||||
},
|
||||
use crate::local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
net::AutoProxyClientStream,
|
||||
utils::establish_tcp_tunnel,
|
||||
};
|
||||
|
||||
use crate::local::socks::socks4::{Address, Command, HandshakeRequest, HandshakeResponse, ResultCode};
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::{
|
||||
|
||||
use log::{debug, error, trace, warn};
|
||||
use shadowsocks::{
|
||||
config::Mode,
|
||||
relay::socks5::{
|
||||
self,
|
||||
Address,
|
||||
@@ -23,7 +24,6 @@ use shadowsocks::{
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
use crate::{
|
||||
config::Mode,
|
||||
local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use shadowsocks::{relay::socks5::Address, ServerAddr};
|
||||
use shadowsocks::{config::Mode, relay::socks5::Address, ServerAddr};
|
||||
|
||||
use crate::{
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
use crate::local::{context::ServiceContext, loadbalancing::PingBalancer};
|
||||
|
||||
use super::{tcprelay::run_tcp_tunnel, udprelay::UdpTunnel};
|
||||
|
||||
@@ -62,15 +59,15 @@ impl Tunnel {
|
||||
}
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, tcp_addr: &ServerAddr, udp_addr: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
vfut.push(self.run_tcp_tunnel(client_config, balancer.clone()).boxed());
|
||||
vfut.push(self.run_tcp_tunnel(tcp_addr, balancer.clone()).boxed());
|
||||
}
|
||||
|
||||
if self.mode.enable_udp() {
|
||||
vfut.push(self.run_udp_tunnel(client_config, balancer).boxed());
|
||||
vfut.push(self.run_udp_tunnel(udp_addr, balancer).boxed());
|
||||
}
|
||||
|
||||
let (res, ..) = future::select_all(vfut).await;
|
||||
|
||||
@@ -31,7 +31,6 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
}
|
||||
|
||||
let mut manager = Manager::new(config.manager.expect("missing manager config"));
|
||||
manager.set_mode(config.mode);
|
||||
|
||||
let mut connect_opts = ConnectOpts {
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
@@ -73,7 +72,7 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
}
|
||||
|
||||
for svr_cfg in config.server {
|
||||
manager.add_server(svr_cfg, None).await;
|
||||
manager.add_server(svr_cfg).await;
|
||||
}
|
||||
|
||||
manager.run().await
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::{collections::HashMap, io, net::SocketAddr, sync::Arc, time::Duration};
|
||||
use futures::future::{self, AbortHandle};
|
||||
use log::{error, info};
|
||||
use shadowsocks::{
|
||||
config::{ServerConfig, ServerType},
|
||||
config::{Mode, ServerConfig, ServerType},
|
||||
context::{Context, SharedContext},
|
||||
crypto::v1::CipherKind,
|
||||
dns_resolver::DnsResolver,
|
||||
@@ -30,7 +30,7 @@ use tokio::sync::Mutex;
|
||||
|
||||
use crate::{
|
||||
acl::AccessControl,
|
||||
config::{ManagerConfig, ManagerServerHost, Mode},
|
||||
config::{ManagerConfig, ManagerServerHost},
|
||||
net::FlowStat,
|
||||
server::Server,
|
||||
};
|
||||
@@ -52,7 +52,6 @@ pub struct Manager {
|
||||
context: SharedContext,
|
||||
servers: Mutex<HashMap<u16, ServerInstance>>,
|
||||
svr_cfg: ManagerConfig,
|
||||
mode: Mode,
|
||||
connect_opts: ConnectOpts,
|
||||
accept_opts: AcceptOpts,
|
||||
udp_expiry_duration: Option<Duration>,
|
||||
@@ -72,7 +71,6 @@ impl Manager {
|
||||
context,
|
||||
servers: Mutex::new(HashMap::new()),
|
||||
svr_cfg,
|
||||
mode: Mode::TcpOnly,
|
||||
connect_opts: ConnectOpts::default(),
|
||||
accept_opts: AcceptOpts::default(),
|
||||
udp_expiry_duration: None,
|
||||
@@ -101,11 +99,6 @@ impl Manager {
|
||||
self.udp_capacity = Some(c);
|
||||
}
|
||||
|
||||
/// Set server's default mode
|
||||
pub fn set_mode(&mut self, mode: Mode) {
|
||||
self.mode = mode;
|
||||
}
|
||||
|
||||
/// Get the manager's configuration
|
||||
pub fn config(&self) -> &ManagerConfig {
|
||||
&self.svr_cfg
|
||||
@@ -166,7 +159,7 @@ impl Manager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add_server(&self, svr_cfg: ServerConfig, mode: Option<Mode>) {
|
||||
pub async fn add_server(&self, svr_cfg: ServerConfig) {
|
||||
// Each server should use a separate Context, but shares
|
||||
//
|
||||
// * AccessControlList
|
||||
@@ -185,8 +178,6 @@ impl Manager {
|
||||
server.set_udp_capacity(c);
|
||||
}
|
||||
|
||||
server.set_mode(mode.unwrap_or(self.mode));
|
||||
|
||||
if let Some(ref acl) = self.acl {
|
||||
server.set_acl(acl.clone());
|
||||
}
|
||||
@@ -261,7 +252,9 @@ impl Manager {
|
||||
},
|
||||
};
|
||||
|
||||
self.add_server(svr_cfg, mode).await;
|
||||
svr_cfg.set_mode(mode.unwrap_or(self.svr_cfg.mode));
|
||||
|
||||
self.add_server(svr_cfg).await;
|
||||
|
||||
Ok(AddResponse("ok".to_owned()))
|
||||
}
|
||||
|
||||
@@ -91,7 +91,6 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
if let Some(d) = config.udp_timeout {
|
||||
server.set_udp_expiry_duration(d);
|
||||
}
|
||||
server.set_mode(config.mode);
|
||||
if let Some(ref m) = config.manager {
|
||||
server.set_manager_addr(m.addr.clone());
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use shadowsocks::{
|
||||
};
|
||||
use tokio::time;
|
||||
|
||||
use crate::{acl::AccessControl, config::Mode, net::FlowStat};
|
||||
use crate::{acl::AccessControl, net::FlowStat};
|
||||
|
||||
use super::{context::ServiceContext, tcprelay::TcpServer, udprelay::UdpServer};
|
||||
|
||||
@@ -26,7 +26,6 @@ use super::{context::ServiceContext, tcprelay::TcpServer, udprelay::UdpServer};
|
||||
pub struct Server {
|
||||
context: Arc<ServiceContext>,
|
||||
svr_cfg: ServerConfig,
|
||||
mode: Mode,
|
||||
udp_expiry_duration: Option<Duration>,
|
||||
udp_capacity: Option<usize>,
|
||||
manager_addr: Option<ManagerAddr>,
|
||||
@@ -44,7 +43,6 @@ impl Server {
|
||||
Server {
|
||||
context,
|
||||
svr_cfg,
|
||||
mode: Mode::TcpOnly,
|
||||
udp_expiry_duration: None,
|
||||
udp_capacity: None,
|
||||
manager_addr: None,
|
||||
@@ -78,11 +76,6 @@ impl Server {
|
||||
self.udp_capacity = Some(c);
|
||||
}
|
||||
|
||||
/// Set server's mode
|
||||
pub fn set_mode(&mut self, mode: Mode) {
|
||||
self.mode = mode;
|
||||
}
|
||||
|
||||
/// Set manager's address to report `stat`
|
||||
pub fn set_manager_addr(&mut self, manager_addr: ManagerAddr) {
|
||||
self.manager_addr = Some(manager_addr);
|
||||
@@ -114,7 +107,7 @@ impl Server {
|
||||
pub async fn run(mut self) -> io::Result<()> {
|
||||
let vfut = FuturesUnordered::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
if self.svr_cfg.mode().enable_tcp() {
|
||||
if let Some(plugin_cfg) = self.svr_cfg.plugin() {
|
||||
let plugin = Plugin::start(plugin_cfg, self.svr_cfg.addr(), PluginMode::Server)?;
|
||||
self.svr_cfg.set_plugin_addr(plugin.local_addr().into());
|
||||
@@ -139,7 +132,7 @@ impl Server {
|
||||
vfut.push(tcp_fut);
|
||||
}
|
||||
|
||||
if self.mode.enable_udp() {
|
||||
if self.svr_cfg.mode().enable_udp() {
|
||||
let udp_fut = self.run_udp_server().boxed();
|
||||
vfut.push(udp_fut);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,61 @@ impl ServerType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Server mode
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Mode {
|
||||
TcpOnly = 0x01,
|
||||
TcpAndUdp = 0x03,
|
||||
UdpOnly = 0x02,
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
/// Check if UDP is enabled
|
||||
pub fn enable_udp(self) -> bool {
|
||||
matches!(self, Mode::UdpOnly | Mode::TcpAndUdp)
|
||||
}
|
||||
|
||||
/// Check if TCP is enabled
|
||||
pub fn enable_tcp(self) -> bool {
|
||||
matches!(self, Mode::TcpOnly | Mode::TcpAndUdp)
|
||||
}
|
||||
|
||||
/// Merge with another Mode
|
||||
pub fn merge(&self, mode: Mode) -> Mode {
|
||||
let me = *self as u8;
|
||||
let fm = mode as u8;
|
||||
match me | fm {
|
||||
0x01 => Mode::TcpOnly,
|
||||
0x02 => Mode::UdpOnly,
|
||||
0x03 => Mode::TcpAndUdp,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 for a server
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ServerConfig {
|
||||
@@ -60,10 +115,14 @@ pub struct ServerConfig {
|
||||
plugin: Option<PluginConfig>,
|
||||
/// Plugin address
|
||||
plugin_addr: Option<ServerAddr>,
|
||||
|
||||
/// Remark (Profile Name), normally used as an identifier of this erver
|
||||
remarks: Option<String>,
|
||||
/// ID (SIP008) is a random generated UUID
|
||||
id: Option<String>,
|
||||
|
||||
/// Mode
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
@@ -88,6 +147,7 @@ impl ServerConfig {
|
||||
plugin_addr: None,
|
||||
remarks: None,
|
||||
id: None,
|
||||
mode: Mode::TcpOnly,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +254,16 @@ impl ServerConfig {
|
||||
self.id = Some(id.into())
|
||||
}
|
||||
|
||||
/// Get server's `Mode`
|
||||
pub fn mode(&self) -> Mode {
|
||||
self.mode
|
||||
}
|
||||
|
||||
/// Set server's `Mode`
|
||||
pub fn set_mode(&mut self, mode: Mode) {
|
||||
self.mode = mode;
|
||||
}
|
||||
|
||||
/// Get URL for QRCode
|
||||
/// ```plain
|
||||
/// ss:// + base64(method:password@host:port)
|
||||
|
||||
@@ -11,12 +11,12 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, ProtocolType},
|
||||
local::socks::client::socks5::Socks5TcpClient,
|
||||
run_local,
|
||||
run_server,
|
||||
shadowsocks::{
|
||||
config::{ServerAddr, ServerConfig},
|
||||
config::{Mode, ServerAddr, ServerConfig},
|
||||
crypto::v1::CipherKind,
|
||||
relay::socks5::Address,
|
||||
},
|
||||
@@ -42,14 +42,14 @@ impl Socks5TestServer {
|
||||
svr_config: {
|
||||
let mut cfg = Config::new(ConfigType::Server);
|
||||
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
|
||||
cfg.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
||||
cfg.server[0].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(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.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
||||
cfg
|
||||
},
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ use log::debug;
|
||||
use tokio::time::{self, Duration};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, ProtocolType},
|
||||
local::socks::client::socks5::Socks5UdpClient,
|
||||
run_local,
|
||||
run_server,
|
||||
shadowsocks::{crypto::v1::CipherKind, relay::socks5::Address, ServerConfig},
|
||||
shadowsocks::{config::Mode, crypto::v1::CipherKind, relay::socks5::Address, ServerConfig},
|
||||
};
|
||||
|
||||
const SERVER_ADDR: &str = "127.0.0.1:8093";
|
||||
@@ -29,19 +29,19 @@ fn get_svr_config() -> Config {
|
||||
PASSWORD.to_owned(),
|
||||
METHOD,
|
||||
)];
|
||||
cfg.mode = Mode::TcpAndUdp;
|
||||
cfg.server[0].set_mode(Mode::TcpAndUdp);
|
||||
cfg
|
||||
}
|
||||
|
||||
fn get_cli_config() -> Config {
|
||||
let mut cfg = Config::new(ConfigType::Local);
|
||||
cfg.local = vec![LocalConfig::new(LOCAL_ADDR.parse().unwrap(), ProtocolType::Socks)];
|
||||
cfg.local[0].mode = Mode::TcpAndUdp;
|
||||
cfg.server = vec![ServerConfig::new(
|
||||
SERVER_ADDR.parse::<SocketAddr>().unwrap(),
|
||||
PASSWORD.to_owned(),
|
||||
METHOD,
|
||||
)];
|
||||
cfg.mode = Mode::TcpAndUdp;
|
||||
cfg
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user