1 use crate::dns;
2 
3 use clockpro_cache::ClockProCache;
4 use coarsetime::{Duration, Instant};
5 use parking_lot::{Mutex, MutexGuard};
6 use std::sync::Arc;
7 
8 #[derive(Clone, Debug)]
9 pub struct CachedResponse {
10     response: Vec<u8>,
11     expiry: Instant,
12     original_ttl: u32,
13 }
14 
15 impl CachedResponse {
new(cache: &Cache, response: Vec<u8>) -> Self16     pub fn new(cache: &Cache, response: Vec<u8>) -> Self {
17         let ttl = dns::min_ttl(&response, cache.ttl_min, cache.ttl_max, cache.ttl_error)
18             .unwrap_or(cache.ttl_error);
19         let expiry = Instant::recent() + Duration::from_secs(u64::from(ttl));
20         CachedResponse {
21             response,
22             expiry,
23             original_ttl: ttl,
24         }
25     }
26 
27     #[inline]
set_tid(&mut self, tid: u16)28     pub fn set_tid(&mut self, tid: u16) {
29         dns::set_tid(&mut self.response, tid)
30     }
31 
32     #[inline]
into_response(self) -> Vec<u8>33     pub fn into_response(self) -> Vec<u8> {
34         self.response
35     }
36 
37     #[inline]
has_expired(&self) -> bool38     pub fn has_expired(&self) -> bool {
39         Instant::recent() > self.expiry
40     }
41 
42     #[inline]
ttl(&self) -> u3243     pub fn ttl(&self) -> u32 {
44         (self.expiry - Instant::recent()).as_secs() as _
45     }
46 
47     #[inline]
original_ttl(&self) -> u3248     pub fn original_ttl(&self) -> u32 {
49         self.original_ttl
50     }
51 }
52 
53 #[derive(Clone, Derivative)]
54 #[derivative(Debug)]
55 pub struct Cache {
56     #[derivative(Debug = "ignore")]
57     cache: Arc<Mutex<ClockProCache<u128, CachedResponse>>>,
58     pub ttl_min: u32,
59     pub ttl_max: u32,
60     pub ttl_error: u32,
61 }
62 
63 impl Cache {
new( clockpro_cache: ClockProCache<u128, CachedResponse>, ttl_min: u32, ttl_max: u32, ttl_error: u32, ) -> Self64     pub fn new(
65         clockpro_cache: ClockProCache<u128, CachedResponse>,
66         ttl_min: u32,
67         ttl_max: u32,
68         ttl_error: u32,
69     ) -> Self {
70         Cache {
71             cache: Arc::new(Mutex::new(clockpro_cache)),
72             ttl_min,
73             ttl_max,
74             ttl_error,
75         }
76     }
77 
78     #[inline]
lock(&self) -> MutexGuard<'_, ClockProCache<u128, CachedResponse>>79     pub fn lock(&self) -> MutexGuard<'_, ClockProCache<u128, CachedResponse>> {
80         self.cache.lock()
81     }
82 }
83