chiark / gitweb /
wip server
[hippotat.git] / server / slocal.rs
index 919c33882cb8a123bcb64d09aa091e8faeb9e86f..56dd853ddfd41782654c83b422343db7ed6a6bda 100644 (file)
@@ -5,8 +5,53 @@
 use super::*;
 
 #[allow(dead_code)] // xxx
-#[throws(PacketError)]
-pub async fn run(_global: &Global,
-                 _rx: mpsc::Receiver<RoutedPacket>) {
-  
+#[allow(unused_variables)] // xxx
+pub async fn run(global: Arc<Global>,
+                 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::next_frame(&mut ipif.tx) =>
+        {
+          let data = data?;
+          let may_route = MayRoute::came_from_outside_hippotatd();
+
+          goodness -= goodness >> GOODNESS_SHIFT;
+
+          match checkn(SlipNoConv, global.config.mtu, &data, |header|{
+            // don't really check the addresses: trusting our local knrel
+            ip_packet_addr::<true>(header)
+          }, |(data, daddr)| route_packet(
+            &global, "ipif", None,
+            data, daddr, may_route.clone()
+          ).map(Ok), |pe| match pe {
+            PE::Empty => Ok(()),
+            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!"))
+              }
+            },
+          }
+        }
+      }
+    }
+  }.await;
+
+  ipif.quitting(None).await;
+  r
 }