From: Ian Jackson Date: Sun, 8 Aug 2021 01:41:44 +0000 (+0100) Subject: client: rate limit when returned data contains only junk X-Git-Tag: hippotat/1.0.0~231 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=a2117ea7988c6479b52293ffb1b3a54853515908;p=hippotat.git client: rate limit when returned data contains only junk Signed-off-by: Ian Jackson --- diff --git a/src/bin/client.rs b/src/bin/client.rs index 491fec3..c796586 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -273,14 +273,21 @@ async fn run_client( reqs.swap_remove(goti); if let Some(got) = got { - reporter.lock().success(); + //eprintln!("got={:?}", DumpHex(&got)); - checkn(SlipNoConv,ic.mtu, &got, &mut rx_queue, |header| { + match checkn(SlipNoConv,ic.mtu, &got, &mut rx_queue, |header| { let addr = ip_packet_addr::(header)?; if addr != ic.link.client.0 { throw!(PE::Dst(addr)) } Ok(()) - }, |e| error!("{} #{}: rx discarding: {}", &ic, req_num, e)); - + }, |e| error!("{} #{}: rx discarding: {}", &ic, req_num, e)) { + Ok(()) => reporter.lock().success(), + Err(ErrorOnlyBad) => { + reqs.push(Box::pin(async { + tokio::time::sleep(ic.http_retry).await; + None + })); + }, + } } }, diff --git a/src/slip.rs b/src/slip.rs index 9baf875..397aa54 100644 --- a/src/slip.rs +++ b/src/slip.rs @@ -24,6 +24,10 @@ impl SlipMime for Slip2Mime { const CONV_TO: Option = Some(true); } impl SlipMime for Mime2Slip { const CONV_TO: Option = Some(false); } impl SlipMime for SlipNoConv { const CONV_TO: Option = None; } +#[derive(Debug)] +pub struct ErrorOnlyBad; + +#[throws(ErrorOnlyBad)] pub fn checkn( mime: M, mtu: u32, @@ -37,13 +41,17 @@ pub fn checkn( { // eprintln!("before: {:?}", DumpHex(data)); if data.is_empty() { return } + let mut ok = false; + let mut err = false; for packet in data.split(|&c| c == SLIP_END) { match check1(mime, mtu, packet, addr_chk) { - Err(e) => error_handler(e), - Ok(packet) => out.extend(iter::once(packet)), + Err(PacketError::Empty) => { } + Err(e) => { err=true; error_handler(e); }, + Ok(packet) => { ok=true; out.extend(iter::once(packet)); }, } } // eprintln!(" after: {:?}", DumpHex(data)); + if err && !ok { throw!(ErrorOnlyBad) } } #[throws(PacketError)]