use crust::PeerId;
use lru_time_cache::LruCache;
use maidsafe_utilities;
use message_filter::MessageFilter;
use messages::RoutingMessage;
use std::time::Duration;
const INCOMING_EXPIRY_DURATION_SECS: u64 = 60 * 20;
const OUTGOING_EXPIRY_DURATION_SECS: u64 = 60 * 10;
pub enum FilteringResult {
NewMessage,
KnownMessage,
KnownMessageAndRoute,
}
pub struct RoutingMessageFilter {
incoming: MessageFilter<RoutingMessage>,
incoming_route: MessageFilter<(RoutingMessage, u8)>,
outgoing: LruCache<(u64, PeerId, u8), ()>,
}
impl RoutingMessageFilter {
pub fn new() -> Self {
let incoming_duration = Duration::from_secs(INCOMING_EXPIRY_DURATION_SECS);
let outgoing_duration = Duration::from_secs(OUTGOING_EXPIRY_DURATION_SECS);
RoutingMessageFilter {
incoming: MessageFilter::with_expiry_duration(incoming_duration),
incoming_route: MessageFilter::with_expiry_duration(incoming_duration),
outgoing: LruCache::with_expiry_duration(outgoing_duration),
}
}
pub fn filter_incoming(&mut self, msg: &RoutingMessage, route: u8) -> FilteringResult {
let known_msg = self.incoming.insert(msg) > 1;
let known_msg_rt = self.incoming_route.insert(&(msg.clone(), route)) > 1;
match (known_msg, known_msg_rt) {
(false, false) => FilteringResult::NewMessage,
(true, false) => FilteringResult::KnownMessage,
(_, true) => FilteringResult::KnownMessageAndRoute,
}
}
pub fn filter_outgoing(&mut self, msg: &RoutingMessage, peer_id: &PeerId, route: u8) -> bool {
let hash = maidsafe_utilities::big_endian_sip_hash(msg);
self.outgoing.insert((hash, *peer_id, route), ()).is_some()
}
#[cfg(feature = "use-mock-crust")]
pub fn clear(&mut self) {
self.incoming.clear();
self.incoming_route.clear();
self.outgoing.clear();
}
}