cs_mwc_bch/network/
seed_iter.rs

1use dns_lookup::lookup_host;
2use rand::{thread_rng, Rng};
3use std::net::IpAddr;
4
5/// Iterates through DNS seeds semi-randomly
6#[derive(Clone)]
7pub struct SeedIter {
8    /// Port that is common to all IPs
9    pub port: u16,
10    seeds: Vec<String>,
11    nodes: Vec<IpAddr>,
12    seed_index: usize,
13    node_index: usize,
14    random_offset: usize,
15}
16
17impl SeedIter {
18    /// Creates a new seed iterator from a list of DNS seeds
19    pub fn new(seeds: &Vec<String>, port: u16) -> SeedIter {
20        SeedIter {
21            seeds: seeds.clone(),
22            port,
23            nodes: Vec::new(),
24            seed_index: 0,
25            node_index: 0,
26            random_offset: thread_rng().gen_range::<usize>(0, 100),
27        }
28    }
29}
30
31impl Iterator for SeedIter {
32    type Item = (IpAddr, u16);
33    fn next(&mut self) -> Option<(IpAddr, u16)> {
34        loop {
35            if self.seed_index == self.seeds.len() {
36                return None;
37            }
38
39            if self.nodes.len() == 0 {
40                let i = (self.seed_index + self.random_offset) % self.seeds.len();
41                info!("Looking up DNS {:?}", self.seeds[i]);
42                match lookup_host(&self.seeds[i]) {
43                    Ok(ip_list) => self.nodes = ip_list,
44                    Err(e) => {
45                        error!("Failed to look up DNS {:?}: {}", self.seeds[i], e);
46                        self.seed_index += 1;
47                        continue;
48                    }
49                }
50            }
51
52            if self.node_index == self.nodes.len() {
53                self.node_index = 0;
54                self.seed_index += 1;
55                self.nodes.clear();
56            } else {
57                let i = (self.node_index + self.random_offset) % self.nodes.len();
58                self.node_index += 1;
59                return Some((self.nodes[i], self.port));
60            }
61        }
62    }
63}