debugging udp server

This commit is contained in:
Y. T. Chung
2015-12-12 21:55:03 +08:00
parent cae280c508
commit a1795611df
5 changed files with 40 additions and 25 deletions

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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<W: Write>(stream: &mut W, addr: SocketAddr, _dest_addr: &socks5::Address)
fn handle_udp_associate_local<W: Write>(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<u8>,
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;
}

View File

@@ -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) => {

View File

@@ -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::<Address, SocketAddr>::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));
}
}
}