diff options
Diffstat (limited to 'src/firewall.rs')
| -rw-r--r-- | src/firewall.rs | 105 |
1 files changed, 0 insertions, 105 deletions
diff --git a/src/firewall.rs b/src/firewall.rs deleted file mode 100644 index 917fe5f..0000000 --- a/src/firewall.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::collections::HashSet; -use std::sync::{Arc, RwLock, RwLockReadGuard}; - -use anyhow::Result; -use async_trait::async_trait; -use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; - -use crate::transport::EncodedMessage; -use crate::transport::{MessageHandler, ParsedMessage, Transport}; - -#[derive(Debug, Clone, Default, Serialize, Deserialize, ToSchema)] -pub struct FirewallRules { - /// Messages from these peers are dropped before the application sees them. - #[serde(default)] - pub inbound: HashSet<String>, - /// Messages to these peers are silently dropped, like a lossy network. - #[serde(default)] - pub outbound: HashSet<String>, -} - -/// Uses a std lock: checks are tiny and the guard is never held across an await. -#[derive(Default)] -pub struct Firewall { - rules: RwLock<FirewallRules>, -} - -impl Firewall { - fn read(&self) -> RwLockReadGuard<'_, FirewallRules> { - self.rules - .read() - .unwrap_or_else(|poisoned| poisoned.into_inner()) - } - - pub fn rules(&self) -> FirewallRules { - self.read().clone() - } - - pub fn set_rules(&self, rules: FirewallRules) { - *self - .rules - .write() - .unwrap_or_else(|poisoned| poisoned.into_inner()) = rules; - } - - pub fn blocks_inbound(&self, peer: &str) -> bool { - self.read().inbound.contains(peer) - } - - pub fn blocks_outbound(&self, peer: &str) -> bool { - self.read().outbound.contains(peer) - } -} - -pub struct FirewallTransport { - inner: Arc<dyn Transport>, - firewall: Arc<Firewall>, -} - -impl FirewallTransport { - pub fn new(inner: Arc<dyn Transport>, firewall: Arc<Firewall>) -> Self { - Self { inner, firewall } - } -} - -#[async_trait] -impl Transport for FirewallTransport { - fn local_id(&self) -> &str { - self.inner.local_id() - } - - async fn resolve_peer(&self, hint: &str) -> Result<String> { - self.inner.resolve_peer(hint).await - } - - fn encode(&self, peer: &str, message: &ParsedMessage) -> Result<EncodedMessage> { - self.inner.encode(peer, message) - } - - async fn send_encoded(&self, message: &EncodedMessage) -> Result<()> { - if self.firewall.blocks_outbound(&message.peer) { - tracing::trace!(peer = %message.peer, "Firewall dropped outbound message"); - return Ok(()); - } - self.inner.send_encoded(message).await - } - - async fn start_consumer(&self, handler: MessageHandler) -> Result<()> { - let firewall = Arc::clone(&self.firewall); - - self.inner - .start_consumer(Box::new(move |sender, message| { - if firewall.blocks_inbound(&sender) { - tracing::trace!(peer = %sender, "Firewall dropped inbound message"); - return Box::pin(async { Ok(()) }); - } - handler(sender, message) - })) - .await - } - - async fn wait_for_exit(&self) -> std::io::Result<std::process::ExitStatus> { - self.inner.wait_for_exit().await - } -} |
