mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
Ban for 60 seconds after 3 errors, adjust ban times
This commit is contained in:
parent
b85cd9297c
commit
dbf7313d2b
@ -109,6 +109,9 @@ pub enum ChorusError {
|
||||
// Filter is underspecified
|
||||
Scraper,
|
||||
|
||||
// Too many errors
|
||||
TooManyErrors,
|
||||
|
||||
// URL Parse
|
||||
UrlParse(url::ParseError),
|
||||
|
||||
@ -166,6 +169,7 @@ impl std::fmt::Display for ChorusError {
|
||||
ChorusError::Rustls(e) => write!(f, "{e}"),
|
||||
ChorusError::Tungstenite(e) => write!(f, "{e}"),
|
||||
ChorusError::Scraper => write!(f, "Filter is underspecified. Scrapers are not allowed"),
|
||||
ChorusError::TooManyErrors => write!(f, "Too many errors"),
|
||||
ChorusError::UrlParse(e) => write!(f, "{e}"),
|
||||
ChorusError::Utf8(e) => write!(f, "{e}"),
|
||||
ChorusError::Utf8Error => write!(f, "UTF-8 error"),
|
||||
|
||||
@ -49,3 +49,14 @@ lazy_static! {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl Globals {
|
||||
pub async fn ban(ipaddr: std::net::IpAddr, seconds: u64) {
|
||||
let mut until = Time::now();
|
||||
until.0 += seconds;
|
||||
if let Some(current_ban) = GLOBALS.banlist.read().await.get(&ipaddr) {
|
||||
until.0 = current_ban.0.max(until.0);
|
||||
}
|
||||
GLOBALS.banlist.write().await.insert(ipaddr, until);
|
||||
}
|
||||
}
|
||||
|
||||
53
src/main.rs
53
src/main.rs
@ -12,7 +12,7 @@ pub mod web;
|
||||
|
||||
use crate::config::{Config, FriendlyConfig};
|
||||
use crate::error::{ChorusError, Error};
|
||||
use crate::globals::GLOBALS;
|
||||
use crate::globals::{Globals, GLOBALS};
|
||||
use crate::reply::NostrReply;
|
||||
use crate::store::Store;
|
||||
use crate::tls::MaybeTlsStream;
|
||||
@ -251,6 +251,7 @@ async fn handle_http_request(
|
||||
websocket,
|
||||
challenge: TextNonce::new().into_string(),
|
||||
user: None,
|
||||
errcount: 0,
|
||||
};
|
||||
|
||||
// Increment count of active websockets
|
||||
@ -262,17 +263,26 @@ async fn handle_http_request(
|
||||
old_num_websockets + 1
|
||||
);
|
||||
|
||||
// Everybody gets a 4-second ban on disconnect to prevent
|
||||
// rapid reconnection
|
||||
let mut ban_seconds: u64 = 4;
|
||||
|
||||
// Handle the websocket
|
||||
if let Err(e) = ws_service.handle_websocket_stream().await {
|
||||
if matches!(
|
||||
e.inner,
|
||||
match e.inner {
|
||||
ChorusError::Tungstenite(tungstenite::error::Error::Protocol(
|
||||
tungstenite::error::ProtocolError::ResetWithoutClosingHandshake
|
||||
))
|
||||
) {
|
||||
// Swallow the boring error
|
||||
} else {
|
||||
log::error!("{}: {}", peer, e);
|
||||
tungstenite::error::ProtocolError::ResetWithoutClosingHandshake,
|
||||
)) => {
|
||||
// So they disconnected ungracefully.
|
||||
// No big deal, no extra ban for that.
|
||||
}
|
||||
ChorusError::TooManyErrors => {
|
||||
ban_seconds = 60;
|
||||
}
|
||||
_ => {
|
||||
log::error!("{}: {}", peer, e);
|
||||
ban_seconds = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,14 +295,8 @@ async fn handle_http_request(
|
||||
old_num_websockets - 1
|
||||
);
|
||||
|
||||
// Everybody gets a 4 second ban on disconnect, to prevent rapid reconnection
|
||||
let ipaddr = peer.ip();
|
||||
let mut until = Time::now();
|
||||
until.0 += 4;
|
||||
if let Some(current_ban) = GLOBALS.banlist.read().await.get(&ipaddr) {
|
||||
until.0 = current_ban.0.max(until.0);
|
||||
}
|
||||
GLOBALS.banlist.write().await.insert(ipaddr, until);
|
||||
// Ban for the appropriate duration
|
||||
Globals::ban(peer.ip(), ban_seconds).await;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
@ -321,6 +325,7 @@ struct WebSocketService {
|
||||
pub websocket: WebSocketStream<Upgraded>,
|
||||
pub challenge: String,
|
||||
pub user: Option<Pubkey>,
|
||||
pub errcount: usize,
|
||||
}
|
||||
|
||||
impl WebSocketService {
|
||||
@ -392,13 +397,21 @@ impl WebSocketService {
|
||||
async fn handle_websocket_message(&mut self, message: Message) -> Result<(), Error> {
|
||||
match message {
|
||||
Message::Text(msg) => {
|
||||
log::debug!("{}: <= {}", self.peer, msg);
|
||||
log::trace!("{}: <= {}", self.peer, msg);
|
||||
// This is defined in nostr.rs
|
||||
if let Err(e) = self.handle_nostr_message(&msg).await {
|
||||
log::error!("{e}");
|
||||
log::error!("msg was {}", msg);
|
||||
self.errcount += 1;
|
||||
log::error!("{}: {e}", self.peer);
|
||||
log::error!("{}: msg was {}", self.peer, msg);
|
||||
let reply = NostrReply::Notice(format!("error: {}", e));
|
||||
self.websocket.send(Message::text(reply.as_json())).await?;
|
||||
if self.errcount > 3 {
|
||||
let reply = NostrReply::Notice(
|
||||
"Too many errors (3). Banned for 60 seconds.".into(),
|
||||
);
|
||||
self.websocket.send(Message::text(reply.as_json())).await?;
|
||||
return Err(ChorusError::TooManyErrors.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Binary(msg) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user