Skip to content

Commit

Permalink
feat(net): add simple implements for sys_sendmsg
Browse files Browse the repository at this point in the history
  • Loading branch information
Stone749990226 committed Aug 18, 2024
1 parent 05389fc commit 6fedbc5
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 4 deletions.
4 changes: 2 additions & 2 deletions kernel/src/syscall/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use crate::{
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct IoVec {
base: usize,
len: usize,
pub base: usize,
pub len: usize,
}

// Defined in <bits/fcntl-linux.h>
Expand Down
1 change: 1 addition & 0 deletions kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ impl<'a> Syscall<'a> {
GETSOCKOPT => self.sys_getsockopt(args[0], args[1], args[2], args[3], args[4]),
SHUTDOWN => self.sys_shutdown(args[0], args[1]),
SOCKETPAIR => self.sys_socketpair(args[0], args[1], args[2], args[3].into()),
SENDMSG => self.sys_sendmsg(args[0], args[1].into(), args[2]).await,
// Miscellaneous
UNAME => self.sys_uname(args[0].into()),
SYSLOG => self.sys_syslog(args[0], args[1].into(), args[2]),
Expand Down
115 changes: 113 additions & 2 deletions kernel/src/syscall/net.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::{sync::Arc, vec::Vec};
use core::intrinsics::unlikely;

use addr::SockAddr;
use log::info;
Expand All @@ -8,9 +9,9 @@ use vfs::pipefs::new_pipe;
use vfs_core::OpenFlags;
use virtio_drivers::PAGE_SIZE;

use super::Syscall;
use super::{fs::IoVec, Syscall};
use crate::{
mm::{UserReadPtr, UserWritePtr},
mm::{UserRdWrPtr, UserReadPtr, UserWritePtr},
net::*,
task::Task,
};
Expand Down Expand Up @@ -342,6 +343,116 @@ impl Syscall<'_> {
}
}

/// ```c
/// struct msghdr {
/// void *msg_name; /* Optional address */
/// socklen_t msg_namelen; /* Size of address */
/// struct iovec *msg_iov; /* Scatter/gather array */
/// size_t msg_iovlen; /* # elements in msg_iov */
/// void *msg_control; /* Ancillary data, see below */
/// size_t msg_controllen; /* Ancillary data buffer len */
/// int msg_flags; /* Flags (unused) */
/// };
/// ```
#[repr(C)]
#[derive(Clone, Copy)]
pub struct MsgHdr {
/// 指向消息的目标地址的指针
pub name: usize,
/// 地址的长度
pub namelen: u32,
/// 指向 iovec 结构体的指针,用于描述消息的数据部分
pub iov: usize,
/// iovec 结构体的数量
pub iovlen: usize,
/// 指向控制数据的指针(例如,附加的元数据)
pub control: usize,
/// 控制数据的长度
pub controllen: usize,
/// 消息标志
pub flags: i32,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct CMsgHdr {
len: usize,
level: i32,
type_: i32,
}

impl Syscall<'_> {
pub async fn sys_sendmsg(
&self,
sockfd: usize,
msg: UserReadPtr<MsgHdr>,
flags: usize,
) -> SyscallResult {
if flags != 0 {
log::error!("[sys_sendmsg] unsupported flags {flags}");
}
// TODO: support flags
let task = self.task;
let socket = task.sockfd_lookup(sockfd)?;
let message = msg.read(&task)?;
if message.controllen != 0 {
log::warn!("[sys_sendmsg] unsupport msg control");
}
let addr = task.read_sockaddr(message.name, message.namelen as _)?;
let iovs = UserReadPtr::<IoVec>::from(message.iov).read_array(&task, message.iovlen)?;
let mut total_len = 0;
for (i, iov) in iovs.iter().enumerate() {
if unlikely(iov.len == 0) {
continue;
}
let ptr = UserWritePtr::<u8>::from(iov.base);
log::info!("[sys_sendmsg] iov #{i}, ptr: {ptr}, len: {}", iov.len);
let buf = ptr.into_mut_slice(&task, iov.len)?;
let send_len = socket.sk.sendto(&buf, Some(addr)).await?;
total_len += send_len;
}
Ok(total_len)
}

/// 目前的实现是,如果Udp Socket收到多个不同Ip地址的数据报如ip1, ip1, ip2,
/// ip3, ip1,recvmsg
// pub async fn sys_recvmsg(
// &self,
// sockfd: usize,
// msg: UserRdWrPtr<MsgHdr>,
// flags: usize,
// ) -> SyscallResult {
// if flags != 0 {
// log::error!("[sys_sendmsg] unsupported flags {flags}");
// }
// // TODO: support flags
// let task = self.task;
// let socket = task.sockfd_lookup(sockfd)?;
// let msg = msg.read(&task)?;
// if msg.controllen != 0 {
// log::warn!("[sys_sendmsg] unsupport msg control");
// }
// let addr = task.read_sockaddr(msg.name, msg.namelen as _)?;
// let iovs = UserReadPtr::<IoVec>::from(msg.iov).read_array(&task,
// msg.iovlen)?; let mut total_len = 0;
// for (i, iov) in iovs.iter().enumerate() {
// if unlikely(iov.len == 0) {
// continue;
// }
// let ptr = UserWritePtr::<u8>::from(iov.base);
// log::info!("[sys_recvmsg] iov #{i}, ptr: {ptr}, len: {}", iov.len);
// let buf = ptr.into_mut_slice(&task, iov.len)?;
// let send_len = socket.sk.sendto(&buf, Some(addr)).await?;
// total_len += send_len;
// }
// Ok(total_len)
// }

pub fn sys_sendmmsg(&self, sockfd: usize) -> SyscallResult {
Ok(0)
}
}

impl Task {
fn sockfd_lookup(&self, sockfd: usize) -> SysResult<Arc<Socket>> {
self.with_fd_table(|table| table.get_file(sockfd))?
Expand Down

0 comments on commit 6fedbc5

Please sign in to comment.