Implemented reconnect

This commit is contained in:
Dennis Schwerdel 2015-11-20 12:09:07 +01:00
parent a448a26e7f
commit 9dc796d52b
2 changed files with 27 additions and 12 deletions

View File

@ -45,7 +45,7 @@ impl PeerList {
PeerList{peers: HashMap::new(), timeout: timeout} PeerList{peers: HashMap::new(), timeout: timeout}
} }
fn timeout(&mut self) { fn timeout(&mut self) -> Vec<SocketAddr> {
let now = SteadyTime::now(); let now = SteadyTime::now();
let mut del: Vec<SocketAddr> = Vec::new(); let mut del: Vec<SocketAddr> = Vec::new();
for (&addr, &timeout) in &self.peers { for (&addr, &timeout) in &self.peers {
@ -53,10 +53,11 @@ impl PeerList {
del.push(addr); del.push(addr);
} }
} }
for addr in del { for addr in &del {
debug!("Forgot peer: {:?}", addr); debug!("Forgot peer: {:?}", addr);
self.peers.remove(&addr); self.peers.remove(addr);
} }
del
} }
fn contains(&mut self, addr: &SocketAddr) -> bool { fn contains(&mut self, addr: &SocketAddr) -> bool {
@ -135,6 +136,7 @@ impl MacTable {
pub struct EthCloud { pub struct EthCloud {
peers: PeerList, peers: PeerList,
reconnect_peers: Vec<SocketAddr>,
mactable: MacTable, mactable: MacTable,
socket: UdpSocket, socket: UdpSocket,
tapdev: TapDevice, tapdev: TapDevice,
@ -142,7 +144,7 @@ pub struct EthCloud {
next_peerlist: SteadyTime, next_peerlist: SteadyTime,
update_freq: Duration, update_freq: Duration,
buffer_out: [u8; 64*1024], buffer_out: [u8; 64*1024],
last_housekeep: SteadyTime, next_housekeep: SteadyTime,
} }
impl EthCloud { impl EthCloud {
@ -158,6 +160,7 @@ impl EthCloud {
info!("Opened tap device {}", tapdev.ifname()); info!("Opened tap device {}", tapdev.ifname());
EthCloud{ EthCloud{
peers: PeerList::new(peer_timeout), peers: PeerList::new(peer_timeout),
reconnect_peers: Vec::new(),
mactable: MacTable::new(mac_timeout), mactable: MacTable::new(mac_timeout),
socket: socket, socket: socket,
tapdev: tapdev, tapdev: tapdev,
@ -165,7 +168,7 @@ impl EthCloud {
next_peerlist: SteadyTime::now(), next_peerlist: SteadyTime::now(),
update_freq: peer_timeout/2, update_freq: peer_timeout/2,
buffer_out: [0; 64*1024], buffer_out: [0; 64*1024],
last_housekeep: SteadyTime::now() next_housekeep: SteadyTime::now()
} }
} }
@ -182,14 +185,24 @@ impl EthCloud {
} }
} }
pub fn connect<A: ToSocketAddrs + fmt::Display>(&mut self, addr: A) -> Result<(), Error> { pub fn connect<A: ToSocketAddrs + fmt::Display>(&mut self, addr: A, reconnect: bool) -> Result<(), Error> {
info!("Connecting to {}", addr); 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) self.send_msg(addr, &udpmessage::Message::GetPeers)
} }
fn housekeep(&mut self) -> Result<(), Error> { fn housekeep(&mut self) -> Result<(), Error> {
debug!("Running housekeeping..."); debug!("Running housekeeping...");
//self.cache.clear();
self.peers.timeout(); self.peers.timeout();
self.mactable.timeout(); self.mactable.timeout();
if self.next_peerlist <= SteadyTime::now() { if self.next_peerlist <= SteadyTime::now() {
@ -201,6 +214,9 @@ impl EthCloud {
} }
self.next_peerlist = SteadyTime::now() + self.update_freq; self.next_peerlist = SteadyTime::now() + self.update_freq;
} }
for addr in self.reconnect_peers.clone() {
try!(self.connect(addr, false));
}
Ok(()) Ok(())
} }
@ -246,7 +262,7 @@ impl EthCloud {
self.peers.add(&peer); self.peers.add(&peer);
for p in &peers { for p in &peers {
if ! self.peers.contains(p) { if ! self.peers.contains(p) {
try!(self.connect(p)); try!(self.connect(p, false));
} }
} }
}, },
@ -299,12 +315,12 @@ impl EthCloud {
} }
} }
// Do the housekeeping // Do the housekeeping
if self.last_housekeep < SteadyTime::now() + Duration::seconds(1) { if self.next_housekeep < SteadyTime::now() {
match self.housekeep() { match self.housekeep() {
Ok(_) => (), Ok(_) => (),
Err(e) => error!("Error: {:?}", e) Err(e) => error!("Error: {:?}", e)
} }
self.last_housekeep = SteadyTime::now() self.next_housekeep = SteadyTime::now() + Duration::seconds(1)
} }
} }
} }

View File

@ -21,7 +21,6 @@ use ethcloud::{Error, Token, EthCloud};
//TODO: Implement IPv6 //TODO: Implement IPv6
//TODO: Encryption //TODO: Encryption
//TODO: Call close //TODO: Call close
//TODO: Reconnect to peers given on command line
struct SimpleLogger; struct SimpleLogger;
@ -88,7 +87,7 @@ fn main() {
Duration::seconds(args.flag_peer_timeout as i64) Duration::seconds(args.flag_peer_timeout as i64)
); );
for addr in args.flag_connect { 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() tapcloud.run()
} }