diff --git a/.vscode/settings.json b/.vscode/settings.json index dddf29cd9..0c3fe06f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ // "rust-analyzer.cargo.target": "loongarch64-unknown-none", // "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf", "rust-analyzer.cargo.target": "x86_64-unknown-none", + "rust-analyzer.check.allTargets": false, "rust-analyzer.check.overrideCommand": [ "make", "check", diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 36bb7846e..0395c8aa7 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -25,6 +25,7 @@ use crate::{ spinlock::{SpinLock, SpinLockGuard}, }, mm::{fault::PageFaultMessage, VmFaultReason}, + net::socket::Socket, time::PosixTimeSpec, }; @@ -654,6 +655,10 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { fn as_pollable_inode(&self) -> Result<&dyn PollableInode, SystemError> { Err(SystemError::ENOSYS) } + + fn as_socket(&self) -> Option<&dyn Socket> { + None + } } impl DowncastArc for dyn IndexNode { diff --git a/kernel/src/net/posix.rs b/kernel/src/net/posix.rs index b4d6c07de..6cc2b2358 100644 --- a/kernel/src/net/posix.rs +++ b/kernel/src/net/posix.rs @@ -42,8 +42,7 @@ use system_error::SystemError; use crate::{ filesystem::vfs::{FileType, IndexNode, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES}, - mm::{verify_area, VirtAddr}, - net::socket::unix::ns::abs::{alloc_abs_addr, look_up_abs_addr}, + net::socket::unix::UnixEndpoint, process::ProcessManager, }; @@ -150,6 +149,15 @@ impl SockAddr { if addr_un.sun_path[0] == 0 { // 抽象地址空间,与文件系统没有关系 + // TODO: Autobind feature + // If a bind(2) call specifies addrlen as sizeof(sa_family_t), or the + // SO_PASSCRED socket option was specified for a socket that was not + // explicitly bound to an address, then the socket is autobound to an + // abstract address. The address consists of a null byte followed by + // 5 bytes in the character set [0-9a-f]. Thus, there is a limit of + // 2^20 autobind addresses. (From Linux 2.1.15, when the autobind + // feature was added, 8 bytes were used, and the limit was thus 2^32 + // autobind addresses. The change to 5 bytes came in Linux 2.3.15.) let path = CStr::from_bytes_until_nul(&addr_un.sun_path[1..]) .map_err(|_| { log::error!("CStr::from_bytes_until_nul fail"); @@ -164,24 +172,25 @@ impl SockAddr { // 向抽象地址管理器申请或查找抽象地址 let spath = String::from(path); log::debug!("abs path: {}", spath); - let abs_find = match look_up_abs_addr(&spath) { - Ok(result) => result, - Err(_) => { - //未找到尝试分配abs - match alloc_abs_addr(spath.clone()) { - Ok(result) => { - log::debug!("alloc abs addr success!"); - return Ok(result); - } - Err(e) => { - log::debug!("alloc abs addr failed!"); - return Err(e); - } - }; - } - }; - log::debug!("find alloc abs addr success!"); - return Ok(abs_find); + todo!("abstract address space not implemented yet"); + // let abs_find = match look_up_abs_addr(&spath) { + // Ok(result) => result, + // Err(_) => { + // //未找到尝试分配abs + // match alloc_abs_addr(spath.clone()) { + // Ok(result) => { + // log::debug!("alloc abs addr success!"); + // return Ok(result); + // } + // Err(e) => { + // log::debug!("alloc abs addr failed!"); + // return Err(e); + // } + // }; + // } + // }; + // log::debug!("find alloc abs addr success!"); + // return Ok(abs_find); } let path = CStr::from_bytes_until_nul(&addr_un.sun_path) @@ -230,8 +239,9 @@ impl SockAddr { inode } }; + let file_abs_path = inode.absolute_path()?; - return Ok(Endpoint::Unixpath((inode.metadata()?.inode_id, path))); + return Ok(Endpoint::Unix(UnixEndpoint::File(file_abs_path))); } _ => { log::warn!("not support address family {:?}", addr.family); @@ -253,109 +263,11 @@ impl SockAddr { .map(|x| x as u32) } - /// @brief 把SockAddr的数据写入用户空间 - /// - /// @param addr 用户空间的SockAddr的地址 - /// @param len 要写入的长度 - /// - /// @return 成功返回写入的长度,失败返回错误码 - pub unsafe fn write_to_user( - &self, - addr: *mut SockAddr, - addr_len: *mut u32, - ) -> Result { - // 当用户传入的地址或者长度为空时,直接返回0 - if addr.is_null() || addr_len.is_null() { - return Ok(0); - } - - // 检查用户传入的地址是否合法 - verify_area( - VirtAddr::new(addr as usize), - core::mem::size_of::(), - ) - .map_err(|_| SystemError::EFAULT)?; - - verify_area( - VirtAddr::new(addr_len as usize), - core::mem::size_of::(), - ) - .map_err(|_| SystemError::EFAULT)?; - - let to_write = core::cmp::min(self.len()?, *addr_len); - if to_write > 0 { - let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write as usize); - buf.copy_from_slice(core::slice::from_raw_parts( - self as *const SockAddr as *const u8, - to_write as usize, - )); - } - *addr_len = self.len()?; - return Ok(to_write); - } - pub unsafe fn is_empty(&self) -> bool { unsafe { self.family == 0 && self.addr_ph.data == [0; 14] } } } -impl From for SockAddr { - fn from(value: Endpoint) -> Self { - match value { - Endpoint::Ip(ip_endpoint) => match ip_endpoint.addr { - smoltcp::wire::IpAddress::Ipv4(ipv4_addr) => { - let addr_in = SockAddrIn { - sin_family: AddressFamily::INet as u16, - sin_port: ip_endpoint.port.to_be(), - sin_addr: ipv4_addr.to_bits(), - sin_zero: [0; 8], - }; - - return SockAddr { addr_in }; - } - _ => { - unimplemented!("not support ipv6"); - } - }, - - Endpoint::LinkLayer(link_endpoint) => { - let addr_ll = SockAddrLl { - sll_family: AddressFamily::Packet as u16, - sll_protocol: 0, - sll_ifindex: link_endpoint.interface as u32, - sll_hatype: 0, - sll_pkttype: 0, - sll_halen: 0, - sll_addr: [0; 8], - }; - - return SockAddr { addr_ll }; - } - - Endpoint::Inode((_, path)) => { - log::debug!("from unix path {:?}", path); - let bytes = path.as_bytes(); - let mut sun_path = [0u8; 108]; - if bytes.len() <= 108 { - sun_path[..bytes.len()].copy_from_slice(bytes); - } else { - panic!("unix address path too long!"); - } - let addr_un = SockAddrUn { - sun_family: AddressFamily::Unix as u16, - sun_path, - }; - return SockAddr { addr_un }; - } - - _ => { - // todo: support other endpoint, like Netlink... - unimplemented!("not support {value:?}"); - } - } - } -} - #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct MsgHdr { diff --git a/kernel/src/net/socket/base.rs b/kernel/src/net/socket/base.rs index a772dacc2..6795bbed8 100644 --- a/kernel/src/net/socket/base.rs +++ b/kernel/src/net/socket/base.rs @@ -1,27 +1,27 @@ -use crate::{libs::wait_queue::WaitQueue, net::posix::MsgHdr}; +use crate::{ + filesystem::vfs::{IndexNode, PollableInode}, + libs::wait_queue::WaitQueue, + net::posix::MsgHdr, +}; use alloc::sync::Arc; use core::any::Any; use core::fmt::Debug; use system_error::SystemError; use super::{ - common::shutdown::ShutdownTemp, + common::shutdown::ShutdownBit, endpoint::Endpoint, posix::{PMSG, PSOL}, - SocketInode, + // SocketInode, }; /// # `Socket` methods /// ## Reference /// - [Posix standard](https://pubs.opengroup.org/onlinepubs/9699919799/) -#[allow(unused_variables)] -pub trait Socket: Sync + Send + Debug + Any { +pub trait Socket: PollableInode { /// # `wait_queue` /// 获取socket的wait queue fn wait_queue(&self) -> &WaitQueue; - /// # `socket_poll` - /// 获取socket的事件。 - fn poll(&self) -> usize; fn send_buffer_size(&self) -> usize; fn recv_buffer_size(&self) -> usize; @@ -29,49 +29,40 @@ pub trait Socket: Sync + Send + Debug + Any { /// 接受连接,仅用于listening stream socket /// ## Block /// 如果没有连接到来,会阻塞 - fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { - Err(SystemError::ENOSYS) - } + fn accept(&self) -> Result<(Arc, Endpoint), SystemError>; + /// # `bind` /// 对应于POSIX的bind函数,用于绑定到本机指定的端点 - fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> { - Err(SystemError::ENOSYS) - } + fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError>; + /// # `close` /// 关闭socket - fn close(&self) -> Result<(), SystemError> { - Ok(()) - } + fn do_close(&self) -> Result<(), SystemError>; + /// # `connect` /// 对应于POSIX的connect函数,用于连接到指定的远程服务器端点 - fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> { - Err(SystemError::ENOSYS) - } + fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError>; + // fnctl // freeaddrinfo // getaddrinfo // getnameinfo /// # `get_peer_name` /// 获取对端的地址 - fn get_peer_name(&self) -> Result { - Err(SystemError::ENOSYS) - } + fn get_peer_name(&self) -> Result; + /// # `get_name` /// 获取socket的地址 - fn get_name(&self) -> Result { - Err(SystemError::ENOSYS) - } + fn get_name(&self) -> Result; + /// # `get_option` /// 对应于 Posix `getsockopt` ,获取socket选项 - fn get_option(&self, level: PSOL, name: usize, value: &mut [u8]) -> Result { - log::warn!("getsockopt is not implemented"); - Ok(0) - } + fn get_option(&self, level: PSOL, name: usize, value: &mut [u8]) -> Result; + /// # `listen` /// 监听socket,仅用于stream socket - fn listen(&self, backlog: usize) -> Result<(), SystemError> { - Err(SystemError::ENOSYS) - } + fn listen(&self, backlog: usize) -> Result<(), SystemError>; + // poll // pselect /// # `read` @@ -80,35 +71,30 @@ pub trait Socket: Sync + Send + Debug + Any { } /// # `recv` /// 接收数据,`read` = `recv` with flags = 0 - fn recv(&self, buffer: &mut [u8], flags: PMSG) -> Result { - Err(SystemError::ENOSYS) - } + fn recv(&self, buffer: &mut [u8], flags: PMSG) -> Result; + /// # `recv_from` fn recv_from( &self, buffer: &mut [u8], flags: PMSG, address: Option, - ) -> Result<(usize, Endpoint), SystemError> { - Err(SystemError::ENOSYS) - } + ) -> Result<(usize, Endpoint), SystemError>; + /// # `recv_msg` - fn recv_msg(&self, msg: &mut MsgHdr, flags: PMSG) -> Result { - Err(SystemError::ENOSYS) - } + fn recv_msg(&self, msg: &mut MsgHdr, flags: PMSG) -> Result; + // select /// # `send` fn send(&self, buffer: &[u8], flags: PMSG) -> Result { Err(SystemError::ENOSYS) } /// # `send_msg` - fn send_msg(&self, msg: &MsgHdr, flags: PMSG) -> Result { - Err(SystemError::ENOSYS) - } + fn send_msg(&self, msg: &MsgHdr, flags: PMSG) -> Result; + /// # `send_to` - fn send_to(&self, buffer: &[u8], flags: PMSG, address: Endpoint) -> Result { - Err(SystemError::ENOSYS) - } + fn send_to(&self, buffer: &[u8], flags: PMSG, address: Endpoint) -> Result; + /// # `set_option` /// Posix `setsockopt` ,设置socket选项 /// ## Parameters @@ -117,16 +103,11 @@ pub trait Socket: Sync + Send + Debug + Any { /// - value 选项的值 /// ## Reference /// https://code.dragonos.org.cn/s?refs=sk_setsockopt&project=linux-6.6.21 - fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> { - log::warn!("setsockopt is not implemented"); - Ok(()) - } + fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError>; + /// # `shutdown` - fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { - // TODO 构建shutdown系统调用 - // set shutdown bit - Err(SystemError::ENOSYS) - } + fn shutdown(&self, how: usize) -> Result<(), SystemError>; + // sockatmark // socket // socketpair @@ -134,7 +115,11 @@ pub trait Socket: Sync + Send + Debug + Any { fn write(&self, buffer: &[u8]) -> Result { self.send(buffer, PMSG::empty()) } - // fn write_buffer(&self, _buf: &[u8]) -> Result { - // todo!() - // } + + fn into_socket(this: Arc) -> Option> + where + Self: Sized, + { + Some(this) + } } diff --git a/kernel/src/net/socket/buffer.rs b/kernel/src/net/socket/buffer.rs index 66334dc16..747fb134e 100644 --- a/kernel/src/net/socket/buffer.rs +++ b/kernel/src/net/socket/buffer.rs @@ -6,19 +6,18 @@ use system_error::SystemError; use crate::libs::spinlock::SpinLock; -#[derive(Debug)] -pub struct Buffer { - metadata: Metadata, - read_buffer: SpinLock>, - write_buffer: SpinLock>, -} +const DEFAULT_BUF_SIZE: usize = 64 * 1024; // 64 KiB + +// #[derive(Debug)] +// pub struct Buffer { +// buffer: +// } impl Buffer { pub fn new() -> Arc { Arc::new(Self { - metadata: Metadata::default(), - read_buffer: SpinLock::new(Vec::new()), - write_buffer: SpinLock::new(Vec::new()), + read_buffer: SpinLock::new(Vec::with_capacity(DEFAULT_BUF_SIZE)), + write_buffer: SpinLock::new(Vec::with_capacity(DEFAULT_BUF_SIZE)), }) } @@ -27,17 +26,9 @@ impl Buffer { } pub fn is_read_buf_full(&self) -> bool { - return self.metadata.buf_size - self.read_buffer.lock().len() == 0; - } - - #[allow(dead_code)] - pub fn is_write_buf_empty(&self) -> bool { - return self.write_buffer.lock().is_empty(); - } - - #[allow(dead_code)] - pub fn is_write_buf_full(&self) -> bool { - return self.write_buffer.lock().len() >= self.metadata.buf_size; + let read_buffer = self.read_buffer.lock(); + let capacity = read_buffer.capacity(); + return self.read_buffer.lo - self.read_buffer.lock().len() == 0; } pub fn read_read_buffer(&self, buf: &mut [u8]) -> Result { @@ -75,21 +66,3 @@ impl Buffer { Ok(len) } } - -#[derive(Debug)] -pub struct Metadata { - /// 默认的元数据缓冲区大小 - #[allow(dead_code)] - metadata_buf_size: usize, - /// 默认的缓冲区大小 - buf_size: usize, -} - -impl Default for Metadata { - fn default() -> Self { - Self { - metadata_buf_size: 1024, - buf_size: 64 * 1024, - } - } -} diff --git a/kernel/src/net/socket/common/shutdown.rs b/kernel/src/net/socket/common/shutdown.rs index 609527ceb..21e1ddd20 100644 --- a/kernel/src/net/socket/common/shutdown.rs +++ b/kernel/src/net/socket/common/shutdown.rs @@ -1,135 +1,38 @@ -// TODO: 其他模块需要实现shutdown的具体逻辑 -#![allow(dead_code)] -use core::sync::atomic::AtomicU8; - -use system_error::SystemError; - -bitflags! { - /// @brief 用于指定socket的关闭类型 - /// 参考:https://code.dragonos.org.cn/xref/linux-6.1.9/include/net/sock.h?fi=SHUTDOWN_MASK#1573 - pub struct ShutdownBit: u8 { - const SHUT_RD = 0; - const SHUT_WR = 1; - const SHUT_RDWR = 2; - } -} - -const RCV_SHUTDOWN: u8 = 0x01; -const SEND_SHUTDOWN: u8 = 0x02; -const SHUTDOWN_MASK: u8 = 0x03; - -#[derive(Debug, Default)] -pub struct Shutdown { - bit: AtomicU8, -} - -impl From for Shutdown { - fn from(shutdown_bit: ShutdownBit) -> Self { - match shutdown_bit { - ShutdownBit::SHUT_RD => Shutdown { - bit: AtomicU8::new(RCV_SHUTDOWN), - }, - ShutdownBit::SHUT_WR => Shutdown { - bit: AtomicU8::new(SEND_SHUTDOWN), - }, - ShutdownBit::SHUT_RDWR => Shutdown { - bit: AtomicU8::new(SHUTDOWN_MASK), - }, - _ => Shutdown::default(), - } - } -} - -impl Shutdown { - pub fn new() -> Self { - Self { - bit: AtomicU8::new(0), - } - } - - pub fn recv_shutdown(&self) { - self.bit - .fetch_or(RCV_SHUTDOWN, core::sync::atomic::Ordering::SeqCst); - } - - pub fn send_shutdown(&self) { - self.bit - .fetch_or(SEND_SHUTDOWN, core::sync::atomic::Ordering::SeqCst); - } - - pub fn is_recv_shutdown(&self) -> bool { - self.bit.load(core::sync::atomic::Ordering::SeqCst) & RCV_SHUTDOWN != 0 - } - - pub fn is_send_shutdown(&self) -> bool { - self.bit.load(core::sync::atomic::Ordering::SeqCst) & SEND_SHUTDOWN != 0 - } - - pub fn is_both_shutdown(&self) -> bool { - self.bit.load(core::sync::atomic::Ordering::SeqCst) & SHUTDOWN_MASK == SHUTDOWN_MASK - } - - pub fn is_empty(&self) -> bool { - self.bit.load(core::sync::atomic::Ordering::SeqCst) == 0 - } - - pub fn from_how(how: usize) -> Self { - Self::from(ShutdownBit::from_bits_truncate(how as u8)) - } - - pub fn get(&self) -> ShutdownTemp { - ShutdownTemp { - bit: self.bit.load(core::sync::atomic::Ordering::SeqCst), - } - } -} - -pub struct ShutdownTemp { +/// Shutdown bit for socket operations. +pub struct ShutdownBit { bit: u8, } -impl ShutdownTemp { +impl ShutdownBit { + const RCV_SHUTDOWN: u8 = 0x01; + const SEND_SHUTDOWN: u8 = 0x02; + const SHUTDOWN_MASK: u8 = 0x03; pub fn is_recv_shutdown(&self) -> bool { - self.bit & RCV_SHUTDOWN != 0 + self.bit & Self::RCV_SHUTDOWN != 0 } pub fn is_send_shutdown(&self) -> bool { - self.bit & SEND_SHUTDOWN != 0 + self.bit & Self::SEND_SHUTDOWN != 0 } pub fn is_both_shutdown(&self) -> bool { - self.bit & SHUTDOWN_MASK == SHUTDOWN_MASK + self.bit & Self::SHUTDOWN_MASK == Self::SHUTDOWN_MASK } pub fn is_empty(&self) -> bool { self.bit == 0 } - - pub fn bits(&self) -> ShutdownBit { - ShutdownBit { bits: self.bit } - } -} - -impl From for ShutdownTemp { - fn from(shutdown_bit: ShutdownBit) -> Self { - match shutdown_bit { - ShutdownBit::SHUT_RD => Self { bit: RCV_SHUTDOWN }, - ShutdownBit::SHUT_WR => Self { bit: SEND_SHUTDOWN }, - ShutdownBit::SHUT_RDWR => Self { bit: SHUTDOWN_MASK }, - _ => Self { bit: 0 }, - } - } } -impl TryFrom for ShutdownTemp { - type Error = SystemError; +impl TryFrom for ShutdownBit { + type Error = system_error::SystemError; fn try_from(value: usize) -> Result { match value { - 0..2 => Ok(ShutdownTemp { + 0..2 => Ok(ShutdownBit { bit: value as u8 + 1, }), - _ => Err(SystemError::EINVAL), + _ => Err(Self::Error::EINVAL), } } } diff --git a/kernel/src/net/socket/endpoint.rs b/kernel/src/net/socket/endpoint.rs index 35fa06bd2..a058ef9ea 100644 --- a/kernel/src/net/socket/endpoint.rs +++ b/kernel/src/net/socket/endpoint.rs @@ -1,22 +1,22 @@ -use crate::{filesystem::vfs::InodeId, net::socket}; +use crate::{ + filesystem::vfs::InodeId, + net::{ + posix::SockAddr, + socket::{self, unix::UnixEndpoint}, + }, +}; use alloc::{string::String, sync::Arc}; pub use smoltcp::wire::IpEndpoint; -use super::unix::ns::abs::AbsHandle; - #[derive(Debug, Clone)] pub enum Endpoint { /// 链路层端点 LinkLayer(LinkLayerEndpoint), /// 网络层端点 Ip(IpEndpoint), - /// inode端点,Unix实际保存的端点 - Inode((Arc, String)), - /// Unix传递id索引和path所用的端点 - Unixpath((InodeId, String)), - /// Unix抽象端点 - Abspath((AbsHandle, String)), + + Unix(UnixEndpoint), } /// @brief 链路层端点 @@ -42,3 +42,15 @@ impl From for Endpoint { Self::Ip(endpoint) } } + +impl Endpoint { + pub fn write_to_user( + &self, + addr: *mut SockAddr, + addr_len: *mut u32, + ) -> Result<(), system_error::SystemError> { + // use system_error::SystemError; + + todo!("write_to_user: {:?}", self); + } +} diff --git a/kernel/src/net/socket/family.rs b/kernel/src/net/socket/family.rs index 26200961a..71b9d64aa 100644 --- a/kernel/src/net/socket/family.rs +++ b/kernel/src/net/socket/family.rs @@ -111,7 +111,7 @@ impl core::convert::TryFrom for AddressFamily { } } -use crate::net::socket; +use crate::filesystem::vfs::IndexNode; use alloc::sync::Arc; use super::PSOCK; @@ -120,5 +120,6 @@ pub trait Family { fn socket( stype: PSOCK, protocol: u32, - ) -> Result, system_error::SystemError>; + is_nonblock: bool, + ) -> Result, system_error::SystemError>; } diff --git a/kernel/src/net/socket/inet/datagram/mod.rs b/kernel/src/net/socket/inet/datagram/mod.rs index cdd51a958..54f303ad0 100644 --- a/kernel/src/net/socket/inet/datagram/mod.rs +++ b/kernel/src/net/socket/inet/datagram/mod.rs @@ -3,6 +3,7 @@ use smoltcp; use system_error::SystemError; use crate::filesystem::epoll::EPollEventType; +use crate::filesystem::vfs::IndexNode; use crate::libs::wait_queue::WaitQueue; use crate::net::socket::{Socket, PMSG}; use crate::{libs::rwlock::RwLock, net::socket::endpoint::Endpoint}; @@ -162,10 +163,6 @@ impl Socket for UdpSocket { &self.wait_queue } - fn poll(&self) -> usize { - self.event().bits() as usize - } - fn bind(&self, local_endpoint: Endpoint) -> Result<(), SystemError> { if let Endpoint::Ip(local_endpoint) = local_endpoint { return self.do_bind(local_endpoint); @@ -269,10 +266,85 @@ impl Socket for UdpSocket { .map(|(len, remote)| (len, Endpoint::Ip(remote))); } - fn close(&self) -> Result<(), SystemError> { + fn do_close(&self) -> Result<(), SystemError> { self.close(); Ok(()) } + + fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { + todo!() + } + + fn get_peer_name(&self) -> Result { + todo!() + } + + fn get_name(&self) -> Result { + todo!() + } + + fn get_option( + &self, + level: crate::net::socket::PSOL, + name: usize, + value: &mut [u8], + ) -> Result { + todo!() + } + + fn listen(&self, backlog: usize) -> Result<(), SystemError> { + todo!() + } + + fn recv_msg( + &self, + msg: &mut crate::net::posix::MsgHdr, + flags: PMSG, + ) -> Result { + todo!() + } + + fn send_msg(&self, msg: &crate::net::posix::MsgHdr, flags: PMSG) -> Result { + todo!() + } + + fn set_option( + &self, + level: crate::net::socket::PSOL, + name: usize, + val: &[u8], + ) -> Result<(), SystemError> { + todo!() + } + + fn shutdown(&self, how: usize) -> Result<(), SystemError> { + todo!() + } +} + +impl crate::filesystem::vfs::PollableInode for UdpSocket { + fn poll( + &self, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result { + Ok(self.event().bits() as usize) + } + + fn add_epitem( + &self, + epitem: Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } + + fn remove_epitem( + &self, + epitm: &Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } } impl InetSocket for UdpSocket { diff --git a/kernel/src/net/socket/inet/stream/mod.rs b/kernel/src/net/socket/inet/stream/mod.rs index 6484d842f..b29e41e85 100644 --- a/kernel/src/net/socket/inet/stream/mod.rs +++ b/kernel/src/net/socket/inet/stream/mod.rs @@ -2,12 +2,10 @@ use alloc::sync::{Arc, Weak}; use core::sync::atomic::{AtomicBool, AtomicUsize}; use system_error::SystemError; +use crate::libs::rwlock::RwLock; use crate::libs::wait_queue::WaitQueue; -use crate::net::socket::common::shutdown::{ShutdownBit, ShutdownTemp}; -use crate::net::socket::endpoint::Endpoint; -use crate::net::socket::{Socket, SocketInode, PMSG, PSOL}; +use crate::net::socket::{common::shutdown::ShutdownBit, endpoint::Endpoint, Socket, PMSG, PSOL}; use crate::sched::SchedMode; -use crate::{libs::rwlock::RwLock, net::socket::common::shutdown::Shutdown}; use smoltcp; mod inner; @@ -21,8 +19,7 @@ type EP = crate::filesystem::epoll::EPollEventType; #[derive(Debug)] pub struct TcpSocket { inner: RwLock>, - #[allow(dead_code)] - shutdown: Shutdown, // TODO set shutdown status + // shutdown: Shutdown, // TODO set shutdown status nonblock: AtomicBool, wait_queue: WaitQueue, self_ref: Weak, @@ -33,7 +30,7 @@ impl TcpSocket { pub fn new(_nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc { Arc::new_cyclic(|me| Self { inner: RwLock::new(Some(inner::Inner::Init(inner::Init::new(ver)))), - shutdown: Shutdown::new(), + // shutdown: Shutdown::new(), nonblock: AtomicBool::new(false), wait_queue: WaitQueue::default(), self_ref: me.clone(), @@ -44,7 +41,7 @@ impl TcpSocket { pub fn new_established(inner: inner::Established, nonblock: bool) -> Arc { Arc::new_cyclic(|me| Self { inner: RwLock::new(Some(inner::Inner::Established(inner))), - shutdown: Shutdown::new(), + // shutdown: Shutdown::new(), nonblock: AtomicBool::new(nonblock), wait_queue: WaitQueue::default(), self_ref: me.clone(), @@ -322,7 +319,7 @@ impl Socket for TcpSocket { self.do_listen(backlog) } - fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { + fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { if self.is_nonblock() { self.try_accept() } else { @@ -335,7 +332,6 @@ impl Socket for TcpSocket { } } } - .map(|(inner, endpoint)| (SocketInode::new(inner), Endpoint::Ip(endpoint))) } fn recv(&self, buffer: &mut [u8], _flags: PMSG) -> Result { @@ -362,26 +358,26 @@ impl Socket for TcpSocket { .recv_buffer_size() } - fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { - let self_shutdown = self.shutdown.get().bits(); - let diff = how.bits().difference(self_shutdown); - match diff.is_empty() { - true => return Ok(()), - false => { - if diff.contains(ShutdownBit::SHUT_RD) { - self.shutdown.recv_shutdown(); - // TODO 协议栈处理 - } - if diff.contains(ShutdownBit::SHUT_WR) { - self.shutdown.send_shutdown(); - // TODO 协议栈处理 - } - } - } + fn shutdown(&self, how: ShutdownBit) -> Result<(), SystemError> { + // let self_shutdown = self.shutdown.get().bits(); + // let diff = how.bits().difference(self_shutdown); + // match diff.is_empty() { + // true => return Ok(()), + // false => { + // if diff.contains(ShutdownBit::SHUT_RD) { + // self.shutdown.recv_shutdown(); + // // TODO 协议栈处理 + // } + // if diff.contains(ShutdownBit::SHUT_WR) { + // self.shutdown.send_shutdown(); + // // TODO 协议栈处理 + // } + // } + // } Ok(()) } - fn close(&self) -> Result<(), SystemError> { + fn do_close(&self) -> Result<(), SystemError> { let Some(inner) = self.inner.write().take() else { log::warn!("TcpSocket::close: already closed, unexpected"); return Ok(()); @@ -494,6 +490,35 @@ impl Socket for TcpSocket { } Ok(()) } + + fn get_option(&self, level: PSOL, name: usize, value: &mut [u8]) -> Result { + todo!() + } + + fn recv_from( + &self, + buffer: &mut [u8], + flags: PMSG, + address: Option, + ) -> Result<(usize, Endpoint), SystemError> { + todo!() + } + + fn recv_msg( + &self, + msg: &mut crate::net::posix::MsgHdr, + flags: PMSG, + ) -> Result { + todo!() + } + + fn send_msg(&self, msg: &crate::net::posix::MsgHdr, flags: PMSG) -> Result { + todo!() + } + + fn send_to(&self, buffer: &[u8], flags: PMSG, address: Endpoint) -> Result { + todo!() + } } impl InetSocket for TcpSocket { diff --git a/kernel/src/net/socket/inet/syscall.rs b/kernel/src/net/socket/inet/syscall.rs index 46c3a0671..1070b26a9 100644 --- a/kernel/src/net/socket/inet/syscall.rs +++ b/kernel/src/net/socket/inet/syscall.rs @@ -2,22 +2,26 @@ use alloc::sync::Arc; use smoltcp::{self, wire::IpProtocol}; use system_error::SystemError; -use crate::net::socket::{ - family, - inet::{TcpSocket, UdpSocket}, - Socket, SocketInode, PSOCK, +use crate::{ + filesystem::vfs::IndexNode, + net::socket::{ + family, + inet::{TcpSocket, UdpSocket}, + Socket, PSOCK, + }, }; fn create_inet_socket( version: smoltcp::wire::IpVersion, socket_type: PSOCK, protocol: smoltcp::wire::IpProtocol, -) -> Result, SystemError> { + is_nonblock: bool, +) -> Result, SystemError> { // log::debug!("type: {:?}, protocol: {:?}", socket_type, protocol); match socket_type { PSOCK::Datagram => match protocol { IpProtocol::HopByHop | IpProtocol::Udp => { - return Ok(UdpSocket::new(false)); + return Ok(UdpSocket::new(is_nonblock)); } _ => { return Err(SystemError::EPROTONOSUPPORT); @@ -26,7 +30,7 @@ fn create_inet_socket( PSOCK::Stream => match protocol { IpProtocol::HopByHop | IpProtocol::Tcp => { log::debug!("create tcp socket"); - return Ok(TcpSocket::new(false, version)); + return Ok(TcpSocket::new(is_nonblock, version)); } _ => { return Err(SystemError::EPROTONOSUPPORT); @@ -43,24 +47,32 @@ fn create_inet_socket( pub struct Inet; impl family::Family for Inet { - fn socket(stype: PSOCK, protocol: u32) -> Result, SystemError> { - let socket = create_inet_socket( + fn socket( + stype: PSOCK, + protocol: u32, + is_nonblock: bool, + ) -> Result, SystemError> { + create_inet_socket( smoltcp::wire::IpVersion::Ipv4, stype, smoltcp::wire::IpProtocol::from(protocol as u8), - )?; - Ok(SocketInode::new(socket)) + is_nonblock, + ) } } pub struct Inet6; impl family::Family for Inet6 { - fn socket(stype: PSOCK, protocol: u32) -> Result, SystemError> { - let socket = create_inet_socket( + fn socket( + stype: PSOCK, + protocol: u32, + is_nonblock: bool, + ) -> Result, SystemError> { + create_inet_socket( smoltcp::wire::IpVersion::Ipv6, stype, smoltcp::wire::IpProtocol::from(protocol as u8), - )?; - Ok(SocketInode::new(socket)) + is_nonblock, + ) } } diff --git a/kernel/src/net/socket/inode.rs b/kernel/src/net/socket/inode.rs index bad855272..8bcddfd35 100644 --- a/kernel/src/net/socket/inode.rs +++ b/kernel/src/net/socket/inode.rs @@ -1,30 +1,18 @@ -use crate::filesystem::vfs::IndexNode; -use alloc::sync::Arc; +use crate::filesystem::vfs::{IndexNode, PollableInode}; +use alloc::{string::String, sync::Arc, vec::Vec}; use system_error::SystemError; -use super::{ - common::shutdown::ShutdownTemp, - endpoint::Endpoint, - posix::{PMSG, PSOL}, - EPollItems, Socket, -}; +use super::Socket; -#[derive(Debug)] -pub struct SocketInode { - inner: Arc, - epoll_items: EPollItems, -} - -impl IndexNode for SocketInode { +impl IndexNode for T { fn read_at( &self, _offset: usize, _len: usize, buf: &mut [u8], - data: crate::libs::spinlock::SpinLockGuard, + _data: crate::libs::spinlock::SpinLockGuard, ) -> Result { - drop(data); - self.inner.read(buf) + self.read(buf) } fn write_at( @@ -32,156 +20,28 @@ impl IndexNode for SocketInode { _offset: usize, _len: usize, buf: &[u8], - data: crate::libs::spinlock::SpinLockGuard, - ) -> Result { - drop(data); - self.inner.write(buf) - } - - /* Following are not yet available in socket */ - fn as_any_ref(&self) -> &dyn core::any::Any { - self - } - - /* filesystem associate interfaces are about unix and netlink socket */ - fn fs(&self) -> Arc { - unimplemented!() - } - - fn list(&self) -> Result, SystemError> { - unimplemented!() - } - - fn open( - &self, _data: crate::libs::spinlock::SpinLockGuard, - _mode: &crate::filesystem::vfs::file::FileMode, - ) -> Result<(), SystemError> { - Ok(()) - } - - fn metadata(&self) -> Result { - let meta = crate::filesystem::vfs::Metadata { - mode: crate::filesystem::vfs::syscall::ModeType::from_bits_truncate(0o755), - file_type: crate::filesystem::vfs::FileType::Socket, - size: self.send_buffer_size() as i64, - ..Default::default() - }; - - return Ok(meta); - } - - fn close( - &self, - _data: crate::libs::spinlock::SpinLockGuard, - ) -> Result<(), SystemError> { - self.inner.close() - } -} - -impl SocketInode { - // pub fn wait_queue(&self) -> WaitQueue { - // self.inner.wait_queue() - // } - - pub fn send_buffer_size(&self) -> usize { - self.inner.send_buffer_size() - } - - pub fn recv_buffer_size(&self) -> usize { - self.inner.recv_buffer_size() - } - - pub fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { - self.inner.accept() - } - - pub fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> { - self.inner.bind(endpoint) - } - - pub fn set_option(&self, level: PSOL, name: usize, value: &[u8]) -> Result<(), SystemError> { - self.inner.set_option(level, name, value) - } - - pub fn get_option( - &self, - level: PSOL, - name: usize, - value: &mut [u8], - ) -> Result { - self.inner.get_option(level, name, value) - } - - pub fn listen(&self, backlog: usize) -> Result<(), SystemError> { - self.inner.listen(backlog) - } - - pub fn send_to( - &self, - buffer: &[u8], - address: Endpoint, - flags: PMSG, ) -> Result { - self.inner.send_to(buffer, flags, address) - } - - pub fn send(&self, buffer: &[u8], flags: PMSG) -> Result { - self.inner.send(buffer, flags) + self.write(buf) } - pub fn recv(&self, buffer: &mut [u8], flags: PMSG) -> Result { - self.inner.recv(buffer, flags) - } - - // TODO receive from split with endpoint or not - pub fn recv_from( - &self, - buffer: &mut [u8], - flags: PMSG, - address: Option, - ) -> Result<(usize, Endpoint), SystemError> { - self.inner.recv_from(buffer, flags, address) - } - - pub fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { - self.inner.shutdown(how) - } - - pub fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> { - self.inner.connect(endpoint) - } - - pub fn get_name(&self) -> Result { - self.inner.get_name() - } - - pub fn get_peer_name(&self) -> Result { - self.inner.get_peer_name() - } - - pub fn new(inner: Arc) -> Arc { - Arc::new(Self { - inner, - epoll_items: EPollItems::default(), - }) + fn fs(&self) -> Arc { + unreachable!("Socket does not have a file system") } - /// # `epoll_items` - /// socket的epoll事件集 - pub fn epoll_items(&self) -> EPollItems { - self.epoll_items.clone() + fn as_any_ref(&self) -> &dyn core::any::Any { + self } - pub fn set_nonblock(&self, _nonblock: bool) { - log::warn!("nonblock is not support yet"); + fn list(&self) -> Result, SystemError> { + Err(SystemError::ENOTDIR) } - pub fn set_close_on_exec(&self, _close_on_exec: bool) { - log::warn!("close_on_exec is not support yet"); + fn as_pollable_inode(&self) -> Result<&dyn PollableInode, SystemError> { + Ok(self) } - pub fn inner(&self) -> Arc { - return self.inner.clone(); + fn as_socket(&self) -> Option<&dyn Socket> { + Some(self) } } diff --git a/kernel/src/net/socket/mod.rs b/kernel/src/net/socket/mod.rs index ed1796e84..f6c9a9429 100644 --- a/kernel/src/net/socket/mod.rs +++ b/kernel/src/net/socket/mod.rs @@ -1,5 +1,5 @@ mod base; -mod buffer; +// mod buffer; mod common; pub mod endpoint; mod family; @@ -17,7 +17,7 @@ pub use common::{ EPollItems, }; pub use family::{AddressFamily, Family}; -pub use inode::SocketInode; +// pub use inode::SocketInode; pub use posix::PMSG; pub use posix::PSO; pub use posix::PSOCK; diff --git a/kernel/src/net/socket/unix/datagram/mod.rs b/kernel/src/net/socket/unix/datagram/mod.rs new file mode 100644 index 000000000..4ad7e1883 --- /dev/null +++ b/kernel/src/net/socket/unix/datagram/mod.rs @@ -0,0 +1,154 @@ +use alloc::boxed::Box; +use alloc::sync::Arc; + +use crate::filesystem::vfs::{IndexNode, PollableInode}; +use crate::libs::spinlock::SpinLock; +use crate::net::socket::Socket; + +/// TODO: Write documentation +struct UnDatagram { + buffer: Arc>>, +} + +impl IndexNode for UnDatagram {} + +impl Socket for UnDatagram { + fn wait_queue(&self) -> &crate::libs::wait_queue::WaitQueue { + todo!() + } + + fn send_buffer_size(&self) -> usize { + todo!() + } + + fn recv_buffer_size(&self) -> usize { + todo!() + } + + fn accept( + &self, + ) -> Result<(Arc, crate::net::socket::endpoint::Endpoint), system_error::SystemError> + { + todo!() + } + + fn bind( + &self, + endpoint: crate::net::socket::endpoint::Endpoint, + ) -> Result<(), system_error::SystemError> { + todo!() + } + + fn close(&self) -> Result<(), system_error::SystemError> { + todo!() + } + + fn connect( + &self, + endpoint: crate::net::socket::endpoint::Endpoint, + ) -> Result<(), system_error::SystemError> { + todo!() + } + + fn get_peer_name( + &self, + ) -> Result { + todo!() + } + + fn get_name( + &self, + ) -> Result { + todo!() + } + + fn get_option( + &self, + level: crate::net::socket::PSOL, + name: usize, + value: &mut [u8], + ) -> Result { + todo!() + } + + fn listen(&self, backlog: usize) -> Result<(), system_error::SystemError> { + todo!() + } + + fn recv( + &self, + buffer: &mut [u8], + flags: crate::net::socket::PMSG, + ) -> Result { + todo!() + } + + fn recv_from( + &self, + buffer: &mut [u8], + flags: crate::net::socket::PMSG, + address: Option, + ) -> Result<(usize, crate::net::socket::endpoint::Endpoint), system_error::SystemError> { + todo!() + } + + fn recv_msg( + &self, + msg: &mut crate::net::posix::MsgHdr, + flags: crate::net::socket::PMSG, + ) -> Result { + todo!() + } + + fn send_msg( + &self, + msg: &crate::net::posix::MsgHdr, + flags: crate::net::socket::PMSG, + ) -> Result { + todo!() + } + + fn send_to( + &self, + buffer: &[u8], + flags: crate::net::socket::PMSG, + address: crate::net::socket::endpoint::Endpoint, + ) -> Result { + todo!() + } + + fn set_option( + &self, + level: crate::net::socket::PSOL, + name: usize, + val: &[u8], + ) -> Result<(), system_error::SystemError> { + todo!() + } + + fn shutdown(&self, how: usize) -> Result<(), system_error::SystemError> { + todo!() + } +} + +impl PollableInode for UnDatagram { + fn poll(&self, private_data: &crate::filesystem::vfs::FilePrivateData) -> Result { + todo!() + } + + fn add_epitem( + &self, + epitem: Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), system_error::SystemError> { + todo!() + } + + fn remove_epitem( + &self, + epitm: &Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), system_error::SystemError> { + todo!() + } +} diff --git a/kernel/src/net/socket/unix/mod.rs b/kernel/src/net/socket/unix/mod.rs index ac99ba36c..a067ee774 100644 --- a/kernel/src/net/socket/unix/mod.rs +++ b/kernel/src/net/socket/unix/mod.rs @@ -1,40 +1,70 @@ pub mod ns; -pub(crate) mod seqpacket; +// pub mod seqpacket; +// pub mod datagram; pub mod stream; -use crate::{filesystem::vfs::InodeId, libs::rwlock::RwLock}; + +use crate::{ + filesystem::vfs::{IndexNode, InodeId, ROOT_INODE}, + net::{ + posix::SockAddrUn, + socket::{unix::ns::AbstractUnixPath, AddressFamily, Socket}, + }, +}; +use alloc::boxed::Box; +use alloc::string::String; use alloc::sync::Arc; -use hashbrown::HashMap; use system_error::SystemError; -use super::{endpoint::Endpoint, Family, SocketInode, PSOCK}; +use super::{Family, PSOCK}; pub struct Unix; -lazy_static! { - pub static ref INODE_MAP: RwLock> = RwLock::new(HashMap::new()); +#[derive(Debug, Clone)] +pub enum UnixEndpoint { + File(String), + Abstract(AbstractUnixPath), } -fn create_unix_socket(sock_type: PSOCK) -> Result, SystemError> { - match sock_type { - PSOCK::Stream | PSOCK::Datagram => stream::StreamSocket::new_inode(), - PSOCK::SeqPacket => seqpacket::SeqpacketSocket::new_inode(false), - _ => Err(SystemError::EPROTONOSUPPORT), +impl From for Box { + fn from(endpoint: UnixEndpoint) -> Self { + use UnixEndpoint::*; + let mut ret: Box = unsafe { Box::new_zeroed().assume_init() }; + ret.sun_family = AddressFamily::Unix as u16; + match endpoint { + File(path) => { + // TODO: handle path length + + ret.sun_path.copy_from_slice(&path.into_bytes()); + } + Abstract(path) => { + path.sun_path(&mut ret.sun_path); + } + }; + ret } } impl Family for Unix { - fn socket(stype: PSOCK, _protocol: u32) -> Result, SystemError> { - let socket = create_unix_socket(stype)?; - Ok(socket) + fn socket( + stype: PSOCK, + _protocol: u32, + is_nonblocking: bool, + ) -> Result, SystemError> { + match stype { + PSOCK::Stream | PSOCK::Datagram => stream::StreamSocket::new_inode(), + // PSOCK::SeqPacket => seqpacket::SeqpacketSocket::new_inode(false), + _ => Err(SystemError::EPROTONOSUPPORT), + } } } impl Unix { pub fn new_pairs( socket_type: PSOCK, - ) -> Result<(Arc, Arc), SystemError> { + is_nonblocking: bool, + ) -> Result<(Arc, Arc), SystemError> { // log::debug!("socket_type {:?}", socket_type); match socket_type { - PSOCK::SeqPacket => seqpacket::SeqpacketSocket::new_pairs(), + // PSOCK::SeqPacket => seqpacket::SeqpacketSocket::new_pairs(is_nonblocking), PSOCK::Stream | PSOCK::Datagram => stream::StreamSocket::new_pairs(), _ => todo!(), } diff --git a/kernel/src/net/socket/unix/ns/abs.rs b/kernel/src/net/socket/unix/ns/abs.rs deleted file mode 100644 index c62493abc..000000000 --- a/kernel/src/net/socket/unix/ns/abs.rs +++ /dev/null @@ -1,171 +0,0 @@ -use core::fmt; - -use crate::{libs::spinlock::SpinLock, net::socket::endpoint::Endpoint}; -use alloc::string::String; -use hashbrown::HashMap; -use ida::IdAllocator; -use system_error::SystemError; - -lazy_static! { - pub static ref ABSHANDLE_MAP: AbsHandleMap = AbsHandleMap::new(); -} - -lazy_static! { - pub static ref ABS_INODE_MAP: SpinLock> = - SpinLock::new(HashMap::new()); -} - -static ABS_ADDRESS_ALLOCATOR: SpinLock = - SpinLock::new(IdAllocator::new(0, (1 << 20) as usize).unwrap()); - -#[derive(Debug, Clone)] -pub struct AbsHandle(usize); - -impl AbsHandle { - pub fn new(name: usize) -> Self { - Self(name) - } - - pub fn name(&self) -> usize { - self.0 - } -} - -impl fmt::Display for AbsHandle { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:05x}", self.0) - } -} - -/// 抽象地址映射表 -/// -/// 负责管理抽象命名空间内的地址 -pub struct AbsHandleMap { - abs_handle_map: SpinLock>, -} - -impl AbsHandleMap { - pub fn new() -> Self { - Self { - abs_handle_map: SpinLock::new(HashMap::new()), - } - } - - /// 插入新的地址映射 - pub fn insert(&self, name: String) -> Result { - let mut guard = self.abs_handle_map.lock(); - - //检查name是否被占用 - if guard.contains_key(&name) { - return Err(SystemError::ENOMEM); - } - - let ads_addr = match self.alloc(name.clone()) { - Some(addr) => addr.clone(), - None => return Err(SystemError::ENOMEM), - }; - guard.insert(name, ads_addr.clone()); - return Ok(ads_addr); - } - - /// 抽象空间地址分配器 - /// - /// ## 返回 - /// - /// 分配到的可用的抽象端点 - pub fn alloc(&self, name: String) -> Option { - let abs_addr = match ABS_ADDRESS_ALLOCATOR.lock().alloc() { - Some(addr) => addr, - //地址被分配 - None => return None, - }; - - let result = Some(Endpoint::Abspath((AbsHandle::new(abs_addr), name))); - - return result; - } - - /// 进行地址映射 - /// - /// ## 参数 - /// - /// name:用户定义的地址 - pub fn look_up(&self, name: &String) -> Option { - let guard = self.abs_handle_map.lock(); - return guard.get(name).cloned(); - } - - /// 移除绑定的地址 - /// - /// ## 参数 - /// - /// name:待删除的地址 - pub fn remove(&self, name: &String) -> Result<(), SystemError> { - let abs_addr = match look_up_abs_addr(name) { - Ok(result) => match result { - Endpoint::Abspath((abshandle, _)) => abshandle.name(), - _ => return Err(SystemError::EINVAL), - }, - Err(_) => return Err(SystemError::EINVAL), - }; - - //释放abs地址分配实例 - ABS_ADDRESS_ALLOCATOR.lock().free(abs_addr); - - //释放entry - let mut guard = self.abs_handle_map.lock(); - guard.remove(name); - - Ok(()) - } -} - -/// 分配抽象地址 -/// -/// ## 返回 -/// -/// 分配到的抽象地址 -pub fn alloc_abs_addr(name: String) -> Result { - ABSHANDLE_MAP.insert(name) -} - -/// 查找抽象地址 -/// -/// ## 参数 -/// -/// name:用户socket字符地址 -/// -/// ## 返回 -/// -/// 查询到的抽象地址 -pub fn look_up_abs_addr(name: &String) -> Result { - match ABSHANDLE_MAP.look_up(name) { - Some(result) => return Ok(result), - None => return Err(SystemError::EINVAL), - } -} - -/// 删除抽象地址 -/// -/// ## 参数 -/// name:待删除的地址 -/// -/// ## 返回 -/// 删除的抽象地址 -pub fn remove_abs_addr(name: &String) -> Result<(), SystemError> { - let abs_addr = match look_up_abs_addr(name) { - Ok(addr) => match addr { - Endpoint::Abspath((addr, _)) => addr, - _ => return Err(SystemError::EINVAL), - }, - Err(_) => return Err(SystemError::EINVAL), - }; - - match ABS_INODE_MAP.lock_irqsave().remove(&abs_addr.name()) { - Some(_) => log::debug!("free abs inode"), - None => log::debug!("not free abs inode"), - } - ABSHANDLE_MAP.remove(name)?; - log::debug!("free abs!"); - Ok(()) -} diff --git a/kernel/src/net/socket/unix/ns/mod.rs b/kernel/src/net/socket/unix/ns/mod.rs index d99b5e678..6bf35743d 100644 --- a/kernel/src/net/socket/unix/ns/mod.rs +++ b/kernel/src/net/socket/unix/ns/mod.rs @@ -1 +1,93 @@ -pub mod abs; +use alloc::collections::BTreeMap; + +use hashbrown::HashMap; +use system_error::SystemError; + +use crate::net::socket::unix::UnixEndpoint; +use crate::net::socket::Socket; +use crate::{filesystem::vfs::InodeId, libs::rwlock::RwLock}; + +use alloc::string::String; +use alloc::sync::Arc; + +lazy_static! { + // and unnamed unix socket, they don't have a path, so we don't store them in the map. + // they will be removed when the socket is closed. + pub static ref ABS_UNIX_MAP: RwLock>> = RwLock::new(HashMap::new()); + pub static ref INO_UNIX_MAP: RwLock>> = RwLock::new(BTreeMap::new()); +} + +#[derive(Debug, Clone, Eq, Hash, PartialEq)] +pub struct AbstractUnixPath(String); + +impl AbstractUnixPath { + pub fn new(path: String) -> Self { + Self(path) + } + + pub fn sun_path(&self, path: &mut [u8]) { + let mut path_bytes = self.0.as_bytes().to_vec(); + if path_bytes.len() > 108 { + path_bytes.truncate(108); + } + path_bytes.push(0); // null-terminate + path[0] = 0; // abstract socket starts with a null byte + path[1..path_bytes.len()].copy_from_slice(&path_bytes); + } +} + +pub(super) struct UnixSockMap { + /// A map of abstract unix sockets, they don't have a path, so we don't store them in the map. + /// They will be removed when the socket is closed. + pub abs_unix_map: RwLock>>, + /// A map of inode unix sockets, they have a path, so we store them in the map. + pub ino_unix_map: RwLock>>, +} + +impl UnixSockMap { + pub fn new() -> Self { + Self { + abs_unix_map: RwLock::new(HashMap::new()), + ino_unix_map: RwLock::new(BTreeMap::new()), + } + } + + /// Try to insert a socket into the map. If the socket already exists, return EEXIST. + pub fn try_insert(&self, endpoint: UnixEndpoint, socket: Arc) -> Result<(), SystemError> { + use UnixEndpoint::*; + match endpoint { + File(path) => { + use alloc::collections::btree_map::Entry::*; + match self.ino_unix_map.write().entry(path) { + Vacant(vacant_entry) => { + vacant_entry.insert(socket); + return Ok(()); + } + Occupied(_) => { + return Err(SystemError::EEXIST); + } + } + } + Abstract(path) => { + use hashbrown::hash_map::Entry::*; + match self.abs_unix_map.write().entry(path) { + Vacant(vacant_entry) => { + vacant_entry.insert(socket); + return Ok(()); + } + Occupied(_) => { + return Err(SystemError::EEXIST); + } + } + } + } + } + + pub fn get(&self, endpoint: &UnixEndpoint) -> Option> { + use UnixEndpoint::*; + match endpoint { + File(ino) => self.ino_unix_map.read().get(ino).cloned(), + Abstract(path) => self.abs_unix_map.read().get(path).cloned(), + } + } +} diff --git a/kernel/src/net/socket/unix/seqpacket/inner.rs b/kernel/src/net/socket/unix/seqpacket/inner.rs index 8294b0dca..56a8c3d47 100644 --- a/kernel/src/net/socket/unix/seqpacket/inner.rs +++ b/kernel/src/net/socket/unix/seqpacket/inner.rs @@ -1,63 +1,67 @@ use alloc::string::String; +use alloc::sync::Weak; use alloc::{collections::VecDeque, sync::Arc}; use core::sync::atomic::{AtomicUsize, Ordering}; +use alloc::boxed::Box; use super::SeqpacketSocket; -use crate::net::socket::common::shutdown::ShutdownTemp; +use crate::filesystem::vfs::IndexNode; +use crate::libs::spinlock::SpinLock; +use crate::net::socket::common::shutdown::ShutdownBit; +use crate::net::socket::unix::UnixEndpoint; use crate::{ libs::mutex::Mutex, - net::socket::{buffer::Buffer, endpoint::Endpoint, SocketInode}, + net::socket::{endpoint::Endpoint}, }; use system_error::SystemError; -#[derive(Debug)] -pub(super) struct Init { - inode: Option, -} - -impl Init { - pub(super) fn new() -> Self { - Self { inode: None } - } - - pub(super) fn bind(&mut self, epoint_to_bind: Endpoint) -> Result<(), SystemError> { - if self.inode.is_some() { - log::error!("the socket is already bound"); - return Err(SystemError::EINVAL); - } - match epoint_to_bind { - Endpoint::Inode(_) => self.inode = Some(epoint_to_bind), - _ => return Err(SystemError::EINVAL), - } - - return Ok(()); - } - - pub fn bind_path(&mut self, sun_path: String) -> Result { - if self.inode.is_none() { - log::error!("the socket is not bound"); - return Err(SystemError::EINVAL); - } - if let Some(Endpoint::Inode((inode, mut path))) = self.inode.take() { - path = sun_path; - let epoint = Endpoint::Inode((inode, path)); - self.inode.replace(epoint.clone()); - return Ok(epoint); - }; - - return Err(SystemError::EINVAL); - } - - pub fn endpoint(&self) -> Option<&Endpoint> { - return self.inode.as_ref(); - } -} +pub const DEFAULT_BUF_SIZE: usize = 64 * 1024; + +// #[derive(Debug)] +// pub(super) struct Init { +// inode: Option<(Arc, String)>, +// } + +// impl Init { +// pub(super) fn new() -> Self { +// Self { inode: None } +// } + +// pub(super) fn bind(&mut self, epoint_to_bind: Arc) -> Result<(), SystemError> { +// if self.inode.is_some() { +// log::error!("the socket is already bound"); +// return Err(SystemError::EINVAL); +// } +// self.inode = Some(epoint_to_bind); + +// return Ok(()); +// } + +// pub fn bind_path(&mut self, sun_path: String) -> Result { +// if self.inode.is_none() { +// log::error!("the socket is not bound"); +// return Err(SystemError::EINVAL); +// } +// if let Some((inode, _)) = self.inode.take() { +// let inode_id = inode.metadata()?.inode_id; +// let epoint = (inode, sun_path.clone()); +// self.inode.replace(epoint.clone()); +// return Ok(Endpoint::Unixpath((inode_id, sun_path))); +// }; + +// return Err(SystemError::EINVAL); +// } + +// pub fn endpoint(&self) -> Option<&Endpoint> { +// return self.inode.as_ref(); +// } +// } #[derive(Debug)] pub(super) struct Listener { inode: Endpoint, backlog: AtomicUsize, - incoming_conns: Mutex>>, + incoming_conns: Mutex>>, } impl Listener { @@ -83,7 +87,7 @@ impl Listener { let socket = Arc::downcast::(conn.inner()).map_err(|_| SystemError::EINVAL)?; let peer = match &*socket.inner.read() { - Inner::Connected(connected) => connected.peer_endpoint().unwrap().clone(), + Status::Connected(connected) => connected.peer_endpoint().unwrap().clone(), _ => return Err(SystemError::ENOTCONN), }; @@ -117,7 +121,7 @@ impl Listener { Some(Endpoint::Inode((new_inode.clone(), path))), client_epoint, ); - *new_server.inner.write() = Inner::Connected(server_conn); + *new_server.inner.write() = Status::Connected(server_conn); incoming_conns.push_back(new_inode); // TODO: epollin @@ -132,50 +136,36 @@ impl Listener { #[derive(Debug)] pub struct Connected { - inode: Option, - peer_inode: Option, - buffer: Arc, + peer_buffer: Weak>>, + buffer: Arc>>, } impl Connected { - /// 默认的缓冲区大小 - #[allow(dead_code)] - pub const DEFAULT_BUF_SIZE: usize = 64 * 1024; pub fn new_pair( inode: Option, peer_inode: Option, ) -> (Connected, Connected) { let this = Connected { - inode: inode.clone(), - peer_inode: peer_inode.clone(), + local_endpoint: inode.clone(), + peer_endpoint: peer_inode.clone(), buffer: Buffer::new(), }; let peer = Connected { - inode: peer_inode, - peer_inode: inode, + local_endpoint: peer_inode, + peer_endpoint: inode, buffer: Buffer::new(), }; (this, peer) } - #[allow(dead_code)] - pub fn set_peer_inode(&mut self, peer_epoint: Option) { - self.peer_inode = peer_epoint; - } - - #[allow(dead_code)] - pub fn set_inode(&mut self, epoint: Option) { - self.inode = epoint; - } - pub fn endpoint(&self) -> Option<&Endpoint> { - self.inode.as_ref() + self.local_endpoint.as_ref() } pub fn peer_endpoint(&self) -> Option<&Endpoint> { - self.peer_inode.as_ref() + self.peer_endpoint.as_ref() } pub fn try_read(&self, buf: &mut [u8]) -> Result { @@ -203,14 +193,14 @@ impl Connected { pub fn can_send(&self) -> Result { // let sebuffer = self.sebuffer.lock(); // 获取锁 // sebuffer.capacity()-sebuffer.len() ==0; - let peer_inode = match self.peer_inode.as_ref().unwrap() { + let peer_inode = match self.peer_endpoint.as_ref().unwrap() { Endpoint::Inode((inode, _)) => inode, _ => return Err(SystemError::EINVAL), }; let peer_socket = Arc::downcast::(peer_inode.inner()) .map_err(|_| SystemError::EINVAL)?; let is_full = match &*peer_socket.inner.read() { - Inner::Connected(connected) => connected.buffer.is_read_buf_full(), + Status::Connected(connected) => connected.buffer.is_read_buf_full(), _ => return Err(SystemError::EINVAL), }; Ok(!is_full) @@ -222,14 +212,14 @@ impl Connected { pub fn send_slice(&self, buf: &[u8]) -> Result { //找到peer_inode,并将write_buffer的内容写入对端的read_buffer - let peer_inode = match self.peer_inode.as_ref().unwrap() { + let peer_inode = match self.peer_endpoint.as_ref().unwrap() { Endpoint::Inode((inode, _)) => inode, _ => return Err(SystemError::EINVAL), }; let peer_socket = Arc::downcast::(peer_inode.inner()) .map_err(|_| SystemError::EINVAL)?; let usize = match &*peer_socket.inner.write() { - Inner::Connected(connected) => { + Status::Connected(connected) => { let usize = connected.buffer.write_read_buffer(buf)?; usize } @@ -239,13 +229,12 @@ impl Connected { Ok(usize) } - pub fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { - if how.is_empty() { - return Err(SystemError::EINVAL); - } else if how.is_send_shutdown() { - unimplemented!("unimplemented!"); - } else if how.is_recv_shutdown() { - unimplemented!("unimplemented!"); + pub fn shutdown(&self, how: ShutdownBit) -> Result<(), SystemError> { + if how.is_send_shutdown() { + log::warn!("shutdown is unimplement"); + } + if how.is_recv_shutdown() { + log::warn!("shutdown is unimplement!"); } Ok(()) @@ -253,8 +242,20 @@ impl Connected { } #[derive(Debug)] -pub(super) enum Inner { - Init(Init), +pub(super) enum Status { + Init, + Bound, Listen(Listener), Connected(Connected), } + +// For a u8: +// 0000 0000 <- non_blocking bit +// ^..^ ^.^ +// Init ~ Connected <-| |-> shutdown bits + +pub struct SeqSockInner { + inner: Status, + non_blocking: bool, + +} diff --git a/kernel/src/net/socket/unix/seqpacket/mod.rs b/kernel/src/net/socket/unix/seqpacket/mod.rs index 4a47e55a7..06016498f 100644 --- a/kernel/src/net/socket/unix/seqpacket/mod.rs +++ b/kernel/src/net/socket/unix/seqpacket/mod.rs @@ -1,19 +1,21 @@ -pub mod inner; +mod inner; +use hashbrown::HashMap; +use inner::Status; use alloc::{ string::String, sync::{Arc, Weak}, + collections::BTreeMap, }; use core::sync::atomic::{AtomicBool, Ordering}; use crate::{ - libs::{rwlock::RwLock, wait_queue::WaitQueue}, - net::socket::{Socket, SocketInode, PMSG}, + filesystem::vfs::{IndexNode, InodeId, PollableInode}, libs::{rwlock::RwLock, spinlock::SpinLock, wait_queue::WaitQueue}, net::socket::{unix::{ns::{AbstractUnixPath, UnixSockMap}, Unix, UnixEndpoint}, Socket, PMSG} }; use crate::{ net::{ posix::MsgHdr, socket::{ - common::shutdown::{Shutdown, ShutdownTemp}, + common::shutdown::{Shutdown, ShutdownBit}, endpoint::Endpoint, }, }, @@ -22,15 +24,15 @@ use crate::{ use system_error::SystemError; -use super::{ - ns::abs::{remove_abs_addr, ABS_INODE_MAP}, - INODE_MAP, -}; - type EP = crate::filesystem::epoll::EPollEventType; + +lazy_static! { + pub static ref SEQ_MAP: UnixSockMap = UnixSockMap::new(); +} + #[derive(Debug)] pub struct SeqpacketSocket { - inner: RwLock, + inner: SpinLock, shutdown: Shutdown, is_nonblocking: AtomicBool, wait_queue: WaitQueue, @@ -38,220 +40,138 @@ pub struct SeqpacketSocket { } impl SeqpacketSocket { - /// 默认的元数据缓冲区大小 - #[allow(dead_code)] - pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024; /// 默认的缓冲区大小 pub const DEFAULT_BUF_SIZE: usize = 64 * 1024; - pub fn new(is_nonblocking: bool) -> Arc { - Arc::new_cyclic(|me| Self { - inner: RwLock::new(inner::Inner::Init(inner::Init::new())), - shutdown: Shutdown::new(), - is_nonblocking: AtomicBool::new(is_nonblocking), - wait_queue: WaitQueue::default(), - self_ref: me.clone(), - }) - } - - pub fn new_inode(is_nonblocking: bool) -> Result, SystemError> { - let socket = SeqpacketSocket::new(is_nonblocking); - let inode = SocketInode::new(socket.clone()); - // 建立时绑定自身为后续能正常获取本端地址 - let _ = match &mut *socket.inner.write() { - inner::Inner::Init(init) => { - init.bind(Endpoint::Inode((inode.clone(), String::from("")))) - } - _ => return Err(SystemError::EINVAL), - }; - return Ok(inode); - } - - #[allow(dead_code)] - pub fn new_connected(connected: inner::Connected, is_nonblocking: bool) -> Arc { - Arc::new_cyclic(|me| Self { - inner: RwLock::new(inner::Inner::Connected(connected)), + pub fn new(is_nonblocking: bool) -> Arc { + Arc::new_cyclic(|me| { Self { + inner: SpinLock::new(Status::Init), shutdown: Shutdown::new(), is_nonblocking: AtomicBool::new(is_nonblocking), wait_queue: WaitQueue::default(), self_ref: me.clone(), - }) + }}) } - pub fn new_pairs() -> Result<(Arc, Arc), SystemError> { - let socket0 = SeqpacketSocket::new(false); - let socket1 = SeqpacketSocket::new(false); - let inode0 = SocketInode::new(socket0.clone()); - let inode1 = SocketInode::new(socket1.clone()); - - let (conn_0, conn_1) = inner::Connected::new_pair( - Some(Endpoint::Inode((inode0.clone(), String::from("")))), - Some(Endpoint::Inode((inode1.clone(), String::from("")))), - ); - *socket0.inner.write() = inner::Inner::Connected(conn_0); - *socket1.inner.write() = inner::Inner::Connected(conn_1); - - return Ok((inode0, inode1)); + // /* + // unnamed + // A stream socket that has not been bound to a pathname using + // bind(2) has no name. Likewise, the two sockets created by + // socketpair(2) are unnamed. When the address of an unnamed + // socket is returned, its length is sizeof(sa_family_t), and + // sun_path should not be inspected. + // */ + // pub fn new_pairs(is_nonblocking: bool) -> Result<(Arc, Arc), SystemError> { + // let inodea = Arc::new_cyclic(|me| { Self { + // peer: OnceLock::new(), + // shutdown: Shutdown::new(), + // is_nonblocking: AtomicBool::new(is_nonblocking), + // wait_queue: WaitQueue::default(), + // self_ref: me.clone(), + // }}); + // let inodeb = Arc::new_cyclic(|me| { Self { + // peer: OnceLock::new(), + // shutdown: Shutdown::new(), + // is_nonblocking: AtomicBool::new(is_nonblocking), + // wait_queue: WaitQueue::default(), + // self_ref: me.clone(), + // }}); + + // inodea.peer.set(Arc::downgrade(&inodeb)); + // inodeb.peer.set(Arc::downgrade(&inodea)); + + // let inode0 = SocketInode::new(inodea); + // let inode1 = SocketInode::new(inodeb); + + // return Ok((inode0, inode1)); + // } + + /// Actually just insert the inode into the map sothat it can be found later. + pub fn do_bind(&self, endpoint: UnixEndpoint) -> Result<(), SystemError> { + SEQ_MAP.try_insert(endpoint, self.self_ref.upgrade().ok_or(SystemError::EINVAL)?) } - fn try_accept(&self) -> Result<(Arc, Endpoint), SystemError> { - match &*self.inner.read() { - inner::Inner::Listen(listen) => listen.try_accept() as _, - _ => { - log::error!("the socket is not listening"); + pub fn do_connect(&self, endpoint: UnixEndpoint) -> Result<(), SystemError> { + match *self.inner.lock() { + Status::Init | Status::Bound => todo!(), + Status::Listen(_) | Status::Connected(_) => { + log::error!("the socket is already bound or connected"); return Err(SystemError::EINVAL); - } + }, } } - fn is_acceptable(&self) -> bool { + fn try_accept(&self) -> Result<(Arc, Endpoint), SystemError> { match &*self.inner.read() { - inner::Inner::Listen(listen) => listen.is_acceptable(), + inner::Status::Listen(listen) => listen.try_accept() as _, _ => { - panic!("the socket is not listening"); + log::error!("the socket is not listening"); + return Err(SystemError::EINVAL); } } } - fn is_peer_shutdown(&self) -> Result { - let peer_shutdown = match self.get_peer_name()? { - Endpoint::Inode((inode, _)) => Arc::downcast::(inode.inner()) - .map_err(|_| SystemError::EINVAL)? - .shutdown - .get() - .is_both_shutdown(), - _ => return Err(SystemError::EINVAL), - }; - Ok(peer_shutdown) - } - - fn can_recv(&self) -> Result { - let can = match &*self.inner.read() { - inner::Inner::Connected(connected) => connected.can_recv(), - _ => return Err(SystemError::ENOTCONN), - }; - Ok(can) - } - - fn is_nonblocking(&self) -> bool { - self.is_nonblocking.load(Ordering::Relaxed) - } - - #[allow(dead_code)] - fn set_nonblocking(&self, nonblocking: bool) { - self.is_nonblocking.store(nonblocking, Ordering::Relaxed); - } + // fn is_acceptable(&self) -> bool { + // match &*self.inner.read() { + // inner::Status::Listen(listen) => listen.is_acceptable(), + // _ => { + // panic!("the socket is not listening"); + // } + // } + // } + + // fn is_peer_shutdown(&self) -> Result { + // let peer_shutdown = match self.get_peer_name()? { + // Endpoint::Inode((inode, _)) => Arc::downcast::(inode.inner()) + // .map_err(|_| SystemError::EINVAL)? + // .shutdown + // .get() + // .is_both_shutdown(), + // _ => return Err(SystemError::EINVAL), + // }; + // Ok(peer_shutdown) + // } + + // fn can_recv(&self) -> Result { + // let can = match &*self.inner.read() { + // inner::Status::Connected(connected) => connected.can_recv(), + // _ => return Err(SystemError::ENOTCONN), + // }; + // Ok(can) + // } + + // fn is_nonblocking(&self) -> bool { + // self.is_nonblocking.load(Ordering::Relaxed) + // } + + // #[allow(dead_code)] + // fn set_nonblocking(&self, nonblocking: bool) { + // self.is_nonblocking.store(nonblocking, Ordering::Relaxed); + // } } impl Socket for SeqpacketSocket { - fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> { - let peer_inode = match endpoint { - Endpoint::Inode((inode, _)) => inode, - Endpoint::Unixpath((inode_id, _)) => { - let inode_guard = INODE_MAP.read_irqsave(); - let inode = inode_guard.get(&inode_id).unwrap(); - match inode { - Endpoint::Inode((inode, _)) => inode.clone(), - _ => return Err(SystemError::EINVAL), - } - } - Endpoint::Abspath((abs_addr, _)) => { - let inode_guard = ABS_INODE_MAP.lock_irqsave(); - let inode = match inode_guard.get(&abs_addr.name()) { - Some(inode) => inode, - None => { - log::debug!("can not find inode from absInodeMap"); - return Err(SystemError::EINVAL); - } - }; - match inode { - Endpoint::Inode((inode, _)) => inode.clone(), - _ => { - log::debug!("when connect, find inode failed!"); - return Err(SystemError::EINVAL); - } - } - } - _ => return Err(SystemError::EINVAL), - }; - // 远端为服务端 - let remote_socket = Arc::downcast::(peer_inode.inner()) - .map_err(|_| SystemError::EINVAL)?; - - let client_epoint = match &mut *self.inner.write() { - inner::Inner::Init(init) => match init.endpoint().cloned() { - Some(end) => { - log::trace!("bind when connect"); - Some(end) - } - None => { - log::trace!("not bind when connect"); - let inode = SocketInode::new(self.self_ref.upgrade().unwrap().clone()); - let epoint = Endpoint::Inode((inode.clone(), String::from(""))); - let _ = init.bind(epoint.clone()); - Some(epoint) - } - }, - inner::Inner::Listen(_) => return Err(SystemError::EINVAL), - inner::Inner::Connected(_) => return Err(SystemError::EISCONN), - }; - // ***阻塞与非阻塞处理还未实现 - // 客户端与服务端建立连接将服务端inode推入到自身的listen_incom队列中, - // accept时从中获取推出对应的socket - match &*remote_socket.inner.read() { - inner::Inner::Listen(listener) => match listener.push_incoming(client_epoint) { - Ok(connected) => { - *self.inner.write() = inner::Inner::Connected(connected); - log::debug!("try to wake up"); - - remote_socket.wait_queue.wakeup(None); - return Ok(()); - } - // ***错误处理 - Err(_) => todo!(), - }, - inner::Inner::Init(_) => { - log::debug!("init einval"); - return Err(SystemError::EINVAL); - } - inner::Inner::Connected(_) => return Err(SystemError::EISCONN), - }; - } fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> { - // 将自身socket的inode与用户端提供路径的文件indoe_id进行绑定 match endpoint { - Endpoint::Unixpath((inodeid, path)) => { - let inode = match &mut *self.inner.write() { - inner::Inner::Init(init) => init.bind_path(path)?, - _ => { - log::error!("socket has listen or connected"); - return Err(SystemError::EINVAL); - } - }; + Endpoint::Unix(unix) => self.do_bind(unix), + _ => Err(SystemError::EINVAL), + } + } - INODE_MAP.write_irqsave().insert(inodeid, inode); - Ok(()) - } - Endpoint::Abspath((abshandle, path)) => { - let inode = match &mut *self.inner.write() { - inner::Inner::Init(init) => init.bind_path(path)?, - _ => { - log::error!("socket has listen or connected"); - return Err(SystemError::EINVAL); - } - }; - ABS_INODE_MAP.lock_irqsave().insert(abshandle.name(), inode); - Ok(()) - } + fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> { + let endpoint = match endpoint { + Endpoint::Unix(unix) => unix, _ => return Err(SystemError::EINVAL), - } + }; + + self.do_connect(endpoint) } - fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { + fn shutdown(&self, how: ShutdownBit) -> Result<(), SystemError> { log::debug!("seqpacket shutdown"); match &*self.inner.write() { - inner::Inner::Connected(connected) => connected.shutdown(how), + inner::Status::Connected(connected) => connected.shutdown(how), _ => Err(SystemError::EINVAL), } } @@ -260,21 +180,21 @@ impl Socket for SeqpacketSocket { let mut state = self.inner.write(); log::debug!("listen into socket"); let epoint = match &*state { - inner::Inner::Init(init) => init.endpoint().ok_or(SystemError::EINVAL)?.clone(), - inner::Inner::Listen(listener) => return listener.listen(backlog), - inner::Inner::Connected(_) => { + inner::Status::Init(init) => init.endpoint().ok_or(SystemError::EINVAL)?.clone(), + inner::Status::Listen(listener) => return listener.listen(backlog), + inner::Status::Connected(_) => { log::error!("the socket is connected"); return Err(SystemError::EINVAL); } }; let listener = inner::Listener::new(epoint, backlog); - *state = inner::Inner::Listen(listener); + *state = inner::Status::Listen(listener); Ok(()) } - fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { + fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { if !self.is_nonblocking() { loop { wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?; @@ -355,7 +275,7 @@ impl Socket for SeqpacketSocket { } } - *self.inner.write() = inner::Inner::Init(inner::Init::new()); + *self.inner.write() = inner::Status::Init(inner::Init::new()); self.wait_queue.wakeup(None); let _ = remove_abs_addr(path); @@ -366,7 +286,7 @@ impl Socket for SeqpacketSocket { fn get_peer_name(&self) -> Result { // 获取对端地址 let endpoint = match &*self.inner.read() { - inner::Inner::Connected(connected) => connected.peer_endpoint().cloned(), + inner::Status::Connected(connected) => connected.peer_endpoint().cloned(), _ => return Err(SystemError::ENOTCONN), }; @@ -380,9 +300,9 @@ impl Socket for SeqpacketSocket { fn get_name(&self) -> Result { // 获取本端地址 let endpoint = match &*self.inner.read() { - inner::Inner::Init(init) => init.endpoint().cloned(), - inner::Inner::Listen(listener) => Some(listener.endpoint().clone()), - inner::Inner::Connected(connected) => connected.endpoint().cloned(), + inner::Status::Init(init) => init.endpoint().cloned(), + inner::Status::Listen(listener) => Some(listener.endpoint().clone()), + inner::Status::Connected(connected) => connected.endpoint().cloned(), }; if let Some(endpoint) = endpoint { @@ -423,7 +343,7 @@ impl Socket for SeqpacketSocket { )?; // connect锁和flag判断顺序不正确,应该先判断在 match &*self.inner.write() { - inner::Inner::Connected(connected) => match connected.try_read(buffer) { + inner::Status::Connected(connected) => match connected.try_read(buffer) { Ok(usize) => { log::debug!("recv from successfully"); return Ok(usize); @@ -459,7 +379,7 @@ impl Socket for SeqpacketSocket { if !flags.contains(PMSG::DONTWAIT) { loop { match &*self.inner.write() { - inner::Inner::Connected(connected) => match connected.try_write(buffer) { + inner::Status::Connected(connected) => match connected.try_write(buffer) { Ok(usize) => { log::debug!("send successfully"); return Ok(usize); @@ -508,7 +428,7 @@ impl Socket for SeqpacketSocket { )?; // connect锁和flag判断顺序不正确,应该先判断在 match &*self.inner.write() { - inner::Inner::Connected(connected) => match connected.recv_slice(buffer) { + inner::Status::Connected(connected) => match connected.recv_slice(buffer) { Ok(usize) => { // log::debug!("recvs from successfully"); return Ok((usize, connected.peer_endpoint().unwrap().clone())); @@ -551,7 +471,7 @@ impl Socket for SeqpacketSocket { mask |= EP::EPOLLRDHUP | EP::EPOLLIN | EP::EPOLLRDNORM; } match &*self.inner.read() { - inner::Inner::Connected(connected) => { + inner::Status::Connected(connected) => { if connected.can_recv() { mask |= EP::EPOLLIN | EP::EPOLLRDNORM; } @@ -568,9 +488,65 @@ impl Socket for SeqpacketSocket { } } } - inner::Inner::Listen(_) => mask |= EP::EPOLLIN, - inner::Inner::Init(_) => mask |= EP::EPOLLOUT, + inner::Status::Listen(_) => mask |= EP::EPOLLIN, + inner::Status::Init => mask |= EP::EPOLLOUT, } mask.bits() as usize } } + +impl IndexNode for SeqpacketSocket { + fn read_at( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + _data: crate::libs::spinlock::SpinLockGuard, + ) -> Result { + todo!() + } + + fn write_at( + &self, + offset: usize, + len: usize, + buf: &[u8], + _data: crate::libs::spinlock::SpinLockGuard, + ) -> Result { + todo!() + } + + fn fs(&self) -> Arc { + unimplemented!("SeqpacketSocket fs is not implemented") + } + + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn list(&self) -> Result, SystemError> { + unimplemented!("SeqpacketSocket list is not implemented") + } +} + +impl PollableInode for SeqpacketSocket { + fn poll(&self, private_data: &crate::filesystem::vfs::FilePrivateData) -> Result { + todo!() + } + + fn add_epitem( + &self, + epitem: Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } + + fn remove_epitem( + &self, + epitm: &Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } +} diff --git a/kernel/src/net/socket/unix/stream/inner.rs b/kernel/src/net/socket/unix/stream/inner.rs index a10e69737..3fc63e896 100644 --- a/kernel/src/net/socket/unix/stream/inner.rs +++ b/kernel/src/net/socket/unix/stream/inner.rs @@ -4,11 +4,10 @@ use log::debug; use system_error::SystemError; use crate::libs::mutex::Mutex; -use crate::net::socket::buffer::Buffer; -use crate::net::socket::common::shutdown::ShutdownTemp; +use crate::net::socket::common::shutdown::ShutdownBit; use crate::net::socket::endpoint::Endpoint; use crate::net::socket::unix::stream::StreamSocket; -use crate::net::socket::SocketInode; +use crate::net::socket::unix::UnixEndpoint; use alloc::collections::VecDeque; use alloc::{string::String, sync::Arc}; @@ -67,13 +66,13 @@ impl Init { #[derive(Debug, Clone)] pub struct Connected { - addr: Option, - peer_addr: Option, + addr: Option, + peer_addr: Option, buffer: Arc, } impl Connected { - pub fn new_pair(addr: Option, peer_addr: Option) -> (Self, Self) { + pub fn new_pair(addr: Option, peer_addr: Option) -> (Self, Self) { let this = Connected { addr: addr.clone(), peer_addr: peer_addr.clone(), @@ -169,7 +168,7 @@ impl Connected { } } #[allow(dead_code)] - pub fn shutdown(&self, how: ShutdownTemp) -> Result<(), SystemError> { + pub fn shutdown(&self, how: ShutdownBit) -> Result<(), SystemError> { if how.is_empty() { return Err(SystemError::EINVAL); } else if how.is_send_shutdown() { diff --git a/kernel/src/net/socket/unix/stream/mod.rs b/kernel/src/net/socket/unix/stream/mod.rs index 10b040d43..7cede6a0d 100644 --- a/kernel/src/net/socket/unix/stream/mod.rs +++ b/kernel/src/net/socket/unix/stream/mod.rs @@ -1,8 +1,9 @@ use crate::{ + filesystem::vfs::{FilePrivateData, IndexNode, PollableInode}, net::{ posix::MsgHdr, socket::{ - common::shutdown::{Shutdown, ShutdownTemp}, + common::shutdown::{Shutdown, ShutdownBit}, endpoint::Endpoint, }, }, @@ -55,20 +56,19 @@ impl StreamSocket { }) } - pub fn new_pairs() -> Result<(Arc, Arc), SystemError> { + pub fn new_pairs() -> Result<(Arc, Arc), SystemError> { let socket0 = StreamSocket::new(); let socket1 = StreamSocket::new(); - let inode0 = SocketInode::new(socket0.clone()); - let inode1 = SocketInode::new(socket1.clone()); - let (conn_0, conn_1) = Connected::new_pair( - Some(Endpoint::Inode((inode0.clone(), String::from("")))), - Some(Endpoint::Inode((inode1.clone(), String::from("")))), - ); - *socket0.inner.write() = Inner::Connected(conn_0); - *socket1.inner.write() = Inner::Connected(conn_1); + // let (conn_0, conn_1) = Connected::new_pair( + // Some(Endpoint::Inode((inode0.clone(), String::from("")))), + // Some(Endpoint::Inode((inode1.clone(), String::from("")))), + // ); + // *socket0.inner.write() = Inner::Connected(conn_0); + // *socket1.inner.write() = Inner::Connected(conn_1); - return Ok((inode0, inode1)); + // return Ok((inode0, inode1)); + todo!() } #[allow(dead_code)] pub fn new_connected(connected: Connected) -> Arc { @@ -81,16 +81,15 @@ impl StreamSocket { }) } - pub fn new_inode() -> Result, SystemError> { + pub fn new_inode() -> Result, SystemError> { let socket = StreamSocket::new(); - let inode = SocketInode::new(socket.clone()); let _ = match &mut *socket.inner.write() { Inner::Init(init) => init.bind(Endpoint::Inode((inode.clone(), String::from("")))), _ => return Err(SystemError::EINVAL), }; - return Ok(inode); + return Ok(socket); } fn is_acceptable(&self) -> bool { @@ -102,7 +101,7 @@ impl StreamSocket { } } - pub fn try_accept(&self) -> Result<(Arc, Endpoint), SystemError> { + pub fn try_accept(&self) -> Result<(Arc, Endpoint), SystemError> { match &*self.inner.read() { Inner::Listener(listener) => listener.try_accept() as _, _ => { @@ -144,7 +143,6 @@ impl Socket for StreamSocket { } None => { debug!("not bind when connected"); - let inode = SocketInode::new(self.self_ref.upgrade().unwrap().clone()); let epoint = Endpoint::Inode((inode.clone(), String::from(""))); let _ = init.bind(epoint.clone()); Some(epoint) @@ -162,9 +160,9 @@ impl Socket for StreamSocket { //找到对端socket let (peer_inode, sun_path) = match server_endpoint { Endpoint::Inode((inode, path)) => (inode, path), - Endpoint::Unixpath((inode_id, path)) => { + Endpoint::Unixpath((inode, path)) => { let inode_guard = INODE_MAP.read_irqsave(); - let inode = inode_guard.get(&inode_id).unwrap(); + let inode = inode_guard.get(&inode).unwrap(); match inode { Endpoint::Inode((inode, _)) => (inode.clone(), path), _ => return Err(SystemError::EINVAL), @@ -194,8 +192,7 @@ impl Socket for StreamSocket { Arc::downcast::(peer_inode.inner()).map_err(|_| SystemError::EINVAL)?; //创建新的对端socket - let new_server_socket = StreamSocket::new(); - let new_server_inode = SocketInode::new(new_server_socket.clone()); + let new_server_inode = StreamSocket::new(); let new_server_endpoint = Some(Endpoint::Inode((new_server_inode.clone(), sun_path))); //获取connect pair let (client_conn, server_conn) = @@ -245,8 +242,8 @@ impl Socket for StreamSocket { } } - fn shutdown(&self, _stype: ShutdownTemp) -> Result<(), SystemError> { - todo!(); + fn shutdown(&self, _stype: ShutdownBit) -> Result<(), SystemError> { + self.do_close() } fn listen(&self, backlog: usize) -> Result<(), SystemError> { @@ -267,7 +264,7 @@ impl Socket for StreamSocket { return Ok(()); } - fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { + fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { debug!("stream server begin accept"); //目前只实现了阻塞式实现 loop { @@ -291,44 +288,7 @@ impl Socket for StreamSocket { return &self.wait_queue; } - fn poll(&self) -> usize { - let mut mask = EP::empty(); - let shutdown = self.shutdown.get(); - - // 参考linux的unix_poll https://code.dragonos.org.cn/xref/linux-6.1.9/net/unix/af_unix.c#3152 - // 用关闭读写端表示连接断开 - if shutdown.is_both_shutdown() || self.is_peer_shutdown().unwrap() { - mask |= EP::EPOLLHUP; - } - - if shutdown.is_recv_shutdown() { - mask |= EP::EPOLLRDHUP | EP::EPOLLIN | EP::EPOLLRDNORM; - } - match &*self.inner.read() { - Inner::Connected(connected) => { - if connected.can_recv() { - mask |= EP::EPOLLIN | EP::EPOLLRDNORM; - } - // if (sk_is_readable(sk)) - // mask |= EPOLLIN | EPOLLRDNORM; - - // TODO:处理紧急情况 EPOLLPRI - // TODO:处理连接是否关闭 EPOLLHUP - if !shutdown.is_send_shutdown() { - if connected.can_send().unwrap() { - mask |= EP::EPOLLOUT | EP::EPOLLWRNORM | EP::EPOLLWRBAND; - } else { - todo!("poll: buffer space not enough"); - } - } - } - Inner::Listener(_) => mask |= EP::EPOLLIN, - Inner::Init(_) => mask |= EP::EPOLLOUT, - } - mask.bits() as usize - } - - fn close(&self) -> Result<(), SystemError> { + fn do_close(&self) -> Result<(), SystemError> { self.shutdown.recv_shutdown(); self.shutdown.send_shutdown(); @@ -555,3 +515,59 @@ impl Socket for StreamSocket { StreamSocket::DEFAULT_BUF_SIZE } } + +impl PollableInode for StreamSocket { + fn poll(&self, private_data: &FilePrivateData) -> Result { + todo!("poll is not implemented yet"); + // let mut mask = EP::empty(); + // let shutdown = self.shutdown.get(); + + // // 参考linux的unix_poll https://code.dragonos.org.cn/xref/linux-6.1.9/net/unix/af_unix.c#3152 + // // 用关闭读写端表示连接断开 + // if shutdown.is_both_shutdown() || self.is_peer_shutdown().unwrap() { + // mask |= EP::EPOLLHUP; + // } + + // if shutdown.is_recv_shutdown() { + // mask |= EP::EPOLLRDHUP | EP::EPOLLIN | EP::EPOLLRDNORM; + // } + // match &*self.inner.read() { + // Inner::Connected(connected) => { + // if connected.can_recv() { + // mask |= EP::EPOLLIN | EP::EPOLLRDNORM; + // } + // // if (sk_is_readable(sk)) + // // mask |= EPOLLIN | EPOLLRDNORM; + + // // TODO:处理紧急情况 EPOLLPRI + // // TODO:处理连接是否关闭 EPOLLHUP + // if !shutdown.is_send_shutdown() { + // if connected.can_send().unwrap() { + // mask |= EP::EPOLLOUT | EP::EPOLLWRNORM | EP::EPOLLWRBAND; + // } else { + // todo!("poll: buffer space not enough"); + // } + // } + // } + // Inner::Listener(_) => mask |= EP::EPOLLIN, + // Inner::Init(_) => mask |= EP::EPOLLOUT, + // } + // Ok(mask.bits() as usize) + } + + fn add_epitem( + &self, + epitem: Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } + + fn remove_epitem( + &self, + epitm: &Arc, + private_data: &crate::filesystem::vfs::FilePrivateData, + ) -> Result<(), SystemError> { + todo!() + } +} diff --git a/kernel/src/net/socket/utils.rs b/kernel/src/net/socket/utils.rs index 372106d40..148977b5f 100644 --- a/kernel/src/net/socket/utils.rs +++ b/kernel/src/net/socket/utils.rs @@ -1,4 +1,4 @@ -use crate::net::socket; +use crate::{filesystem::vfs::IndexNode, net::socket}; use alloc::sync::Arc; use socket::Family; use system_error::SystemError; @@ -8,19 +8,19 @@ pub fn create_socket( socket_type: socket::PSOCK, protocol: u32, is_nonblock: bool, - is_close_on_exec: bool, -) -> Result, SystemError> { + _is_close_on_exec: bool, +) -> Result, SystemError> { type AF = socket::AddressFamily; let inode = match family { - AF::INet => socket::inet::Inet::socket(socket_type, protocol)?, + AF::INet => socket::inet::Inet::socket(socket_type, protocol, is_nonblock)?, // AF::INet6 => socket::inet::Inet6::socket(socket_type, protocol)?, - AF::Unix => socket::unix::Unix::socket(socket_type, protocol)?, + AF::Unix => socket::unix::Unix::socket(socket_type, protocol, is_nonblock)?, _ => { log::warn!("unsupport address family"); return Err(SystemError::EAFNOSUPPORT); } }; - inode.set_nonblock(is_nonblock); - inode.set_close_on_exec(is_close_on_exec); + // inode.set_nonblock(is_nonblock); + // inode.set_close_on_exec(is_close_on_exec); return Ok(inode); } diff --git a/kernel/src/net/syscall.rs b/kernel/src/net/syscall.rs index 2d90eff96..e2b528547 100644 --- a/kernel/src/net/syscall.rs +++ b/kernel/src/net/syscall.rs @@ -1,5 +1,3 @@ -use alloc::sync::Arc; -use log::debug; use system_error::SystemError; use crate::{ @@ -57,10 +55,8 @@ impl Syscall { let file = File::new(inode, FileMode::O_RDWR)?; // 把socket添加到当前进程的文件描述符表中 let binding = ProcessManager::current_pcb().fd_table(); - let mut fd_table_guard = binding.write(); - let fd: Result = - fd_table_guard.alloc_fd(file, None).map(|x| x as usize); - drop(fd_table_guard); + + let fd = binding.write().alloc_fd(file, None).map(|x| x as usize); return fd; } @@ -95,7 +91,7 @@ impl Syscall { } // 创建一对新的unix socket pair - let (inode0, inode1) = Unix::new_pairs(stype)?; + let (inode0, inode1) = Unix::new_pairs(stype, socket_type.is_nonblock())?; fds[0] = fd_table_guard.alloc_fd(File::new(inode0, FileMode::O_RDWR)?, None)?; fds[1] = fd_table_guard.alloc_fd(File::new(inode1, FileMode::O_RDWR)?, None)?; @@ -118,10 +114,11 @@ impl Syscall { optval: &[u8], ) -> Result { let sol = socket::PSOL::try_from(level as u32)?; - let socket: Arc = ProcessManager::current_pcb() + let socket = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; - debug!("setsockopt: level = {:?} ", sol); + let socket = socket.as_socket().unwrap(); + log::debug!("setsockopt: level = {:?} ", sol); return socket.set_option(sol, optname, optval).map(|_| 0); } @@ -143,9 +140,10 @@ impl Syscall { ) -> Result { // 获取socket let optval = optval as *mut u32; - let socket: Arc = ProcessManager::current_pcb() + let inode = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); use socket::{PSO, PSOL}; @@ -175,7 +173,7 @@ impl Syscall { } } } - drop(socket); + drop(inode); // To manipulate options at any other level the // protocol number of the appropriate protocol controlling the @@ -209,6 +207,7 @@ impl Syscall { let socket = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = socket.as_socket().unwrap(); socket.connect(endpoint)?; Ok(0) } @@ -229,9 +228,10 @@ impl Syscall { // addrlen // ); let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; - let socket: Arc = ProcessManager::current_pcb() + let socket = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = socket.as_socket().unwrap(); // log::debug!("bind: socket={:?}", socket); socket.bind(endpoint)?; Ok(0) @@ -261,12 +261,13 @@ impl Syscall { let flags = socket::PMSG::from_bits_truncate(flags); - let socket: Arc = ProcessManager::current_pcb() + let inode = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); if let Some(endpoint) = endpoint { - return socket.send_to(buf, endpoint, flags); + return socket.send_to(buf, flags, endpoint); } else { return socket.send(buf, flags); } @@ -288,9 +289,10 @@ impl Syscall { addr: *mut SockAddr, addr_len: *mut u32, ) -> Result { - let socket: Arc = ProcessManager::current_pcb() + let inode = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); let flags = socket::PMSG::from_bits_truncate(flags); if addr.is_null() { @@ -303,10 +305,7 @@ impl Syscall { if unsafe { address.is_empty() } { let (recv_len, endpoint) = socket.recv_from(buf, flags, None)?; - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to_user(addr, addr_len)?; - } + endpoint.write_to_user(addr, addr_len)?; return Ok(recv_len); } else { // 从socket中读取数据 @@ -328,16 +327,20 @@ impl Syscall { // 检查每个缓冲区地址是否合法,生成iovecs let iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? }; - let socket: Arc = ProcessManager::current_pcb() - .get_socket(fd as i32) - .ok_or(SystemError::EBADF)?; + let (buf, recv_size) = { + let inode = ProcessManager::current_pcb() + .get_socket(fd as i32) + .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); - let flags = socket::PMSG::from_bits_truncate(flags); + let flags = socket::PMSG::from_bits_truncate(flags); - let mut buf = iovs.new_buf(true); - // 从socket中读取数据 - let recv_size = socket.recv(&mut buf, flags)?; - drop(socket); + 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]); @@ -352,9 +355,10 @@ impl Syscall { /// /// @return 成功返回0,失败返回错误码 pub fn listen(fd: usize, backlog: usize) -> Result { - let socket: Arc = ProcessManager::current_pcb() + let inode = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); socket.listen(backlog).map(|_| 0) } @@ -365,11 +369,11 @@ impl Syscall { /// /// @return 成功返回0,失败返回错误码 pub fn shutdown(fd: usize, how: usize) -> Result { - let socket: Arc = ProcessManager::current_pcb() + let inode = ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)?; - socket.shutdown(how.try_into()?)?; - return Ok(0); + let socket = inode.as_socket().unwrap(); + socket.shutdown(how).map(|()| 0) } /// @brief sys_accept系统调用的实际执行函数 @@ -424,13 +428,15 @@ impl Syscall { addrlen: *mut u32, flags: u32, ) -> Result { - let socket: Arc = ProcessManager::current_pcb() - .get_socket(fd as i32) - .ok_or(SystemError::EBADF)?; - - // 从socket中接收连接 - let (new_socket, remote_endpoint) = socket.accept()?; - drop(socket); + let (new_socket, remote_endpoint) = { + let inode = ProcessManager::current_pcb() + .get_socket(fd as i32) + .ok_or(SystemError::EBADF)?; + let socket = inode.as_socket().unwrap(); + + // 从socket中接收连接 + socket.accept()? + }; // debug!("accept: new_socket={:?}", new_socket); // Insert the new socket into the file descriptor vector @@ -449,12 +455,8 @@ impl Syscall { .alloc_fd(File::new(new_socket, file_mode)?, None)?; // debug!("accept: new_fd={}", new_fd); if !addr.is_null() { - // debug!("accept: write remote_endpoint to user"); // 将对端地址写入用户空间 - let sockaddr_in = SockAddr::from(remote_endpoint); - unsafe { - sockaddr_in.write_to_user(addr, addrlen)?; - } + remote_endpoint.write_to_user(addr, addrlen)?; } return Ok(new_fd as usize); } @@ -477,15 +479,13 @@ impl Syscall { if addr.is_null() { return Err(SystemError::EINVAL); } - let endpoint = ProcessManager::current_pcb() + ProcessManager::current_pcb() .get_socket(fd as i32) .ok_or(SystemError::EBADF)? - .get_name()?; - - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to_user(addr, addrlen)?; - } + .as_socket() + .unwrap() + .get_name()? + .write_to_user(addr, addrlen)?; return Ok(0); } @@ -505,17 +505,14 @@ impl Syscall { return Err(SystemError::EINVAL); } - let socket: Arc = ProcessManager::current_pcb() + ProcessManager::current_pcb() .get_socket(fd as i32) - .ok_or(SystemError::EBADF)?; - - let endpoint: Endpoint = socket.get_peer_name()?; - drop(socket); + .ok_or(SystemError::EBADF)? + .as_socket() + .unwrap() + .get_peer_name()? + .write_to_user(addr, addrlen)?; - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to_user(addr, addrlen)?; - } return Ok(0); } } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 28406669f..e184feb91 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -39,7 +39,6 @@ use crate::{ }, libs::{ align::AlignedBox, - casting::DowncastArc, futex::{ constant::{FutexFlag, FUTEX_BITSET_MATCH_ANY}, futex::{Futex, RobustListHead}, @@ -57,7 +56,6 @@ use crate::{ VirtAddr, }, namespaces::{mnt_namespace::FsStruct, pid_namespace::PidStrcut, NsProxy}, - net::socket::SocketInode, sched::{ completion::Completion, cpu_rq, fair::FairSchedEntity, prio::MAX_PRIO, DequeueFlag, EnqueueFlag, OnRq, SchedMode, WakeupFlags, __schedule, @@ -1053,6 +1051,8 @@ impl ProcessControlBlock { /// 根据文件描述符序号,获取socket对象的Arc指针 /// + /// this is a helper function + /// /// ## 参数 /// /// - `fd` 文件描述符序号 @@ -1060,7 +1060,7 @@ impl ProcessControlBlock { /// ## 返回值 /// /// Option(&mut Box) socket对象的可变引用. 如果文件描述符不是socket,那么返回None - pub fn get_socket(&self, fd: i32) -> Option> { + pub fn get_socket(&self, fd: i32) -> Option> { let binding = ProcessManager::current_pcb().fd_table(); let fd_table_guard = binding.read(); @@ -1070,11 +1070,8 @@ impl ProcessControlBlock { if f.file_type() != FileType::Socket { return None; } - let socket: Arc = f - .inode() - .downcast_arc::() - .expect("Not a socket inode"); - return Some(socket); + let inode = f.inode(); + return Some(inode); } /// 当前进程退出时,让初始进程收养所有子进程