Add my_ip feature

pull/34/head
Frank Denis 4 years ago
parent 2a96c5f985
commit 75166216b9

@ -114,6 +114,11 @@ daemonize = false
# chroot = "/var/empty"
## Queries sent to that name will return the client IP address.
## This can be very useful for debugging, or to check that relaying works.
my_ip = "my.ip"
####################################
# DNSCrypt settings #

@ -43,7 +43,7 @@ impl BlackList {
while line.ends_with('.') {
line = &line[..line.len() - 1];
}
let qname = line.as_bytes().to_vec().to_ascii_lowercase();
let qname = line.as_bytes().to_ascii_lowercase();
if qname.is_empty() {
bail!("Unexpected blacklist rule at line {}", line_nb)
}
@ -53,7 +53,7 @@ impl BlackList {
}
pub fn find(&self, qname: &[u8]) -> bool {
let qname = qname.to_vec().to_ascii_lowercase();
let qname = qname.to_ascii_lowercase();
let mut qname = qname.as_slice();
let map = &self.inner.map;
let mut iterations = self.max_iterations;

@ -81,6 +81,7 @@ pub struct Config {
pub daemonize: bool,
pub pid_file: Option<PathBuf>,
pub log_file: Option<PathBuf>,
pub my_ip: Option<String>,
#[cfg(feature = "metrics")]
pub metrics: Option<MetricsConfig>,
pub anonymized_dns: Option<AnonymizedDNSConfig>,

@ -2,7 +2,7 @@ use crate::dnscrypt_certs::*;
use crate::errors::*;
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use std::net::{Ipv4Addr, Ipv6Addr};
use std::net::IpAddr;
use std::sync::Arc;
pub const DNS_MAX_HOSTNAME_SIZE: usize = 256;
@ -622,7 +622,7 @@ pub fn serve_blocked_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error>
Ok(packet)
}
pub fn serve_a_response(client_packet: Vec<u8>, ip: Ipv4Addr) -> Result<Vec<u8>, Error> {
pub fn serve_ip_response(client_packet: Vec<u8>, ip: IpAddr, ttl: u32) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");
ensure!(
@ -637,31 +637,21 @@ pub fn serve_a_response(client_packet: Vec<u8>, ip: Ipv4Addr) -> Result<Vec<u8>,
authoritative_response(&mut packet);
ancount_inc(&mut packet)?;
packet.write_u16::<BigEndian>(0xc000 + DNS_HEADER_SIZE as u16)?;
packet.write_u16::<BigEndian>(DNS_TYPE_A)?;
packet.write_u16::<BigEndian>(DNS_CLASS_INET)?;
packet.write_u32::<BigEndian>(60)?;
packet.extend_from_slice(&ip.octets());
Ok(packet)
}
pub fn serve_aaaa_response(client_packet: Vec<u8>, ip: Ipv6Addr) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");
ensure!(
!is_response(&client_packet),
"Question expected, but got a response instead"
);
let offset = skip_name(&client_packet, DNS_HEADER_SIZE)?;
let mut packet = client_packet;
ensure!(packet.len() - offset >= 4, "Short packet");
packet.truncate(offset + 4);
an_ns_ar_count_clear(&mut packet);
authoritative_response(&mut packet);
ancount_inc(&mut packet)?;
packet.write_u16::<BigEndian>(0xc000 + DNS_HEADER_SIZE as u16)?;
packet.write_u16::<BigEndian>(DNS_TYPE_AAAA)?;
packet.write_u16::<BigEndian>(DNS_CLASS_INET)?;
packet.write_u32::<BigEndian>(60)?;
packet.extend_from_slice(&ip.octets());
match ip {
IpAddr::V4(ip) => {
packet.write_u16::<BigEndian>(DNS_TYPE_A)?;
packet.write_u16::<BigEndian>(DNS_CLASS_INET)?;
packet.write_u32::<BigEndian>(ttl)?;
packet.write_u16::<BigEndian>(4)?;
packet.extend_from_slice(&ip.octets());
}
IpAddr::V6(ip) => {
packet.write_u16::<BigEndian>(DNS_TYPE_AAAA)?;
packet.write_u16::<BigEndian>(DNS_CLASS_INET)?;
packet.write_u32::<BigEndian>(ttl)?;
packet.write_u16::<BigEndian>(16)?;
packet.extend_from_slice(&ip.octets());
}
};
Ok(packet)
}

@ -49,6 +49,7 @@ pub struct Globals {
pub anonymized_dns_allow_non_reserved_ports: bool,
pub anonymized_dns_blacklisted_ips: Vec<IpAddr>,
pub access_control_tokens: Option<Vec<String>>,
pub my_ip: Option<Vec<u8>>,
#[cfg(feature = "metrics")]
#[derivative(Debug = "ignore")]
pub varz: Varz,

@ -704,6 +704,7 @@ fn main() -> Result<(), Error> {
anonymized_dns_allow_non_reserved_ports,
anonymized_dns_blacklisted_ips,
access_control_tokens,
my_ip: config.my_ip.map(|ip| ip.as_bytes().to_ascii_lowercase()),
#[cfg(feature = "metrics")]
varz: Varz::default(),
});

@ -8,7 +8,7 @@ use byteorder::{BigEndian, ByteOrder};
use rand::prelude::*;
use siphasher::sip128::Hasher128;
use std::hash::Hasher;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use tokio::net::{TcpStream, UdpSocket};
use tokio::prelude::*;
@ -169,16 +169,15 @@ pub async fn get_cached_response_or_resolve(
mut packet: &mut Vec<u8>,
) -> Result<Vec<u8>, Error> {
let packet_qname = dns::qname(&packet)?;
if &packet_qname == b"my.ip" {
let client_ip = match client_ctx {
ClientCtx::Udp(u) => u.client_addr,
ClientCtx::Tcp(t) => t.client_connection.peer_addr()?,
if let Some(my_ip) = &globals.my_ip {
if &packet_qname.to_ascii_lowercase() == my_ip {
let client_ip = match client_ctx {
ClientCtx::Udp(u) => u.client_addr,
ClientCtx::Tcp(t) => t.client_connection.peer_addr()?,
}
.ip();
return serve_ip_response(packet.to_vec(), client_ip, 1);
}
.ip();
return match client_ip {
IpAddr::V4(ip) => serve_a_response(packet.to_vec(), ip),
IpAddr::V6(ip) => serve_aaaa_response(packet.to_vec(), ip),
};
}
if let Some(blacklist) = &globals.blacklist {
if blacklist.find(&packet_qname) {

Loading…
Cancel
Save