twizzler_net/
server.rs

1use secgate::TwzError;
2use smoltcp::phy::{DeviceCapabilities, Medium, RxToken, TxToken};
3use twizzler::object::{MapFlags, Object, RawObject};
4use twizzler_abi::syscall::ThreadSyncSleep;
5use twizzler_io::packet::PacketObject;
6use twizzler_queue::{Queue, QueueBase};
7
8use crate::{
9    ClientMsg, ClientMsgKind, ClientRet, INVALID_PACKET, PacketNum, PacketSet, ServerMsg,
10    ServerMsgKind, ServerRet, client::NetClientOpenInfo, endpoint::Pair,
11};
12
13pub struct NetServer {
14    client_tx: Pair<ClientMsg, ServerRet>,
15    client_rx: Pair<ServerMsg, ClientRet>,
16    pending_client_tx: PacketSet,
17    pending_client_id: Option<u32>,
18}
19
20impl NetServer {
21    pub fn client_tx_packet_object(&self) -> &PacketObject {
22        self.client_tx.packet_object()
23    }
24
25    pub fn rx_waiter(&self) -> ThreadSyncSleep {
26        self.client_tx.rx_waiter()
27    }
28
29    pub fn completions_waiter(&self) -> ThreadSyncSleep {
30        self.client_rx.comp_waiters()
31    }
32
33    pub fn has_pending_msg_from_client(&self) -> bool {
34        self.client_tx.has_pending_msg()
35            || self
36                .pending_client_tx
37                .0
38                .iter()
39                .any(|p| *p != INVALID_PACKET)
40    }
41
42    pub fn open(info: &NetClientOpenInfo) -> Result<Self, TwzError> {
43        let tx_queue = Object::<QueueBase<ClientMsg, ServerRet>>::map(
44            info.tx_queue,
45            MapFlags::READ | MapFlags::WRITE,
46        )?;
47        let rx_queue = Object::<QueueBase<ServerMsg, ClientRet>>::map(
48            info.rx_queue,
49            MapFlags::READ | MapFlags::WRITE,
50        )?;
51        let tx = Pair::new(
52            PacketObject::from(Object::map(info.tx_buf, MapFlags::READ | MapFlags::WRITE)?),
53            Queue::from(tx_queue.handle().clone()),
54        );
55        let rx = Pair::new(
56            PacketObject::from(Object::map(info.rx_buf, MapFlags::READ | MapFlags::WRITE)?),
57            Queue::from(rx_queue.handle().clone()),
58        );
59        Ok(Self {
60            client_tx: tx,
61            client_rx: rx,
62            pending_client_id: None,
63            pending_client_tx: PacketSet::new(),
64        })
65    }
66}
67
68impl smoltcp::phy::Device for NetServer {
69    type RxToken<'a>
70        = NetServerRxToken<'a>
71    where
72        Self: 'a;
73
74    type TxToken<'a>
75        = NetServerTxToken<'a>
76    where
77        Self: 'a;
78
79    fn receive(
80        &mut self,
81        timestamp: smoltcp::time::Instant,
82    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
83        let idx = self
84            .pending_client_tx
85            .0
86            .iter()
87            .position(|x| *x != INVALID_PACKET);
88        if let Some(idx) = idx {
89            let next = self.pending_client_tx.0[idx];
90            self.pending_client_tx.0[idx] = INVALID_PACKET;
91            self.client_rx.check_completions();
92
93            return Some((
94                NetServerRxToken {
95                    ns: self,
96                    packet: next,
97                },
98                NetServerTxToken {
99                    ns: self,
100                    packet: self.client_rx.allocate_packet().unwrap(),
101                    consumed: false,
102                },
103            ));
104        }
105
106        if let Some(pending_id) = self.pending_client_id.take() {
107            self.client_tx.complete(pending_id, ServerRet {});
108        }
109
110        let (id, msg) = self.client_tx.recv_msg()?;
111        self.pending_client_id = Some(id);
112        match msg.kind {
113            ClientMsgKind::Tx(packet_set) => {
114                self.pending_client_tx = packet_set;
115            }
116        }
117        self.receive(timestamp)
118    }
119
120    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
121        self.client_rx.check_completions();
122        let packet = self.client_rx.allocate_packet()?;
123        Some(NetServerTxToken {
124            ns: self,
125            packet,
126            consumed: false,
127        })
128    }
129
130    fn capabilities(&self) -> DeviceCapabilities {
131        let mut cap = DeviceCapabilities::default();
132        cap.medium = Medium::Ethernet;
133        cap.max_transmission_unit = 1514;
134        cap.max_burst_size = Some(1);
135        cap
136    }
137}
138
139pub struct NetServerTxToken<'a> {
140    ns: &'a NetServer,
141    pub packet: PacketNum,
142    consumed: bool,
143}
144
145pub struct NetServerRxToken<'a> {
146    ns: &'a NetServer,
147    pub packet: PacketNum,
148}
149
150impl TxToken for NetServerTxToken<'_> {
151    fn consume<R, F>(mut self, len: usize, f: F) -> R
152    where
153        F: FnOnce(&mut [u8]) -> R,
154    {
155        if len > self.ns.client_rx.packet_size() {
156            panic!(
157                "packet size exceeded ({} {})",
158                len,
159                self.ns.client_rx.packet_size()
160            );
161        }
162        let mem = self.ns.client_rx.packet_mem_mut(self.packet);
163        let ret = f(&mut mem[0..len]);
164        self.consumed = true;
165
166        self.ns
167            .client_rx
168            .send_packets(&[self.packet], |s| ServerMsg {
169                kind: ServerMsgKind::Tx(s),
170            })
171            .expect("failed to send packet");
172
173        ret
174    }
175}
176
177impl RxToken for NetServerRxToken<'_> {
178    fn consume<R, F>(self, f: F) -> R
179    where
180        F: FnOnce(&mut [u8]) -> R,
181    {
182        let mem = self.ns.client_tx.packet_mem_mut(self.packet);
183        f(mem)
184    }
185}
186
187impl Drop for NetServerTxToken<'_> {
188    fn drop(&mut self) {
189        if !self.consumed {
190            self.ns.client_rx.release_packet(self.packet);
191        }
192    }
193}