diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c16bcd..64095f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project follows [semantic versioning](http://semver.org). - [fixed] Fixed wrong hex address formatting - [fixed] Fixed peer exchange for more than 65000 peers - [fixed] Initializing crypto for benchmarks +- [fixed] Removing learned addresses of lost peers ### v0.4.3 (2016-02-02) diff --git a/src/benches.rs b/src/benches.rs index b3ec0e0..b7b47de 100644 --- a/src/benches.rs +++ b/src/benches.rs @@ -60,6 +60,7 @@ fn message_encode(b: &mut Bencher) { b.iter(|| { encode(&mut options, &mut msg, &mut buf[..], &mut crypto); }); + b.bytes = 1400; } #[bench] @@ -73,6 +74,7 @@ fn message_decode(b: &mut Bencher) { b.iter(|| { decode(&mut res, &mut crypto).unwrap(); }); + b.bytes = 1400; } #[bench] @@ -82,7 +84,8 @@ fn switch_learn(b: &mut Bencher) { let peer = "1.2.3.4:5678".to_socket_addrs().unwrap().next().unwrap(); b.iter(|| { table.learn(addr.clone(), None, peer); - }) + }); + b.bytes = 1400; } #[bench] @@ -93,8 +96,8 @@ fn switch_lookup(b: &mut Bencher) { table.learn(addr.clone(), None, peer); b.iter(|| { table.lookup(&addr); - }) - + }); + b.bytes = 1400; } #[bench] @@ -103,7 +106,8 @@ fn ethernet_parse(b: &mut Bencher) { data[5] = 45; b.iter(|| { Frame::parse(&data).unwrap() - }) + }); + b.bytes = 1400; } #[bench] @@ -112,7 +116,8 @@ fn ipv4_parse(b: &mut Bencher) { data[0] = 4*16; b.iter(|| { Packet::parse(&data).unwrap() - }) + }); + b.bytes = 1400; } #[bench] @@ -121,14 +126,16 @@ fn ipv6_parse(b: &mut Bencher) { data[0] = 6*16; b.iter(|| { Packet::parse(&data).unwrap() - }) + }); + b.bytes = 1400; } #[bench] fn now(b: &mut Bencher) { b.iter(|| { util_now() - }) + }); + b.bytes = 1400; } #[bench] @@ -142,6 +149,7 @@ fn epoll_wait(b: &mut Bencher) { b.iter(|| { epoll::wait(epoll_handle, &mut events, 1000).unwrap() }); + b.bytes = 1400; } #[bench] diff --git a/src/cloud.rs b/src/cloud.rs index abc7f9a..313652d 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -250,6 +250,7 @@ impl GenericCloud

{ try!(self.send_msg(addr, &mut Message::Data(payload, start, end))) } else { warn!("Destination for {} not found in peers: {}", dst, addr); + self.table.remove(&dst); } }, None => { @@ -314,6 +315,7 @@ impl GenericCloud

{ }, Message::Close => { self.peers.remove(&peer); + self.table.remove_all(&peer); } } Ok(()) @@ -332,10 +334,10 @@ impl GenericCloud

{ let mut events = [epoll::EpollEvent{events: 0, data: 0}; 2]; let mut buffer = [0; 64*1024]; loop { - let count = try_fail!(epoll::wait(epoll_handle, &mut events, 1000), "Epoll wait failed: {}"); + let count = try_fail!(epoll::wait(epoll_handle, &mut events, 1000), "Epoll wait failed: {}") as usize; // Process events for i in 0..count { - match &events[i as usize].data { + match &events[i].data { &0 => { let (size, src) = try_fail!(self.socket.recv_from(&mut buffer), "Failed to read from network socket: {}"); match decode(&mut buffer[..size], &mut self.crypto).and_then(|(options, msg)| self.handle_net_message(src, options, msg)) { diff --git a/src/ethernet.rs b/src/ethernet.rs index 2ca3e07..a4a4771 100644 --- a/src/ethernet.rs +++ b/src/ethernet.rs @@ -97,7 +97,20 @@ impl Table for SwitchTable { } } - fn remove_all(&mut self, _addr: SocketAddr) { - unimplemented!() + #[inline] + fn remove(&mut self, key: &Address) -> bool { + self.table.remove(key).is_some() + } + + fn remove_all(&mut self, addr: &SocketAddr) { + let mut remove = Vec::new(); + for (key, val) in self.table.iter() { + if &val.address == addr { + remove.push(key.clone()); + } + } + for key in remove { + self.table.remove(&key); + } } } diff --git a/src/ip.rs b/src/ip.rs index ac4ae1e..b26fa0b 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -111,7 +111,40 @@ impl Table for RoutingTable { //nothing to do } - fn remove_all(&mut self, _addr: SocketAddr) { - unimplemented!() + #[inline] + fn remove(&mut self, addr: &Address) -> bool { + let len = addr.len as usize; + let mut found = false; + let mut found_len: isize = -1; + for i in 0..len+1 { + if let Some(group) = self.0.get(&addr.data[0..len-i]) { + for entry in group { + let mut match_len = 0; + for j in 0..addr.len as usize { + let b = addr.data[j] ^ entry.bytes[j]; + if b == 0 { + match_len += 8; + } else { + match_len += b.leading_zeros(); + break; + } + } + if match_len as u8 >= entry.prefix_len && match_len as isize > found_len { + found = true; + found_len = match_len as isize; + } + } + } + } + if found { + self.0.remove(&addr.data[0..found_len as usize]); + } + found + } + + fn remove_all(&mut self, addr: &SocketAddr) { + for (_key, entry) in self.0.iter_mut() { + entry.retain(|entr| &entr.address != addr); + } } } diff --git a/src/types.rs b/src/types.rs index dc58c41..f31ee84 100644 --- a/src/types.rs +++ b/src/types.rs @@ -219,7 +219,8 @@ pub trait Table { fn learn(&mut self, Address, Option, SocketAddr); fn lookup(&mut self, &Address) -> Option; fn housekeep(&mut self); - fn remove_all(&mut self, SocketAddr); + fn remove(&mut self, &Address) -> bool; + fn remove_all(&mut self, &SocketAddr); } pub trait Protocol: Sized {