chiark / gitweb /
893a0700050bd5d27f6c4faf2efabb0f58deef38
[hippotat.git] / server / slocal.rs
1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use super::*;
6
7 #[allow(dead_code)] // xxx
8 #[allow(unused_variables)] // xxx
9 pub async fn run(global: Arc<Global>,
10                  rx: mpsc::Receiver<RoutedPacket>,
11                  mut ipif: Ipif) -> Result<Void,AE> {
12   let r = async {
13     let mut goodness: i32 = 0;
14     const GOODNESS_SHIFT: u8 = 8;
15     const GOODNESS_MIN: i32 = -16;
16
17     loop {
18       select!{
19         biased;
20
21         // xxx something something rx something
22
23         data = Ipif::next_frame(&mut ipif.tx) =>
24         {
25           let data = data?;
26           let may_route = MayRoute::came_from_outside_hippotatd();
27
28           goodness -= goodness >> GOODNESS_SHIFT;
29
30           match checkn(SlipNoConv, global.config.mtu, &data, |header|{
31             let saddr = ip_packet_addr::<false>(header)?;
32             let daddr = ip_packet_addr::<true>(header)?;
33             Ok((saddr,daddr))
34           }, |(data, (saddr, daddr))| {
35             let global = &global;
36             let may_route = &may_route;
37             async move {
38               if ! global.config.vnetwork.iter().any(|n| n.contains(&saddr)) {
39                 // pretent as if this came from route
40                 trace!(
41                   target: "hippotatd",
42  "discard to={:?} via=ipif user=local from-outside-vnets-={:?}",
43                   daddr, saddr);
44                 return Ok(())
45               }
46
47               route_packet(
48                 &global, "ipif", None,
49                 data, daddr, may_route.clone()
50               ).await;
51
52               Ok(())
53             }
54           }, |pe| Ok(match pe {
55             PE::Empty => { },
56             other => throw!(other),
57           })).await {
58             Ok(()) => goodness += 1,
59             Err(e) => {
60               goodness -= 1;
61               error!("[good={}] invalid data from local tx ipif {}",
62                      goodness, e);
63               if goodness < GOODNESS_MIN {
64                 throw!(anyhow!("too many bad packets, too few good ones!"))
65               }
66             },
67           }
68         }
69       }
70     }
71   }.await;
72
73   ipif.quitting(None).await;
74   r
75 }