mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-23 15:29:10 +00:00
Pass proxy via URL
This commit is contained in:
parent
0fb58bec5d
commit
3223ca4e22
3 changed files with 64 additions and 42 deletions
|
@ -11,6 +11,7 @@ env_logger = "0.10"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mio = { version = "0.8", features = ["os-poll", "net", "os-ext"] }
|
mio = { version = "0.8", features = ["os-poll", "net", "os-ext"] }
|
||||||
smoltcp = { version = "0.9", features = ["std"] }
|
smoltcp = { version = "0.9", features = ["std"] }
|
||||||
|
url = "2.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ctor = "0.1"
|
ctor = "0.1"
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod socks5;
|
||||||
pub mod tun2proxy;
|
pub mod tun2proxy;
|
||||||
pub mod virtdevice;
|
pub mod virtdevice;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
pub enum ProxyType {
|
pub enum ProxyType {
|
||||||
Socks5,
|
Socks5,
|
||||||
Http,
|
Http,
|
||||||
|
|
103
src/main.rs
103
src/main.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::{SocketAddr, ToSocketAddrs};
|
||||||
|
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::Parser;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
|
|
||||||
use tun2proxy::tun2proxy::Credentials;
|
use tun2proxy::tun2proxy::Credentials;
|
||||||
|
@ -11,55 +11,76 @@ use tun2proxy::{main_entry, ProxyType};
|
||||||
#[command(author, version, about = "Tunnel interface to proxy.", long_about = None)]
|
#[command(author, version, about = "Tunnel interface to proxy.", long_about = None)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// Name of the tun interface
|
/// Name of the tun interface
|
||||||
#[arg(short, long, value_name = "name")]
|
#[arg(short, long, value_name = "name", default_value = "tun0")]
|
||||||
tun: String,
|
tun: String,
|
||||||
|
|
||||||
/// What proxy type to run
|
/// What proxy type to run
|
||||||
#[arg(short, long = "proxy", value_name = "type", value_enum)]
|
#[arg(short, long = "proxy", value_parser = proxy_url_parser)]
|
||||||
proxy_type: ArgProxyType,
|
proxy: ArgProxy,
|
||||||
|
|
||||||
/// Server address with format ip:port
|
|
||||||
#[clap(short, long, value_name = "ip:port")]
|
|
||||||
addr: SocketAddr,
|
|
||||||
|
|
||||||
/// Username for authentication
|
|
||||||
#[clap(long, value_name = "username")]
|
|
||||||
username: Option<String>,
|
|
||||||
|
|
||||||
/// Password for authentication
|
|
||||||
#[clap(long, value_name = "password")]
|
|
||||||
password: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
#[derive(Clone)]
|
||||||
enum ArgProxyType {
|
struct ArgProxy {
|
||||||
/// SOCKS5 server to use
|
proxy_type: ProxyType,
|
||||||
Socks5,
|
addr: SocketAddr,
|
||||||
/// HTTP server to use
|
credentials: Credentials,
|
||||||
Http,
|
}
|
||||||
|
|
||||||
|
fn proxy_url_parser(s: &str) -> Result<ArgProxy, String> {
|
||||||
|
let url = url::Url::parse(s).map_err(|_| format!("`{s}` is not a valid proxy URL"))?;
|
||||||
|
let host = url
|
||||||
|
.host_str()
|
||||||
|
.ok_or(format!("`{s}` does not contain a host"))?;
|
||||||
|
|
||||||
|
let mut url_host = String::from(host);
|
||||||
|
let port = url.port().ok_or(format!("`{s}` does not contain a port"))?;
|
||||||
|
url_host.push(':');
|
||||||
|
url_host.push_str(port.to_string().as_str());
|
||||||
|
|
||||||
|
let mut addr_iter = url_host
|
||||||
|
.to_socket_addrs()
|
||||||
|
.map_err(|_| format!("`{host}` could not be resolved"))?;
|
||||||
|
|
||||||
|
let addr = addr_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(format!("`{host}` does not resolve to a usable IP address"))?;
|
||||||
|
|
||||||
|
let credentials = if url.username() == "" && url.password().is_none() {
|
||||||
|
Credentials::none()
|
||||||
|
} else {
|
||||||
|
Credentials::new(
|
||||||
|
String::from(url.username()),
|
||||||
|
String::from(url.password().unwrap_or("")),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let scheme = url.scheme();
|
||||||
|
|
||||||
|
let proxy_type = match url.scheme().to_ascii_lowercase().as_str() {
|
||||||
|
"socks5" => Some(ProxyType::Socks5),
|
||||||
|
"http" => Some(ProxyType::Http),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.ok_or(format!("`{scheme}` is an invalid proxy type"))?;
|
||||||
|
|
||||||
|
Ok(ArgProxy {
|
||||||
|
proxy_type,
|
||||||
|
addr,
|
||||||
|
credentials,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let credentials = if args.username.is_some() || args.password.is_some() {
|
let addr = args.proxy.addr;
|
||||||
Credentials::new(
|
log::info!("Proxy server: {addr}");
|
||||||
args.username.unwrap_or(String::from("")),
|
|
||||||
args.password.unwrap_or(String::from("")),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Credentials::none()
|
|
||||||
};
|
|
||||||
|
|
||||||
match args.proxy_type {
|
main_entry(
|
||||||
ArgProxyType::Socks5 => {
|
&args.tun,
|
||||||
log::info!("SOCKS5 server: {}", args.addr);
|
args.proxy.addr,
|
||||||
main_entry(&args.tun, args.addr, ProxyType::Socks5, credentials);
|
args.proxy.proxy_type,
|
||||||
}
|
args.proxy.credentials,
|
||||||
ArgProxyType::Http => {
|
);
|
||||||
log::info!("HTTP server: {}", args.addr);
|
|
||||||
main_entry(&args.tun, args.addr, ProxyType::Http, credentials);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue