diff --git a/src/bin/local.rs b/src/bin/local.rs index 560765fa..f6b0de46 100644 --- a/src/bin/local.rs +++ b/src/bin/local.rs @@ -220,7 +220,7 @@ fn main() { .ok().expect("`threads` should be an integer"); Scheduler::new().with_workers(threads).run(move|| { - if matches.occurrences_of("VERBOSE") >= 1 { + if matches.occurrences_of("VERBOSE") >= 2 { Scheduler::spawn(move|| { loop { coio::sleep_ms(1000); diff --git a/src/bin/socks5-tool.rs b/src/bin/socks5-tool.rs index ca5746f9..a3bf7c38 100644 --- a/src/bin/socks5-tool.rs +++ b/src/bin/socks5-tool.rs @@ -13,12 +13,12 @@ use std::net::TcpStream; use std::net::{IpAddr, SocketAddr}; use std::net::lookup_host; use std::io::Cursor; -use std::io::{stdin, stdout}; -use std::io::{Read, Write, self}; +use std::io::stdout; +use std::io::{Write, self}; use shadowsocks::relay::socks5::*; -fn do_tcp(svr_addr: &Address, proxy_addr: &SocketAddr) { +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]); @@ -29,12 +29,9 @@ fn do_tcp(svr_addr: &Address, proxy_addr: &SocketAddr) { panic!("Proxy server needs authentication"); } - let mut data = Vec::new(); - stdin().read_to_end(&mut data).unwrap(); - let req_header = TcpRequestHeader::new(Command::TcpConnect, svr_addr.clone()); req_header.write_to(&mut proxy_stream).unwrap(); - proxy_stream.write(&data).unwrap(); + proxy_stream.write(msg.as_bytes()).unwrap(); let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap(); match resp_header.reply { @@ -47,7 +44,7 @@ fn do_tcp(svr_addr: &Address, proxy_addr: &SocketAddr) { io::copy(&mut proxy_stream, &mut stdout()).unwrap(); } -fn do_udp(svr_addr: &Address, proxy_addr: &SocketAddr, local_addr: &SocketAddr) { +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(); @@ -92,17 +89,15 @@ fn do_udp(svr_addr: &Address, proxy_addr: &SocketAddr, local_addr: &SocketAddr) } }; - let mut data = Vec::new(); - stdin().read_to_end(&mut data).unwrap(); - let mut bufw = Vec::new(); let udp_header = UdpAssociateHeader::new(0, svr_addr.clone()); udp_header.write_to(&mut bufw).unwrap(); - bufw.write(&data).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(); @@ -135,6 +130,10 @@ fn main() { .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() { @@ -152,10 +151,12 @@ fn main() { 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); + 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); + do_udp(&svr_addr, &proxy_addr, &local_addr, msg); } } diff --git a/src/relay/tcprelay/local.rs b/src/relay/tcprelay/local.rs index 6885c52c..51485df8 100644 --- a/src/relay/tcprelay/local.rs +++ b/src/relay/tcprelay/local.rs @@ -29,7 +29,7 @@ use std::collections::BTreeMap; use coio::Builder; use coio::net::{TcpListener, TcpStream, Shutdown}; -use config::Config; +use config::{Config, ClientConfig}; use relay::{self, COROUTINE_STACK_SIZE, socks5}; use relay::loadbalancing::server::{LoadBalancer, RoundRobin}; @@ -74,10 +74,14 @@ impl TcpRelayLocal { resp.write_to(writer) } - fn handle_udp_associate_local(stream: &mut W, addr: SocketAddr, _dest_addr: &socks5::Address) + fn handle_udp_associate_local(stream: &mut W, + _addr: SocketAddr, + _dest_addr: &socks5::Address, + local_conf: ClientConfig) -> io::Result<()> { let reply = socks5::TcpResponseHeader::new(socks5::Reply::Succeeded, - socks5::Address::SocketAddress(addr)); + socks5::Address::SocketAddress(local_conf)); + trace!("Replying Header for UDP ASSOCIATE, {:?}", reply); try!(reply.write_to(stream)); // TODO: record this client's information for udprelay local server to validate @@ -90,7 +94,8 @@ impl TcpRelayLocal { server_addr: SocketAddr, password: Vec, encrypt_method: CipherType, - enable_udp: bool) { + enable_udp: bool, + local_conf: ClientConfig) { let sockname = match stream.peer_addr() { Ok(sockname) => sockname, Err(err) => { @@ -298,7 +303,7 @@ impl TcpRelayLocal { socks5::Command::UdpAssociate => { info!("{} requests for UDP ASSOCIATE", sockname); if cfg!(feature = "enable-udp") && enable_udp { - TcpRelayLocal::handle_udp_associate_local(&mut local_writer, sockname, &addr) + TcpRelayLocal::handle_udp_associate_local(&mut local_writer, sockname, &addr, local_conf) .unwrap_or_else(|err| error!("Failed to write UDP ASSOCIATE response: {:?}", err)); } else { warn!("UDP ASSOCIATE is disabled"); @@ -395,13 +400,15 @@ impl TcpRelayLocal { let encrypt_method = server_cfg.method.clone(); let pwd = encrypt_method.bytes_to_key(server_cfg.password.as_bytes()); let enable_udp = self.config.enable_udp; + let local_conf = local_conf.clone(); Builder::new().stack_size(COROUTINE_STACK_SIZE).spawn(move || TcpRelayLocal::handle_client(stream, server_addr, pwd, encrypt_method, - enable_udp)); + enable_udp, + local_conf)); succeed = true; break; } diff --git a/src/relay/udprelay/local.rs b/src/relay/udprelay/local.rs index 64ba03fd..70093080 100644 --- a/src/relay/udprelay/local.rs +++ b/src/relay/udprelay/local.rs @@ -152,6 +152,7 @@ impl UdpRelayLocal { } None => { let s = server_load_balancer.pick_server().clone(); + debug!("UDP associate picked a server: {:?}", s); match server_addr.get(&s.addr) { Some(saddr) => { diff --git a/src/relay/udprelay/server.rs b/src/relay/udprelay/server.rs index 84e32d0c..9b08f80c 100644 --- a/src/relay/udprelay/server.rs +++ b/src/relay/udprelay/server.rs @@ -47,9 +47,14 @@ impl UdpRelayServer { } fn accept_loop(svr_config: ServerConfig) { - let socket = UdpSocket::bind(&(&svr_config.addr[..], svr_config.port)) - .ok().expect("Unable to bind UDP socket"); - debug!("UDP server is binding {}", svr_config.addr); + let socket = match UdpSocket::bind(&(&svr_config.addr[..], svr_config.port)) { + Ok(sock) => sock, + Err(err) => { + error!("Unable to bind UDP socket: {:?}", err); + return; + } + }; + debug!("UDP server is binding {}:{}", svr_config.addr, svr_config.port); let client_map_arc = Arc::new(Mutex::new( LruCache::::new(UDP_RELAY_SERVER_LRU_CACHE_CAPACITY))); @@ -202,7 +207,8 @@ impl UdpRelayServer { pub fn run(&self) { for s in self.config.server.iter() { let s = s.clone(); - Builder::new().stack_size(COROUTINE_STACK_SIZE).spawn(move || UdpRelayServer::accept_loop(s)); + Builder::new().stack_size(COROUTINE_STACK_SIZE) + .spawn(move || UdpRelayServer::accept_loop(s)); } } }