mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
debugging udp server
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user