Skip to content

Commit

Permalink
update: remove hardcoded config parts in SS
Browse files Browse the repository at this point in the history
  • Loading branch information
erikziyunchi committed Jan 7, 2024
1 parent 931e049 commit f784313
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 31 deletions.
19 changes: 11 additions & 8 deletions crates/wasm/src/connections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,30 @@ impl ConnFile {
}

// A Connection normally contains both in & outbound streams + a config
pub struct Connection {
pub struct Connection<T> {
pub inbound_conn: ConnFile,
pub outbound_conn: ConnFile,

pub config: Config,
pub config: T,
}

impl Default for Connection {
impl<T: Default> Default for Connection<T> {
fn default() -> Self {
Self::new()
Self {
inbound_conn: ConnFile::new(),
outbound_conn: ConnFile::new(),
config: T::default(),
}
}
}

impl Connection {
impl<T> Connection<T> {
// A default constructor
pub fn new() -> Self {
pub fn new(config: T) -> Self {
Connection {
inbound_conn: ConnFile::new(),
outbound_conn: ConnFile::new(),

config: Config::new(),
config,
}
}

Expand Down
5 changes: 2 additions & 3 deletions crates/wasm/src/dialer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::*;
use anyhow::{anyhow, Ok};

pub struct Dialer {
pub file_conn: Connection,
pub file_conn: Connection<Config>,
pub config: Config,
}

Expand All @@ -16,15 +16,14 @@ impl Default for Dialer {
impl Dialer {
pub fn new() -> Self {
Dialer {
file_conn: Connection::new(),
file_conn: Connection::default(),
config: Config::new(),
}
}

pub fn dial(&mut self) -> Result<i32, anyhow::Error> {
info!("[WASM] running in dial func...");

// FIXME: hardcoded the filename for now, make it a config later
let fd: i32 = self.tcp_connect()?;

if fd < 0 {
Expand Down
1 change: 0 additions & 1 deletion crates/wasm/src/v1/async_listener_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ fn _listener_creation() -> Result<i32, std::io::Error> {
}
};

// FIXME: hardcoded the filename for now, make it a config later
let stream = StreamConfigV1::init(global_conn.config.local_address.clone(), global_conn.config.local_port, "LISTEN".to_string());

let encoded: Vec<u8> = bincode::serialize(&stream).expect("Failed to serialize");
Expand Down
1 change: 0 additions & 1 deletion crates/wasm/src/v1/dial_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ impl Dialer {

let mut fd: i32 = -1;

// FIXME: hardcoded the filename for now, make it a config later
fd = self.tcp_connect()?;

if fd < 0 {
Expand Down
1 change: 0 additions & 1 deletion examples/clients/cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ pub fn parse_and_execute() -> Result<(), anyhow::Error> {
pub fn execute(_conf: WATERConfig) -> Result<(), anyhow::Error> {
// let mut water_client = runtime::WATERClient::new(conf)?;

// // FIXME: hardcoded the addr & port for now
// water_client.connect("", 0)?;

// loop {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn _listener_creation() -> Result<i32, std::io::Error> {
}
};

// FIXME: hardcoded the filename for now, make it a config later
// NOTE: hardcoded the filename for now, make it a config later
let stream = StreamConfigV1::init(
global_conn.config.local_address.clone(),
global_conn.config.local_port,
Expand Down
37 changes: 37 additions & 0 deletions examples/water_bins/ss_client_wasm_v1/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! Specific config for the ss client, with more fields like password,
//! and others like cipher method(adding later)

use serde::Deserialize;

// A Config currently contains the local + remote ip & port
#[derive(Debug, Deserialize, Clone)]
pub struct SSConfig {
pub remote_address: String,
pub remote_port: u32,
pub local_address: String,
pub local_port: u32,
pub password: String,
pub bypass: bool,
// NOTE: will add the config for ciphter method later
// pub method: CipherKind,
}

impl Default for SSConfig {
fn default() -> Self {
Self::new()
}
}

// implement a constructor for the config
impl SSConfig {
pub fn new() -> Self {
SSConfig {
remote_address: String::from("example.com"),
remote_port: 8082,
local_address: String::from("127.0.0.1"),
local_port: 8080,
password: String::from("Test!23"),
bypass: false,
}
}
}
7 changes: 5 additions & 2 deletions examples/water_bins/ss_client_wasm_v1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use std::{
fmt::{self, Debug},
future::Future,
io::{self, ErrorKind, Read},
net::SocketAddr,
net::{IpAddr, SocketAddr},
os::fd::FromRawFd,
pin::Pin,
slice,
str::FromStr,
sync::Mutex,
task::{Context, Poll},
vec,
Expand All @@ -32,6 +33,7 @@ use tracing::{debug, info, Level};
// =================== MODULES ===================
pub mod aead;
pub mod client;
pub mod config;
pub mod crypto_io;
pub mod socks5;
pub mod utils;
Expand All @@ -40,6 +42,7 @@ pub mod water;
// =================== DEPENDENCIES FROM MODULES ===================
use aead::{DecryptedReader, EncryptedWriter};
use client::*;
use config::*;
use crypto_io::*;
use socks5::*;
use utils::*;
Expand All @@ -54,6 +57,6 @@ pub static V1: i32 = 0;

// create a mutable global variable stores a pointer to the config
lazy_static! {
pub static ref CONN: Mutex<Connection> = Mutex::new(Connection::new());
pub static ref CONN: Mutex<Connection<SSConfig>> = Mutex::new(Connection::new(SSConfig::new()));
pub static ref DIALER: Mutex<Dialer> = Mutex::new(Dialer::new());
}
75 changes: 61 additions & 14 deletions examples/water_bins/ss_client_wasm_v1/src/water.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;

use bytes::{BufMut, BytesMut};
use shadowsocks_crypto::v1::openssl_bytes_to_key;

#[cfg(target_family = "wasm")]
#[export_name = "_water_init"]
Expand Down Expand Up @@ -29,7 +30,7 @@ pub fn _process_config(fd: i32) {
let mut config = String::new();
match config_file.read_to_string(&mut config) {
Ok(_) => {
let config: Config = match serde_json::from_str(&config) {
let config: SSConfig = match serde_json::from_str(&config) {
Ok(config) => config,
Err(e) => {
eprintln!("[WASM] > _process_config ERROR: {}", e);
Expand Down Expand Up @@ -83,6 +84,40 @@ async fn _start_listen(bypass: bool) -> std::io::Result<()> {
// Convert to tokio TcpListener.
let listener = TcpListener::from_std(standard)?;

// Initialize the variables for the server address and the encryption key
let mut server_addr: Address = Address::SocketAddress(SocketAddr::from(([127, 0, 0, 1], 8088)));
let mut enc_key = vec![0u8; CIPHER_METHOD.key_len()].into_boxed_slice();

{
let global_conn = match CONN.lock() {
Ok(conn) => conn,
Err(e) => {
eprintln!("[WASM] > ERROR: {}", e);
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"failed to lock CONN",
));
}
};

// getting the server ip address
match IpAddr::from_str(&global_conn.config.remote_address) {
Ok(ip_addr) => {
server_addr = Address::SocketAddress(SocketAddr::from((
ip_addr,
global_conn.config.remote_port as u16,
)));
println!("Server address: {}", server_addr);
}
Err(e) => {
eprintln!("Failed to parse IP address: {}", e);
}
}

// getting the enc_key derived from the password
openssl_bytes_to_key(global_conn.config.password.as_bytes(), &mut enc_key);
}

info!("[WASM] Starting to listen...");

loop {
Expand All @@ -95,10 +130,14 @@ async fn _start_listen(bypass: bool) -> std::io::Result<()> {
}
};

// Clone server_addr + enc_key for each iteration of the loop.
let server_addr_clone = server_addr.clone();
let enc_key_clone = enc_key.clone();

// Spawn a background task for each new connection.
tokio::spawn(async move {
eprintln!("[WASM] > CONNECTED");
match _handle_connection(socket, bypass).await {
match _handle_connection(socket, server_addr_clone, enc_key_clone, bypass).await {
Ok(()) => eprintln!("[WASM] > DISCONNECTED"),
Err(e) => eprintln!("[WASM] > ERROR: {}", e),
}
Expand All @@ -107,7 +146,12 @@ async fn _start_listen(bypass: bool) -> std::io::Result<()> {
}

// SS handle incoming connections
async fn _handle_connection(stream: TcpStream, bypass: bool) -> std::io::Result<()> {
async fn _handle_connection(
stream: TcpStream,
server_addr: Address,
key: Box<[u8]>,
bypass: bool,
) -> std::io::Result<()> {
let mut inbound_con = Socks5Handler::new(stream);
inbound_con.socks5_greet().await.expect("Failed to greet");

Expand All @@ -120,16 +164,18 @@ async fn _handle_connection(stream: TcpStream, bypass: bool) -> std::io::Result<
if bypass {
_connect_bypass(&target_addr, &mut inbound_con).await?;
} else {
_connect(target_addr, &mut inbound_con).await?;
_connect(target_addr, server_addr, key, &mut inbound_con).await?;
}

Ok(())
}

async fn _connect(target_addr: Address, inbound_con: &mut Socks5Handler) -> std::io::Result<()> {
// FIXME: hardcoded server ip:address for now + only support connection with ip:port
let server_addr = Address::SocketAddress(SocketAddr::from(([127, 0, 0, 1], 8388)));

async fn _connect(
target_addr: Address,
server_addr: Address,
key: Box<[u8]>,
inbound_con: &mut Socks5Handler,
) -> std::io::Result<()> {
let server_stream = _dial_remote(&server_addr).expect("Failed to dial to SS-Server");

// Constructing the response header
Expand All @@ -140,10 +186,11 @@ async fn _connect(target_addr: Address, inbound_con: &mut Socks5Handler) -> std:
inbound_con.socks5_response(&mut buf).await;

// FIXME: hardcoded the key which derived from the password: "Test!23"
let key = [
128, 218, 128, 160, 125, 72, 115, 9, 187, 165, 163, 169, 92, 177, 35, 201, 49, 245, 92,
203, 57, 152, 63, 149, 108, 132, 60, 128, 201, 206, 82, 226,
];
// let key = [
// 128, 218, 128, 160, 125, 72, 115, 9, 187, 165, 163, 169, 92, 177, 35, 201, 49, 245, 92,
// 203, 57, 152, 63, 149, 108, 132, 60, 128, 201, 206, 82, 226,
// ];

// creating the client proxystream -- contains cryptostream with both AsyncRead and AsyncWrite implemented
let mut proxy = ProxyClientStream::from_stream(server_stream, target_addr, CIPHER_METHOD, &key);

Expand Down Expand Up @@ -192,7 +239,7 @@ async fn _connect_bypass(
pub fn _dial_remote(target: &Address) -> Result<TcpStream, std::io::Error> {
let mut tcp_dialer = Dialer::new();

// NOTE: only support ip:port for now, add DNS resolver helper from Host later
// TODO: only support ip:port for now, add DNS resolver helper from Host later
match target {
Address::SocketAddress(addr) => {
tcp_dialer.config.remote_address = addr.ip().to_string();
Expand Down Expand Up @@ -249,7 +296,7 @@ pub fn _listener_creation() -> Result<i32, std::io::Error> {
global_conn.config.local_address, global_conn.config.local_port
);

// FIXME: hardcoded the filename for now, make it a config later
// NOTE: hardcoded the filename for now, make it a config later
let stream = StreamConfigV1::init(
global_conn.config.local_address.clone(),
global_conn.config.local_port,
Expand Down
Binary file modified examples/water_bins/ss_client_wasm_v1/ss_client_wasm.wasm
100644 → 100755
Binary file not shown.
Binary file modified tests/test_wasm/ss_client_wasm.wasm
Binary file not shown.
2 changes: 2 additions & 0 deletions tests/tests/ss_testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ async fn wasm_managed_shadowsocks_async() -> Result<(), Box<dyn std::error::Erro
"remote_port": 8088,
"local_address": "127.0.0.1",
"local_port": 8080,
"password": "Test!23",
"bypass": false
}
"#;
Expand Down Expand Up @@ -201,6 +202,7 @@ async fn wasm_managed_shadowsocks_bypass_async() -> Result<(), Box<dyn std::erro
"remote_port": 10085,
"local_address": "127.0.0.1",
"local_port": 10086,
"password": "Test!23",
"bypass": true
}
"#;
Expand Down

0 comments on commit f784313

Please sign in to comment.