mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-11-06 16:14:11 +00:00
* Socks5 library, main tcp relay implementation migrated with async/await * UDP relay local migrated to async/await * UDP relay server migrated to async/await * Migrated UDP DNS to async/await, follows tokio-process * Removed unused uses, add dyn keyword for TraitObjects * [#151] Uses dl.google.com/generate_204 to check connection latency * Make sslocal/ssserver TCP relay work successfully, disabled UDP and DNS relay temporary * Handshake before performing actual read & write * Wraps timeout logic into a Connection<S> struct * Make UDP relay work again * Local uses copy directly * Completely removed unused ssdns * Fixed test * Uses tokio::main macro for main entrance * Fixed a missing use in local.rs * Updated travis openssl to 1.1.0L * Windows signal * Migrated tokio 0.2 release with std::future support fix #173 * fixed windows monitor build * Uses tokio on crates.io * ctrl_c is a Future * Run tests with single tokio runtime * Uses spawn_blocking only with threaded runtime * Killing all detached Tasks if server is exited * Updated version to v1.8.0 * Removed unused pin-project * Uses dns resolver built in tokio * Explicitly uses threaded scheduler by default * Reverted, it is threaded scheduler by default * Updated bytes to v0.5 * Updated many dependencies * Add a tunnel app (#175) It can be used to benchmark. Usage: sstunnel -v -s 127.0.0.1:8488 -m plain -k password -b 127.0.0.1:1090 -f 127.0.0.1:5201 "-f xxx" : the target/forwad address xxx * Removed unused remote-dns config field (ssdns is removed) * Separated TCP local tunneling to its own module * Implements FromStr for Address * Fixed typo * Add tunnel unit test * Updated tokio to v0.2.2, fixed basic scheduler bug * Removed Connection, uses try_timeout instead. Revert back to use 8K buffer * Revert "Removed Connection, uses try_timeout instead. Revert back to use 8K buffer" This reverts commit82f698e520. * Uses Delay instead of Timeout * Delay doesnt return io::Result * Revert "Delay doesnt return io::Result" This reverts commit74dc294d16. * Fixed bug, Connection timeout should be shared between read & write operations
120 lines
3.5 KiB
Rust
120 lines
3.5 KiB
Rust
use std::net::{SocketAddr, ToSocketAddrs};
|
|
|
|
use tokio::prelude::*;
|
|
use tokio::time::{self, Duration};
|
|
|
|
use shadowsocks::{
|
|
config::{Config, ConfigType, Mode, ServerConfig},
|
|
crypto::CipherType,
|
|
relay::{socks5::Address, tcprelay::client::Socks5Client},
|
|
run_local, run_server,
|
|
};
|
|
|
|
pub struct Socks5TestServer {
|
|
local_addr: SocketAddr,
|
|
svr_config: Config,
|
|
cli_config: Config,
|
|
}
|
|
|
|
impl Socks5TestServer {
|
|
pub fn new<S, L>(svr_addr: S, local_addr: L, pwd: &str, method: CipherType, enable_udp: bool) -> Socks5TestServer
|
|
where
|
|
S: ToSocketAddrs,
|
|
L: ToSocketAddrs,
|
|
{
|
|
let svr_addr = svr_addr.to_socket_addrs().unwrap().next().unwrap();
|
|
let local_addr = local_addr.to_socket_addrs().unwrap().next().unwrap();
|
|
|
|
Socks5TestServer {
|
|
local_addr,
|
|
svr_config: {
|
|
let mut cfg = Config::new(ConfigType::Server);
|
|
cfg.server = vec![ServerConfig::basic(svr_addr, pwd.to_owned(), method)];
|
|
cfg.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
|
cfg
|
|
},
|
|
cli_config: {
|
|
let mut cfg = Config::new(ConfigType::Local);
|
|
cfg.local = Some(local_addr);
|
|
cfg.server = vec![ServerConfig::basic(svr_addr, pwd.to_owned(), method)];
|
|
cfg.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
|
cfg
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn client_addr(&self) -> &SocketAddr {
|
|
&self.local_addr
|
|
}
|
|
|
|
pub async fn run(&self) {
|
|
let svr_cfg = self.svr_config.clone();
|
|
tokio::spawn(run_server(svr_cfg));
|
|
|
|
let client_cfg = self.cli_config.clone();
|
|
tokio::spawn(run_local(client_cfg));
|
|
|
|
time::delay_for(Duration::from_secs(1)).await;
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn socks5_relay_stream() {
|
|
let _ = env_logger::try_init();
|
|
|
|
const SERVER_ADDR: &str = "127.0.0.1:8100";
|
|
const LOCAL_ADDR: &str = "127.0.0.1:8200";
|
|
|
|
const PASSWORD: &str = "test-password";
|
|
const METHOD: CipherType = CipherType::Aes256Cfb;
|
|
|
|
let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);
|
|
svr.run().await;
|
|
|
|
let mut c = Socks5Client::connect(
|
|
Address::DomainNameAddress("www.example.com".to_owned(), 80),
|
|
svr.client_addr(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
let req = b"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n";
|
|
c.write_all(req).await.unwrap();
|
|
c.flush().await.unwrap();
|
|
|
|
let mut buf = Vec::new();
|
|
c.read_to_end(&mut buf).await.unwrap();
|
|
|
|
println!("Got reply from server: {}", String::from_utf8(buf).unwrap());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn socks5_relay_aead() {
|
|
let _ = env_logger::try_init();
|
|
|
|
const SERVER_ADDR: &str = "127.0.0.1:8110";
|
|
const LOCAL_ADDR: &str = "127.0.0.1:8210";
|
|
|
|
const PASSWORD: &str = "test-password";
|
|
const METHOD: CipherType = CipherType::Aes256Gcm;
|
|
|
|
let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);
|
|
svr.run().await;
|
|
|
|
let mut c = Socks5Client::connect(
|
|
Address::DomainNameAddress("www.example.com".to_owned(), 80),
|
|
svr.client_addr(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
let req = b"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n";
|
|
c.write_all(req).await.unwrap();
|
|
c.flush().await.unwrap();
|
|
|
|
let mut buf = Vec::new();
|
|
c.read_to_end(&mut buf).await.unwrap();
|
|
|
|
println!("Got reply from server: {}", String::from_utf8(buf).unwrap());
|
|
}
|