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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
extern crate ip;
extern crate rotor;
extern crate time;
extern crate rand;
extern crate void;
extern crate dns_parser;
extern crate resolv_conf;
#[macro_use] extern crate quick_error;
mod error;
mod config;
mod fsm;
mod resolver;
use std::io;
use std::marker::PhantomData;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use rotor::{EarlyScope, PollOpt, EventSet, Notifier};
use rotor::mio::udp::UdpSocket;
pub use config::Config;
pub use error::Error;
pub use dns_parser::QueryType;
type Id = u16;
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum Query {
LookupIpv4(String),
}
#[derive(Debug)]
pub enum Answer {
Ipv4(Vec<Ipv4Addr>),
}
struct Request {
id: Id,
query: Query,
server: SocketAddr,
notifiers: Vec<(Arc<Mutex<Option<Arc<CacheEntry>>>>, Notifier)>,
}
#[derive(Debug)]
pub struct CacheEntry {
pub value: Answer,
pub expire: time::SteadyTime,
}
struct DnsMachine {
config: Config,
running: HashMap<Id, Request>,
cache: HashMap<Query, Arc<CacheEntry>>,
sock: UdpSocket,
}
pub struct Fsm<C>(Arc<Mutex<DnsMachine>>, PhantomData<*const C>);
pub struct Resolver(Arc<Mutex<DnsMachine>>);
pub fn create_resolver<C>(scope: &mut EarlyScope, config: Config)
-> Result<(Resolver, Fsm<C>), io::Error>
{
let machine = DnsMachine {
config: config,
running: HashMap::new(),
cache: HashMap::new(),
sock: try!(UdpSocket::bound(&SocketAddr::V4(
SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)))),
};
try!(scope.register(&machine.sock,
EventSet::readable(), PollOpt::level()));
let arc = Arc::new(Mutex::new(machine));
Ok((Resolver(arc.clone()), Fsm(arc.clone(), PhantomData)))
}