use socks5_impl::{client::UdpClientImpl, protocol::UserKey, Result};
use std::time::Duration;
#[derive(clap::Parser, Debug, Clone, PartialEq, Eq)]
#[command(author, version, about = "Udp client through socks5 proxy", long_about = None)]
pub struct CmdOpt {
#[clap(short, long, value_name = "addr:port")]
proxy_addr: String,
#[clap(short, long, value_name = "addr:port")]
target_addr: String,
#[clap(short, long, value_name = "data")]
data: String,
#[clap(short, long, value_name = "user name")]
username: Option<String>,
#[clap(short = 'w', long, value_name = "password")]
password: Option<String>,
#[clap(long, value_name = "seconds", default_value = "2")]
timeout: u64,
}
#[tokio::main]
async fn main() -> Result<()> {
let opt: CmdOpt = clap::Parser::parse();
let user_key = match (opt.username, opt.password) {
(Some(username), Some(password)) => Some(UserKey::new(username, password)),
_ => None,
};
let timeout = Duration::from_secs(opt.timeout);
let data = UdpClientImpl::datagram(&opt.proxy_addr, &opt.target_addr, user_key)
.await?
.transfer_data(opt.data.as_bytes(), timeout)
.await?;
println!("{}", std::str::from_utf8(data.as_slice())?);
Ok(())
}