1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use std::io;
use std::sync::{Arc, Mutex};
use rotor::GenericScope;
use {Query, Resolver, CacheEntry, Request, TimeEntry};
quick_error! {
#[derive(Debug)]
pub enum QueryError {
TruncatedPacket {
description("query results in packet truncation")
}
Net(err: io::Error) {
description(err.description())
display("{}", err)
cause(err)
from()
}
}
}
impl Resolver {
pub fn query<S>(&self, query: Query, scope: &mut GenericScope)
-> Result<Arc<Mutex<Option<Arc<CacheEntry>>>>, QueryError>
where S: GenericScope
{
let ref mut res = *self.0.lock().unwrap();
if let Some(cache) = res.cache.get(&query).map(|x| x.clone()) {
if scope.now() > cache.expire {
res.cache.remove(&query);
} else {
scope.notifier().wakeup().unwrap();
return Ok(Arc::new(Mutex::new(Some(cache.clone()))));
}
}
let server = 0;
let id = try!(res.send_request(&query, server));
let result = Arc::new(Mutex::new(None));
let deadline = scope.now() + res.config.timeout;
res.running.insert(id, Request {
id: id,
query: query,
nameserver_index: server,
attempts: 1,
server: res.config.nameservers[server],
deadline: deadline,
notifiers: vec![(result.clone(), scope.notifier())],
});
res.timeouts.push(TimeEntry(deadline, id));
res.notifier.wakeup().unwrap();
Ok(result)
}
}