Skip to content

Commit 50b9e44

Browse files
Socket::INet: recv
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent d29cb66 commit 50b9e44

File tree

8 files changed

+143
-14
lines changed

8 files changed

+143
-14
lines changed

src/aero_kernel/src/drivers/e1000.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ impl Device {
592592
}
593593

594594
fn handle_irq(&self) {
595-
self.e1000.lock().handle_irq()
595+
self.e1000.lock_irq().handle_irq()
596596
}
597597
}
598598

src/aero_kernel/src/net/ethernet.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,13 @@ impl PacketHeader<Header> for Packet<Eth> {
8585
super::default_device().send(packet);
8686
}
8787
}
88+
89+
fn recv(&self) {
90+
match self.header().typ {
91+
Type::Ip => {
92+
let packet: Packet<ip::Ipv4> = self.upgrade();
93+
packet.recv()
94+
}
95+
}
96+
}
8897
}

src/aero_kernel/src/net/ip.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ impl Header {
6363
fn set_length(&mut self, length: u16) {
6464
self.length = BigEndian::from(length);
6565
}
66+
67+
fn length(&self) -> BigEndian<u16> {
68+
self.length
69+
}
6670
}
6771

6872
#[derive(Clone)]
@@ -103,4 +107,17 @@ impl PacketHeader<Header> for Packet<Ipv4> {
103107
fn send(&self) {
104108
self.downgrade().send() // send the ethernet packet
105109
}
110+
111+
fn recv(&self) {
112+
let mut packet = self.clone();
113+
let header = self.header();
114+
115+
packet.len = header.length().to_native() as usize;
116+
match header.protocol {
117+
Type::Udp => {
118+
let packet: Packet<udp::Udp> = packet.upgrade();
119+
packet.recv();
120+
}
121+
}
122+
}
106123
}

