diff --git a/build/src/main.rs b/build/src/main.rs index b8e797df8..86918c76a 100644 --- a/build/src/main.rs +++ b/build/src/main.rs @@ -55,7 +55,7 @@ const COMMON_ARGS: &[&str] = &[ "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-netdev", - "user,id=net01,hostfwd=tcp::30022-:22,hostfwd=tcp::30080-:8080", + "user,id=net01,hostfwd=tcp::30033-:22,hostfwd=tcp::30088-:8080", "-object", "filter-dump,id=filter0,netdev=net01,file=virtio-net.pcap", ]; diff --git a/framework/jinux-frame/src/arch/x86/timer/mod.rs b/framework/jinux-frame/src/arch/x86/timer/mod.rs index 2a7bfd2c1..bff0a8a1a 100644 --- a/framework/jinux-frame/src/arch/x86/timer/mod.rs +++ b/framework/jinux-frame/src/arch/x86/timer/mod.rs @@ -3,14 +3,15 @@ pub mod hpet; pub mod pit; use core::any::Any; -use core::sync::atomic::{AtomicU64, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec}; -use spin::{Mutex, Once}; +use spin::Once; use trapframe::TrapFrame; use crate::arch::x86::kernel; use crate::config::TIMER_FREQ; +use crate::sync::SpinLock; use crate::trap::IrqAllocateHandle; use self::apic::APIC_TIMER_CALLBACK; @@ -21,7 +22,7 @@ pub static TICK: AtomicU64 = AtomicU64::new(0); static TIMER_IRQ: Once = Once::new(); pub fn init() { - TIMEOUT_LIST.call_once(|| Mutex::new(BinaryHeap::new())); + TIMEOUT_LIST.call_once(|| SpinLock::new(BinaryHeap::new())); if kernel::apic::APIC_INSTANCE.is_completed() { apic::init(); } else { @@ -53,13 +54,13 @@ fn timer_callback(trap_frame: &TrapFrame) { } } -static TIMEOUT_LIST: Once>>> = Once::new(); +static TIMEOUT_LIST: Once>>> = Once::new(); pub struct TimerCallback { expire_ms: u64, data: Arc, callback: Box, - enable: Mutex, + enable: AtomicBool, } impl TimerCallback { @@ -72,7 +73,7 @@ impl TimerCallback { expire_ms: timeout_ms, data, callback, - enable: Mutex::new(true), + enable: AtomicBool::new(true), } } @@ -82,16 +83,16 @@ impl TimerCallback { /// disable this timeout pub fn disable(&self) { - *self.enable.lock() = false; + self.enable.store(false, Ordering::Release) } /// enable this timeout pub fn enable(&self) { - *self.enable.lock() = true; + self.enable.store(false, Ordering::Release) } pub fn is_enable(&self) -> bool { - *self.enable.lock() + self.enable.load(Ordering::Acquire) } } @@ -125,7 +126,7 @@ where T: Any + Send + Sync, { let timer_callback = TimerCallback::new( - TICK.load(Ordering::SeqCst) + timeout, + TICK.load(Ordering::Acquire) + timeout, Arc::new(data), Box::new(callback), ); @@ -137,5 +138,5 @@ where /// The time since the system boots up. /// The currently returned results are in milliseconds. pub fn read_monotonic_milli_seconds() -> u64 { - TICK.load(Ordering::SeqCst) * (1000 / TIMER_FREQ) + TICK.load(Ordering::Acquire) * (1000 / TIMER_FREQ) } diff --git a/regression/apps/scripts/nettest.sh b/regression/apps/scripts/nettest.sh index 980ad35bc..0f17522ce 100755 --- a/regression/apps/scripts/nettest.sh +++ b/regression/apps/scripts/nettest.sh @@ -3,9 +3,12 @@ NETTEST_DIR=/regression/network cd ${NETTEST_DIR} echo "Start net test......" -./tcp_server & -./tcp_client -./udp_server & -./udp_client +# ./tcp_server & +# ./tcp_client +# ./udp_server & +# ./udp_client +./unix_server & +./unix_client +./socketpair echo "All net test passed" diff --git a/services/libs/jinux-std/src/fs/fs_resolver.rs b/services/libs/jinux-std/src/fs/fs_resolver.rs index 94f9ee003..650d8703c 100644 --- a/services/libs/jinux-std/src/fs/fs_resolver.rs +++ b/services/libs/jinux-std/src/fs/fs_resolver.rs @@ -370,7 +370,7 @@ impl<'a> TryFrom<&'a str> for FsPath<'a> { /// Example: /// /// The path "/dir/file/" will be split to ("/dir", "file/"). -fn split_path(path: &str) -> (&str, &str) { +pub fn split_path(path: &str) -> (&str, &str) { let file_name = path .split_inclusive('/') .filter(|&x| x != "/") diff --git a/services/libs/jinux-std/src/fs/pipe.rs b/services/libs/jinux-std/src/fs/pipe.rs index a813e19c5..ee1bba7f3 100644 --- a/services/libs/jinux-std/src/fs/pipe.rs +++ b/services/libs/jinux-std/src/fs/pipe.rs @@ -18,27 +18,7 @@ impl PipeReader { impl FileLike for PipeReader { fn read(&self, buf: &mut [u8]) -> Result { - let is_nonblocking = self.consumer.is_nonblocking(); - - // Fast path - let res = self.consumer.read(buf); - if should_io_return(&res, is_nonblocking) { - return res; - } - - // Slow path - let mask = IoEvents::IN; - let poller = Poller::new(); - loop { - let res = self.consumer.read(buf); - if should_io_return(&res, is_nonblocking) { - return res; - } - let events = self.poll(mask, Some(&poller)); - if events.is_empty() { - poller.wait(); - } - } + self.consumer.read(buf) } fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents { @@ -104,27 +84,7 @@ impl PipeWriter { impl FileLike for PipeWriter { fn write(&self, buf: &[u8]) -> Result { - let is_nonblocking = self.producer.is_nonblocking(); - - // Fast path - let res = self.producer.write(buf); - if should_io_return(&res, is_nonblocking) { - return res; - } - - // Slow path - let mask = IoEvents::OUT; - let poller = Poller::new(); - loop { - let res = self.producer.write(buf); - if should_io_return(&res, is_nonblocking) { - return res; - } - let events = self.poll(mask, Some(&poller)); - if events.is_empty() { - poller.wait(); - } - } + self.producer.write(buf) } fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents { diff --git a/services/libs/jinux-std/src/fs/ramfs/fs.rs b/services/libs/jinux-std/src/fs/ramfs/fs.rs index 407b5860a..7c1b86d74 100644 --- a/services/libs/jinux-std/src/fs/ramfs/fs.rs +++ b/services/libs/jinux-std/src/fs/ramfs/fs.rs @@ -117,6 +117,15 @@ impl Inode_ { } } + pub fn new_socket(ino: usize, mode: InodeMode, sb: &SuperBlock) -> Self { + Self { + inner: Inner::Socket, + metadata: Metadata::new_socket(ino, mode, sb), + this: Weak::default(), + fs: Weak::default(), + } + } + pub fn new_device( ino: usize, mode: InodeMode, @@ -153,6 +162,7 @@ enum Inner { File, SymLink(Str256), Device(Arc), + Socket, } impl Inner { @@ -489,6 +499,24 @@ impl Inode for RamInode { self_inode.metadata.nlinks += 1; dir_inode } + InodeType::SymLink => { + let sym_inode = Arc::new(RamInode(RwLock::new(Inode_::new_symlink( + fs.alloc_id(), + mode, + &fs.sb(), + )))); + sym_inode.0.write().fs = self_inode.fs.clone(); + sym_inode + } + InodeType::Socket => { + let socket_inode = Arc::new(RamInode(RwLock::new(Inode_::new_socket( + fs.alloc_id(), + mode, + &fs.sb(), + )))); + socket_inode.0.write().fs = self_inode.fs.clone(); + socket_inode + } _ => { panic!("unsupported inode type"); } diff --git a/services/libs/jinux-std/src/fs/utils/channel.rs b/services/libs/jinux-std/src/fs/utils/channel.rs index c1a277ae0..fa6e8a572 100644 --- a/services/libs/jinux-std/src/fs/utils/channel.rs +++ b/services/libs/jinux-std/src/fs/utils/channel.rs @@ -134,6 +134,30 @@ impl Producer { impl Producer { pub fn write(&self, buf: &[T]) -> Result { + let is_nonblocking = self.is_nonblocking(); + + // Fast path + let res = self.try_write(buf); + if should_io_return(&res, is_nonblocking) { + return res; + } + + // Slow path + let mask = IoEvents::OUT; + let poller = Poller::new(); + loop { + let res = self.try_write(buf); + if should_io_return(&res, is_nonblocking) { + return res; + } + let events = self.poll(mask, Some(&poller)); + if events.is_empty() { + poller.wait(); + } + } + } + + fn try_write(&self, buf: &[T]) -> Result { if self.is_shutdown() || self.is_peer_shutdown() { return_errno!(Errno::EPIPE); } @@ -198,10 +222,33 @@ impl Consumer { impl Consumer { pub fn read(&self, buf: &mut [T]) -> Result { + let is_nonblocking = self.is_nonblocking(); + + // Fast path + let res = self.try_read(buf); + if should_io_return(&res, is_nonblocking) { + return res; + } + + // Slow path + let mask = IoEvents::IN; + let poller = Poller::new(); + loop { + let res = self.try_read(buf); + if should_io_return(&res, is_nonblocking) { + return res; + } + let events = self.poll(mask, Some(&poller)); + if events.is_empty() { + poller.wait(); + } + } + } + + fn try_read(&self, buf: &mut [T]) -> Result { if self.is_shutdown() { return_errno!(Errno::EPIPE); } - if buf.len() == 0 { return Ok(0); } @@ -347,3 +394,14 @@ fn check_status_flags(flags: StatusFlags) -> Result<()> { } Ok(()) } + +fn should_io_return(res: &Result, is_nonblocking: bool) -> bool { + if is_nonblocking { + return true; + } + match res { + Ok(_) => true, + Err(e) if e.error() == Errno::EAGAIN => false, + Err(_) => true, + } +} diff --git a/services/libs/jinux-std/src/fs/utils/dentry.rs b/services/libs/jinux-std/src/fs/utils/dentry.rs index eac0cfa0e..f4823b030 100644 --- a/services/libs/jinux-std/src/fs/utils/dentry.rs +++ b/services/libs/jinux-std/src/fs/utils/dentry.rs @@ -5,7 +5,7 @@ use alloc::string::String; use core::sync::atomic::{AtomicU32, Ordering}; use core::time::Duration; -use super::{FileSystem, InodeMode, InodeType, Metadata, MountNode, Vnode, NAME_MAX}; +use super::{FileSystem, Inode, InodeMode, InodeType, Metadata, Vnode, NAME_MAX}; lazy_static! { static ref DCACHE: Mutex>> = Mutex::new(BTreeMap::new()); @@ -162,6 +162,8 @@ impl Dentry { /// Get the mount node which the dentry belongs to. pub fn mount_node(&self) -> Arc { self.mount_node.upgrade().unwrap() + pub fn inode(&self) -> Weak { + self.vnode.inode() } /// Create a dentry by making inode. diff --git a/services/libs/jinux-std/src/fs/utils/inode.rs b/services/libs/jinux-std/src/fs/utils/inode.rs index 5bc33255f..1044fa0e9 100644 --- a/services/libs/jinux-std/src/fs/utils/inode.rs +++ b/services/libs/jinux-std/src/fs/utils/inode.rs @@ -204,6 +204,25 @@ impl Metadata { rdev: device.id().into(), } } + + pub fn new_socket(ino: usize, mode: InodeMode, sb: &SuperBlock) -> Metadata { + Self { + dev: 0, + ino, + size: 0, + blk_size: sb.bsize, + blocks: 0, + atime: Default::default(), + mtime: Default::default(), + ctime: Default::default(), + type_: InodeType::Socket, + mode, + nlinks: 1, + uid: 0, + gid: 0, + rdev: 0, + } + } } pub trait Inode: Any + Sync + Send { diff --git a/services/libs/jinux-std/src/fs/utils/vnode.rs b/services/libs/jinux-std/src/fs/utils/vnode.rs index aef281141..e8b944f98 100644 --- a/services/libs/jinux-std/src/fs/utils/vnode.rs +++ b/services/libs/jinux-std/src/fs/utils/vnode.rs @@ -211,6 +211,11 @@ impl Vnode { self.inner.read().inode.metadata() } + pub fn inode(&self) -> Weak { + let inner = self.inner.read(); + Arc::downgrade(&inner.inode) + } + pub fn inode_type(&self) -> InodeType { self.inner.read().inode.metadata().type_ } diff --git a/services/libs/jinux-std/src/net/socket/mod.rs b/services/libs/jinux-std/src/net/socket/mod.rs index 0924cb53c..aa992d090 100644 --- a/services/libs/jinux-std/src/net/socket/mod.rs +++ b/services/libs/jinux-std/src/net/socket/mod.rs @@ -6,6 +6,7 @@ pub use self::util::sock_options::{SockOptionLevel, SockOptionName}; pub use self::util::sockaddr::SocketAddr; pub mod ip; +pub mod unix; mod util; /// Operations defined on a socket. diff --git a/services/libs/jinux-std/src/net/socket/util/shutdown_cmd.rs b/services/libs/jinux-std/src/net/socket/util/shutdown_cmd.rs index ba059b10e..374682f99 100644 --- a/services/libs/jinux-std/src/net/socket/util/shutdown_cmd.rs +++ b/services/libs/jinux-std/src/net/socket/util/shutdown_cmd.rs @@ -13,3 +13,13 @@ pub enum SockShutdownCmd { /// Shutdown receptions and transmissions SHUT_RDWR = 2, } + +impl SockShutdownCmd { + pub fn shut_read(&self) -> bool { + *self == Self::SHUT_RD || *self == Self::SHUT_RDWR + } + + pub fn shut_write(&self) -> bool { + *self == Self::SHUT_WR || *self == Self::SHUT_RDWR + } +} diff --git a/services/libs/jinux-std/src/net/socket/util/sockaddr.rs b/services/libs/jinux-std/src/net/socket/util/sockaddr.rs index 9714008d1..b77d195de 100644 --- a/services/libs/jinux-std/src/net/socket/util/sockaddr.rs +++ b/services/libs/jinux-std/src/net/socket/util/sockaddr.rs @@ -6,7 +6,7 @@ type PortNum = u16; #[derive(Debug)] pub enum SocketAddr { - Unix, + Unix(String), IPv4(Ipv4Address, PortNum), IPv6, } diff --git a/services/libs/jinux-std/src/syscall/accept.rs b/services/libs/jinux-std/src/syscall/accept.rs index d6d06c9e4..fcce6f0c8 100644 --- a/services/libs/jinux-std/src/syscall/accept.rs +++ b/services/libs/jinux-std/src/syscall/accept.rs @@ -1,4 +1,5 @@ -use crate::util::write_socket_addr_to_user; +use crate::util::net::write_socket_addr_to_user; +use crate::util::read_val_from_user; use crate::{fs::file_table::FileDescripter, prelude::*}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; @@ -8,9 +9,10 @@ use super::SYS_ACCEPT; pub fn sys_accept( sockfd: FileDescripter, sockaddr_ptr: Vaddr, - addr_len: u32, + addr_len_ptr: Vaddr, ) -> Result { log_syscall_entry!(SYS_ACCEPT); + let addr_len: i32 = read_val_from_user(addr_len_ptr)?; debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addr_len = {addr_len}"); let current = current!(); get_socket_without_holding_filetable_lock!(socket, current, sockfd); diff --git a/services/libs/jinux-std/src/syscall/bind.rs b/services/libs/jinux-std/src/syscall/bind.rs index bb5f9d3e3..7e9d001c5 100644 --- a/services/libs/jinux-std/src/syscall/bind.rs +++ b/services/libs/jinux-std/src/syscall/bind.rs @@ -1,5 +1,5 @@ use crate::log_syscall_entry; -use crate::util::read_socket_addr_from_user; +use crate::util::net::read_socket_addr_from_user; use crate::{fs::file_table::FileDescripter, prelude::*}; use super::SyscallReturn; diff --git a/services/libs/jinux-std/src/syscall/connect.rs b/services/libs/jinux-std/src/syscall/connect.rs index 0c55929d1..a305e1edc 100644 --- a/services/libs/jinux-std/src/syscall/connect.rs +++ b/services/libs/jinux-std/src/syscall/connect.rs @@ -2,7 +2,7 @@ use crate::fs::file_table::FileDescripter; use crate::get_socket_without_holding_filetable_lock; use crate::log_syscall_entry; use crate::prelude::*; -use crate::util::read_socket_addr_from_user; +use crate::util::net::read_socket_addr_from_user; use super::SyscallReturn; use super::SYS_CONNECT; diff --git a/services/libs/jinux-std/src/syscall/getpeername.rs b/services/libs/jinux-std/src/syscall/getpeername.rs index e5baa2fc6..ad232844c 100644 --- a/services/libs/jinux-std/src/syscall/getpeername.rs +++ b/services/libs/jinux-std/src/syscall/getpeername.rs @@ -1,11 +1,17 @@ -use crate::util::write_socket_addr_to_user; +use crate::util::net::write_socket_addr_to_user; +use crate::util::read_val_from_user; use crate::{fs::file_table::FileDescripter, log_syscall_entry, prelude::*}; use super::SyscallReturn; use super::SYS_GETPEERNAME; -pub fn sys_getpeername(sockfd: FileDescripter, addr: Vaddr, addrlen: u32) -> Result { +pub fn sys_getpeername( + sockfd: FileDescripter, + addr: Vaddr, + addrlen_ptr: Vaddr, +) -> Result { log_syscall_entry!(SYS_GETPEERNAME); + let addrlen: i32 = read_val_from_user(addrlen_ptr)?; debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}"); let socket_addr = { let current = current!(); diff --git a/services/libs/jinux-std/src/syscall/getsockname.rs b/services/libs/jinux-std/src/syscall/getsockname.rs index b865391f5..12f080047 100644 --- a/services/libs/jinux-std/src/syscall/getsockname.rs +++ b/services/libs/jinux-std/src/syscall/getsockname.rs @@ -1,13 +1,19 @@ use crate::fs::file_table::FileDescripter; use crate::log_syscall_entry; use crate::prelude::*; -use crate::util::write_socket_addr_to_user; +use crate::util::net::write_socket_addr_to_user; +use crate::util::read_val_from_user; use super::SyscallReturn; use super::SYS_GETSOCKNAME; -pub fn sys_getsockname(sockfd: FileDescripter, addr: Vaddr, addrlen: u32) -> Result { +pub fn sys_getsockname( + sockfd: FileDescripter, + addr: Vaddr, + addrlen_ptr: Vaddr, +) -> Result { log_syscall_entry!(SYS_GETSOCKNAME); + let addrlen: i32 = read_val_from_user(addrlen_ptr)?; debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}"); let socket_addr = { let current = current!(); diff --git a/services/libs/jinux-std/src/syscall/mod.rs b/services/libs/jinux-std/src/syscall/mod.rs index 1a7154a44..df44b0933 100644 --- a/services/libs/jinux-std/src/syscall/mod.rs +++ b/services/libs/jinux-std/src/syscall/mod.rs @@ -86,6 +86,7 @@ use self::sendto::sys_sendto; use self::setsockopt::sys_setsockopt; use self::shutdown::sys_shutdown; use self::socket::sys_socket; +use self::socketpair::sys_socketpair; mod accept; mod access; @@ -157,6 +158,7 @@ mod setpgid; mod setsockopt; mod shutdown; mod socket; +mod socketpair; mod stat; mod statfs; mod symlink; @@ -240,6 +242,7 @@ define_syscall_nums!( SYS_LISTEN = 50, SYS_GETSOCKNAME = 51, SYS_GETPEERNAME = 52, + SYS_SOCKETPAIR = 53, SYS_SETSOCKOPT = 54, SYS_GETSOCKOPT = 55, SYS_CLONE = 56, @@ -400,6 +403,7 @@ pub fn syscall_dispatch( SYS_LISTEN => syscall_handler!(2, sys_listen, args), SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args), SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args), + SYS_SOCKETPAIR => syscall_handler!(4, sys_socketpair, args), SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args), SYS_GETSOCKOPT => syscall_handler!(5, sys_getsockopt, args), SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()), diff --git a/services/libs/jinux-std/src/syscall/recvfrom.rs b/services/libs/jinux-std/src/syscall/recvfrom.rs index 2b0eabc94..3dccf15b6 100644 --- a/services/libs/jinux-std/src/syscall/recvfrom.rs +++ b/services/libs/jinux-std/src/syscall/recvfrom.rs @@ -1,7 +1,6 @@ use crate::net::socket::SendRecvFlags; -use crate::util::{ - read_val_from_user, write_bytes_to_user, write_socket_addr_to_user, write_val_to_user, -}; +use crate::util::net::write_socket_addr_to_user; +use crate::util::{read_val_from_user, write_bytes_to_user, write_val_to_user}; use crate::{fs::file_table::FileDescripter, prelude::*}; use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry}; diff --git a/services/libs/jinux-std/src/syscall/sendto.rs b/services/libs/jinux-std/src/syscall/sendto.rs index 06636cc46..e1f56a8fc 100644 --- a/services/libs/jinux-std/src/syscall/sendto.rs +++ b/services/libs/jinux-std/src/syscall/sendto.rs @@ -3,8 +3,8 @@ use crate::get_socket_without_holding_filetable_lock; use crate::log_syscall_entry; use crate::net::socket::SendRecvFlags; use crate::prelude::*; +use crate::util::net::read_socket_addr_from_user; use crate::util::read_bytes_from_user; -use crate::util::read_socket_addr_from_user; use super::SyscallReturn; use super::SYS_SENDTO; diff --git a/services/libs/jinux-std/src/syscall/socket.rs b/services/libs/jinux-std/src/syscall/socket.rs index c70df3156..9f91c257f 100644 --- a/services/libs/jinux-std/src/syscall/socket.rs +++ b/services/libs/jinux-std/src/syscall/socket.rs @@ -1,7 +1,7 @@ use crate::fs::file_handle::FileLike; -use crate::net::socket::ip::DatagramSocket; -use crate::net::socket::ip::StreamSocket; -use crate::util::net::SaFamily; +use crate::net::socket::ip::{DatagramSocket, StreamSocket}; +use crate::net::socket::unix::UnixStreamSocket; +use crate::util::net::{Protocol, SaFamily, SockFlags, SockType, SOCK_TYPE_MASK}; use crate::{log_syscall_entry, prelude::*}; use super::SyscallReturn; @@ -19,6 +19,9 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32) -> Result Arc::new(UnixStreamSocket::new( + sock_flags.contains(SockFlags::SOCK_NONBLOCK), + )) as Arc, ( SaFamily::AF_INET, SockType::SOCK_STREAM, @@ -36,70 +39,3 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32) -> Result Result { read_bytes_from_user(addr, &mut buffer)?; Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?)) } - -pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result { - debug_assert!(addr_len >= core::mem::size_of::()); - let sockaddr: SockAddr = read_val_from_user(addr)?; - let socket_addr = match sockaddr.sa_family()? { - SaFamily::AF_UNSPEC => { - return_errno_with_message!(Errno::EINVAL, "the socket addr family is unspecified") - } - SaFamily::AF_UNIX => { - debug_assert!(addr_len >= core::mem::size_of::()); - let sock_addr_un: SockAddrUn = read_val_from_user(addr)?; - todo!() - } - SaFamily::AF_INET => { - debug_assert!(addr_len >= core::mem::size_of::()); - let sock_addr_in: SockAddrIn = read_val_from_user(addr)?; - SocketAddr::from(sock_addr_in) - } - SaFamily::AF_INET6 => { - debug_assert!(addr_len >= core::mem::size_of::()); - let sock_addr_in6: SockAddrIn6 = read_val_from_user(addr)?; - todo!() - } - _ => { - return_errno_with_message!(Errno::EAFNOSUPPORT, "cannot support address for the family") - } - }; - Ok(socket_addr) -} - -pub fn write_socket_addr_to_user( - socket_addr: &SocketAddr, - dest: Vaddr, - max_len: usize, -) -> Result { - match socket_addr { - SocketAddr::Unix => todo!(), - SocketAddr::IPv4(addr, port) => { - let in_addr = InAddr::from(*addr); - let sock_addr_in = SockAddrIn::new(*port, in_addr); - let write_size = core::mem::size_of::(); - debug_assert!(max_len >= write_size); - write_val_to_user(dest, &sock_addr_in)?; - Ok(write_size) - } - SocketAddr::IPv6 => todo!(), - } -} diff --git a/services/libs/jinux-std/src/util/net.rs b/services/libs/jinux-std/src/util/net.rs deleted file mode 100644 index 966cbb6e8..000000000 --- a/services/libs/jinux-std/src/util/net.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::net::iface::Ipv4Address; -use crate::net::socket::SocketAddr; -use crate::prelude::*; - -#[macro_export] -macro_rules! get_socket_without_holding_filetable_lock { - ($name:tt, $current: expr, $sockfd: expr) => { - let file_like = { - let file_table = $current.file_table().lock(); - file_table.get_file($sockfd)?.clone() - // Drop filetable here to avoid locking - }; - let $name = file_like - .as_socket() - .ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the file is not socket"))?; - }; -} - -#[derive(Debug, Clone, Copy, Pod)] -#[repr(C)] -/// PlaceHolder -pub struct SockAddr { - sa_family: u16, // SaFamily - sa_data: [u8; 14], -} - -impl SockAddr { - pub fn sa_family(&self) -> Result { - Ok(SaFamily::try_from(self.sa_family as i32)?) - } -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, Pod)] -pub struct SockAddrUn { - sun_family: u16, // Always SaFamily::AF_UNIX - sun_path: [u8; 108], -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, Pod)] -/// IPv4 4-byte address -pub struct InAddr { - s_addr: [u8; 4], -} - -impl InAddr { - pub fn as_bytes(&self) -> &[u8] { - &self.s_addr - } - - pub fn from_bytes(bytes: &[u8]) -> Self { - debug_assert!(bytes.len() == 4); - let mut s_addr = [0u8; 4]; - s_addr.copy_from_slice(bytes); - Self { s_addr } - } -} - -#[derive(Debug, Clone, Copy, Pod)] -#[repr(C)] -pub struct PortNum { - port: [u8; 2], -} - -impl PortNum { - pub fn as_u16(&self) -> u16 { - u16::from_be_bytes(self.port) - } - - pub fn from_u16(value: u16) -> Self { - let bytes = value.to_be_bytes(); - Self { port: bytes } - } -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, Pod)] -/// IPv4 socket address -pub struct SockAddrIn { - /// always SaFamily::AF_INET - sin_family: u16, - /// Port number - sin_port_t: PortNum, - /// IPv4 address - sin_addr: InAddr, - /// Pad to size of 'SockAddr' structure (16 bytes) - _pad: [u8; 8], -} - -impl SockAddrIn { - pub fn new(port: u16, addr: InAddr) -> Self { - let port = PortNum::from_u16(port); - Self { - sin_family: SaFamily::AF_INET as _, - sin_port_t: port, - sin_addr: addr, - _pad: [0u8; 8], - } - } -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, Pod)] -/// IPv6 address -pub struct In6Addr { - s6_addr: [u8; 16], -} - -impl In6Addr { - pub fn as_bytes(&self) -> &[u8] { - &self.s6_addr - } -} - -/// IPv6 socket address -#[repr(C)] -#[derive(Debug, Clone, Copy, Pod)] -pub struct SockAddrIn6 { - /// always SaFamily::AF_INET6 - sin6_family: u16, - /// Port number - sin6_port: PortNum, - /// IPv6 flow information - sin6_flowinfo: u32, - /// IPv6 address - sin6_addr: In6Addr, - // Scope ID - sin6_scope_id: u32, -} - -/// Address family. The definition is from https://elixir.bootlin.com/linux/v6.0.9/source/include/linux/socket.h. -#[repr(i32)] -#[derive(Debug, Clone, Copy, TryFromInt)] -#[allow(non_camel_case_types)] -pub enum SaFamily { - AF_UNSPEC = 0, - AF_UNIX = 1, /* Unix domain sockets */ - //AF_LOCAL 1 /* POSIX name for AF_UNIX */ - AF_INET = 2, /* Internet IP Protocol */ - AF_AX25 = 3, /* Amateur Radio AX.25 */ - AF_IPX = 4, /* Novell IPX */ - AF_APPLETALK = 5, /* AppleTalk DDP */ - AF_NETROM = 6, /* Amateur Radio NET/ROM */ - AF_BRIDGE = 7, /* Multiprotocol bridge */ - AF_ATMPVC = 8, /* ATM PVCs */ - AF_X25 = 9, /* Reserved for X.25 project */ - AF_INET6 = 10, /* IP version 6 */ - AF_ROSE = 11, /* Amateur Radio X.25 PLP */ - AF_DECnet = 12, /* Reserved for DECnet project */ - AF_NETBEUI = 13, /* Reserved for 802.2LLC project*/ - AF_SECURITY = 14, /* Security callback pseudo AF */ - AF_KEY = 15, /* PF_KEY key management API */ - AF_NETLINK = 16, - //AF_ROUTE = AF_NETLINK /* Alias to emulate 4.4BSD */ - AF_PACKET = 17, /* Packet family */ - AF_ASH = 18, /* Ash */ - AF_ECONET = 19, /* Acorn Econet */ - AF_ATMSVC = 20, /* ATM SVCs */ - AF_RDS = 21, /* RDS sockets */ - AF_SNA = 22, /* Linux SNA Project (nutters!) */ - AF_IRDA = 23, /* IRDA sockets */ - AF_PPPOX = 24, /* PPPoX sockets */ - AF_WANPIPE = 25, /* Wanpipe API Sockets */ - AF_LLC = 26, /* Linux LLC */ - AF_IB = 27, /* Native InfiniBand address */ - AF_MPLS = 28, /* MPLS */ - AF_CAN = 29, /* Controller Area Network */ - AF_TIPC = 30, /* TIPC sockets */ - AF_BLUETOOTH = 31, /* Bluetooth sockets */ - AF_IUCV = 32, /* IUCV sockets */ - AF_RXRPC = 33, /* RxRPC sockets */ - AF_ISDN = 34, /* mISDN sockets */ - AF_PHONET = 35, /* Phonet sockets */ - AF_IEEE802154 = 36, /* IEEE802154 sockets */ - AF_CAIF = 37, /* CAIF sockets */ - AF_ALG = 38, /* Algorithm sockets */ - AF_NFC = 39, /* NFC sockets */ - AF_VSOCK = 40, /* vSockets */ - AF_KCM = 41, /* Kernel Connection Multiplexor*/ - AF_QIPCRTR = 42, /* Qualcomm IPC Router */ - AF_SMC = 43, /* smc sockets: reserve number for - * PF_SMC protocol family that - * reuses AF_INET address family - */ - AF_XDP = 44, /* XDP sockets */ - AF_MCTP = 45, /* Management component - * transport protocol - */ - AF_MAX = 46, /* For now.. */ -} - -impl From for Ipv4Address { - fn from(value: InAddr) -> Self { - let addr = value.as_bytes(); - Ipv4Address::from_bytes(addr) - } -} - -impl From for InAddr { - fn from(value: Ipv4Address) -> Self { - let bytes = value.as_bytes(); - InAddr::from_bytes(bytes) - } -} - -impl From for SocketAddr { - fn from(value: SockAddrIn) -> Self { - let port = value.sin_port_t.as_u16(); - let addr = Ipv4Address::from(value.sin_addr); - SocketAddr::IPv4(addr, port) - } -}