mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-17 05:31:27 +08:00
147 lines
4.3 KiB
Rust
147 lines
4.3 KiB
Rust
#![cfg(all(feature = "local", feature = "server"))]
|
|
|
|
use std::{
|
|
net::{SocketAddr, ToSocketAddrs},
|
|
str,
|
|
};
|
|
|
|
use tokio::{
|
|
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
|
time::{self, Duration},
|
|
};
|
|
|
|
use shadowsocks_service::{
|
|
config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig},
|
|
local::socks::client::socks5::Socks5TcpClient,
|
|
run_local, run_server,
|
|
shadowsocks::{
|
|
config::{Mode, ServerAddr, ServerConfig},
|
|
crypto::CipherKind,
|
|
relay::socks5::Address,
|
|
},
|
|
};
|
|
|
|
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: CipherKind, 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![ServerInstanceConfig::with_server_config(
|
|
ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),
|
|
)];
|
|
cfg.server[0]
|
|
.config
|
|
.set_mode(if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly });
|
|
cfg
|
|
},
|
|
cli_config: {
|
|
let mut cfg = Config::new(ConfigType::Local);
|
|
cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr(
|
|
ServerAddr::from(local_addr),
|
|
ProtocolType::Socks,
|
|
))];
|
|
cfg.local[0].config.mode = if enable_udp { Mode::TcpAndUdp } else { Mode::TcpOnly };
|
|
cfg.server = vec![ServerInstanceConfig::with_server_config(
|
|
ServerConfig::new(svr_addr, pwd.to_owned(), method).unwrap(),
|
|
)];
|
|
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::sleep(Duration::from_secs(1)).await;
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "stream-cipher")]
|
|
#[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: CipherKind = CipherKind::AES_128_CFB128;
|
|
|
|
let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);
|
|
svr.run().await;
|
|
|
|
let mut c = Socks5TcpClient::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 r = BufReader::new(c);
|
|
|
|
let mut buf = Vec::new();
|
|
r.read_until(b'\n', &mut buf).await.unwrap();
|
|
|
|
let http_status = b"HTTP/1.0 200 OK\r\n";
|
|
assert!(buf.starts_with(http_status));
|
|
}
|
|
|
|
#[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: CipherKind = CipherKind::AES_256_GCM;
|
|
|
|
let svr = Socks5TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD, false);
|
|
svr.run().await;
|
|
|
|
let mut c = Socks5TcpClient::connect(
|
|
Address::DomainNameAddress("detectportal.firefox.com".to_owned(), 80),
|
|
svr.client_addr(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
let req = b"GET /success.txt HTTP/1.0\r\nHost: detectportal.firefox.com\r\nAccept: */*\r\n\r\n";
|
|
c.write_all(req).await.unwrap();
|
|
c.flush().await.unwrap();
|
|
|
|
let mut r = BufReader::new(c);
|
|
|
|
let mut buf = Vec::new();
|
|
r.read_until(b'\n', &mut buf).await.unwrap();
|
|
|
|
let http_status = b"HTTP/1.0 200 OK\r\n";
|
|
assert!(buf.starts_with(http_status));
|
|
}
|