From 412cf3951cc659ba3c78291aaf2d696b524bdd48 Mon Sep 17 00:00:00 2001 From: "Y. T. Chung" Date: Thu, 27 Oct 2016 09:34:48 +0800 Subject: [PATCH] updated readme, appveyor and remove unused tool --- Cargo.toml | 5 -- README.md | 22 +++-- appveyor.yml | 8 +- src/bin/socks5-tool.rs | 188 ----------------------------------------- 4 files changed, 15 insertions(+), 208 deletions(-) delete mode 100644 src/bin/socks5-tool.rs diff --git a/Cargo.toml b/Cargo.toml index b7ef6298..df78ab75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,11 +35,6 @@ path = "src/bin/local.rs" name = "ssserver" path = "src/bin/server.rs" -#[[bin]] -# -#name = "socks5-tool" -#path = "src/bin/socks5-tool.rs" - [[bin]] name = "ssurl" diff --git a/README.md b/README.md index aba677cf..30bafb9b 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ It is **unstable**! If you encounter any problems, please open an issue. ## Dependencies * libcrypto (OpenSSL) -* Rust nightly -* Cargo ## Usage @@ -87,7 +85,7 @@ In shadowsocks-rust, we also have an extended configuration file format, which i The `sslocal` will use a load balancing algorithm to dispatch packages to all servers. -Start local and server shadowsocks with +Start local and server ShadowSocks with ``` cargo run --bin sslocal -- -c config.json @@ -98,23 +96,23 @@ List all available arguments with `-h`. ## Useful Tools -1. `socks5-tool` is to demonstrate how to write a Socks5 client. - -2. `ssurl` is for encoding and decoding ShadowSocks URLs. Example: `ss://YWVzLTI1Ni1jZmI6aGVsbG93b3JsZF9mdWNrQDEyNy4wLjAuMTo4Mzg4` +1. `ssurl` is for encoding and decoding ShadowSocks URLs. Example: `ss://YWVzLTI1Ni1jZmI6aGVsbG93b3JsZF9mdWNrQDEyNy4wLjAuMTo4Mzg4` ## Notes It supports the following features: -* CONNECT, UDP ASSOCIATE commands -* Crypto algorithms defined in `Cargo.toml` -* **Load balancing** +- [x] Socks5 CONNECT command +- [ ] UDP ASSOCIATE command +- [x] HTTP Proxy protocol +- [x] Various crypto algorithms +- [x] Load balancing (multiple servers) ## TODO - [ ] Documentation - [ ] `BIND` command -- [ ] Socks5 authentication +- [ ] Socks5 authentication - [x] Extend configuration format - [ ] Fully testing on servers - [ ] Performance testing and improvement @@ -122,8 +120,8 @@ It supports the following features: - [ ] PAC - [x] Improved logging format (waiting for the new official log crate) - [ ] Support more ciphers without depending on `libcrypto` (waiting for an acceptable Rust crypto lib implementation) -- [ ] Windows support. (Depending on mio and coio-rs) -- [ ] Build with stable. (Depending on coio) +- [x] Windows support. (Depending on mio and coio-rs) +- [x] Build with stable. (Depending on coio) - [x] Support HTTP Proxy protocol ## License diff --git a/appveyor.yml b/appveyor.yml index dc483829..e25eb640 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,12 +7,14 @@ environment: - TARGET: x86_64-pc-windows-msvc BITS: 64 OPENSSL_VERSION: 1_1_0b - - TARGET: i686-pc-windows-msvc - BITS: 32 - OPENSSL_VERSION: 1_1_0b + MSYS2: 1 + # - TARGET: i686-pc-windows-msvc + # BITS: 32 + # OPENSSL_VERSION: 1_1_0b - TARGET: i686-pc-windows-gnu BITS: 32 OPENSSL_VERSION: 1_1_0b + MSYS2: 1 install: - ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-${env:OPENSSL_VERSION}.exe" - Win%BITS%OpenSSL-%OPENSSL_VERSION%.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL" diff --git a/src/bin/socks5-tool.rs b/src/bin/socks5-tool.rs deleted file mode 100644 index aec600cc..00000000 --- a/src/bin/socks5-tool.rs +++ /dev/null @@ -1,188 +0,0 @@ -#![feature(lookup_host)] - -extern crate clap; -#[macro_use] -extern crate log; -extern crate shadowsocks; -extern crate ip; - -use clap::{App, Arg}; - -use std::net::UdpSocket; -use std::net::TcpStream; -use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; -use std::net::lookup_host; -use std::io::Cursor; -use std::io::stdout; -use std::io::{self, Write}; - -use ip::IpAddr; - -use shadowsocks::relay::socks5::*; - -fn do_tcp(svr_addr: &Address, proxy_addr: &SocketAddr, msg: &str) { - let mut proxy_stream = TcpStream::connect(proxy_addr).unwrap(); - - let shake_req = HandshakeRequest::new(vec![0x00]); - shake_req.write_to(&mut proxy_stream).unwrap(); - let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap(); - - if shake_resp.chosen_method != 0x00 { - panic!("Proxy server needs authentication"); - } - - let req_header = TcpRequestHeader::new(Command::TcpConnect, svr_addr.clone()); - req_header.write_to(&mut proxy_stream).unwrap(); - proxy_stream.write(msg.as_bytes()).unwrap(); - - let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap(); - match resp_header.reply { - Reply::Succeeded => {} - _ => { - panic!("Failed with error {:?}", resp_header.reply); - } - } - - io::copy(&mut proxy_stream, &mut stdout()).unwrap(); -} - -fn do_udp(svr_addr: &Address, proxy_addr: &SocketAddr, local_addr: &SocketAddr, msg: &str) { - let udp_proxy_addr = { - let mut proxy_stream = TcpStream::connect(proxy_addr).unwrap(); - - let shake_req = HandshakeRequest::new(vec![0x00]); - shake_req.write_to(&mut proxy_stream).unwrap(); - let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap(); - - if shake_resp.chosen_method != 0x00 { - panic!("Proxy server needs authentication"); - } - - let req_header = TcpRequestHeader::new(Command::UdpAssociate, svr_addr.clone()); - req_header.write_to(&mut proxy_stream).unwrap(); - - let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap(); - match resp_header.reply { - Reply::Succeeded => {} - _ => { - panic!("Failed with error {:?}", resp_header.reply); - } - } - - resp_header.address - }; - - let udp_socket = UdpSocket::bind(local_addr).unwrap(); - - let proxy_real_addr = match udp_proxy_addr { - Address::SocketAddress(sock) => sock, - Address::DomainNameAddress(dm, port) => { - let host = match lookup_host(&dm) { - Ok(mut hosts) => { - match hosts.next() { - Some(h) => h, - None => panic!("No hosts could be found by {:?}", dm), - } - } - Err(err) => panic!("LookupHost: {:?}", err), - }; - - match host { - SocketAddr::V4(v4) => SocketAddr::V4(SocketAddrV4::new(*v4.ip(), port)), - SocketAddr::V6(v6) => { - SocketAddr::V6(SocketAddrV6::new(*v6.ip(), port, v6.flowinfo(), v6.scope_id())) - } - } - } - }; - - let mut bufw = Vec::new(); - let udp_header = UdpAssociateHeader::new(0, svr_addr.clone()); - udp_header.write_to(&mut bufw).unwrap(); - bufw.write(msg.as_bytes()).unwrap(); - udp_socket.send_to(&bufw, proxy_real_addr).unwrap(); - - let mut buf = [0; 0xffff]; - let (len, _) = udp_socket.recv_from(&mut buf).unwrap(); - println!("Got buf: {:?}", &buf[..len]); - - let mut bufr = Cursor::new(&buf[..len]); - let _ = UdpAssociateHeader::read_from(&mut bufr).unwrap(); - - io::copy(&mut bufr, &mut stdout()).unwrap(); -} - -fn main() { - - let matches = App::new("socks5-tool") - .author("Y. T. Chung ") - .about("Socks5 protocol test tool") - .arg(Arg::with_name("SERVER_ADDR") - .short("s") - .long("server-addr") - .takes_value(true) - .required(true) - .help("Server address")) - .arg(Arg::with_name("SERVER_PORT") - .short("p") - .long("server-port") - .takes_value(true) - .required(true) - .help("Server port")) - .arg(Arg::with_name("PROXY_ADDR") - .short("x") - .long("proxy-addr") - .takes_value(true) - .required(true) - .help("Proxy address")) - .arg(Arg::with_name("LOCAL_ADDR") - .short("b") - .long("local-addr") - .takes_value(true) - .required(false) - .help("Local address")) - .arg(Arg::with_name("PROTOCOL") - .short("t") - .long("protocol") - .takes_value(true) - .required(true) - .help("Protocol to use")) - .arg(Arg::with_name("MESSAGE") - .short("m") - .long("message") - .takes_value(true) - .required(true) - .help("Message to be sent")) - .get_matches(); - - let is_tcp = match matches.value_of("PROTOCOL").unwrap() { - "tcp" => true, - "udp" => false, - protocol => panic!("Unsupported protocol {:?}", protocol), - }; - - let proxy_addr: SocketAddr = matches.value_of("PROXY_ADDR").unwrap().parse().unwrap(); - - let svr_port: u16 = matches.value_of("SERVER_PORT").unwrap().parse().unwrap(); - let svr_addr_str = matches.value_of("SERVER_ADDR").unwrap(); - let svr_addr = match svr_addr_str.parse::() { - Ok(ip) => { - let addr = match ip { - IpAddr::V4(v4) => SocketAddr::V4(SocketAddrV4::new(v4, svr_port)), - IpAddr::V6(v6) => SocketAddr::V6(SocketAddrV6::new(v6, svr_port, 0, 0)), - }; - - Address::SocketAddress(addr) - } - Err(..) => Address::DomainNameAddress(svr_addr_str.to_owned(), svr_port), - }; - - let msg = matches.value_of("MESSAGE").unwrap(); - - if is_tcp { - do_tcp(&svr_addr, &proxy_addr, msg); - } else { - let local_addr: SocketAddr = matches.value_of("LOCAL_ADDR").unwrap().parse().unwrap(); - do_udp(&svr_addr, &proxy_addr, &local_addr, msg); - } -}