client_ttl_jitter -> client_ttl_holdon

pull/37/head
Frank Denis 4 years ago
parent 04fdf73046
commit 561ebd07f4

@ -83,11 +83,11 @@ cache_ttl_max = 86400
cache_ttl_error = 600 cache_ttl_error = 600
## DNS cache: to avoid bursts of traffic when an RRSET expires, ## DNS cache: to avoid bursts of traffic for popular queries when an
## introduce jitter to the decreasing TTL sent to clients when the ## RRSET expires, hold a TTL received from an upstream server for
## actual TTL goes below that value. ## `client_ttl_holdon` seconds before decreasing it in client responses.
client_ttl_jitter = 60 client_ttl_holdon = 60
## Run as a background process ## Run as a background process

@ -9,6 +9,7 @@ use std::sync::Arc;
pub struct CachedResponse { pub struct CachedResponse {
response: Vec<u8>, response: Vec<u8>,
expiry: Instant, expiry: Instant,
original_ttl: u32,
} }
impl CachedResponse { impl CachedResponse {
@ -16,24 +17,37 @@ impl CachedResponse {
let ttl = dns::min_ttl(&response, cache.ttl_min, cache.ttl_max, cache.ttl_error) let ttl = dns::min_ttl(&response, cache.ttl_min, cache.ttl_max, cache.ttl_error)
.unwrap_or(cache.ttl_error); .unwrap_or(cache.ttl_error);
let expiry = Instant::recent() + Duration::from_secs(u64::from(ttl)); let expiry = Instant::recent() + Duration::from_secs(u64::from(ttl));
CachedResponse { response, expiry } CachedResponse {
response,
expiry,
original_ttl: ttl,
}
} }
#[inline]
pub fn set_tid(&mut self, tid: u16) { pub fn set_tid(&mut self, tid: u16) {
dns::set_tid(&mut self.response, tid) dns::set_tid(&mut self.response, tid)
} }
#[inline]
pub fn into_response(self) -> Vec<u8> { pub fn into_response(self) -> Vec<u8> {
self.response self.response
} }
#[inline]
pub fn has_expired(&self) -> bool { pub fn has_expired(&self) -> bool {
Instant::recent() > self.expiry Instant::recent() > self.expiry
} }
#[inline]
pub fn ttl(&self) -> u32 { pub fn ttl(&self) -> u32 {
(self.expiry - Instant::recent()).as_secs() as _ (self.expiry - Instant::recent()).as_secs() as _
} }
#[inline]
pub fn original_ttl(&self) -> u32 {
self.original_ttl
}
} }
#[derive(Clone, Derivative)] #[derive(Clone, Derivative)]

@ -82,7 +82,7 @@ pub struct Config {
pub pid_file: Option<PathBuf>, pub pid_file: Option<PathBuf>,
pub log_file: Option<PathBuf>, pub log_file: Option<PathBuf>,
pub my_ip: Option<String>, pub my_ip: Option<String>,
pub client_ttl_jitter: Option<u32>, pub client_ttl_holdon: Option<u32>,
#[cfg(feature = "metrics")] #[cfg(feature = "metrics")]
pub metrics: Option<MetricsConfig>, pub metrics: Option<MetricsConfig>,
pub anonymized_dns: Option<AnonymizedDNSConfig>, pub anonymized_dns: Option<AnonymizedDNSConfig>,

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

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

@ -7,6 +7,7 @@ use crate::ClientCtx;
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use rand::prelude::*; use rand::prelude::*;
use siphasher::sip128::Hasher128; use siphasher::sip128::Hasher128;
use std::cmp;
use std::hash::Hasher; use std::hash::Hasher;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use tokio::net::{TcpStream, UdpSocket}; use tokio::net::{TcpStream, UdpSocket};
@ -226,11 +227,12 @@ pub async fn get_cached_response_or_resolve(
#[cfg(feature = "metrics")] #[cfg(feature = "metrics")]
globals.varz.client_queries_cached.inc(); globals.varz.client_queries_cached.inc();
cached_response.set_tid(original_tid); cached_response.set_tid(original_tid);
let original_ttl = cached_response.original_ttl();
let mut ttl = cached_response.ttl(); let mut ttl = cached_response.ttl();
if ttl < globals.client_ttl_jitter { if ttl.saturating_add(globals.client_ttl_holdon) > original_ttl {
let jitter = rand::thread_rng().gen::<u32>() % globals.client_ttl_jitter; ttl = original_ttl;
ttl = globals.client_ttl_jitter.saturating_add(jitter);
} }
ttl = cmp::max(1, ttl);
let mut response = cached_response.into_response(); let mut response = cached_response.into_response();
dns::set_ttl(&mut response, ttl)?; dns::set_ttl(&mut response, ttl)?;
dns::recase_qname(&mut response, &packet_qname)?; dns::recase_qname(&mut response, &packet_qname)?;

Loading…
Cancel
Save