#![cfg(all(feature = "local", feature = "server"))] use std::net::SocketAddr; use log::debug; use tokio::time::{self, Duration}; use shadowsocks_service::{ config::{Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig}, local::socks::client::socks5::Socks5UdpClient, run_local, run_server, shadowsocks::{ServerConfig, config::Mode, crypto::CipherKind, relay::socks5::Address}, }; const SERVER_ADDR: &str = "127.0.0.1:8093"; const LOCAL_ADDR: &str = "127.0.0.1:8291"; const UDP_ECHO_SERVER_ADDR: &str = "127.0.0.1:50403"; const PASSWORD: &str = "test-password"; const METHOD: CipherKind = CipherKind::AES_128_GCM; fn get_svr_config() -> Config { let mut cfg = Config::new(ConfigType::Server); cfg.server = vec![ServerInstanceConfig::with_server_config( ServerConfig::new(SERVER_ADDR.parse::().unwrap(), PASSWORD.to_owned(), METHOD).unwrap(), )]; cfg.server[0].config.set_mode(Mode::TcpAndUdp); cfg } fn get_cli_config() -> Config { let mut cfg = Config::new(ConfigType::Local); cfg.local = vec![LocalInstanceConfig::with_local_config(LocalConfig::new_with_addr( LOCAL_ADDR.parse().unwrap(), ProtocolType::Socks, ))]; cfg.local[0].config.mode = Mode::TcpAndUdp; cfg.server = vec![ServerInstanceConfig::with_server_config( ServerConfig::new(SERVER_ADDR.parse::().unwrap(), PASSWORD.to_owned(), METHOD).unwrap(), )]; cfg } fn get_client_addr() -> SocketAddr { LOCAL_ADDR.parse().unwrap() } fn start_server() { tokio::spawn(run_server(get_svr_config())); } fn start_local() { tokio::spawn(run_local(get_cli_config())); } fn start_udp_echo_server() { use tokio::net::UdpSocket; tokio::spawn(async { let l = UdpSocket::bind(UDP_ECHO_SERVER_ADDR).await.unwrap(); debug!("UDP echo server started {}", UDP_ECHO_SERVER_ADDR); let mut buf = vec![0u8; 65536]; let (amt, src) = l.recv_from(&mut buf).await.unwrap(); debug!("UDP echo received {} bytes from {}", amt, src); l.send_to(&buf[..amt], &src).await.unwrap(); debug!("UDP echo sent {} bytes to {}", amt, src); }); } #[tokio::test] async fn udp_relay() { let _ = env_logger::try_init(); let remote_addr = Address::SocketAddress(UDP_ECHO_SERVER_ADDR.parse().unwrap()); start_server(); start_local(); start_udp_echo_server(); // Wait until all server starts time::sleep(Duration::from_secs(1)).await; let mut l = Socks5UdpClient::bind("127.0.0.1:0".parse::().unwrap()) .await .unwrap(); l.associate(&get_client_addr()).await.unwrap(); let payload = b"HEllo WORld"; l.send_to(0, payload, &remote_addr).await.unwrap(); let mut buf = vec![0u8; 65536]; let (amt, _, recv_addr) = time::timeout(Duration::from_secs(5), l.recv_from(&mut buf)) .await .unwrap() .unwrap(); println!("Received {} buf size={} {:?}", recv_addr, amt, &buf[..amt]); assert_eq!(recv_addr, remote_addr); assert_eq!(&buf[..amt], payload); }