mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
support multiple local servers in configuration file
ref #452 - support `locals` in configuration file, running multiple local server instance simultaneously - support `unix://` in `dns` configuration BREAKING CHANGE: - `sslocal`'s `--dns-addr` is now only available in Android - shadowsocks-service's `Config` struct have lots of changes
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -1471,7 +1471,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "shadowsocks"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
dependencies = [
|
||||
"arc-swap 1.2.0",
|
||||
"async-trait",
|
||||
@@ -1515,7 +1515,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "shadowsocks-rust"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
dependencies = [
|
||||
"byte_string",
|
||||
"byteorder",
|
||||
@@ -1536,7 +1536,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "shadowsocks-service"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"byte_string",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shadowsocks-rust"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
authors = ["Shadowsocks Contributors"]
|
||||
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
|
||||
repository = "https://github.com/shadowsocks/shadowsocks-rust"
|
||||
@@ -122,7 +122,7 @@ mimalloc = { version = "0.1", optional = true }
|
||||
tcmalloc = { version = "0.3", optional = true }
|
||||
jemallocator = { version = "0.3", optional = true }
|
||||
|
||||
shadowsocks-service = { version = "1.9.2", path = "./crates/shadowsocks-service" }
|
||||
shadowsocks-service = { version = "1.10.0", path = "./crates/shadowsocks-service" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
daemonize = "0.4"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
|
||||
#[cfg(feature = "local-dns")]
|
||||
use shadowsocks_service::local::dns::NameServerAddr;
|
||||
@@ -24,6 +24,7 @@ validate_type!(
|
||||
ServerAddr,
|
||||
"should be either ip:port or domain:port"
|
||||
);
|
||||
validate_type!(validate_ip_addr, IpAddr, "should be a valid IPv4 or IPv6 address");
|
||||
validate_type!(validate_socket_addr, SocketAddr, "should be ip:port");
|
||||
validate_type!(validate_address, Address, "should be either ip:port or domain:port");
|
||||
validate_type!(
|
||||
|
||||
141
bin/sslocal.rs
141
bin/sslocal.rs
@@ -17,7 +17,7 @@ use shadowsocks_service::config::RedirType;
|
||||
use shadowsocks_service::shadowsocks::relay::socks5::Address;
|
||||
use shadowsocks_service::{
|
||||
acl::AccessControl,
|
||||
config::{Config, ConfigType, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
run_local,
|
||||
shadowsocks::{
|
||||
config::{ServerAddr, ServerConfig},
|
||||
@@ -151,9 +151,16 @@ fn main() {
|
||||
app = clap_app!(@app (app)
|
||||
(@arg LOCAL_DNS_ADDR: --("local-dns-addr") +takes_value required_if("PROTOCOL", "dns") {validator::validate_name_server_addr} "Specify the address of local DNS server, send queries directly")
|
||||
(@arg REMOTE_DNS_ADDR: --("remote-dns-addr") +takes_value required_if("PROTOCOL", "dns") {validator::validate_address} "Specify the address of remote DNS server, send queries through shadowsocks' tunnel")
|
||||
|
||||
);
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
app = clap_app!(@app (app)
|
||||
(@arg DNS_LOCAL_ADDR: --("dns-addr") +takes_value requires_all(&["REMOTE_DNS_ADDR"]) {validator::validate_server_addr} "DNS address, listen to this address if specified")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
@@ -193,22 +200,6 @@ fn main() {
|
||||
None => Config::new(ConfigType::Local),
|
||||
};
|
||||
|
||||
let protocol = match matches.value_of("PROTOCOL") {
|
||||
Some("socks") => ProtocolType::Socks,
|
||||
#[cfg(feature = "local-http")]
|
||||
Some("http") => ProtocolType::Http,
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
Some("tunnel") => ProtocolType::Tunnel,
|
||||
#[cfg(feature = "local-redir")]
|
||||
Some("redir") => ProtocolType::Redir,
|
||||
#[cfg(feature = "local-dns")]
|
||||
Some("dns") => ProtocolType::Dns,
|
||||
Some(p) => panic!("not supported `protocol` \"{}\"", p),
|
||||
None => ProtocolType::Socks,
|
||||
};
|
||||
|
||||
config.local_protocol = protocol;
|
||||
|
||||
if let Some(svr_addr) = matches.value_of("SERVER_ADDR") {
|
||||
let password = matches.value_of("PASSWORD").expect("password");
|
||||
let method = matches
|
||||
@@ -253,26 +244,6 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-dns")]
|
||||
{
|
||||
use shadowsocks_service::local::dns::NameServerAddr;
|
||||
|
||||
if let Some(local_dns_addr) = matches.value_of("LOCAL_DNS_ADDR") {
|
||||
let addr = local_dns_addr.parse::<NameServerAddr>().expect("local dns address");
|
||||
config.local_dns_addr = Some(addr);
|
||||
}
|
||||
|
||||
if let Some(remote_dns_addr) = matches.value_of("REMOTE_DNS_ADDR") {
|
||||
let addr = remote_dns_addr.parse::<Address>().expect("remote dns address");
|
||||
config.remote_dns_addr = Some(addr);
|
||||
}
|
||||
|
||||
if let Some(dns_relay_addr) = matches.value_of("DNS_LOCAL_ADDR") {
|
||||
let addr = dns_relay_addr.parse::<ServerAddr>().expect("dns relay address");
|
||||
config.dns_bind_addr = Some(addr);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
if matches.is_present("VPN_MODE") {
|
||||
// A socket `protect_path` in CWD
|
||||
@@ -282,7 +253,78 @@ fn main() {
|
||||
|
||||
if let Some(local_addr) = matches.value_of("LOCAL_ADDR") {
|
||||
let local_addr = local_addr.parse::<ServerAddr>().expect("local bind addr");
|
||||
config.local_addr = Some(local_addr);
|
||||
|
||||
let protocol = match matches.value_of("PROTOCOL") {
|
||||
Some("socks") => ProtocolType::Socks,
|
||||
#[cfg(feature = "local-http")]
|
||||
Some("http") => ProtocolType::Http,
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
Some("tunnel") => ProtocolType::Tunnel,
|
||||
#[cfg(feature = "local-redir")]
|
||||
Some("redir") => ProtocolType::Redir,
|
||||
#[cfg(feature = "local-dns")]
|
||||
Some("dns") => ProtocolType::Dns,
|
||||
Some(p) => panic!("not supported `protocol` \"{}\"", p),
|
||||
None => ProtocolType::Socks,
|
||||
};
|
||||
|
||||
let mut local_config = LocalConfig::new(local_addr, protocol);
|
||||
|
||||
if let Some(udp_bind_addr) = matches.value_of("UDP_BIND_ADDR") {
|
||||
local_config.udp_addr = Some(udp_bind_addr.parse::<ServerAddr>().expect("udp-bind-addr"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
if let Some(faddr) = matches.value_of("FORWARD_ADDR") {
|
||||
let addr = faddr.parse::<Address>().expect("forward-addr");
|
||||
local_config.forward_addr = Some(addr);
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-redir")]
|
||||
{
|
||||
if let Some(tcp_redir) = matches.value_of("TCP_REDIR") {
|
||||
local_config.tcp_redir = tcp_redir.parse::<RedirType>().expect("TCP redir type");
|
||||
}
|
||||
|
||||
if let Some(udp_redir) = matches.value_of("UDP_REDIR") {
|
||||
local_config.udp_redir = udp_redir.parse::<RedirType>().expect("UDP redir type");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-dns")]
|
||||
{
|
||||
use shadowsocks_service::local::dns::NameServerAddr;
|
||||
|
||||
if let Some(local_dns_addr) = matches.value_of("LOCAL_DNS_ADDR") {
|
||||
let addr = local_dns_addr.parse::<NameServerAddr>().expect("local dns address");
|
||||
local_config.local_dns_addr = Some(addr);
|
||||
}
|
||||
|
||||
if let Some(remote_dns_addr) = matches.value_of("REMOTE_DNS_ADDR") {
|
||||
let addr = remote_dns_addr.parse::<Address>().expect("remote dns address");
|
||||
local_config.remote_dns_addr = Some(addr);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
if protocol != ProtocolType::Dns {
|
||||
// Start a DNS local server binding to DNS_LOCAL_ADDR
|
||||
//
|
||||
// This is a special route only for shadowsocks-android
|
||||
if let Some(dns_relay_addr) = matches.value_of("DNS_LOCAL_ADDR") {
|
||||
let addr = dns_relay_addr.parse::<ServerAddr>().expect("dns relay address");
|
||||
|
||||
let mut local_dns_config = LocalConfig::new(addr, ProtocolType::Dns);
|
||||
|
||||
// The `local_dns_addr` and `remote_dns_addr` are for this DNS server (for compatibility)
|
||||
local_dns_config.local_dns_addr = local_config.local_dns_addr.take();
|
||||
local_dns_config.remote_dns_addr = local_config.remote_dns_addr.take();
|
||||
|
||||
config.local.push(local_dns_config);
|
||||
}
|
||||
}
|
||||
|
||||
config.local.push(local_config);
|
||||
}
|
||||
|
||||
// override the config's mode if UDP_ONLY is set
|
||||
@@ -326,23 +368,6 @@ fn main() {
|
||||
config.ipv6_first = true;
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
if let Some(faddr) = matches.value_of("FORWARD_ADDR") {
|
||||
let addr = faddr.parse::<Address>().expect("forward-addr");
|
||||
config.forward = Some(addr);
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-redir")]
|
||||
{
|
||||
if let Some(tcp_redir) = matches.value_of("TCP_REDIR") {
|
||||
config.tcp_redir = tcp_redir.parse::<RedirType>().expect("TCP redir type");
|
||||
}
|
||||
|
||||
if let Some(udp_redir) = matches.value_of("UDP_REDIR") {
|
||||
config.udp_redir = udp_redir.parse::<RedirType>().expect("UDP redir type");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(udp_timeout) = matches.value_of("UDP_TIMEOUT") {
|
||||
config.udp_timeout = Some(Duration::from_secs(udp_timeout.parse::<u64>().expect("udp-timeout")));
|
||||
}
|
||||
@@ -351,10 +376,6 @@ fn main() {
|
||||
config.udp_max_associations = Some(udp_max_assoc.parse::<usize>().expect("udp-max-associations"));
|
||||
}
|
||||
|
||||
if let Some(udp_bind_addr) = matches.value_of("UDP_BIND_ADDR") {
|
||||
config.udp_bind_addr = Some(udp_bind_addr.parse::<ServerAddr>().expect("udp-bind-addr"));
|
||||
}
|
||||
|
||||
if let Some(bs) = matches.value_of("INBOUND_SEND_BUFFER_SIZE") {
|
||||
config.inbound_send_buffer_size = Some(bs.parse::<u32>().expect("inbound-send-buffer-size"));
|
||||
}
|
||||
@@ -370,7 +391,7 @@ fn main() {
|
||||
|
||||
// DONE READING options
|
||||
|
||||
if config.local_addr.is_none() {
|
||||
if config.local.is_empty() {
|
||||
eprintln!(
|
||||
"missing `local_address`, consider specifying it by --local-addr command line option, \
|
||||
or \"local_address\" and \"local_port\" in configuration file"
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
//! *It should be notice that the extented configuration file is not suitable for the server
|
||||
//! side.*
|
||||
|
||||
use std::{
|
||||
net::{IpAddr, SocketAddr},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
|
||||
use clap::{clap_app, Arg};
|
||||
use futures::future::{self, Either};
|
||||
@@ -22,7 +19,7 @@ use shadowsocks_service::{
|
||||
config::{Config, ConfigType, ManagerConfig, ManagerServerHost, Mode},
|
||||
run_manager,
|
||||
shadowsocks::{
|
||||
config::{ManagerAddr, ServerAddr},
|
||||
config::ManagerAddr,
|
||||
crypto::v1::{available_ciphers, CipherKind},
|
||||
},
|
||||
};
|
||||
@@ -50,7 +47,7 @@ fn main() {
|
||||
the only required fields are \"manager_address\" and \"manager_port\". \
|
||||
Servers defined will be created when process is started.")
|
||||
|
||||
(@arg BIND_ADDR: -b --("bind-addr") +takes_value "Bind address, outbound socket will bind this address")
|
||||
(@arg BIND_ADDR: -b --("bind-addr") +takes_value {validator::validate_ip_addr} "Bind address, outbound socket will bind this address")
|
||||
(@arg SERVER_HOST: -s --("server-host") +takes_value "Host name or IP address of your remote server")
|
||||
|
||||
(@arg NO_DELAY: --("no-delay") !takes_value "Set TCP_NODELAY option for socket")
|
||||
@@ -137,11 +134,7 @@ fn main() {
|
||||
};
|
||||
|
||||
if let Some(bind_addr) = matches.value_of("BIND_ADDR") {
|
||||
let bind_addr = match bind_addr.parse::<IpAddr>() {
|
||||
Ok(ip) => ServerAddr::from(SocketAddr::new(ip, 0)),
|
||||
Err(..) => ServerAddr::from((bind_addr, 0)),
|
||||
};
|
||||
|
||||
let bind_addr = bind_addr.parse::<IpAddr>().expect("bind-addr");
|
||||
config.local_addr = Some(bind_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
//! *It should be notice that the extented configuration file is not suitable for the server
|
||||
//! side.*
|
||||
|
||||
use std::{
|
||||
net::{IpAddr, SocketAddr},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{net::IpAddr, time::Duration};
|
||||
|
||||
use clap::{clap_app, Arg};
|
||||
use futures::future::{self, Either};
|
||||
@@ -48,7 +45,7 @@ fn main() {
|
||||
|
||||
(@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 "Bind address, outbound socket will bind this address")
|
||||
(@arg BIND_ADDR: -b --("bind-addr") +takes_value {validator::validate_ip_addr} "Bind address, outbound socket will bind this address")
|
||||
|
||||
(@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")
|
||||
@@ -175,11 +172,7 @@ fn main() {
|
||||
}
|
||||
|
||||
if let Some(bind_addr) = matches.value_of("BIND_ADDR") {
|
||||
let bind_addr = match bind_addr.parse::<IpAddr>() {
|
||||
Ok(ip) => ServerAddr::from(SocketAddr::new(ip, 0)),
|
||||
Err(..) => ServerAddr::from((bind_addr, 0)),
|
||||
};
|
||||
|
||||
let bind_addr = bind_addr.parse::<IpAddr>().expect("bind-addr");
|
||||
config.local_addr = Some(bind_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shadowsocks-service"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
authors = ["Shadowsocks Contributors"]
|
||||
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
|
||||
repository = "https://github.com/shadowsocks/shadowsocks-rust"
|
||||
@@ -105,7 +105,7 @@ regex = "1.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
json5 = "0.3"
|
||||
|
||||
shadowsocks = { version = "1.9.2", path = "../shadowsocks" }
|
||||
shadowsocks = { version = "1.10.0", path = "../shadowsocks" }
|
||||
|
||||
strum = { version = "0.20", optional = true }
|
||||
strum_macros = { version = "0.20", optional = true }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
57
crates/shadowsocks-service/src/dns/mod.rs
Normal file
57
crates/shadowsocks-service/src/dns/mod.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
//! DNS resolvers
|
||||
|
||||
use shadowsocks::{dns_resolver::DnsResolver, net::ConnectOpts};
|
||||
|
||||
use crate::config::DnsConfig;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub async fn build_dns_resolver(dns: DnsConfig, ipv6_first: bool, connect_opts: &ConnectOpts) -> Option<DnsResolver> {
|
||||
match dns {
|
||||
DnsConfig::System => {
|
||||
#[cfg(feature = "trust-dns")]
|
||||
if crate::hint_support_default_system_resolver() {
|
||||
use log::warn;
|
||||
|
||||
return match DnsResolver::trust_dns_system_resolver(ipv6_first).await {
|
||||
Ok(r) => Some(r),
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"initialize trust-dns DNS system resolver failed, fallback to default system resolver, error: {}",
|
||||
err
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
#[cfg(feature = "trust-dns")]
|
||||
DnsConfig::TrustDns(dns) => match DnsResolver::trust_dns_resolver(dns, ipv6_first).await {
|
||||
Ok(r) => Some(r),
|
||||
Err(err) => {
|
||||
use log::warn;
|
||||
|
||||
warn!(
|
||||
"initialize trust-dns DNS resolver failed, fallback to default system resolver, error: {}",
|
||||
err
|
||||
);
|
||||
None
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "local-dns")]
|
||||
DnsConfig::LocalDns(ns) => {
|
||||
use crate::{config::Mode, local::dns::dns_resolver::DnsResolver as LocalDnsResolver};
|
||||
use log::trace;
|
||||
|
||||
trace!("initializing direct DNS resolver for {}", ns);
|
||||
|
||||
let mut resolver = LocalDnsResolver::new(ns);
|
||||
resolver.set_mode(Mode::TcpAndUdp);
|
||||
resolver.set_ipv6_first(ipv6_first);
|
||||
resolver.set_connect_opts(connect_opts.clone());
|
||||
|
||||
Some(DnsResolver::custom_resolver(resolver))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,7 @@ pub use shadowsocks;
|
||||
|
||||
pub mod acl;
|
||||
pub mod config;
|
||||
mod dns;
|
||||
#[cfg(feature = "local")]
|
||||
pub mod local;
|
||||
#[cfg(feature = "manager")]
|
||||
|
||||
@@ -19,6 +19,7 @@ use shadowsocks::{
|
||||
lookup_then,
|
||||
net::{TcpListener, UdpSocket as ShadowUdpSocket},
|
||||
relay::{udprelay::MAXIMUM_UDP_PAYLOAD_SIZE, Address},
|
||||
ServerAddr,
|
||||
};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
@@ -32,7 +33,7 @@ use trust_dns_resolver::proto::{
|
||||
|
||||
use crate::{
|
||||
acl::AccessControl,
|
||||
config::{ClientConfig, Mode},
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
@@ -69,7 +70,7 @@ impl Dns {
|
||||
}
|
||||
|
||||
/// Run server
|
||||
pub async fn run(self, bind_addr: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, bind_addr: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let client = Arc::new(DnsClient::new(self.context.clone(), balancer, self.mode));
|
||||
|
||||
let tcp_fut = self.run_tcp_server(bind_addr, client.clone());
|
||||
@@ -83,12 +84,10 @@ impl Dns {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_tcp_server(&self, bind_addr: &ClientConfig, client: Arc<DnsClient>) -> io::Result<()> {
|
||||
async fn run_tcp_server(&self, bind_addr: &ServerAddr, client: Arc<DnsClient>) -> io::Result<()> {
|
||||
let listener = match *bind_addr {
|
||||
ClientConfig::SocketAddr(ref saddr) => {
|
||||
TcpListener::bind_with_opts(saddr, self.context.accept_opts()).await?
|
||||
}
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => TcpListener::bind_with_opts(saddr, self.context.accept_opts()).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(self.context.context_ref(), dname, port, |addr| {
|
||||
TcpListener::bind_with_opts(&addr, self.context.accept_opts()).await
|
||||
})?
|
||||
@@ -190,10 +189,10 @@ impl Dns {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_udp_server(&self, bind_addr: &ClientConfig, client: Arc<DnsClient>) -> io::Result<()> {
|
||||
async fn run_udp_server(&self, bind_addr: &ServerAddr, client: Arc<DnsClient>) -> io::Result<()> {
|
||||
let socket = match *bind_addr {
|
||||
ClientConfig::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(&self.context.context_ref(), dname, port, |addr| {
|
||||
ShadowUdpSocket::listen(&addr).await
|
||||
})?
|
||||
|
||||
@@ -17,10 +17,7 @@ use hyper::{
|
||||
use log::{error, info};
|
||||
use shadowsocks::{config::ServerAddr, lookup_then};
|
||||
|
||||
use crate::{
|
||||
config::ClientConfig,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
use crate::local::{context::ServiceContext, loadbalancing::PingBalancer};
|
||||
|
||||
use super::{client_cache::ProxyClientCache, connector::BypassConnector, dispatcher::HttpDispatcher};
|
||||
|
||||
@@ -47,7 +44,7 @@ impl Http {
|
||||
}
|
||||
|
||||
/// Run server
|
||||
pub async fn run(self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let bypass_client = Client::builder().build::<_, Body>(BypassConnector::new(self.context.clone()));
|
||||
|
||||
let context = self.context.clone();
|
||||
|
||||
@@ -4,18 +4,23 @@
|
||||
use std::path::PathBuf;
|
||||
use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use futures::{
|
||||
future,
|
||||
stream::{FuturesUnordered, StreamExt},
|
||||
FutureExt,
|
||||
};
|
||||
use log::{error, trace, warn};
|
||||
#[cfg(any(feature = "local-dns", feature = "trust-dns"))]
|
||||
use shadowsocks::dns_resolver::DnsResolver;
|
||||
use shadowsocks::{
|
||||
net::{AcceptOpts, ConnectOpts},
|
||||
plugin::{Plugin, PluginMode},
|
||||
};
|
||||
|
||||
use crate::config::{Config, ConfigType, ProtocolType};
|
||||
#[cfg(feature = "local-flow-stat")]
|
||||
use crate::net::FlowStat;
|
||||
use crate::{
|
||||
config::{Config, ConfigType, ProtocolType},
|
||||
dns::build_dns_resolver,
|
||||
};
|
||||
|
||||
use self::{
|
||||
context::ServiceContext,
|
||||
@@ -38,7 +43,7 @@ pub mod utils;
|
||||
|
||||
/// Starts a shadowsocks local server
|
||||
pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
assert!(config.config_type == ConfigType::Local && config.local_addr.is_some());
|
||||
assert!(config.config_type == ConfigType::Local && !config.local.is_empty());
|
||||
assert!(config.server.len() > 0);
|
||||
|
||||
trace!("{:?}", config);
|
||||
@@ -83,101 +88,34 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;
|
||||
accept_opts.tcp.nodelay = config.no_delay;
|
||||
|
||||
// #[cfg(all(feature = "local-dns", feature = "trust-dns"))]
|
||||
// if let Some(socket_addr) = config.local_dns_addr {
|
||||
// use trust_dns_resolver::config::{NameServerConfig, Protocol, ResolverConfig};
|
||||
//
|
||||
// trace!("initializing direct DNS resolver for {}", socket_addr);
|
||||
//
|
||||
// let mut resolver_config = ResolverConfig::new();
|
||||
//
|
||||
// resolver_config.add_name_server(NameServerConfig {
|
||||
// socket_addr,
|
||||
// protocol: Protocol::Udp,
|
||||
// tls_dns_name: None,
|
||||
// trust_nx_responses: false,
|
||||
// #[cfg(feature = "dns-over-tls")]
|
||||
// tls_config: None,
|
||||
// });
|
||||
// resolver_config.add_name_server(NameServerConfig {
|
||||
// socket_addr,
|
||||
// protocol: Protocol::Tcp,
|
||||
// tls_dns_name: None,
|
||||
// trust_nx_responses: false,
|
||||
// #[cfg(feature = "dns-over-tls")]
|
||||
// tls_config: None,
|
||||
// });
|
||||
//
|
||||
// match DnsResolver::trust_dns_resolver(Some(resolver_config), config.ipv6_first).await {
|
||||
// Ok(r) => {
|
||||
// context.set_dns_resolver(Arc::new(r));
|
||||
// }
|
||||
// Err(err) => {
|
||||
// error!(
|
||||
// "initialize DNS resolver failed, nameserver: {}, error: {}",
|
||||
// socket_addr, err
|
||||
// );
|
||||
// return Err(err);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(feature = "local-dns")]
|
||||
if let Some(ref ns) = config.local_dns_addr {
|
||||
use crate::{config::Mode, local::dns::dns_resolver::DnsResolver as LocalDnsResolver};
|
||||
|
||||
trace!("initializing direct DNS resolver for {}", ns);
|
||||
|
||||
let mut resolver = LocalDnsResolver::new(ns.clone());
|
||||
resolver.set_mode(Mode::TcpAndUdp);
|
||||
resolver.set_ipv6_first(config.ipv6_first);
|
||||
resolver.set_connect_opts(context.connect_opts_ref().clone());
|
||||
context.set_dns_resolver(Arc::new(DnsResolver::custom_resolver(resolver)));
|
||||
}
|
||||
|
||||
#[cfg(feature = "trust-dns")]
|
||||
if context.dns_resolver().is_system_resolver() {
|
||||
if config.dns.is_some() || crate::hint_support_default_system_resolver() {
|
||||
let r = match config.dns {
|
||||
None => DnsResolver::trust_dns_system_resolver(config.ipv6_first).await,
|
||||
Some(dns) => DnsResolver::trust_dns_resolver(dns, config.ipv6_first).await,
|
||||
};
|
||||
|
||||
match r {
|
||||
Ok(r) => {
|
||||
context.set_dns_resolver(Arc::new(r));
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"initialize DNS resolver failed, fallback to system resolver, error: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(resolver) = build_dns_resolver(config.dns, config.ipv6_first, context.connect_opts_ref()).await {
|
||||
context.set_dns_resolver(Arc::new(resolver));
|
||||
}
|
||||
|
||||
if let Some(acl) = config.acl {
|
||||
context.set_acl(acl);
|
||||
}
|
||||
|
||||
let client_config = config.local_addr.expect("local server requires local address");
|
||||
assert!(!config.local.is_empty(), "no valid local server configuration");
|
||||
|
||||
let context = Arc::new(context);
|
||||
|
||||
let mut vfut = Vec::new();
|
||||
let vfut = FuturesUnordered::new();
|
||||
|
||||
let enable_tcp = match config.local_protocol {
|
||||
ProtocolType::Socks => config.mode.enable_tcp(),
|
||||
// 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(),
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
ProtocolType::Tunnel => config.mode.enable_tcp(),
|
||||
ProtocolType::Tunnel => mode.enable_tcp(),
|
||||
#[cfg(feature = "local-http")]
|
||||
ProtocolType::Http => true,
|
||||
#[cfg(feature = "local-redir")]
|
||||
ProtocolType::Redir => config.mode.enable_tcp(),
|
||||
ProtocolType::Redir => mode.enable_tcp(),
|
||||
#[cfg(feature = "local-dns")]
|
||||
ProtocolType::Dns => config.mode.enable_tcp(),
|
||||
};
|
||||
ProtocolType::Dns => mode.enable_tcp(),
|
||||
});
|
||||
|
||||
if enable_tcp {
|
||||
// Start plugins for TCP proxies
|
||||
@@ -241,20 +179,20 @@ 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;
|
||||
// #[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 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 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);
|
||||
// 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());
|
||||
}
|
||||
// vfut.push(server.run(bind_addr, balancer.clone()).boxed());
|
||||
// }
|
||||
|
||||
#[cfg(feature = "local-flow-stat")]
|
||||
if let Some(stat_path) = config.stat_path {
|
||||
@@ -264,11 +202,15 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
vfut.push(report_fut.boxed());
|
||||
}
|
||||
|
||||
match config.local_protocol {
|
||||
for local_config in config.local {
|
||||
let balancer = balancer.clone();
|
||||
let client_addr = local_config.addr;
|
||||
|
||||
match local_config.protocol {
|
||||
ProtocolType::Socks => {
|
||||
use self::socks::Socks;
|
||||
|
||||
let mut server = Socks::with_context(context);
|
||||
let mut server = Socks::with_context(context.clone());
|
||||
server.set_mode(config.mode);
|
||||
|
||||
if let Some(c) = config.udp_max_associations {
|
||||
@@ -277,22 +219,22 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
if let Some(d) = config.udp_timeout {
|
||||
server.set_udp_expiry_duration(d);
|
||||
}
|
||||
if let Some(b) = config.udp_bind_addr {
|
||||
server.set_udp_bind_addr(b);
|
||||
if let Some(b) = local_config.udp_addr {
|
||||
server.set_udp_bind_addr(b.clone());
|
||||
}
|
||||
if config.no_delay {
|
||||
server.set_nodelay(true);
|
||||
}
|
||||
|
||||
vfut.push(server.run(&client_config, balancer).boxed());
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-tunnel")]
|
||||
ProtocolType::Tunnel => {
|
||||
use self::tunnel::Tunnel;
|
||||
|
||||
let forward_addr = config.forward.expect("tunnel requires forward address");
|
||||
let forward_addr = local_config.forward_addr.expect("tunnel requires forward address");
|
||||
|
||||
let mut server = Tunnel::with_context(context, forward_addr);
|
||||
let mut server = Tunnel::with_context(context.clone(), forward_addr.clone());
|
||||
|
||||
if let Some(c) = config.udp_max_associations {
|
||||
server.set_udp_capacity(c);
|
||||
@@ -305,20 +247,20 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
server.set_nodelay(true);
|
||||
}
|
||||
|
||||
vfut.push(server.run(&client_config, balancer).boxed());
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-http")]
|
||||
ProtocolType::Http => {
|
||||
use self::http::Http;
|
||||
|
||||
let server = Http::with_context(context);
|
||||
vfut.push(server.run(&client_config, balancer).boxed());
|
||||
let server = Http::with_context(context.clone());
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-redir")]
|
||||
ProtocolType::Redir => {
|
||||
use self::redir::Redir;
|
||||
|
||||
let mut server = Redir::with_context(context);
|
||||
let mut server = Redir::with_context(context.clone());
|
||||
if let Some(c) = config.udp_max_associations {
|
||||
server.set_udp_capacity(c);
|
||||
}
|
||||
@@ -329,17 +271,31 @@ pub async fn run(mut config: Config) -> io::Result<()> {
|
||||
if config.no_delay {
|
||||
server.set_nodelay(true);
|
||||
}
|
||||
server.set_tcp_redir(config.tcp_redir);
|
||||
server.set_udp_redir(config.udp_redir);
|
||||
server.set_tcp_redir(local_config.tcp_redir);
|
||||
server.set_udp_redir(local_config.udp_redir);
|
||||
|
||||
vfut.push(server.run(&client_config, balancer).boxed());
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
#[cfg(feature = "local-dns")]
|
||||
ProtocolType::Dns => {}
|
||||
ProtocolType::Dns => {
|
||||
use self::dns::Dns;
|
||||
|
||||
let mut server = {
|
||||
let local_addr = local_config.local_dns_addr.expect("missing local_dns_addr");
|
||||
let remote_addr = local_config.remote_dns_addr.expect("missing remote_dns_addr");
|
||||
|
||||
Dns::with_context(context.clone(), local_addr.clone(), remote_addr.clone())
|
||||
};
|
||||
server.set_mode(config.mode);
|
||||
|
||||
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (res, ..) = future::select_all(vfut).await;
|
||||
res
|
||||
// let (res, ..) = future::select_all(vfut).await;
|
||||
let (res, _) = vfut.into_future().await;
|
||||
res.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-flow-stat")]
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use shadowsocks::ServerAddr;
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, Mode, RedirType},
|
||||
config::{Mode, RedirType},
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
@@ -73,7 +74,7 @@ impl Redir {
|
||||
}
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
@@ -88,7 +89,7 @@ impl Redir {
|
||||
res
|
||||
}
|
||||
|
||||
async fn run_tcp_tunnel(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_tcp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
run_tcp_redir(
|
||||
self.context.clone(),
|
||||
client_config,
|
||||
@@ -99,7 +100,7 @@ impl Redir {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn run_udp_tunnel(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_udp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let server = UdpRedir::new(
|
||||
self.context.clone(),
|
||||
self.udp_redir,
|
||||
|
||||
@@ -8,14 +8,14 @@ use std::{
|
||||
};
|
||||
|
||||
use log::{debug, error, info, trace};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, relay::socks5::Address};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, relay::socks5::Address, ServerAddr};
|
||||
use tokio::{
|
||||
net::{TcpListener, TcpStream},
|
||||
time,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, RedirType},
|
||||
config::RedirType,
|
||||
local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
@@ -111,14 +111,14 @@ async fn handle_redir_client(
|
||||
|
||||
pub async fn run_tcp_redir(
|
||||
context: Arc<ServiceContext>,
|
||||
client_config: &ClientConfig,
|
||||
client_config: &ServerAddr,
|
||||
balancer: PingBalancer,
|
||||
redir_ty: RedirType,
|
||||
nodelay: bool,
|
||||
) -> io::Result<()> {
|
||||
let listener = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => TcpListener::bind_redir(redir_ty, *saddr).await?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => TcpListener::bind_redir(redir_ty, *saddr).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(context.context_ref(), dname, port, |addr| {
|
||||
TcpListener::bind_redir(redir_ty, addr).await
|
||||
})?
|
||||
|
||||
@@ -12,10 +12,11 @@ use log::{error, info, trace, warn};
|
||||
use shadowsocks::{
|
||||
lookup_then,
|
||||
relay::{socks5::Address, udprelay::MAXIMUM_UDP_PAYLOAD_SIZE},
|
||||
ServerAddr,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, RedirType},
|
||||
config::RedirType,
|
||||
local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
@@ -112,10 +113,10 @@ impl UdpRedir {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let listener = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => UdpRedirSocket::listen(self.redir_ty, *saddr)?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => UdpRedirSocket::listen(self.redir_ty, *saddr)?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(self.context.context_ref(), dname, port, |addr| {
|
||||
UdpRedirSocket::listen(self.redir_ty, addr)
|
||||
})?
|
||||
|
||||
@@ -4,11 +4,11 @@ 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};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, ServerAddr};
|
||||
use tokio::{net::TcpStream, time};
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, Mode},
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct Socks {
|
||||
mode: Mode,
|
||||
udp_expiry_duration: Option<Duration>,
|
||||
udp_capacity: Option<usize>,
|
||||
udp_bind_addr: Option<ClientConfig>,
|
||||
udp_bind_addr: Option<ServerAddr>,
|
||||
nodelay: bool,
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ impl Socks {
|
||||
///
|
||||
/// * If `mode` is `tcp_only`, then it will still return this address for `UDP_ASSOCIATE` command
|
||||
/// * Otherwise, UDP relay will bind to this address
|
||||
pub fn set_udp_bind_addr(&mut self, a: ClientConfig) {
|
||||
pub fn set_udp_bind_addr(&mut self, a: ServerAddr) {
|
||||
self.udp_bind_addr = Some(a);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ impl Socks {
|
||||
}
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
@@ -96,12 +96,12 @@ impl Socks {
|
||||
res
|
||||
}
|
||||
|
||||
async fn run_tcp_server(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_tcp_server(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let listener = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => {
|
||||
ShadowTcpListener::bind_with_opts(saddr, self.context.accept_opts()).await?
|
||||
}
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(self.context.context_ref(), dname, port, |addr| {
|
||||
ShadowTcpListener::bind_with_opts(&addr, self.context.accept_opts()).await
|
||||
})?
|
||||
@@ -157,7 +157,7 @@ impl Socks {
|
||||
#[cfg(feature = "local-socks4")]
|
||||
async fn handle_tcp_client(
|
||||
context: Arc<ServiceContext>,
|
||||
udp_bind_addr: Option<Arc<ClientConfig>>,
|
||||
udp_bind_addr: Option<Arc<ServerAddr>>,
|
||||
stream: TcpStream,
|
||||
balancer: PingBalancer,
|
||||
peer_addr: SocketAddr,
|
||||
@@ -194,7 +194,7 @@ impl Socks {
|
||||
#[cfg(not(feature = "local-socks4"))]
|
||||
async fn handle_tcp_client(
|
||||
context: Arc<ServiceContext>,
|
||||
udp_bind_addr: Option<Arc<ClientConfig>>,
|
||||
udp_bind_addr: Option<Arc<ServerAddr>>,
|
||||
stream: TcpStream,
|
||||
balancer: PingBalancer,
|
||||
peer_addr: SocketAddr,
|
||||
@@ -205,7 +205,7 @@ impl Socks {
|
||||
handler.handle_socks5_client(stream, peer_addr).await
|
||||
}
|
||||
|
||||
async fn run_udp_server(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_udp_server(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let server = Socks5UdpServer::new(self.context.clone(), self.udp_expiry_duration, self.udp_capacity);
|
||||
|
||||
let udp_bind_addr = self.udp_bind_addr.as_ref().unwrap_or(client_config);
|
||||
|
||||
@@ -7,7 +7,8 @@ use std::{
|
||||
};
|
||||
|
||||
use log::{debug, error, trace, warn};
|
||||
use shadowsocks::relay::socks5::{
|
||||
use shadowsocks::{
|
||||
relay::socks5::{
|
||||
self,
|
||||
Address,
|
||||
Command,
|
||||
@@ -16,11 +17,13 @@ use shadowsocks::relay::socks5::{
|
||||
Reply,
|
||||
TcpRequestHeader,
|
||||
TcpResponseHeader,
|
||||
},
|
||||
ServerAddr,
|
||||
};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, Mode},
|
||||
config::Mode,
|
||||
local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
@@ -32,7 +35,7 @@ use crate::{
|
||||
|
||||
pub struct Socks5TcpHandler {
|
||||
context: Arc<ServiceContext>,
|
||||
udp_bind_addr: Option<Arc<ClientConfig>>,
|
||||
udp_bind_addr: Option<Arc<ServerAddr>>,
|
||||
nodelay: bool,
|
||||
balancer: PingBalancer,
|
||||
mode: Mode,
|
||||
@@ -41,7 +44,7 @@ pub struct Socks5TcpHandler {
|
||||
impl Socks5TcpHandler {
|
||||
pub fn new(
|
||||
context: Arc<ServiceContext>,
|
||||
udp_bind_addr: Option<Arc<ClientConfig>>,
|
||||
udp_bind_addr: Option<Arc<ServerAddr>>,
|
||||
nodelay: bool,
|
||||
balancer: PingBalancer,
|
||||
mode: Mode,
|
||||
|
||||
@@ -18,16 +18,14 @@ use shadowsocks::{
|
||||
socks5::{Address, UdpAssociateHeader},
|
||||
udprelay::MAXIMUM_UDP_PAYLOAD_SIZE,
|
||||
},
|
||||
ServerAddr,
|
||||
};
|
||||
use tokio::{net::UdpSocket, time};
|
||||
|
||||
use crate::{
|
||||
config::ClientConfig,
|
||||
local::{
|
||||
use crate::local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
net::{UdpAssociationManager, UdpInboundWrite},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -69,10 +67,10 @@ impl Socks5UdpServer {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let socket = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(&self.context.context_ref(), dname, port, |addr| {
|
||||
ShadowUdpSocket::listen(&addr).await
|
||||
})?
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use shadowsocks::relay::socks5::Address;
|
||||
use shadowsocks::{relay::socks5::Address, ServerAddr};
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, Mode},
|
||||
config::Mode,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
};
|
||||
|
||||
@@ -62,7 +62,7 @@ impl Tunnel {
|
||||
}
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
@@ -77,7 +77,7 @@ impl Tunnel {
|
||||
res
|
||||
}
|
||||
|
||||
async fn run_tcp_tunnel(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_tcp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
run_tcp_tunnel(
|
||||
self.context.clone(),
|
||||
client_config,
|
||||
@@ -88,7 +88,7 @@ impl Tunnel {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn run_udp_tunnel(&self, client_config: &ClientConfig, balancer: PingBalancer) -> io::Result<()> {
|
||||
async fn run_udp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
|
||||
let mut server = UdpTunnel::new(self.context.clone(), self.udp_expiry_duration, self.udp_capacity);
|
||||
server.run(client_config, balancer, &self.forward_addr).await
|
||||
}
|
||||
|
||||
@@ -3,29 +3,26 @@
|
||||
use std::{io, net::SocketAddr, sync::Arc, time::Duration};
|
||||
|
||||
use log::{error, info, trace};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, relay::socks5::Address};
|
||||
use shadowsocks::{lookup_then, net::TcpListener as ShadowTcpListener, relay::socks5::Address, ServerAddr};
|
||||
use tokio::{net::TcpStream, time};
|
||||
|
||||
use crate::{
|
||||
config::ClientConfig,
|
||||
local::{
|
||||
use crate::local::{
|
||||
context::ServiceContext,
|
||||
loadbalancing::PingBalancer,
|
||||
net::AutoProxyClientStream,
|
||||
utils::establish_tcp_tunnel,
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn run_tcp_tunnel(
|
||||
context: Arc<ServiceContext>,
|
||||
client_config: &ClientConfig,
|
||||
client_config: &ServerAddr,
|
||||
balancer: PingBalancer,
|
||||
forward_addr: &Address,
|
||||
nodelay: bool,
|
||||
) -> io::Result<()> {
|
||||
let listener = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => ShadowTcpListener::bind_with_opts(saddr, context.accept_opts()).await?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => ShadowTcpListener::bind_with_opts(saddr, context.accept_opts()).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(context.context_ref(), dname, port, |addr| {
|
||||
ShadowTcpListener::bind_with_opts(&addr, context.accept_opts()).await
|
||||
})?
|
||||
|
||||
@@ -14,6 +14,7 @@ use shadowsocks::{
|
||||
socks5::Address,
|
||||
udprelay::{ProxySocket, MAXIMUM_UDP_PAYLOAD_SIZE},
|
||||
},
|
||||
ServerAddr,
|
||||
};
|
||||
use spin::Mutex as SpinMutex;
|
||||
use tokio::{
|
||||
@@ -23,7 +24,6 @@ use tokio::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::ClientConfig,
|
||||
local::{context::ServiceContext, loadbalancing::PingBalancer},
|
||||
net::MonProxySocket,
|
||||
};
|
||||
@@ -71,13 +71,13 @@ impl UdpTunnel {
|
||||
|
||||
pub async fn run(
|
||||
&mut self,
|
||||
client_config: &ClientConfig,
|
||||
client_config: &ServerAddr,
|
||||
balancer: PingBalancer,
|
||||
forward_addr: &Address,
|
||||
) -> io::Result<()> {
|
||||
let socket = match *client_config {
|
||||
ClientConfig::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ClientConfig::DomainName(ref dname, port) => {
|
||||
ServerAddr::SocketAddr(ref saddr) => ShadowUdpSocket::listen(&saddr).await?,
|
||||
ServerAddr::DomainName(ref dname, port) => {
|
||||
lookup_then!(&self.context.context_ref(), dname, port, |addr| {
|
||||
ShadowUdpSocket::listen(&addr).await
|
||||
})?
|
||||
|
||||
@@ -2,17 +2,15 @@
|
||||
//!
|
||||
//! Service for managing multiple relay servers. [Manage Multiple Users](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users)
|
||||
|
||||
use std::io::{self, ErrorKind};
|
||||
#[cfg(feature = "trust-dns")]
|
||||
use std::sync::Arc;
|
||||
use std::{io, sync::Arc};
|
||||
|
||||
use log::{trace, warn};
|
||||
use shadowsocks::{
|
||||
config::ServerAddr,
|
||||
net::{AcceptOpts, ConnectOpts},
|
||||
};
|
||||
use shadowsocks::net::{AcceptOpts, ConnectOpts};
|
||||
|
||||
use crate::config::{Config, ConfigType};
|
||||
use crate::{
|
||||
config::{Config, ConfigType},
|
||||
dns::build_dns_resolver,
|
||||
};
|
||||
|
||||
pub use self::server::Manager;
|
||||
|
||||
@@ -35,28 +33,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);
|
||||
|
||||
#[cfg(feature = "trust-dns")]
|
||||
if config.dns.is_some() || crate::hint_support_default_system_resolver() {
|
||||
use shadowsocks::dns_resolver::DnsResolver;
|
||||
|
||||
let r = match config.dns {
|
||||
None => DnsResolver::trust_dns_system_resolver(config.ipv6_first).await,
|
||||
Some(dns) => DnsResolver::trust_dns_resolver(dns, config.ipv6_first).await,
|
||||
};
|
||||
|
||||
match r {
|
||||
Ok(r) => {
|
||||
manager.set_dns_resolver(Arc::new(r));
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"initialize DNS resolver failed, fallback to system resolver, error: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut connect_opts = ConnectOpts {
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fwmark: config.outbound_fwmark,
|
||||
@@ -64,16 +40,7 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
#[cfg(target_os = "android")]
|
||||
vpn_protect_path: config.outbound_vpn_protect_path,
|
||||
|
||||
bind_local_addr: match config.local_addr {
|
||||
None => None,
|
||||
Some(ServerAddr::SocketAddr(sa)) => Some(sa.ip()),
|
||||
Some(ServerAddr::DomainName(..)) => {
|
||||
return Err(io::Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"local_addr must be a SocketAddr",
|
||||
));
|
||||
}
|
||||
},
|
||||
bind_local_addr: config.local_addr,
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
|
||||
bind_interface: config.outbound_bind_interface,
|
||||
@@ -90,6 +57,10 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;
|
||||
accept_opts.tcp.nodelay = config.no_delay;
|
||||
|
||||
if let Some(resolver) = build_dns_resolver(config.dns, config.ipv6_first, &connect_opts).await {
|
||||
manager.set_dns_resolver(Arc::new(resolver));
|
||||
}
|
||||
|
||||
manager.set_connect_opts(connect_opts);
|
||||
manager.set_accept_opts(accept_opts);
|
||||
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
//! Shadowsocks server
|
||||
|
||||
use std::{
|
||||
io::{self, ErrorKind},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{io, sync::Arc};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use log::{trace, warn};
|
||||
#[cfg(feature = "trust-dns")]
|
||||
use shadowsocks::dns_resolver::DnsResolver;
|
||||
use shadowsocks::{
|
||||
config::ServerAddr,
|
||||
net::{AcceptOpts, ConnectOpts},
|
||||
};
|
||||
use shadowsocks::net::{AcceptOpts, ConnectOpts};
|
||||
|
||||
use crate::config::{Config, ConfigType};
|
||||
use crate::{
|
||||
config::{Config, ConfigType},
|
||||
dns::build_dns_resolver,
|
||||
};
|
||||
|
||||
pub use self::server::Server;
|
||||
|
||||
@@ -56,16 +51,7 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
#[cfg(target_os = "android")]
|
||||
vpn_protect_path: config.outbound_vpn_protect_path,
|
||||
|
||||
bind_local_addr: match config.local_addr {
|
||||
None => None,
|
||||
Some(ServerAddr::SocketAddr(sa)) => Some(sa.ip()),
|
||||
Some(ServerAddr::DomainName(..)) => {
|
||||
return Err(io::Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"local_addr must be a SocketAddr",
|
||||
));
|
||||
}
|
||||
},
|
||||
bind_local_addr: config.local_addr,
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios"))]
|
||||
bind_interface: config.outbound_bind_interface,
|
||||
@@ -82,25 +68,9 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;
|
||||
accept_opts.tcp.nodelay = config.no_delay;
|
||||
|
||||
#[cfg(feature = "trust-dns")]
|
||||
let resolver = if config.dns.is_some() || crate::hint_support_default_system_resolver() {
|
||||
let r = match config.dns {
|
||||
None => DnsResolver::trust_dns_system_resolver(config.ipv6_first).await,
|
||||
Some(dns) => DnsResolver::trust_dns_resolver(dns, config.ipv6_first).await,
|
||||
};
|
||||
|
||||
match r {
|
||||
Ok(r) => Some(Arc::new(r)),
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"initialize DNS resolver failed, fallback to system resolver, error: {}",
|
||||
err
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
let resolver = match build_dns_resolver(config.dns, config.ipv6_first, &connect_opts).await {
|
||||
Some(resolver) => Some(Arc::new(resolver)),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let acl = config.acl.map(Arc::new);
|
||||
@@ -108,7 +78,6 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
for svr_cfg in config.server {
|
||||
let mut server = Server::new(svr_cfg);
|
||||
|
||||
#[cfg(feature = "trust-dns")]
|
||||
if let Some(ref r) = resolver {
|
||||
server.set_dns_resolver(r.clone());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use futures::{future, FutureExt};
|
||||
use futures::{stream::FuturesUnordered, FutureExt, StreamExt};
|
||||
use log::{error, trace};
|
||||
use shadowsocks::{
|
||||
config::{ManagerAddr, ServerConfig},
|
||||
@@ -112,7 +112,7 @@ impl Server {
|
||||
|
||||
/// Start serving
|
||||
pub async fn run(mut self) -> io::Result<()> {
|
||||
let mut vfut = Vec::new();
|
||||
let vfut = FuturesUnordered::new();
|
||||
|
||||
if self.mode.enable_tcp() {
|
||||
if let Some(plugin_cfg) = self.svr_cfg.plugin() {
|
||||
@@ -149,7 +149,10 @@ impl Server {
|
||||
vfut.push(manager_fut);
|
||||
}
|
||||
|
||||
let _ = future::select_all(vfut).await;
|
||||
let (res, _) = vfut.into_future().await;
|
||||
if let Some(Err(err)) = res {
|
||||
error!("servers exited with error: {}", err);
|
||||
}
|
||||
|
||||
let err = io::Error::new(ErrorKind::Other, "server exited unexpectly");
|
||||
Err(err)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "shadowsocks"
|
||||
version = "1.9.2"
|
||||
version = "1.10.0"
|
||||
authors = ["Shadowsocks Contributors"]
|
||||
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
|
||||
repository = "https://github.com/shadowsocks/shadowsocks-rust"
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
{
|
||||
"locals": [
|
||||
{
|
||||
"local_address": "127.0.0.1",
|
||||
"local_port": 1080
|
||||
},
|
||||
{
|
||||
"local_address": "127.0.0.1",
|
||||
"local_port": 3128,
|
||||
"protocol": "http"
|
||||
},
|
||||
{
|
||||
"local_address": "127.0.0.1",
|
||||
"local_port": 53,
|
||||
"protocol": "tunnel",
|
||||
"forward_address": "8.8.8.8",
|
||||
"forward_port": 53
|
||||
}
|
||||
],
|
||||
"servers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 8388,
|
||||
"password": "password-svr1",
|
||||
"method": "bf-cfb"
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 8384,
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8384,
|
||||
"password": "password-svr2",
|
||||
"method": "aes-256-cfb"
|
||||
"method": "chacha20-ietf-poly1305"
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 8385,
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8385,
|
||||
"password": "password-svr3",
|
||||
"method": "rc4-md5"
|
||||
"method": "aes-128-gcm"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
16
tests/dns.rs
16
tests/dns.rs
@@ -10,7 +10,7 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, ProtocolType},
|
||||
config::{Config, ConfigType},
|
||||
run_local,
|
||||
run_server,
|
||||
};
|
||||
@@ -19,10 +19,17 @@ use shadowsocks_service::{
|
||||
async fn dns_relay() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut local_config = Config::load_from_str(
|
||||
let local_config = Config::load_from_str(
|
||||
r#"{
|
||||
"local_port": 6110,
|
||||
"locals": [
|
||||
{
|
||||
"local_address": "127.0.0.1",
|
||||
"local_port": 6110,
|
||||
"protocol": "dns",
|
||||
"local_dns_address": "114.114.114.114",
|
||||
"remote_dns_address": "8.8.8.8"
|
||||
}
|
||||
],
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 6120,
|
||||
"password": "password",
|
||||
@@ -31,9 +38,6 @@ async fn dns_relay() {
|
||||
ConfigType::Local,
|
||||
)
|
||||
.unwrap();
|
||||
local_config.local_protocol = ProtocolType::Dns;
|
||||
local_config.local_dns_addr = Some("114.114.114.114:53".parse().unwrap());
|
||||
local_config.remote_dns_addr = Some("8.8.8.8:53".parse().unwrap());
|
||||
|
||||
let server_config = Config::load_from_str(
|
||||
r#"{
|
||||
|
||||
@@ -9,7 +9,7 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, ProtocolType},
|
||||
config::{Config, ConfigType},
|
||||
run_local,
|
||||
run_server,
|
||||
};
|
||||
@@ -18,10 +18,15 @@ use shadowsocks_service::{
|
||||
async fn http_proxy() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut local_config = Config::load_from_str(
|
||||
let local_config = Config::load_from_str(
|
||||
r#"{
|
||||
"locals": [
|
||||
{
|
||||
"local_port": 5110,
|
||||
"local_address": "127.0.0.1",
|
||||
"protocol": "http"
|
||||
}
|
||||
],
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 5120,
|
||||
"password": "password",
|
||||
@@ -30,7 +35,6 @@ async fn http_proxy() {
|
||||
ConfigType::Local,
|
||||
)
|
||||
.unwrap();
|
||||
local_config.local_protocol = ProtocolType::Http;
|
||||
|
||||
let server_config = Config::load_from_str(
|
||||
r#"{
|
||||
|
||||
@@ -11,7 +11,7 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, ProtocolType},
|
||||
local::socks::client::Socks4TcpClient,
|
||||
run_local,
|
||||
run_server,
|
||||
@@ -45,9 +45,8 @@ impl Socks4TestServer {
|
||||
},
|
||||
cli_config: {
|
||||
let mut cfg = Config::new(ConfigType::Local);
|
||||
cfg.local_addr = Some(ServerAddr::from(local_addr));
|
||||
cfg.local = vec![LocalConfig::new(ServerAddr::from(local_addr), ProtocolType::Socks)];
|
||||
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
|
||||
cfg.local_protocol = ProtocolType::Socks;
|
||||
cfg
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
local::socks::client::socks5::Socks5TcpClient,
|
||||
run_local,
|
||||
run_server,
|
||||
@@ -47,10 +47,9 @@ impl Socks5TestServer {
|
||||
},
|
||||
cli_config: {
|
||||
let mut cfg = Config::new(ConfigType::Local);
|
||||
cfg.local_addr = Some(ServerAddr::from(local_addr));
|
||||
cfg.local = vec![LocalConfig::new(ServerAddr::from(local_addr), ProtocolType::Socks)];
|
||||
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
|
||||
cfg.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
||||
cfg.local_protocol = ProtocolType::Socks;
|
||||
cfg
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,20 +11,26 @@ use tokio::{
|
||||
};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, ProtocolType},
|
||||
config::{Config, ConfigType},
|
||||
run_local,
|
||||
run_server,
|
||||
shadowsocks::relay::socks5::Address,
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn tcp_tunnel() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut local_config = Config::load_from_str(
|
||||
let local_config = Config::load_from_str(
|
||||
r#"{
|
||||
"locals": [
|
||||
{
|
||||
"local_port": 9110,
|
||||
"local_address": "127.0.0.1",
|
||||
"protocol": "tunnel",
|
||||
"forward_address": "www.example.com",
|
||||
"forward_port": 80
|
||||
}
|
||||
],
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 9120,
|
||||
"password": "password",
|
||||
@@ -33,8 +39,6 @@ async fn tcp_tunnel() {
|
||||
ConfigType::Local,
|
||||
)
|
||||
.unwrap();
|
||||
local_config.local_protocol = ProtocolType::Tunnel;
|
||||
local_config.forward = Some("www.example.com:80".parse::<Address>().unwrap());
|
||||
|
||||
let server_config = Config::load_from_str(
|
||||
r#"{
|
||||
@@ -75,10 +79,17 @@ async fn udp_tunnel() {
|
||||
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut local_config = Config::load_from_str(
|
||||
let local_config = Config::load_from_str(
|
||||
r#"{
|
||||
"locals": [
|
||||
{
|
||||
"local_port": 9210,
|
||||
"local_address": "127.0.0.1",
|
||||
"protocol": "tunnel",
|
||||
"forward_address": "8.8.8.8",
|
||||
"forward_port": 53
|
||||
}
|
||||
],
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 9220,
|
||||
"password": "password",
|
||||
@@ -88,8 +99,6 @@ async fn udp_tunnel() {
|
||||
ConfigType::Local,
|
||||
)
|
||||
.unwrap();
|
||||
local_config.local_protocol = ProtocolType::Tunnel;
|
||||
local_config.forward = Some("8.8.8.8:53".parse::<Address>().unwrap());
|
||||
|
||||
let server_config = Config::load_from_str(
|
||||
r#"{
|
||||
|
||||
@@ -7,7 +7,7 @@ use log::debug;
|
||||
use tokio::time::{self, Duration};
|
||||
|
||||
use shadowsocks_service::{
|
||||
config::{Config, ConfigType, Mode, ProtocolType},
|
||||
config::{Config, ConfigType, LocalConfig, Mode, ProtocolType},
|
||||
local::socks::client::socks5::Socks5UdpClient,
|
||||
run_local,
|
||||
run_server,
|
||||
@@ -35,14 +35,13 @@ fn get_svr_config() -> Config {
|
||||
|
||||
fn get_cli_config() -> Config {
|
||||
let mut cfg = Config::new(ConfigType::Local);
|
||||
cfg.local_addr = Some(LOCAL_ADDR.parse().unwrap());
|
||||
cfg.local = vec![LocalConfig::new(LOCAL_ADDR.parse().unwrap(), ProtocolType::Socks)];
|
||||
cfg.server = vec![ServerConfig::new(
|
||||
SERVER_ADDR.parse::<SocketAddr>().unwrap(),
|
||||
PASSWORD.to_owned(),
|
||||
METHOD,
|
||||
)];
|
||||
cfg.mode = Mode::TcpAndUdp;
|
||||
cfg.local_protocol = ProtocolType::Socks;
|
||||
cfg
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user