Skip to main content

os/net/
port_table.rs

1use alloc::{sync::Arc, vec::Vec};
2use lazy_static::lazy_static;
3use lose_net_stack::packets::tcp::TCPPacket;
4
5use crate::fs::File;
6use crate::sync::UPIntrFreeCell;
7use crate::task::TaskControlBlock;
8
9use super::tcp::TCP;
10
11pub struct Port {
12    pub port: u16,
13    pub receivable: bool,
14    pub schedule: Option<Arc<TaskControlBlock>>,
15}
16
17lazy_static! {
18    static ref LISTEN_TABLE: UPIntrFreeCell<Vec<Option<Port>>> =
19        unsafe { UPIntrFreeCell::new(Vec::new()) };
20}
21
22pub fn listen(port: u16) -> Option<usize> {
23    let mut listen_table = LISTEN_TABLE.exclusive_access();
24    let mut index = usize::MAX;
25    for i in 0..listen_table.len() {
26        if listen_table[i].is_none() {
27            index = i;
28            break;
29        }
30    }
31
32    let listen_port = Port {
33        port,
34        receivable: false,
35        schedule: None,
36    };
37
38    if index == usize::MAX {
39        listen_table.push(Some(listen_port));
40        Some(listen_table.len() - 1)
41    } else {
42        listen_table[index] = Some(listen_port);
43        Some(index)
44    }
45}
46
47// can accept request
48pub fn accept(listen_index: usize, task: Arc<TaskControlBlock>) {
49    let mut listen_table = LISTEN_TABLE.exclusive_access();
50    assert!(listen_index < listen_table.len());
51    let listen_port = listen_table[listen_index].as_mut();
52    assert!(listen_port.is_some());
53    let listen_port = listen_port.unwrap();
54    listen_port.receivable = true;
55    listen_port.schedule = Some(task);
56}
57
58pub fn port_acceptable(listen_index: usize) -> bool {
59    let mut listen_table = LISTEN_TABLE.exclusive_access();
60    assert!(listen_index < listen_table.len());
61
62    let listen_port = listen_table[listen_index].as_mut();
63    listen_port.map_or(false, |x| x.receivable)
64}
65
66// check whether it can accept request
67pub fn check_accept(port: u16, tcp_packet: &TCPPacket) -> Option<()> {
68    LISTEN_TABLE.exclusive_session(|listen_table| {
69        let mut listen_ports: Vec<&mut Option<Port>> = listen_table
70            .iter_mut()
71            .filter(|x| match x {
72                Some(t) => t.port == port && t.receivable == true,
73                None => false,
74            })
75            .collect();
76        if listen_ports.len() == 0 {
77            None
78        } else {
79            let listen_port = listen_ports[0].as_mut().unwrap();
80            let task = listen_port.schedule.clone().unwrap();
81            // wakeup_task(Arc::clone(&listen_port.schedule.clone().unwrap()));
82            listen_port.schedule = None;
83            listen_port.receivable = false;
84
85            accept_connection(port, tcp_packet, task);
86            Some(())
87        }
88    })
89}
90
91pub fn accept_connection(_port: u16, tcp_packet: &TCPPacket, task: Arc<TaskControlBlock>) {
92    let process = task.process.upgrade().unwrap();
93    let mut inner = process.inner_exclusive_access();
94    let fd = inner.alloc_fd();
95
96    let tcp_socket = TCP::new(
97        tcp_packet.source_ip,
98        tcp_packet.dest_port,
99        tcp_packet.source_port,
100        tcp_packet.seq,
101        tcp_packet.ack,
102    );
103
104    inner.fd_table[fd] = Some(Arc::new(tcp_socket));
105
106    let cx = task.inner_exclusive_access().get_trap_cx();
107    cx.x[10] = fd;
108}
109
110// store in the fd_table, delete the listen table when close the application.
111pub struct PortFd(usize);
112
113impl PortFd {
114    pub fn new(port_index: usize) -> Self {
115        PortFd(port_index)
116    }
117}
118
119impl Drop for PortFd {
120    fn drop(&mut self) {
121        LISTEN_TABLE.exclusive_access()[self.0] = None
122    }
123}
124
125impl File for PortFd {
126    fn readable(&self) -> bool {
127        false
128    }
129
130    fn writable(&self) -> bool {
131        false
132    }
133
134    fn read(&self, _buf: crate::mm::UserBuffer) -> usize {
135        0
136    }
137
138    fn write(&self, _buf: crate::mm::UserBuffer) -> usize {
139        0
140    }
141}