network/manager/
mod.rs

1mod context;
2mod device;
3mod runner;
4mod stack;
5
6use alloc::{vec, vec::Vec};
7pub use context::*;
8use file_system::{DirectCharacterDevice, Path};
9pub use runner::*;
10use smoltcp::{
11    phy::Device,
12    socket::{dns, icmp, tcp, udp},
13};
14use synchronization::once_lock::OnceLock;
15use synchronization::{
16    Arc, blocking_mutex::raw::CriticalSectionRawMutex, rwlock::RwLock, signal::Signal,
17};
18use task::{SpawnerIdentifier, TaskIdentifier};
19use virtual_file_system::VirtualFileSystem;
20
21use crate::{
22    DnsSocket, Error, IcmpSocket, Result, TcpSocket, UdpSocket,
23    manager::{
24        device::NetworkDevice,
25        stack::{Stack, StackInner},
26    },
27};
28
29static MANAGER_INSTANCE: OnceLock<Manager> = OnceLock::new();
30
31pub fn get_instance() -> &'static Manager {
32    MANAGER_INSTANCE
33        .try_get()
34        .expect("Manager is not initialized")
35}
36
37pub fn initialize(
38    _task_manager: &'static task::Manager,
39    _virtual_file_system: &'static VirtualFileSystem,
40    random_device: &'static dyn DirectCharacterDevice,
41) -> &'static Manager {
42    MANAGER_INSTANCE.get_or_init(|| Manager::new(random_device))
43}
44
45pub fn get_smoltcp_time() -> smoltcp::time::Instant {
46    let time_manager = time::get_instance();
47    let current_time = time_manager
48        .get_current_time()
49        .expect("Failed to get current time");
50
51    smoltcp::time::Instant::from_millis(current_time.as_millis() as i64)
52}
53
54type StackList = Vec<Stack>;
55
56pub struct Manager {
57    pub(crate) random_device: &'static dyn DirectCharacterDevice,
58    pub(crate) stacks: RwLock<CriticalSectionRawMutex, StackList>,
59}
60
61impl Manager {
62    pub fn new(random_device: &'static dyn DirectCharacterDevice) -> Self {
63        Manager {
64            random_device,
65            stacks: RwLock::new(Vec::new()),
66        }
67    }
68
69    fn generate_seed(&self) -> Result<u64> {
70        let mut buffer = [0u8; 8];
71        self.random_device
72            .read(&mut buffer, 0)
73            .map_err(Error::FailedToGenerateSeed)?;
74        Ok(u64::from_le_bytes(buffer))
75    }
76
77    pub(crate) async fn find_first_available_stack(stacks: &StackList) -> Option<Stack> {
78        for stack in stacks {
79            let available = stack.with(|s| s.is_available()).await;
80
81            if available {
82                return Some(stack.clone());
83            }
84        }
85
86        None
87    }
88
89    pub(crate) async fn find_stack(stacks: &StackList, name: &str) -> Option<Stack> {
90        for stack in stacks {
91            let stack_name = stack.with(|s| s.name.clone()).await;
92
93            if stack_name.as_str() == name {
94                return Some(stack.clone());
95            }
96        }
97
98        None
99    }
100
101    pub async fn mount_interface(
102        &self,
103        task: TaskIdentifier,
104        name: &str,
105        mut device: impl Device + 'static,
106        controller_device: impl DirectCharacterDevice + 'static,
107        spawner: Option<SpawnerIdentifier>,
108    ) -> Result<()> {
109        let mut stacks = self.stacks.write().await;
110
111        if Self::find_stack(&stacks, name).await.is_some() {
112            return Err(Error::DuplicateIdentifier);
113        }
114
115        let random_seed = self.generate_seed()?;
116        let now = get_smoltcp_time();
117
118        let stack_inner = StackInner::new(name, &mut device, controller_device, random_seed, now);
119
120        // Create a wake signal for runner/stack communication
121        let wake_signal: WakeSignal = Arc::new(Signal::new());
122
123        let stack = Stack::new(stack_inner, wake_signal.clone());
124
125        let mut runner = StackRunner::new(stack.clone(), device, wake_signal);
126
127        let task_manager = task::get_instance();
128
129        task_manager
130            .spawn(
131                task,
132                "Network Interface Runner",
133                spawner,
134                move |_| async move {
135                    runner.run().await;
136                },
137            )
138            .await
139            .map_err(Error::FailedToSpawnNetworkTask)?;
140
141        let path = Path::NETWORK_DEVICES
142            .join(Path::from_str(name))
143            .ok_or(Error::InvalidIdentifier)?;
144
145        let device = NetworkDevice::new(stack.clone());
146
147        let virtual_file_system = virtual_file_system::get_instance();
148
149        match virtual_file_system
150            .create_directory(task, &Path::NETWORK_DEVICES)
151            .await
152        {
153            Ok(_) => {}
154            Err(virtual_file_system::Error::AlreadyExists) => {}
155            Err(e) => return Err(Error::FailedToMountDevice(e)),
156        };
157
158        match virtual_file_system.remove(task, &path).await {
159            Ok(_) => {}
160            Err(virtual_file_system::Error::FileSystem(file_system::Error::NotFound)) => {}
161            Err(e) => return Err(Error::FailedToMountDevice(e)),
162        };
163
164        virtual_file_system
165            .mount_character_device(task, path, device)
166            .await
167            .map_err(Error::FailedToMountDevice)?;
168
169        stacks.push(stack);
170
171        Ok(())
172    }
173
174    pub async fn new_dns_socket(&self, interface_name: Option<&str>) -> Result<DnsSocket> {
175        let stacks = self.stacks.read().await;
176
177        let stack = if let Some(name) = interface_name {
178            Self::find_stack(&stacks, name)
179                .await
180                .ok_or(Error::NotFound)?
181        } else {
182            Self::find_first_available_stack(&stacks)
183                .await
184                .ok_or(Error::NotFound)?
185        };
186
187        let handle = stack
188            .with_mutable(|s| {
189                let socket = dns::Socket::new(&s.dns_servers, vec![]);
190                s.add_socket(socket)
191            })
192            .await;
193
194        let context = SocketContext {
195            handle,
196            stack: stack.clone(),
197            closed: false,
198        };
199        let socket = DnsSocket::new(context);
200
201        Ok(socket)
202    }
203
204    pub async fn new_tcp_socket(
205        &self,
206        transmit_buffer_size: usize,
207        receive_buffer_size: usize,
208        interface_name: Option<&str>,
209    ) -> Result<TcpSocket> {
210        let stacks = self.stacks.read().await;
211
212        let stack = if let Some(name) = interface_name {
213            Self::find_stack(&stacks, name)
214                .await
215                .ok_or(Error::NotFound)?
216        } else {
217            Self::find_first_available_stack(&stacks)
218                .await
219                .ok_or(Error::NotFound)?
220        };
221
222        let send_buffer = tcp::SocketBuffer::new(vec![0u8; transmit_buffer_size]);
223        let receive_buffer = tcp::SocketBuffer::new(vec![0u8; receive_buffer_size]);
224
225        let socket = tcp::Socket::new(receive_buffer, send_buffer);
226        let handle = stack.with_mutable(|s| s.add_socket(socket)).await;
227
228        let context = SocketContext {
229            handle,
230            stack: stack.clone(),
231            closed: false,
232        };
233
234        Ok(TcpSocket::new(context))
235    }
236
237    pub async fn new_udp_socket(
238        &self,
239        transmit_buffer_size: usize,
240        receive_buffer_size: usize,
241        receive_meta_buffer_size: usize,
242        transmit_meta_buffer_size: usize,
243        interface_name: Option<&str>,
244    ) -> Result<UdpSocket> {
245        let stacks = self.stacks.read().await;
246
247        let stack = if let Some(name) = interface_name {
248            Self::find_stack(&stacks, name)
249                .await
250                .ok_or(Error::NotFound)?
251        } else {
252            Self::find_first_available_stack(&stacks)
253                .await
254                .ok_or(Error::NotFound)?
255        };
256
257        let receive_meta_buffer = udp::PacketBuffer::new(
258            vec![udp::PacketMetadata::EMPTY; receive_meta_buffer_size],
259            vec![0u8; receive_buffer_size],
260        );
261        let transmit_meta_buffer = udp::PacketBuffer::new(
262            vec![udp::PacketMetadata::EMPTY; transmit_meta_buffer_size],
263            vec![0u8; transmit_buffer_size],
264        );
265
266        let socket = udp::Socket::new(receive_meta_buffer, transmit_meta_buffer);
267        let handle = stack.with_mutable(|s| s.add_socket(socket)).await;
268
269        let context = SocketContext {
270            handle,
271            stack: stack.clone(),
272            closed: false,
273        };
274
275        Ok(UdpSocket::new(context))
276    }
277
278    pub async fn new_icmp_socket(
279        &self,
280        receive_buffer_size: usize,
281        transmit_buffer_size: usize,
282        receive_meta_buffer_size: usize,
283        transmit_meta_buffer_size: usize,
284        interface_name: Option<&str>,
285    ) -> Result<IcmpSocket> {
286        let stacks = self.stacks.read().await;
287
288        let stack = if let Some(name) = interface_name {
289            Self::find_stack(&stacks, name)
290                .await
291                .ok_or(Error::NotFound)?
292        } else {
293            Self::find_first_available_stack(&stacks)
294                .await
295                .ok_or(Error::NotFound)?
296        };
297
298        let receive_buffer = icmp::PacketBuffer::new(
299            vec![icmp::PacketMetadata::EMPTY; receive_meta_buffer_size],
300            vec![0u8; receive_buffer_size],
301        );
302        let transmit_buffer = icmp::PacketBuffer::new(
303            vec![icmp::PacketMetadata::EMPTY; transmit_meta_buffer_size],
304            vec![0u8; transmit_buffer_size],
305        );
306
307        let socket = icmp::Socket::new(receive_buffer, transmit_buffer);
308        let handle = stack.with_mutable(|s| s.add_socket(socket)).await;
309
310        let context = SocketContext {
311            handle,
312            stack: stack.clone(),
313            closed: false,
314        };
315
316        let socket = IcmpSocket::new(context);
317
318        Ok(socket)
319    }
320}