Files
shadowsocks-rust/tests/socks4.rs
T
ty 07583f3cc8 Refactored and separate library into crates (#345)
* Refactored and separate library into crates

- shadowsocks: the core feature of shadowsocks
- shadowsocks-service: library for building shadowsocks services
    - dns, http, redir, socks, tunnel
    - load balancer
- shadowsocks-rust: release binaries

fix #347

* unified DnsResolver implementation

* unified local service common parameters into ServiceContext

- ServiceContext is common parameters shared between all local
implementations
- Completely removed https local support

* add #292 reply attack protection

* migrated redir local server

* support customizing outbound socket bind address

* manager outbound socket should accepts connect_opts

* republic local implementations

* socks5 udp server should always listen to client address

* socks4 controlled by local-socks4 feature

* socks4 also obey mode configuration

* socks server tcp cannot be disable. add support of udp-bind-addr parameter

* add udp-bind-addr for customizing udp-relay bind-addr

* local-dns infra, support customizing resolver

* fully implements DNS relay server

* support binding to specific interface on Linux-like platform

* tcp cannot be disabled in socks

* enable local-flow-stat

* fixed windows build

* fixed android specific warnings and compile errors

* allow udp_only mode in socks5

* dns relay listens to both TCP and UDP, mode controls outbound upstreams

* dns relay retries twice if request failed

* doc

* fix DnsClient typo

* fix stream EncryptWriter bug

* allow disable logging output

updated dependencies

* add readme

* refine doc

* remove depending on trust-dns-client

* socks4/4a client

* allow socks5 udp_only mode, fixes compile warning

* create standalone socks5 UDP relay server

- socks5 UDP association full cone (NAT2)

* server udp relay supports full cone (NAT2)

* acl moved to crate root

* redir udp relay support full cone (NAT2)

* standard socks5 udp test must use tcp_and_udp mode

* set server context fields with pub APIs

* udp_max_associations and udp_timeout default value set in Config

* local dns resolver retry with fixed attempts

* max_udp_association keeps unlimited by default

* fixed logging binary name

* pops first exited future result for local and server

* update reverse target index cache

* fix ProxyClientStreamWriteHalf that allows sending empty buffers

ref #232

* remove unused import when socks4 is disabled

* make balancer become a globally shared object

* print plugin exit status

* control local, server, manager services in features
2020-12-20 19:06:21 +08:00

101 lines
2.7 KiB
Rust

#![cfg(all(feature = "local-socks4", feature = "server"))]
use std::{
net::{SocketAddr, ToSocketAddrs},
str,
};
use tokio::{
prelude::*,
time::{self, Duration},
};
use shadowsocks_service::{
config::{Config, ConfigType, ProtocolType},
local::socks::client::Socks4TcpClient,
run_local,
run_server,
shadowsocks::{
config::{ServerAddr, ServerConfig},
crypto::v1::CipherKind,
},
};
pub struct Socks4TestServer {
local_addr: SocketAddr,
svr_config: Config,
cli_config: Config,
}
impl Socks4TestServer {
pub fn new<S, L>(svr_addr: S, local_addr: L, pwd: &str, method: CipherKind) -> Socks4TestServer
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();
Socks4TestServer {
local_addr,
svr_config: {
let mut cfg = Config::new(ConfigType::Server);
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
cfg
},
cli_config: {
let mut cfg = Config::new(ConfigType::Local);
cfg.local_addr = Some(ServerAddr::from(local_addr));
cfg.server = vec![ServerConfig::new(svr_addr, pwd.to_owned(), method)];
cfg.local_protocol = ProtocolType::Socks;
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;
}
}
#[tokio::test]
async fn socks4_relay_connect() {
let _ = env_logger::try_init();
const SERVER_ADDR: &str = "127.0.0.1:7100";
const LOCAL_ADDR: &str = "127.0.0.1:7200";
const PASSWORD: &str = "test-password";
const METHOD: CipherKind = CipherKind::AES_128_GCM;
let svr = Socks4TestServer::new(SERVER_ADDR, LOCAL_ADDR, PASSWORD, METHOD);
svr.run().await;
static HTTP_REQUEST: &[u8] = b"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n";
let mut c = Socks4TcpClient::connect(("www.example.com", 80), LOCAL_ADDR, Vec::new())
.await
.unwrap();
c.write_all(HTTP_REQUEST).await.unwrap();
c.flush().await.unwrap();
let mut buf = Vec::new();
c.read_to_end(&mut buf).await.unwrap();
println!("Got reply from server: {}", str::from_utf8(&buf).unwrap());
let http_status = b"HTTP/1.0 200 OK\r\n";
buf.starts_with(http_status);
}