src/aero_kernel/src/net/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub trait PacketBaseTrait {
7979
pub trait PacketTrait: PacketBaseTrait {
8080
fn header_size(&self) -> usize;
8181

82+
// TODO: Rename as_slice{_mut} to payload{_mut}?
8283
fn as_slice_mut(&mut self) -> &mut [u8] {
8384
let hsize = self.header_size();
8485

@@ -87,6 +88,15 @@ pub trait PacketTrait: PacketBaseTrait {
8788

8889
unsafe { core::slice::from_raw_parts_mut(start.as_mut_ptr(), size) }
8990
}
91+
92+
fn as_slice(&self) -> &[u8] {
93+
let hsize = self.header_size();
94+
95+
let start = self.addr() + hsize;
96+
let size = self.len() - hsize;
97+
98+
unsafe { core::slice::from_raw_parts(start.as_ptr(), size) }
99+
}
90100
}
91101

92102
impl<T: ConstPacketKind> PacketTrait for Packet<T> {
@@ -138,6 +148,7 @@ pub trait PacketDownHierarchy<B: ConstPacketKind>: PacketBaseTrait {
138148

139149
pub trait PacketHeader<H>: PacketBaseTrait {
140150
fn send(&self);
151+
fn recv(&self);
141152

142153
fn header(&self) -> &H {
143154
self.addr().read_mut::<H>().unwrap()
@@ -155,9 +166,8 @@ fn packet_processor_thread() {
155166
let device = default_device();
156167

157168
loop {
158-
log::debug!("bruh!");
159169
let packet = device.recv();
160-
log::debug!("{packet:?}");
170+
packet.packet.recv();
161171
}
162172
}
163173

src/aero_kernel/src/net/udp.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ impl PacketHeader<Header> for Packet<Udp> {
6262

6363
self.downgrade().send() // send the IP packet
6464
}
65+
66+
fn recv(&self) {
67+
let header = self.header();
68+
let dest_port = header.dst_port().to_native();
69+
70+
let handlers = HANDLERS.read();
71+
let handler = handlers
72+
.get(&dest_port)
73+
.expect("udp: no handler registered");
74+
75+
handler.recv(self.clone())
76+
}
6577
}
6678

6779
#[repr(C, packed)]
@@ -82,11 +94,17 @@ impl Header {
8294
checksum::calculate_with_len(self, length.to_native() as usize),
8395
]);
8496
}
97+
98+
fn dst_port(&self) -> BigEndian<u16> {
99+
self.dst_port
100+
}
85101
}
86102

87103
static HANDLERS: RwLock<BTreeMap<u16, Arc<dyn UdpHandler>>> = RwLock::new(BTreeMap::new());
88104

89-
pub trait UdpHandler: Send + Sync {}
105+
pub trait UdpHandler: Send + Sync {
106+
fn recv(&self, packet: Packet<Udp>);
107+
}
90108

91109
pub fn alloc_ephemeral_port(socket: Arc<dyn UdpHandler>) -> Option<u16> {
92110
const EPHEMERAL_START: u16 = 49152;

src/aero_kernel/src/socket/inet.rs

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
1717
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919

20-
use aero_syscall::{IpProtocol, SocketAddrInet, SocketType, SyscallError};
20+
use aero_syscall::socket::MessageHeader;
21+
use aero_syscall::{IpProtocol, OpenFlags, SocketAddrInet, SocketType, SyscallError};
2122
use alloc::sync::{Arc, Weak};
2223
use alloc::vec::Vec;
24+
use spin::Once;
2325

24-
use crate::fs::inode::{FileType, INodeInterface, Metadata};
26+
use crate::fs::cache::DirCacheItem;
27+
use crate::fs::file_table::FileHandle;
28+
use crate::fs::inode::{FileType, INodeInterface, Metadata, PollFlags};
2529
use crate::fs::{self, FileSystemError};
2630
use crate::net::ip::Ipv4Addr;
2731
use crate::net::udp::{self, Udp, UdpHandler};
2832
use crate::net::{Packet, PacketHeader, PacketTrait};
29-
use crate::utils::sync::Mutex;
33+
use crate::utils::sync::{BlockQueue, Mutex};
3034

3135
#[derive(Default)]
3236
enum SocketState {
@@ -41,22 +45,32 @@ struct InetSocketInner {
4145
/// The address that the socket has been bound to.
4246
address: Option<SocketAddrInet>,
4347
state: SocketState,
48+
incoming: Vec<Packet<Udp>>,
4449
}
4550

4651
pub struct InetSocket {
4752
typ: SocketType,
4853
protocol: IpProtocol,
4954
inner: Mutex<InetSocketInner>,
55+
wq: BlockQueue,
56+
handle: Once<Arc<FileHandle>>,
5057

5158
sref: Weak<Self>,
5259
}
5360

5461
impl InetSocket {
5562
pub fn new(typ: SocketType, protocol: IpProtocol) -> Result<Arc<Self>, SyscallError> {
63+
if typ != SocketType::Dgram && protocol != IpProtocol::Udp {
64+
return Err(SyscallError::EINVAL);
65+
}
66+
5667
Ok(Arc::new_cyclic(|sref| Self {
5768
typ,
5869
protocol,
5970

71+
wq: BlockQueue::new(),
72+
handle: Once::new(),
73+
6074
inner: Mutex::new(Default::default()),
6175
sref: sref.clone(),
6276
}))
@@ -88,9 +102,27 @@ impl InetSocket {
88102
_ => unreachable!(),
89103
}
90104
}
105+
106+
pub fn is_non_block(&self) -> bool {
107+
self.handle
108+
.get()
109+
.expect("inet: not bound to an fd")
110+
.flags
111+
.read()
112+
.contains(OpenFlags::O_NONBLOCK)
113+
}
91114
}
92115

93116
impl INodeInterface for InetSocket {
117+
fn open(
118+
&self,
119+
_flags: aero_syscall::OpenFlags,
120+
handle: Arc<FileHandle>,
121+
) -> fs::Result<Option<DirCacheItem>> {
122+
self.handle.call_once(|| handle);
123+
Ok(None)
124+
}
125+
94126
fn metadata(&self) -> fs::Result<fs::inode::Metadata> {
95127
Ok(Metadata {
96128
id: 0,
@@ -130,7 +162,7 @@ impl INodeInterface for InetSocket {
130162
}
131163
}
132164

133-
fn send(&self, message_hdr: &mut aero_syscall::socket::MessageHeader) -> fs::Result<usize> {
165+
fn send(&self, message_hdr: &mut MessageHeader) -> fs::Result<usize> {
134166
let name = message_hdr
135167
.name_mut::<SocketAddrInet>()
136168
.cloned()
@@ -139,9 +171,17 @@ impl INodeInterface for InetSocket {
139171
let dest_port = name.port.to_native();
140172
let dest_ip = Ipv4Addr::new(name.addr());
141173

142-
let src_port = self.src_port().unwrap_or_else(|| {
143-
udp::alloc_ephemeral_port(self.sref()).expect("inet: out of ephemeral ports")
144-
});
174+
let src_port;
175+
176+
if let Some(port) = self.src_port() {
177+
src_port = port;
178+
} else {
179+
src_port = udp::alloc_ephemeral_port(self.sref()).ok_or(FileSystemError::WouldBlock)?;
180+
log::debug!("Inet::send(): allocated ephemeral port {}", src_port);
181+
182+
// FIXME: handle ephemeral port INET socket
183+
return Err(FileSystemError::NotSupported);
184+
}
145185

146186
let data = message_hdr
147187
.iovecs()
@@ -159,6 +199,41 @@ impl INodeInterface for InetSocket {
159199
packet.send();
160200
Ok(data.len())
161201
}
202+
203+
fn recv(&self, message_hdr: &mut MessageHeader) -> fs::Result<usize> {
204+
if self.inner.lock_irq().incoming.is_empty() && self.is_non_block() {
205+
return Err(FileSystemError::WouldBlock);
206+
}
207+
208+
let mut this = self.wq.block_on(&self.inner, |e| !e.incoming.is_empty())?;
209+
let packet = this.incoming.pop().expect("recv: someone was greedy");
210+
211+
let mut data = packet.as_slice().to_vec();
212+
213+
Ok(message_hdr
214+
.iovecs_mut()
215+
.iter_mut()
216+
.map(|iovec| {
217+
let iovec = iovec.as_slice_mut();
218+
let size = core::cmp::min(iovec.len(), data.len());
219+
iovec.copy_from_slice(&data.drain(..size).collect::<Vec<_>>());
220+
size
221+
})
222+
.sum::<usize>())
223+
}
224+
225+
fn poll(&self, table: Option<&mut fs::inode::PollTable>) -> fs::Result<PollFlags> {
226+
if let Some(table) = table {
227+
table.insert(&self.wq);
228+
}
229+
230+
Ok(PollFlags::OUT)
231+
}
162232
}
163233

164-
impl UdpHandler for InetSocket {}
234+
impl UdpHandler for InetSocket {
235+
fn recv(&self, packet: Packet<Udp>) {
236+
self.inner.lock_irq().incoming.push(packet);
237+
self.wq.notify_complete();
238+
}
239+
}

src/aero_kernel/src/syscall/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallErro
381381

382382
aero_syscall::prelude::F_SETFL => {
383383
let flags = OpenFlags::from_bits_truncate(arg);
384-
handle.flags.write().insert(flags);
384+
*handle.flags.write() = flags;
385385

386386
Ok(0)
387387
}

src/aero_kernel/src/syscall/net.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn create_socket(
124124

125125
let socket = match domain as u32 {
126126
AF_UNIX => UnixSocket::new() as Arc<dyn INodeInterface>,
127-
PF_INET => InetSocket::new(typ, protocol)? as Arc<dyn INodeInterface>,
127+
AF_INET => InetSocket::new(typ, protocol)? as Arc<dyn INodeInterface>,
128128

129129
_ => {
130130
log::warn!(

0 commit comments

Comments
 (0)