updated readme, appveyor and remove unused tool

This commit is contained in:
Y. T. Chung
2016-10-27 09:34:48 +08:00
parent 68fd3b6aa6
commit 412cf3951c
4 changed files with 15 additions and 208 deletions

View File

@@ -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"

View File

@@ -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
- [ ] <del>`BIND` command</del>
- [ ] Socks5 authentication
- [ ] <del>Socks5 authentication</del>
- [x] Extend configuration format
- [ ] Fully testing on servers
- [ ] Performance testing and improvement
@@ -122,8 +120,8 @@ It supports the following features:
- [ ] <del>PAC</del>
- [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. <del>(Depending on mio and coio-rs)</del>
- [x] Build with stable. <del>(Depending on coio)</del>
- [x] Support HTTP Proxy protocol
## License

View File

@@ -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"

View File

@@ -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 <zonyitoo@gmail.com>")
.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::<IpAddr>() {
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);
}
}