Pick IPv4 or IPv6 wildcard source addresses according to the destination

Fixes #10
pull/12/head
Frank Denis 5 years ago
parent 4c40d334ac
commit 5b77be1ac0

@ -2,7 +2,7 @@ use crate::*;
use byteorder::{BigEndian, ByteOrder};
use failure::ensure;
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::sync::Arc;
use tokio::net::UdpSocket;
@ -52,7 +52,7 @@ pub async fn handle_anonymized_dns(
let upstream_address = SocketAddr::new(ip, port);
ensure!(
!globals.listen_addrs.contains(&upstream_address)
&& globals.external_addr != upstream_address,
&& globals.external_addr != Some(upstream_address),
"Would be relaying to self"
);
let encrypted_packet = &encrypted_packet[ANONYMIZED_DNSCRYPT_OVERHEAD..];
@ -72,7 +72,23 @@ pub async fn handle_anonymized_dns(
!= ANONYMIZED_DNSCRYPT_QUERY_MAGIC,
"Loop detected"
);
let mut ext_socket = UdpSocket::bind(&globals.external_addr).await?;
let mut ext_socket = match globals.external_addr {
Some(x) => UdpSocket::bind(x).await?,
None => match upstream_address {
SocketAddr::V4(_) => {
UdpSocket::bind(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))).await?
}
SocketAddr::V6(s) => {
UdpSocket::bind(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::UNSPECIFIED,
0,
s.flowinfo(),
s.scope_id(),
)))
.await?
}
},
};
ext_socket.connect(&upstream_address).await?;
ext_socket.send(&encrypted_packet).await?;
let mut response = vec![0u8; DNSCRYPT_UDP_RESPONSE_MAX_SIZE];

@ -53,7 +53,7 @@ pub struct FilteringConfig {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Config {
pub listen_addrs: Vec<ListenAddrConfig>,
pub external_addr: IpAddr,
pub external_addr: Option<IpAddr>,
pub upstream_addr: SocketAddr,
pub state_file: PathBuf,
pub udp_timeout: u32,

@ -25,7 +25,7 @@ pub struct Globals {
pub provider_name: String,
pub provider_kp: SignKeyPair,
pub listen_addrs: Vec<SocketAddr>,
pub external_addr: SocketAddr,
pub external_addr: Option<SocketAddr>,
pub upstream_addr: SocketAddr,
pub tls_upstream_addr: Option<SocketAddr>,
pub udp_timeout: Duration,

@ -237,13 +237,12 @@ async fn tls_proxy(
Some(tls_upstream_addr) => tls_upstream_addr,
};
let std_socket = match globals.external_addr {
SocketAddr::V4(_) => net2::TcpBuilder::new_v4()?
.bind(&globals.external_addr)?
.to_tcp_stream()?,
SocketAddr::V6(_) => net2::TcpBuilder::new_v6()?
.only_v6(true)?
.bind(&globals.external_addr)?
.to_tcp_stream()?,
Some(x @ SocketAddr::V4(_)) => net2::TcpBuilder::new_v4()?.bind(&x)?.to_tcp_stream()?,
Some(x @ SocketAddr::V6(_)) => net2::TcpBuilder::new_v6()?.bind(&x)?.to_tcp_stream()?,
None => match tls_upstream_addr {
SocketAddr::V4(_) => net2::TcpBuilder::new_v4()?.to_tcp_stream()?,
SocketAddr::V6(_) => net2::TcpBuilder::new_v6()?.to_tcp_stream()?,
},
};
let mut ext_socket =
TcpStream::connect_std(std_socket, tls_upstream_addr, &Default::default()).await?;
@ -501,7 +500,7 @@ fn main() -> Result<(), Error> {
provider_name if provider_name.starts_with("2.dnscrypt-cert.") => provider_name.to_string(),
provider_name => format!("2.dnscrypt-cert.{}", provider_name),
};
let external_addr = SocketAddr::new(config.external_addr, 0);
let external_addr = config.external_addr.map(|addr| SocketAddr::new(addr, 0));
let mut runtime_builder = tokio::runtime::Builder::new();
runtime_builder.name_prefix("encrypted-dns-");

@ -7,7 +7,7 @@ use byteorder::{BigEndian, ByteOrder};
use rand::prelude::*;
use siphasher::sip128::Hasher128;
use std::hash::Hasher;
use std::net::SocketAddr;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use tokio::net::{TcpStream, UdpSocket};
use tokio::prelude::*;
@ -19,10 +19,15 @@ pub async fn resolve_udp(
has_cached_response: bool,
) -> Result<Vec<u8>, Error> {
let std_socket = match globals.external_addr {
SocketAddr::V4(_) => net2::UdpBuilder::new_v4()?.bind(&globals.external_addr)?,
SocketAddr::V6(_) => net2::UdpBuilder::new_v6()?
.only_v6(true)?
.bind(&globals.external_addr)?,
Some(x @ SocketAddr::V4(_)) => net2::UdpBuilder::new_v4()?.bind(&x)?,
Some(x @ SocketAddr::V6(_)) => net2::UdpBuilder::new_v6()?.bind(&x)?,
None => match globals.upstream_addr {
SocketAddr::V4(_) => net2::UdpBuilder::new_v4()?
.bind(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0)))?,
SocketAddr::V6(s) => net2::UdpBuilder::new_v6()?.bind(SocketAddr::V6(
SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, s.flowinfo(), s.scope_id()),
))?,
},
};
let mut ext_socket = UdpSocket::from_std(std_socket, &Default::default())?;
ext_socket.connect(&globals.upstream_addr).await?;
@ -66,13 +71,12 @@ pub async fn resolve_tcp(
tid: u16,
) -> Result<Vec<u8>, Error> {
let std_socket = match globals.external_addr {
SocketAddr::V4(_) => net2::TcpBuilder::new_v4()?
.bind(&globals.external_addr)?
.to_tcp_stream()?,
SocketAddr::V6(_) => net2::TcpBuilder::new_v6()?
.only_v6(true)?
.bind(&globals.external_addr)?
.to_tcp_stream()?,
Some(x @ SocketAddr::V4(_)) => net2::TcpBuilder::new_v4()?.bind(&x)?.to_tcp_stream()?,
Some(x @ SocketAddr::V6(_)) => net2::TcpBuilder::new_v6()?.bind(&x)?.to_tcp_stream()?,
None => match globals.upstream_addr {
SocketAddr::V4(_) => net2::TcpBuilder::new_v4()?.to_tcp_stream()?,
SocketAddr::V6(_) => net2::TcpBuilder::new_v6()?.to_tcp_stream()?,
},
};
let mut ext_socket =
TcpStream::connect_std(std_socket, &globals.upstream_addr, &Default::default()).await?;

Loading…
Cancel
Save