Refactor into lib, Implement udp-test -is
to run full test in the same process
This commit is contained in:
parent
e5a318c14c
commit
13314675a7
@ -9,7 +9,8 @@ Testing:
|
|||||||
|
|
||||||
`udp-test` is a utility to send a UDP packet and then receive a UDP packet and ensure they are the same, this verifies packets sent through proxy/proxyd are unmolested
|
`udp-test` is a utility to send a UDP packet and then receive a UDP packet and ensure they are the same, this verifies packets sent through proxy/proxyd are unmolested
|
||||||
`test.sh` runs udp-test against itself and then through proxyd/proxy
|
`test.sh` runs udp-test against itself and then through proxyd/proxy
|
||||||
`udp-test -s` runs udp-test against itself through proxyd/proxy
|
`udp-test -s` runs udp-test against itself through proxyd/proxy by spawning actual binaries
|
||||||
|
`udp-test -is` runs udp-test against itself through proxyd/proxy in same executable by using library, so does not test command line parsing etc
|
||||||
|
|
||||||
Testing with GNU netcat:
|
Testing with GNU netcat:
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use std::process::{exit, Command};
|
use std::process::{exit, Command};
|
||||||
use std::{env, thread};
|
use std::{env, thread};
|
||||||
use wireguard_proxy::Args;
|
use wireguard_proxy::{Args, ProxyClient, ProxyServer};
|
||||||
|
|
||||||
const PONG: [u8; 246] = [
|
const PONG: [u8; 246] = [
|
||||||
0x6A, 0x2, 0x6B, 0xC, 0x6C, 0x3F, 0x6D, 0xC, 0xA2, 0xEA, 0xDA, 0xB6, 0xDC, 0xD6, 0x6E, 0x0,
|
0x6A, 0x2, 0x6B, 0xC, 0x6C, 0x3F, 0x6D, 0xC, 0xA2, 0xEA, 0xDA, 0xB6, 0xDC, 0xD6, 0x6E, 0x0,
|
||||||
@ -70,10 +70,10 @@ impl Server {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let raw_args = env::args().collect();
|
let raw_args = env::args().collect();
|
||||||
let args = Args::new(&raw_args);
|
let args = Args::new(&raw_args);
|
||||||
let first_arg = args.get_str(1, "127.0.0.1:51821");
|
let mut first_arg = args.get_str(1, "127.0.0.1:51821");
|
||||||
if first_arg.contains("-h") {
|
if first_arg.contains("-h") {
|
||||||
println!(
|
println!(
|
||||||
"usage: {} [-h] [-s run a self test through proxy/proxyd] [udp_host, 127.0.0.1:51821] [udp_target, 127.0.0.1:51821] [socket_timeout, 1]",
|
"usage: {} [-h] [-s run a self test through proxy/proxyd] [-is run a self test through proxy/proxyd without spawning other processes] [udp_host, 127.0.0.1:51821] [udp_target, 127.0.0.1:51821] [socket_timeout, 10]",
|
||||||
args.get_str(0, "udp-test")
|
args.get_str(0, "udp-test")
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -123,12 +123,57 @@ fn main() {
|
|||||||
.code()
|
.code()
|
||||||
.expect("could not get udp-test exit code"),
|
.expect("could not get udp-test exit code"),
|
||||||
);
|
);
|
||||||
|
} else if first_arg.contains("-is") {
|
||||||
|
let host = "127.0.0.1:51822";
|
||||||
|
let tcp_host = "127.0.0.1:5555";
|
||||||
|
let sleep = Duration::from_secs(5);
|
||||||
|
|
||||||
|
let proxy_server = ProxyServer::new(
|
||||||
|
tcp_host.to_owned(),
|
||||||
|
host.to_owned(),
|
||||||
|
"127.0.0.1".to_owned(),
|
||||||
|
30000,
|
||||||
|
30100,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"udp_target: {}, udp_bind_host_range: 127.0.0.1:30000-30100, socket_timeout: {:?}",
|
||||||
|
proxy_server.client_handler.udp_target, proxy_server.client_handler.socket_timeout,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("executing: wireguard-proxyd '{}' '{}'", tcp_host, host);
|
||||||
|
thread::spawn(move || proxy_server.start().expect("error running proxy_server"));
|
||||||
|
println!("waiting: {:?} for wireguard-proxyd to come up.....", sleep);
|
||||||
|
thread::sleep(sleep);
|
||||||
|
|
||||||
|
let proxy_client = ProxyClient::new(
|
||||||
|
"127.0.0.1:51821".to_owned(),
|
||||||
|
"127.0.0.1:51820".to_owned(),
|
||||||
|
tcp_host.to_owned().to_owned(),
|
||||||
|
15,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"udp_host: {}, udp_target: {}, tcp_target: {}, socket_timeout: {:?}",
|
||||||
|
proxy_client.udp_host,
|
||||||
|
proxy_client.udp_target,
|
||||||
|
proxy_client.tcp_target,
|
||||||
|
proxy_client.socket_timeout,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("executing: wireguard-proxy");
|
||||||
|
thread::spawn(move || proxy_client.start().expect("error running proxy_client"));
|
||||||
|
println!("waiting: {:?} for wireguard-proxy to come up.....", sleep);
|
||||||
|
thread::sleep(sleep);
|
||||||
|
|
||||||
|
first_arg = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
let server = Server::new(
|
let server = Server::new(
|
||||||
first_arg.to_owned(),
|
first_arg.to_owned(),
|
||||||
args.get_str(2, "127.0.0.1:51821").to_owned(),
|
args.get_str(2, "127.0.0.1:51821").to_owned(),
|
||||||
args.get(3, 1),
|
args.get(3, 10),
|
||||||
);
|
);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
|
@ -1,52 +1,5 @@
|
|||||||
use std::net::{TcpStream, UdpSocket};
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::thread;
|
use wireguard_proxy::{Args, ProxyClient};
|
||||||
use wireguard_proxy::{Args, TcpUdpPipe};
|
|
||||||
|
|
||||||
struct Server {
|
|
||||||
udp_host: String,
|
|
||||||
udp_target: String,
|
|
||||||
tcp_target: String,
|
|
||||||
socket_timeout: Option<Duration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Server {
|
|
||||||
fn new(udp_host: String, udp_target: String, tcp_target: String, secs: u64) -> Server {
|
|
||||||
Server {
|
|
||||||
udp_host,
|
|
||||||
udp_target,
|
|
||||||
tcp_target,
|
|
||||||
socket_timeout: match secs {
|
|
||||||
0 => None,
|
|
||||||
x => Some(Duration::from_secs(x)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start(&self) -> std::io::Result<usize> {
|
|
||||||
let tcp_stream = TcpStream::connect(&self.tcp_target)?;
|
|
||||||
|
|
||||||
tcp_stream.set_read_timeout(self.socket_timeout)?;
|
|
||||||
|
|
||||||
let udp_socket = UdpSocket::bind(&self.udp_host)?;
|
|
||||||
udp_socket.set_read_timeout(self.socket_timeout)?;
|
|
||||||
//udp_socket.connect(&self.udp_target)?; // this isn't strictly needed... just filters who we can receive from
|
|
||||||
|
|
||||||
let mut udp_pipe = TcpUdpPipe::new(tcp_stream, udp_socket);
|
|
||||||
let mut udp_pipe_clone = udp_pipe.try_clone()?;
|
|
||||||
thread::spawn(move || loop {
|
|
||||||
udp_pipe_clone
|
|
||||||
.udp_to_tcp()
|
|
||||||
.expect("cannot write to tcp_clone");
|
|
||||||
});
|
|
||||||
|
|
||||||
loop {
|
|
||||||
udp_pipe.tcp_to_udp()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let raw_args = env::args().collect();
|
let raw_args = env::args().collect();
|
||||||
@ -59,7 +12,7 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let server = Server::new(
|
let proxy_client = ProxyClient::new(
|
||||||
args.get_str(1, "127.0.0.1:51821").to_owned(),
|
args.get_str(1, "127.0.0.1:51821").to_owned(),
|
||||||
args.get_str(2, "127.0.0.1:51820").to_owned(),
|
args.get_str(2, "127.0.0.1:51820").to_owned(),
|
||||||
args.get_str(3, "127.0.0.1:5555").to_owned(),
|
args.get_str(3, "127.0.0.1:5555").to_owned(),
|
||||||
@ -68,8 +21,11 @@ fn main() {
|
|||||||
|
|
||||||
println!(
|
println!(
|
||||||
"udp_host: {}, udp_target: {}, tcp_target: {}, socket_timeout: {:?}",
|
"udp_host: {}, udp_target: {}, tcp_target: {}, socket_timeout: {:?}",
|
||||||
server.udp_host, server.udp_target, server.tcp_target, server.socket_timeout,
|
proxy_client.udp_host,
|
||||||
|
proxy_client.udp_target,
|
||||||
|
proxy_client.tcp_target,
|
||||||
|
proxy_client.socket_timeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
server.start().expect("error running server");
|
proxy_client.start().expect("error running proxy_client");
|
||||||
}
|
}
|
||||||
|
@ -1,70 +1,5 @@
|
|||||||
use std::net::{TcpListener, TcpStream, UdpSocket};
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use wireguard_proxy::{Args, ProxyServer};
|
||||||
use std::thread;
|
|
||||||
use wireguard_proxy::{Args, TcpUdpPipe};
|
|
||||||
|
|
||||||
struct Server {
|
|
||||||
udp_target: String,
|
|
||||||
udp_host: String,
|
|
||||||
udp_low_port: u16,
|
|
||||||
udp_high_port: u16,
|
|
||||||
socket_timeout: Option<Duration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Server {
|
|
||||||
fn new(
|
|
||||||
udp_target: String,
|
|
||||||
udp_host: String,
|
|
||||||
udp_low_port: u16,
|
|
||||||
udp_high_port: u16,
|
|
||||||
secs: u64,
|
|
||||||
) -> Server {
|
|
||||||
Server {
|
|
||||||
udp_target,
|
|
||||||
udp_host,
|
|
||||||
udp_low_port,
|
|
||||||
udp_high_port,
|
|
||||||
socket_timeout: match secs {
|
|
||||||
0 => None,
|
|
||||||
x => Some(Duration::from_secs(x)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_client(&self, tcp_stream: TcpStream) -> std::io::Result<usize> {
|
|
||||||
tcp_stream.set_read_timeout(self.socket_timeout)?;
|
|
||||||
|
|
||||||
let mut port = self.udp_low_port;
|
|
||||||
let udp_socket = loop {
|
|
||||||
match UdpSocket::bind((&self.udp_host[..], port)) {
|
|
||||||
Ok(sock) => break sock,
|
|
||||||
Err(_) => {
|
|
||||||
port += 1;
|
|
||||||
if port > self.udp_high_port {
|
|
||||||
panic!("cannot find free port, increase range?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
udp_socket.set_read_timeout(self.socket_timeout)?;
|
|
||||||
udp_socket.connect(&self.udp_target)?;
|
|
||||||
|
|
||||||
let mut udp_pipe = TcpUdpPipe::new(tcp_stream, udp_socket);
|
|
||||||
let mut udp_pipe_clone = udp_pipe.try_clone()?;
|
|
||||||
thread::spawn(move || loop {
|
|
||||||
udp_pipe_clone
|
|
||||||
.udp_to_tcp()
|
|
||||||
.expect("cannot write to tcp_clone");
|
|
||||||
});
|
|
||||||
|
|
||||||
loop {
|
|
||||||
udp_pipe.tcp_to_udp()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let raw_args = env::args().collect();
|
let raw_args = env::args().collect();
|
||||||
@ -76,7 +11,6 @@ fn main() {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let host = args.get_str(1, "127.0.0.1:5555");
|
|
||||||
|
|
||||||
let udp_bind_host_range_str = args.get_str(3, "127.0.0.1:30000-40000");
|
let udp_bind_host_range_str = args.get_str(3, "127.0.0.1:30000-40000");
|
||||||
let mut udp_bind_host_range = udp_bind_host_range_str.split(":");
|
let mut udp_bind_host_range = udp_bind_host_range_str.split(":");
|
||||||
@ -100,35 +34,21 @@ fn main() {
|
|||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.expect("udp_bind_host_range low port invalid");
|
.expect("udp_bind_host_range low port invalid");
|
||||||
|
|
||||||
let server = Arc::new(Server::new(
|
let proxy_server = ProxyServer::new(
|
||||||
|
args.get_str(1, "127.0.0.1:5555").to_owned(),
|
||||||
args.get_str(2, "127.0.0.1:51820").to_owned(),
|
args.get_str(2, "127.0.0.1:51820").to_owned(),
|
||||||
udp_host.to_string(),
|
udp_host.to_string(),
|
||||||
udp_low_port,
|
udp_low_port,
|
||||||
udp_high_port,
|
udp_high_port,
|
||||||
args.get(4, 0),
|
args.get(4, 0),
|
||||||
));
|
);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"udp_target: {}, udp_bind_host_range: {}, socket_timeout: {:?}",
|
"udp_target: {}, udp_bind_host_range: {}, socket_timeout: {:?}",
|
||||||
server.udp_target, udp_bind_host_range_str, server.socket_timeout,
|
proxy_server.client_handler.udp_target,
|
||||||
|
udp_bind_host_range_str,
|
||||||
|
proxy_server.client_handler.socket_timeout,
|
||||||
);
|
);
|
||||||
|
|
||||||
let listener = TcpListener::bind(&host).unwrap();
|
proxy_server.start().expect("error running proxy_server");
|
||||||
println!("Listening for connections on {}", &host);
|
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
|
||||||
match stream {
|
|
||||||
Ok(stream) => {
|
|
||||||
let server = server.clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
server
|
|
||||||
.handle_client(stream)
|
|
||||||
.expect("error handling connection")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("Unable to connect: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
142
src/lib.rs
142
src/lib.rs
@ -1,6 +1,9 @@
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::{TcpStream, UdpSocket};
|
use std::net::{TcpListener, TcpStream, UdpSocket};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub struct Args<'a> {
|
pub struct Args<'a> {
|
||||||
args: &'a Vec<String>,
|
args: &'a Vec<String>,
|
||||||
@ -74,3 +77,140 @@ impl TcpUdpPipe {
|
|||||||
//assert_eq!(sent, len);
|
//assert_eq!(sent, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ProxyClient {
|
||||||
|
pub udp_host: String,
|
||||||
|
pub udp_target: String,
|
||||||
|
pub tcp_target: String,
|
||||||
|
pub socket_timeout: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyClient {
|
||||||
|
pub fn new(udp_host: String, udp_target: String, tcp_target: String, secs: u64) -> ProxyClient {
|
||||||
|
ProxyClient {
|
||||||
|
udp_host,
|
||||||
|
udp_target,
|
||||||
|
tcp_target,
|
||||||
|
socket_timeout: match secs {
|
||||||
|
0 => None,
|
||||||
|
x => Some(Duration::from_secs(x)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(&self) -> std::io::Result<usize> {
|
||||||
|
let tcp_stream = TcpStream::connect(&self.tcp_target)?;
|
||||||
|
|
||||||
|
tcp_stream.set_read_timeout(self.socket_timeout)?;
|
||||||
|
|
||||||
|
let udp_socket = UdpSocket::bind(&self.udp_host)?;
|
||||||
|
udp_socket.set_read_timeout(self.socket_timeout)?;
|
||||||
|
//udp_socket.connect(&self.udp_target)?; // this isn't strictly needed... just filters who we can receive from
|
||||||
|
|
||||||
|
let mut udp_pipe = TcpUdpPipe::new(tcp_stream, udp_socket);
|
||||||
|
let mut udp_pipe_clone = udp_pipe.try_clone()?;
|
||||||
|
thread::spawn(move || loop {
|
||||||
|
udp_pipe_clone
|
||||||
|
.udp_to_tcp()
|
||||||
|
.expect("cannot write to tcp_clone");
|
||||||
|
});
|
||||||
|
|
||||||
|
loop {
|
||||||
|
udp_pipe.tcp_to_udp()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ProxyServer {
|
||||||
|
pub tcp_host: String,
|
||||||
|
pub client_handler: Arc<ProxyServerClientHandler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyServer {
|
||||||
|
pub fn new(
|
||||||
|
tcp_host: String,
|
||||||
|
udp_target: String,
|
||||||
|
udp_host: String,
|
||||||
|
udp_low_port: u16,
|
||||||
|
udp_high_port: u16,
|
||||||
|
secs: u64,
|
||||||
|
) -> ProxyServer {
|
||||||
|
let client_handler = Arc::new(ProxyServerClientHandler {
|
||||||
|
udp_target,
|
||||||
|
udp_host,
|
||||||
|
udp_low_port,
|
||||||
|
udp_high_port,
|
||||||
|
socket_timeout: match secs {
|
||||||
|
0 => None,
|
||||||
|
x => Some(Duration::from_secs(x)),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ProxyServer {
|
||||||
|
tcp_host,
|
||||||
|
client_handler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(&self) -> std::io::Result<()> {
|
||||||
|
let listener = TcpListener::bind(&self.tcp_host)?;
|
||||||
|
println!("Listening for connections on {}", &self.tcp_host);
|
||||||
|
|
||||||
|
for stream in listener.incoming() {
|
||||||
|
match stream {
|
||||||
|
Ok(stream) => {
|
||||||
|
let client_handler = self.client_handler.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
client_handler
|
||||||
|
.handle_client(stream)
|
||||||
|
.expect("error handling connection")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Unable to connect: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ProxyServerClientHandler {
|
||||||
|
pub udp_target: String,
|
||||||
|
pub udp_host: String,
|
||||||
|
pub udp_low_port: u16,
|
||||||
|
pub udp_high_port: u16,
|
||||||
|
pub socket_timeout: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyServerClientHandler {
|
||||||
|
pub fn handle_client(&self, tcp_stream: TcpStream) -> std::io::Result<usize> {
|
||||||
|
tcp_stream.set_read_timeout(self.socket_timeout)?;
|
||||||
|
|
||||||
|
let mut port = self.udp_low_port;
|
||||||
|
let udp_socket = loop {
|
||||||
|
match UdpSocket::bind((&self.udp_host[..], port)) {
|
||||||
|
Ok(sock) => break sock,
|
||||||
|
Err(_) => {
|
||||||
|
port += 1;
|
||||||
|
if port > self.udp_high_port {
|
||||||
|
panic!("cannot find free port, increase range?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
udp_socket.set_read_timeout(self.socket_timeout)?;
|
||||||
|
udp_socket.connect(&self.udp_target)?;
|
||||||
|
|
||||||
|
let mut udp_pipe = TcpUdpPipe::new(tcp_stream, udp_socket);
|
||||||
|
let mut udp_pipe_clone = udp_pipe.try_clone()?;
|
||||||
|
thread::spawn(move || loop {
|
||||||
|
udp_pipe_clone
|
||||||
|
.udp_to_tcp()
|
||||||
|
.expect("cannot write to tcp_clone");
|
||||||
|
});
|
||||||
|
|
||||||
|
loop {
|
||||||
|
udp_pipe.tcp_to_udp()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user