chiark / gitweb /
some done todos
[hippotat.git] / server / slocal.rs
index 3c1f5331c5a50acc244f518c26aabaf4b79f6de1..19944119e00deb2a2b070b3c94bb950b2e10fd27 100644 (file)
@@ -7,19 +7,68 @@ use super::*;
 #[allow(dead_code)] // xxx
 #[allow(unused_variables)] // xxx
 pub async fn run(global: Arc<Global>,
-                 rx: mpsc::Receiver<RoutedPacket>,
+                 mut 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 = rx.recv() =>
+        {
+          let data = data.ok_or_else(|| anyhow!("rx stream end!"))?;
+          let mut data = &*data.data;
+          let mut slip_end = &[SLIP_END][..];
+          let mut buf = Buf::chain(&mut data, &mut slip_end);
+          ipif.rx.write_all_buf(&mut buf).await
+            .context("write to ipif")?;
+        },
 
-        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 process1(SlipNoConv, global.config.mtu, &data, |header|{
+            let saddr = ip_packet_addr::<false>(header)?;
+            let daddr = ip_packet_addr::<true>(header)?;
+            Ok((saddr,daddr))
+          }) {
+            Err(PE::Empty) => { },
+
+            Err(pe) => {
+              goodness -= 1;
+              error!("[good={}] invalid data from local tx ipif {}",
+                     goodness, pe);
+              if goodness < GOODNESS_MIN {
+                throw!(anyhow!("too many bad packets, too few good ones!"))
+              }
+            },
+
+            Ok((ref data, (ref saddr, ref daddr)))
+            if ! global.config.vnetwork.iter().any(|n| n.contains(saddr)) => {
+              // pretent as if this came from route
+              trace!(
+                target: "hippotatd",
+ "discard to={:?} came=ipif user=local len={} outside-vnets: from={:?}",
+                daddr, saddr, data.len());
+            },
+
+            Ok((data, (saddr, daddr))) => {
+              goodness += 1;
+              route_packet(
+                &global, "ipif", None,
+                data, daddr, may_route.clone()
+              ).await;
+            }
+          }
+        },
       }
     }
   }.await;