diff --git a/src/ethcloud.rs b/src/ethcloud.rs index 1a30f41..69360ee 100644 --- a/src/ethcloud.rs +++ b/src/ethcloud.rs @@ -45,7 +45,7 @@ impl PeerList { PeerList{peers: HashMap::new(), timeout: timeout} } - fn timeout(&mut self) { + fn timeout(&mut self) -> Vec { let now = SteadyTime::now(); let mut del: Vec = Vec::new(); for (&addr, &timeout) in &self.peers { @@ -53,10 +53,11 @@ impl PeerList { del.push(addr); } } - for addr in del { + for addr in &del { debug!("Forgot peer: {:?}", addr); - self.peers.remove(&addr); + self.peers.remove(addr); } + del } fn contains(&mut self, addr: &SocketAddr) -> bool { @@ -135,6 +136,7 @@ impl MacTable { pub struct EthCloud { peers: PeerList, + reconnect_peers: Vec, mactable: MacTable, socket: UdpSocket, tapdev: TapDevice, @@ -142,7 +144,7 @@ pub struct EthCloud { next_peerlist: SteadyTime, update_freq: Duration, buffer_out: [u8; 64*1024], - last_housekeep: SteadyTime, + next_housekeep: SteadyTime, } impl EthCloud { @@ -158,6 +160,7 @@ impl EthCloud { info!("Opened tap device {}", tapdev.ifname()); EthCloud{ peers: PeerList::new(peer_timeout), + reconnect_peers: Vec::new(), mactable: MacTable::new(mac_timeout), socket: socket, tapdev: tapdev, @@ -165,7 +168,7 @@ impl EthCloud { next_peerlist: SteadyTime::now(), update_freq: peer_timeout/2, buffer_out: [0; 64*1024], - last_housekeep: SteadyTime::now() + next_housekeep: SteadyTime::now() } } @@ -182,14 +185,24 @@ impl EthCloud { } } - pub fn connect(&mut self, addr: A) -> Result<(), Error> { + pub fn connect(&mut self, addr: A, reconnect: bool) -> Result<(), Error> { info!("Connecting to {}", addr); + if let Ok(mut addrs) = addr.to_socket_addrs() { + while let Some(addr) = addrs.next() { + if self.peers.contains(&addr) { + return Ok(()); + } + } + } + if reconnect { + let addr = addr.to_socket_addrs().unwrap().next().unwrap(); + self.reconnect_peers.push(addr); + } self.send_msg(addr, &udpmessage::Message::GetPeers) } fn housekeep(&mut self) -> Result<(), Error> { debug!("Running housekeeping..."); - //self.cache.clear(); self.peers.timeout(); self.mactable.timeout(); if self.next_peerlist <= SteadyTime::now() { @@ -201,6 +214,9 @@ impl EthCloud { } self.next_peerlist = SteadyTime::now() + self.update_freq; } + for addr in self.reconnect_peers.clone() { + try!(self.connect(addr, false)); + } Ok(()) } @@ -246,7 +262,7 @@ impl EthCloud { self.peers.add(&peer); for p in &peers { if ! self.peers.contains(p) { - try!(self.connect(p)); + try!(self.connect(p, false)); } } }, @@ -299,12 +315,12 @@ impl EthCloud { } } // Do the housekeeping - if self.last_housekeep < SteadyTime::now() + Duration::seconds(1) { + if self.next_housekeep < SteadyTime::now() { match self.housekeep() { Ok(_) => (), Err(e) => error!("Error: {:?}", e) } - self.last_housekeep = SteadyTime::now() + self.next_housekeep = SteadyTime::now() + Duration::seconds(1) } } } diff --git a/src/main.rs b/src/main.rs index 536e3f7..6a940a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,6 @@ use ethcloud::{Error, Token, EthCloud}; //TODO: Implement IPv6 //TODO: Encryption //TODO: Call close -//TODO: Reconnect to peers given on command line struct SimpleLogger; @@ -88,7 +87,7 @@ fn main() { Duration::seconds(args.flag_peer_timeout as i64) ); for addr in args.flag_connect { - tapcloud.connect(&addr as &str).expect("Failed to send"); + tapcloud.connect(&addr as &str, true).expect("Failed to send"); } tapcloud.run() }