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::<true>(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
+ }));
+ },
+ }
}
},
impl SlipMime for Mime2Slip { const CONV_TO: Option<bool> = Some(false); }
impl SlipMime for SlipNoConv { const CONV_TO: Option<bool> = None; }
+#[derive(Debug)]
+pub struct ErrorOnlyBad;
+
+#[throws(ErrorOnlyBad)]
pub fn checkn<AC, EH, OUT, M: SlipMime+Copy>(
mime: M,
mtu: u32,
{
// 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)]