mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2026-09-08 23:57:59 +08:00
* feat: 新增veth和bridge结构体,尚未详细测试 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(net): 完善一下已有的bridge以及veth设备,增加一些调试信息 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(net): 完善veth网卡驱动,能通过测例;简单修改vridge设备,尚未测试 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(routing): 简单添加路由子系统,尚未完成 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(veth): 增加veth默认对端路由 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(socket): 恢复udp socket中的wait_queue等待 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(net): 补充bridge的实现 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(bridge): 更改测试程序 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 重命名测试程序 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 更改veth&beidge测试程序的toml Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 暂时添加route_iface以及route_table Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: draft router Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 实现简单的路由功能,未详细测试 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 添加netlink框架,内核相应的处理逻辑以及读取写入用户空间尚未完成 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netlink): 完善netlink的读写部分,增加addr的内核处理逻辑 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 移动routing的位置 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 补充netlink的阻塞等待逻辑&&fmt Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netns): 添加网络命名空间 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netns): 删除全局路由,使用当前netns下的路由 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netlink): 将netlink socket移入netns中 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 完成netlink addr消息的支持,增加测试程序 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netlink): 消除一些warning Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * fix: 新建netns时插入loopback网卡到设备列表 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 将veth和bridge测试程序改用C完成 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(gdb): 增加gdb debug可选项 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * fix: 修复SockAddrIn结构体中的sin_addr字节序问题,确保正确处理IPv4地址 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 手糊实现路由功能,后续需要更改事件驱动 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netlink): 补充getlink方法以及相关结构体 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * Refactor network driver interfaces and introduce NAPI support - Removed the default_iface parameter. - Introduced a new NAPI module to manage network polling and scheduling. - Updated the Iface trait to include a napi_struct method for NAPI support. - Modified Veth network interfaces to integrate with the new NAPI structure. - Refactored the Router implementation to remove unnecessary polling threads and wait queues. - Updated NetNamespace to manage a list of bridge devices. - Cleaned up various unused methods and comments across network-related files. Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 将virtio网卡的处理逻辑移动进ksoftirqd中 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(netlink): 暂时为多播消息添加allow unused,消除warning Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(nat): 实现SNAT和DNAT Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat(epoll): 更改epoll唤醒判断的逻辑,支持socket加入epoll Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 修改test_bind,防止爆内存 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 添加一个路由todo信息 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * fix: rebase主线之后修改冲突 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: fmt Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 清除无用日志 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 补充一个panic信息 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 将kernel文件夹重命名为kern Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: 删除netlink测试程序中的linux/netlink.h头文件 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> --------- Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
519 lines
17 KiB
Rust
519 lines
17 KiB
Rust
use system_error::SystemError;
|
|
|
|
use crate::{
|
|
filesystem::vfs::{
|
|
file::{File, FileMode},
|
|
iov::IoVecs,
|
|
},
|
|
net::socket::{unix::stream::UnixStreamSocket, AddressFamily, PSOCK},
|
|
process::ProcessManager,
|
|
syscall::Syscall,
|
|
};
|
|
|
|
use super::{
|
|
posix::{MsgHdr, PosixArgsSocketType, SockAddr},
|
|
socket::{self, common::ShutdownBit, endpoint::Endpoint},
|
|
};
|
|
|
|
/// Flags for socket, socketpair, accept4
|
|
const SOCK_CLOEXEC: FileMode = FileMode::O_CLOEXEC;
|
|
const SOCK_NONBLOCK: FileMode = FileMode::O_NONBLOCK;
|
|
|
|
impl Syscall {
|
|
/// @brief sys_socket系统调用的实际执行函数
|
|
///
|
|
/// @param address_family 地址族
|
|
/// @param socket_type socket类型
|
|
/// @param protocol 传输协议
|
|
pub fn socket(
|
|
address_family: usize,
|
|
socket_type: usize,
|
|
protocol: usize,
|
|
) -> Result<usize, SystemError> {
|
|
// 打印收到的参数
|
|
// log::debug!(
|
|
// "socket: address_family={:?}, socket_type={:?}, protocol={:?}",
|
|
// address_family,
|
|
// socket_type,
|
|
// protocol
|
|
// );
|
|
let address_family = socket::AddressFamily::try_from(address_family as u16)?;
|
|
let type_arg = PosixArgsSocketType::from_bits_truncate(socket_type as u32);
|
|
let is_nonblock = type_arg.is_nonblock();
|
|
let is_close_on_exec = type_arg.is_cloexec();
|
|
let stype = socket::PSOCK::try_from(type_arg)?;
|
|
// log::debug!("type_arg {:?} stype {:?}", type_arg, stype);
|
|
|
|
let inode = socket::create_socket(
|
|
address_family,
|
|
stype,
|
|
protocol as u32,
|
|
is_nonblock,
|
|
is_close_on_exec,
|
|
)?;
|
|
|
|
let file = File::new(inode, FileMode::O_RDWR)?;
|
|
// 把socket添加到当前进程的文件描述符表中
|
|
ProcessManager::current_pcb()
|
|
.fd_table()
|
|
.write()
|
|
.alloc_fd(file, None)
|
|
.map(|x| x as usize)
|
|
}
|
|
|
|
/// # sys_socketpair系统调用的实际执行函数
|
|
///
|
|
/// ## 参数
|
|
/// - `address_family`: 地址族
|
|
/// - `socket_type`: socket类型
|
|
/// - `protocol`: 传输协议
|
|
/// - `fds`: 用于返回文件描述符的数组
|
|
pub fn socketpair(
|
|
address_family: usize,
|
|
socket_type: usize,
|
|
protocol: usize,
|
|
fds: &mut [i32],
|
|
) -> Result<usize, SystemError> {
|
|
let address_family = AddressFamily::try_from(address_family as u16)?;
|
|
let socket_type = PosixArgsSocketType::from_bits_truncate(socket_type as u32);
|
|
let stype = socket::PSOCK::try_from(socket_type)?;
|
|
|
|
let binding = ProcessManager::current_pcb().fd_table();
|
|
let mut fd_table_guard = binding.write();
|
|
|
|
// check address family, only support AF_UNIX
|
|
if address_family != AddressFamily::Unix {
|
|
log::warn!(
|
|
"only support AF_UNIX, {:?} with protocol {:?} is not supported",
|
|
address_family,
|
|
protocol
|
|
);
|
|
return Err(SystemError::EAFNOSUPPORT);
|
|
}
|
|
|
|
let nonblocking = socket_type.contains(PosixArgsSocketType::NONBLOCK);
|
|
|
|
let (socket_a, socket_b) = match (address_family, stype) {
|
|
(AddressFamily::Unix, PSOCK::Stream) => UnixStreamSocket::new_pair(nonblocking, false),
|
|
(AddressFamily::Unix, PSOCK::SeqPacket) => {
|
|
UnixStreamSocket::new_pair(nonblocking, true)
|
|
}
|
|
_ => {
|
|
return Err(SystemError::EAFNOSUPPORT);
|
|
}
|
|
};
|
|
|
|
fds[0] = fd_table_guard.alloc_fd(File::new(socket_a, FileMode::O_RDWR)?, None)?;
|
|
fds[1] = fd_table_guard.alloc_fd(File::new(socket_b, FileMode::O_RDWR)?, None)?;
|
|
|
|
drop(fd_table_guard);
|
|
Ok(0)
|
|
}
|
|
|
|
/// @brief sys_setsockopt系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param level 选项级别
|
|
/// @param optname 选项名称
|
|
/// @param optval 选项值
|
|
/// @param optlen optval缓冲区长度
|
|
pub fn setsockopt(
|
|
fd: usize,
|
|
level: usize,
|
|
optname: usize,
|
|
optval: &[u8],
|
|
) -> Result<usize, SystemError> {
|
|
let sol = socket::PSOL::try_from(level as u32)?;
|
|
let socket = ProcessManager::current_pcb().get_socket_inode(fd as i32)?;
|
|
log::debug!("setsockopt: level = {:?} ", sol);
|
|
return socket
|
|
.as_socket()
|
|
.unwrap()
|
|
.set_option(sol, optname, optval)
|
|
.map(|_| 0);
|
|
}
|
|
|
|
/// @brief sys_getsockopt系统调用的实际执行函数
|
|
///
|
|
/// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param level 选项级别
|
|
/// @param optname 选项名称
|
|
/// @param optval 返回的选项值
|
|
/// @param optlen 返回的optval缓冲区长度
|
|
pub fn getsockopt(
|
|
fd: usize,
|
|
level: usize,
|
|
optname: usize,
|
|
optval: *mut u8,
|
|
optlen: *mut u32,
|
|
) -> Result<usize, SystemError> {
|
|
// 获取socket
|
|
let optval = optval as *mut u32;
|
|
let socket_inode = ProcessManager::current_pcb().get_socket_inode(fd as i32)?;
|
|
let socket = socket_inode.as_socket().unwrap();
|
|
|
|
use socket::{PSO, PSOL};
|
|
|
|
let level = PSOL::try_from(level as u32)?;
|
|
|
|
if matches!(level, PSOL::SOCKET) {
|
|
let optname = PSO::try_from(optname as u32).map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
match optname {
|
|
PSO::SNDBUF => {
|
|
// 返回发送缓冲区大小
|
|
unsafe {
|
|
*optval = socket.send_buffer_size() as u32;
|
|
*optlen = core::mem::size_of::<u32>() as u32;
|
|
}
|
|
return Ok(0);
|
|
}
|
|
PSO::RCVBUF => {
|
|
// 返回默认的接收缓冲区大小
|
|
unsafe {
|
|
*optval = socket.recv_buffer_size() as u32;
|
|
*optlen = core::mem::size_of::<u32>() as u32;
|
|
}
|
|
return Ok(0);
|
|
}
|
|
_ => {
|
|
return Err(SystemError::ENOPROTOOPT);
|
|
}
|
|
}
|
|
}
|
|
|
|
// To manipulate options at any other level the
|
|
// protocol number of the appropriate protocol controlling the
|
|
// option is supplied. For example, to indicate that an option is
|
|
// to be interpreted by the TCP protocol, level should be set to the
|
|
// protocol number of TCP.
|
|
|
|
if matches!(level, PSOL::TCP) {
|
|
use socket::inet::stream::TcpOption;
|
|
let optname =
|
|
TcpOption::try_from(optname as i32).map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
match optname {
|
|
TcpOption::Congestion => return Ok(0),
|
|
_ => {
|
|
return Err(SystemError::ENOPROTOOPT);
|
|
}
|
|
}
|
|
}
|
|
return Err(SystemError::ENOPROTOOPT);
|
|
}
|
|
|
|
/// @brief sys_connect系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn connect(fd: usize, addr: *const SockAddr, addrlen: u32) -> Result<usize, SystemError> {
|
|
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.connect(endpoint)?;
|
|
Ok(0)
|
|
}
|
|
|
|
/// @brief sys_bind系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn bind(fd: usize, addr: *const SockAddr, addrlen: u32) -> Result<usize, SystemError> {
|
|
// 打印收到的参数
|
|
// log::debug!(
|
|
// "bind: fd={:?}, family={:?}, addrlen={:?}",
|
|
// fd,
|
|
// (unsafe { addr.as_ref().unwrap().family }),
|
|
// addrlen
|
|
// );
|
|
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.bind(endpoint)?;
|
|
Ok(0)
|
|
}
|
|
|
|
/// @brief sys_sendto系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param buf 发送缓冲区
|
|
/// @param flags 标志
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回发送的字节数,失败返回错误码
|
|
pub fn sendto(
|
|
fd: usize,
|
|
buf: &[u8],
|
|
flags: u32,
|
|
addr: *const SockAddr,
|
|
addrlen: u32,
|
|
) -> Result<usize, SystemError> {
|
|
let endpoint = if addr.is_null() {
|
|
None
|
|
} else {
|
|
Some(SockAddr::to_endpoint(addr, addrlen)?)
|
|
};
|
|
|
|
let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
|
let socket_inode = ProcessManager::current_pcb().get_socket_inode(fd as i32)?;
|
|
let socket = socket_inode.as_socket().unwrap();
|
|
|
|
if let Some(endpoint) = endpoint {
|
|
return socket.send_to(buf, flags, endpoint);
|
|
} else {
|
|
return socket.send(buf, flags);
|
|
}
|
|
}
|
|
|
|
/// @brief sys_recvfrom系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param buf 接收缓冲区
|
|
/// @param flags 标志
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回接收的字节数,失败返回错误码
|
|
pub fn recvfrom(
|
|
fd: usize,
|
|
buf: &mut [u8],
|
|
flags: u32,
|
|
addr: *mut SockAddr,
|
|
addr_len: *mut u32,
|
|
) -> Result<usize, SystemError> {
|
|
let socket_inode = ProcessManager::current_pcb().get_socket_inode(fd as i32)?;
|
|
let socket = socket_inode.as_socket().unwrap();
|
|
|
|
let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
|
if addr.is_null() {
|
|
let (n, _) = socket.recv_from(buf, flags, None)?;
|
|
return Ok(n);
|
|
}
|
|
|
|
// address is not null
|
|
let address = unsafe { addr.as_ref() }.ok_or(SystemError::EINVAL)?;
|
|
|
|
if unsafe { address.is_empty() } {
|
|
let (recv_len, endpoint) = socket.recv_from(buf, flags, None)?;
|
|
endpoint.write_to_user(addr, addr_len)?;
|
|
return Ok(recv_len);
|
|
} else {
|
|
// 从socket中读取数据
|
|
let addr_len = *unsafe { addr_len.as_ref() }.ok_or(SystemError::EINVAL)?;
|
|
let address = SockAddr::to_endpoint(addr, addr_len)?;
|
|
let (recv_len, _) = socket.recv_from(buf, flags, Some(address))?;
|
|
return Ok(recv_len);
|
|
};
|
|
}
|
|
|
|
/// @brief sys_recvmsg系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param msg MsgHdr
|
|
/// @param flags 标志,暂时未使用
|
|
///
|
|
/// @return 成功返回接收的字节数,失败返回错误码
|
|
pub fn recvmsg(fd: usize, msg: &mut MsgHdr, flags: u32) -> Result<usize, SystemError> {
|
|
// 检查每个缓冲区地址是否合法,生成iovecs
|
|
let iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
|
|
|
|
let (buf, recv_size) = {
|
|
let socket_inode = ProcessManager::current_pcb().get_socket_inode(fd as i32)?;
|
|
let socket = socket_inode.as_socket().unwrap();
|
|
|
|
let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
|
let mut buf = iovs.new_buf(true);
|
|
// 从socket中读取数据
|
|
let recv_size = socket.recv(&mut buf, flags)?;
|
|
|
|
(buf, recv_size)
|
|
};
|
|
|
|
// 将数据写入用户空间的iovecs
|
|
iovs.scatter(&buf[..recv_size]);
|
|
|
|
return Ok(recv_size);
|
|
}
|
|
|
|
/// @brief sys_listen系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param backlog 队列最大连接数
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> {
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.listen(backlog)
|
|
.map(|_| 0)
|
|
}
|
|
|
|
/// @brief sys_shutdown系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param how 关闭方式
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> {
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.shutdown(ShutdownBit::try_from(how)?)
|
|
.map(|()| 0)
|
|
}
|
|
|
|
/// @brief sys_accept系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回新的文件描述符,失败返回错误码
|
|
pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> {
|
|
return Self::do_accept(fd, addr, addrlen, 0);
|
|
}
|
|
|
|
/// sys_accept4 - accept a connection on a socket
|
|
///
|
|
///
|
|
/// If flags is 0, then accept4() is the same as accept(). The
|
|
/// following values can be bitwise ORed in flags to obtain different
|
|
/// behavior:
|
|
///
|
|
/// - SOCK_NONBLOCK
|
|
/// Set the O_NONBLOCK file status flag on the open file
|
|
/// description (see open(2)) referred to by the new file
|
|
/// descriptor. Using this flag saves extra calls to fcntl(2)
|
|
/// to achieve the same result.
|
|
///
|
|
/// - SOCK_CLOEXEC
|
|
/// Set the close-on-exec (FD_CLOEXEC) flag on the new file
|
|
/// descriptor. See the description of the O_CLOEXEC flag in
|
|
/// open(2) for reasons why this may be useful.
|
|
pub fn accept4(
|
|
fd: usize,
|
|
addr: *mut SockAddr,
|
|
addrlen: *mut u32,
|
|
mut flags: u32,
|
|
) -> Result<usize, SystemError> {
|
|
// 如果flags不合法,返回错误
|
|
if (flags & (!(SOCK_CLOEXEC | SOCK_NONBLOCK)).bits()) != 0 {
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
|
|
if SOCK_NONBLOCK != FileMode::O_NONBLOCK && ((flags & SOCK_NONBLOCK.bits()) != 0) {
|
|
flags = (flags & !FileMode::O_NONBLOCK.bits()) | FileMode::O_NONBLOCK.bits();
|
|
}
|
|
|
|
return Self::do_accept(fd, addr, addrlen, flags);
|
|
}
|
|
|
|
fn do_accept(
|
|
fd: usize,
|
|
addr: *mut SockAddr,
|
|
addrlen: *mut u32,
|
|
flags: u32,
|
|
) -> Result<usize, SystemError> {
|
|
let (new_socket, remote_endpoint) = {
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.accept()?
|
|
};
|
|
|
|
// debug!("accept: new_socket={:?}", new_socket);
|
|
// Insert the new socket into the file descriptor vector
|
|
|
|
let mut file_mode = FileMode::O_RDWR;
|
|
if flags & SOCK_NONBLOCK.bits() != 0 {
|
|
file_mode |= FileMode::O_NONBLOCK;
|
|
}
|
|
if flags & SOCK_CLOEXEC.bits() != 0 {
|
|
file_mode |= FileMode::O_CLOEXEC;
|
|
}
|
|
|
|
let new_fd = ProcessManager::current_pcb()
|
|
.fd_table()
|
|
.write()
|
|
.alloc_fd(File::new(new_socket, file_mode)?, None)?;
|
|
// debug!("accept: new_fd={}", new_fd);
|
|
if !addr.is_null() {
|
|
// 将对端地址写入用户空间
|
|
remote_endpoint.write_to_user(addr, addrlen)?;
|
|
}
|
|
return Ok(new_fd as usize);
|
|
}
|
|
|
|
/// @brief sys_getsockname系统调用的实际执行函数
|
|
///
|
|
/// Returns the current address to which the socket
|
|
/// sockfd is bound, in the buffer pointed to by addr.
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn getsockname(
|
|
fd: usize,
|
|
addr: *mut SockAddr,
|
|
addrlen: *mut u32,
|
|
) -> Result<usize, SystemError> {
|
|
if addr.is_null() {
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.local_endpoint()?
|
|
.write_to_user(addr, addrlen)?;
|
|
return Ok(0);
|
|
}
|
|
|
|
/// @brief sys_getpeername系统调用的实际执行函数
|
|
///
|
|
/// @param fd 文件描述符
|
|
/// @param addr SockAddr
|
|
/// @param addrlen 地址长度
|
|
///
|
|
/// @return 成功返回0,失败返回错误码
|
|
pub fn getpeername(
|
|
fd: usize,
|
|
addr: *mut SockAddr,
|
|
addrlen: *mut u32,
|
|
) -> Result<usize, SystemError> {
|
|
if addr.is_null() {
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
|
|
ProcessManager::current_pcb()
|
|
.get_socket_inode(fd as i32)?
|
|
.as_socket()
|
|
.unwrap()
|
|
.remote_endpoint()?
|
|
.write_to_user(addr, addrlen)?;
|
|
|
|
return Ok(0);
|
|
}
|
|
}
|