rx: mpsc::Receiver<RoutedPacket>,
mut ipif: Ipif) -> Result<Void,AE> {
let r = async {
+ let mut goodness: i32 = 0;
+ const GOODNESS_SHIFT: u8 = 8;
+ const GOODNESS_MIN: i32 = -16;
+
loop {
select!{
biased;
// xxx something something rx something
- data = ipif.tx.next_segment() =>
+ data = Ipif::next_frame(&mut ipif.tx) =>
{
- let data = data.context("read from ipif")?;
+ let data = data?;
+ let may_route = MayRoute::came_from_outside_hippotatd();
+
+ goodness -= goodness >> GOODNESS_SHIFT;
+
+ match checkn(SlipNoConv, global.config.mtu, &data, |header|{
+ let saddr = ip_packet_addr::<false>(header)?;
+ let daddr = ip_packet_addr::<true>(header)?;
+ if ! global.config.vnetwork.iter().any(|n| n.contains(&saddr)) {
+ throw!(PE::Src(saddr))
+ }
+ Ok(daddr)
+ }, |(data, daddr)| route_packet(
+ &global, "ipif", None,
+ data, daddr, may_route.clone()
+ ).map(Ok), |pe| Ok(match pe {
+ PE::Empty => { },
+ PE::Src(saddr) => trace!(
+ target: "hippotatd",
+ "ipif local discard outside-vnets saddr={:?}",
+ saddr
+ ),
+ other => throw!(other),
+ })).await {
+ Ok(()) => goodness += 1,
+ Err(e) => {
+ goodness -= 1;
+ error!("[good={}] invalid data from local tx ipif {}",
+ goodness, e);
+ if goodness < GOODNESS_MIN {
+ throw!(anyhow!("too many bad packets, too few good ones!"))
+ }
+ },
+ }
}
}
}