Enable virtual DNS by default for the CLI.

This commit enables virtual DNS by default for the CLI.

Pros for this decision:
  - It works out of the box in most cases.
  - Users do not need to install third-party software.
  - Users do not need to update their /etc/resolv.conf.

Cons:
  - Not every server might support this.
  - Hijacking port 53 without asking is somewhat intrusive.

Also, make the --dns argument an enum type. In the future, native
support for DNS over TCP/TLS might be added. In that case we could e.g.
supply tcp://1.1.1.1 to the --dns argument without breaking the CLI.
This commit is contained in:
B. Blechschmidt 2023-03-23 21:59:18 +01:00
parent 7695ba9c39
commit 6b7f550e7a
3 changed files with 20 additions and 7 deletions

View file

@ -12,13 +12,25 @@ struct Args {
#[arg(short, long, value_name = "name", default_value = "tun0")] #[arg(short, long, value_name = "name", default_value = "tun0")]
tun: String, tun: String,
/// The proxy URL in the form proto://[username[:password]@]host:port /// Proxy URL in the form proto://[username[:password]@]host:port
#[arg(short, long, value_parser = Proxy::from_url, value_name = "URL")] #[arg(short, long, value_parser = Proxy::from_url, value_name = "URL")]
proxy: Proxy, proxy: Proxy,
/// Enable virtual DNS feature /// DNS handling
#[arg(short = 'd', long = "dns")] #[arg(
virtual_dns: bool, short,
long,
value_name = "method",
value_enum,
default_value = "virtual"
)]
dns: ArgDns,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
enum ArgDns {
Virtual,
None,
} }
fn main() { fn main() {
@ -31,7 +43,7 @@ fn main() {
log::info!("Proxy {proxy_type} server: {addr}"); log::info!("Proxy {proxy_type} server: {addr}");
let mut options = Options::new(); let mut options = Options::new();
if args.virtual_dns { if args.dns == ArgDns::Virtual {
options = options.with_virtual_dns(); options = options.with_virtual_dns();
} }

View file

@ -501,7 +501,8 @@ impl<'a> TunToProxy<'a> {
// The connection handler builds up the connection or encapsulates the data. // The connection handler builds up the connection or encapsulates the data.
// Therefore, we now expect it to write data to the server. // Therefore, we now expect it to write data to the server.
self.write_to_server(&resolved_conn); self.write_to_server(&resolved_conn);
} else if resolved_conn.proto == IpProtocol::Udp.into() { } else if resolved_conn.proto == IpProtocol::Udp.into() && resolved_conn.dst.port == 53
{
if let Some(virtual_dns) = &mut self.options.virtdns { if let Some(virtual_dns) = &mut self.options.virtdns {
let payload = &frame[_payload_offset.._payload_offset + _payload_size]; let payload = &frame[_payload_offset.._payload_offset + _payload_size];
if let Some(response) = virtual_dns.receive_query(payload) { if let Some(response) = virtual_dns.receive_query(payload) {

View file

@ -34,7 +34,7 @@ pub struct VirtualDns {
impl Default for VirtualDns { impl Default for VirtualDns {
fn default() -> Self { fn default() -> Self {
let start_addr = Ipv4Addr::from_str("198.18.0.0").unwrap(); let start_addr = Ipv4Addr::from_str("198.18.0.0").unwrap();
let cidr = Ipv4Cidr::new(start_addr.into(), 28); let cidr = Ipv4Cidr::new(start_addr.into(), 15);
Self { Self {
next_addr: start_addr.into(), next_addr: start_addr.into(),