From 57f466537434c577559fe67976f604ee0f54ecca Mon Sep 17 00:00:00 2001 From: YXalix <516875454@qq.com> Date: Wed, 24 Apr 2024 15:07:09 +0800 Subject: [PATCH 1/2] Add udp multicast support --- modules/axnet/Cargo.toml | 2 +- modules/axnet/src/lib.rs | 4 +- modules/axnet/src/smoltcp_impl/mod.rs | 34 ++++++++++++- modules/axnet/src/smoltcp_impl/udp.rs | 14 +++++- ulib/axstarry/src/syscall_net/imp.rs | 12 +++-- ulib/axstarry/src/syscall_net/socket.rs | 63 ++++++++++++++++++++++--- 6 files changed, 115 insertions(+), 14 deletions(-) diff --git a/modules/axnet/Cargo.toml b/modules/axnet/Cargo.toml index 6e396e1012..ecfc518e34 100644 --- a/modules/axnet/Cargo.toml +++ b/modules/axnet/Cargo.toml @@ -39,7 +39,7 @@ features = [ "medium-ethernet", "medium-ip", "proto-ipv4", - "socket-raw", "socket-icmp", "socket-udp", "socket-tcp", "socket-dns", + "socket-raw", "socket-icmp", "socket-udp", "socket-tcp", "socket-dns", "proto-igmp", # "fragmentation-buffer-size-65536", "proto-ipv4-fragmentation", # "reassembly-buffer-size-65536", "reassembly-buffer-count-32", # "assembler-max-segment-count-32", diff --git a/modules/axnet/src/lib.rs b/modules/axnet/src/lib.rs index 36b0669e81..6afbc9c495 100644 --- a/modules/axnet/src/lib.rs +++ b/modules/axnet/src/lib.rs @@ -34,8 +34,10 @@ cfg_if::cfg_if! { pub use self::net_impl::TcpSocket; pub use self::net_impl::UdpSocket; +pub use self::net_impl::{ + add_membership, dns_query, from_core_sockaddr, into_core_sockaddr, poll_interfaces, +}; pub use self::net_impl::{bench_receive, bench_transmit}; -pub use self::net_impl::{dns_query, from_core_sockaddr, into_core_sockaddr, poll_interfaces}; pub use smoltcp::time::Duration; pub use smoltcp::wire::{IpAddress as IpAddr, IpEndpoint as SocketAddr, Ipv4Address as Ipv4Addr}; diff --git a/modules/axnet/src/smoltcp_impl/mod.rs b/modules/axnet/src/smoltcp_impl/mod.rs index ea2da327b7..57026a790f 100644 --- a/modules/axnet/src/smoltcp_impl/mod.rs +++ b/modules/axnet/src/smoltcp_impl/mod.rs @@ -6,6 +6,7 @@ mod listen_table; mod tcp; mod udp; use alloc::vec; +use axerrno::{AxError, AxResult}; use core::cell::RefCell; use core::ops::DerefMut; @@ -16,7 +17,7 @@ use driver_net::{DevError, NetBufPtr}; use lazy_init::LazyInit; use smoltcp::iface::{Config, Interface, SocketHandle, SocketSet}; use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken}; -use smoltcp::socket::{self, AnySocket}; +use smoltcp::socket::{self, AnySocket, Socket}; use smoltcp::time::Instant; use smoltcp::wire::{EthernetAddress, HardwareAddress, IpAddress, IpCidr}; @@ -130,6 +131,23 @@ impl<'a> SocketSetWrapper<'a> { f(socket) } + pub fn bind_check(&self, addr: IpAddress, port: u16) -> AxResult { + let mut sockets = self.0.lock(); + error!("checking addr: {:?}, port: {}", addr, port); + for item in sockets.iter_mut() { + match item.1 { + Socket::Udp(s) => { + error!("{}", s.endpoint().port); + if s.endpoint().port == port { + return Err(AxError::AddrInUse); + } + } + _ => continue, + }; + } + Ok(()) + } + pub fn poll_interfaces(&self) { #[cfg(feature = "ip")] { @@ -334,6 +352,20 @@ pub fn bench_receive() { ETH0.dev.lock().bench_receive_bandwidth(); } +/// Add multicast_addr to the loopback device. +pub fn add_membership(_multicast_addr: IpAddress, _interface_addr: IpAddress) { + #[cfg(feature = "ip")] + { + let timestamp = + Instant::from_micros_const((current_time_nanos() / NANOS_PER_MICROS) as i64); + let _ = LOOPBACK.lock().join_multicast_group( + LOOPBACK_DEV.lock().deref_mut(), + _multicast_addr, + timestamp, + ); + } +} + pub(crate) fn init(_net_dev: AxNetDevice) { #[cfg(feature = "ip")] { diff --git a/modules/axnet/src/smoltcp_impl/udp.rs b/modules/axnet/src/smoltcp_impl/udp.rs index 1030f10c88..1e65914014 100644 --- a/modules/axnet/src/smoltcp_impl/udp.rs +++ b/modules/axnet/src/smoltcp_impl/udp.rs @@ -70,6 +70,15 @@ impl UdpSocket { self.nonblock.store(nonblocking, Ordering::Release); } + /// Set the TTL (time-to-live) option for this socket. + /// + /// The TTL is the number of hops that a packet is allowed to live. + pub fn set_socket_ttl(&self, ttl: u8) { + SOCKET_SET.with_socket_mut::(self.handle, |socket| { + socket.set_hop_limit(Some(ttl)) + }); + } + /// Binds an unbound socket to the given address and port. /// /// It's must be called before [`send_to`](Self::send_to) and @@ -89,6 +98,9 @@ impl UdpSocket { addr: (!is_unspecified(local_endpoint.addr)).then_some(local_endpoint.addr), port: local_endpoint.port, }; + + SOCKET_SET.bind_check(local_endpoint.addr, local_endpoint.port)?; + SOCKET_SET.with_socket_mut::(self.handle, |socket| { socket.bind(endpoint).or_else(|e| match e { BindError::InvalidState => ax_err!(AlreadyExists, "socket bind() failed"), @@ -190,11 +202,11 @@ impl UdpSocket { /// Close the socket. pub fn shutdown(&self) -> AxResult { + SOCKET_SET.poll_interfaces(); SOCKET_SET.with_socket_mut::(self.handle, |socket| { debug!("UDP socket {}: shutting down", self.handle); socket.close(); }); - SOCKET_SET.poll_interfaces(); Ok(()) } diff --git a/ulib/axstarry/src/syscall_net/imp.rs b/ulib/axstarry/src/syscall_net/imp.rs index e4bf5fbb1c..d211731b09 100644 --- a/ulib/axstarry/src/syscall_net/imp.rs +++ b/ulib/axstarry/src/syscall_net/imp.rs @@ -459,15 +459,21 @@ pub fn syscall_set_sock_opt(args: [usize; 6]) -> SyscallResult { let opt = unsafe { from_raw_parts(opt_value, opt_len as usize) }; match level { - SocketOptionLevel::IP => Ok(0), + SocketOptionLevel::IP => { + let Ok(option) = IpOption::try_from(opt_name) else { + warn!("[setsockopt()] option {opt_name} not supported in socket level"); + return Ok(0); + }; + + option.set(socket, opt) + } SocketOptionLevel::Socket => { let Ok(option) = SocketOption::try_from(opt_name) else { warn!("[setsockopt()] option {opt_name} not supported in socket level"); return Ok(0); }; - option.set(socket, opt); - Ok(0) + option.set(socket, opt) } SocketOptionLevel::Tcp => { let Ok(option) = TcpSocketOption::try_from(opt_name) else { diff --git a/ulib/axstarry/src/syscall_net/socket.rs b/ulib/axstarry/src/syscall_net/socket.rs index b52fe2132b..35b57e099a 100644 --- a/ulib/axstarry/src/syscall_net/socket.rs +++ b/ulib/axstarry/src/syscall_net/socket.rs @@ -12,13 +12,13 @@ use axfs::api::{FileIO, FileIOType, OpenFlags, Read, Write}; use axlog::warn; use axnet::{ - from_core_sockaddr, into_core_sockaddr, poll_interfaces, IpAddr, SocketAddr, TcpSocket, - UdpSocket, + add_membership, from_core_sockaddr, into_core_sockaddr, poll_interfaces, IpAddr, SocketAddr, + TcpSocket, UdpSocket, }; use axsync::Mutex; use num_enum::TryFromPrimitive; -use crate::TimeVal; +use crate::{SyscallError, SyscallResult, TimeVal}; pub const SOCKET_TYPE_MASK: usize = 0xFF; @@ -67,6 +67,16 @@ pub enum SocketOptionLevel { Tcp = 6, } +#[derive(TryFromPrimitive, Debug)] +#[repr(usize)] +#[allow(non_camel_case_types)] +pub enum IpOption { + IP_MULTICAST_IF = 32, + IP_MULTICAST_TTL = 33, + IP_MULTICAST_LOOP = 34, + IP_ADD_MEMBERSHIP = 35, +} + #[derive(TryFromPrimitive, Debug)] #[repr(usize)] #[allow(non_camel_case_types)] @@ -78,6 +88,7 @@ pub enum SocketOption { SO_RCVBUF = 8, SO_KEEPALIVE = 9, SO_RCVTIMEO = 20, + SO_SNDTIMEO = 21, } #[derive(TryFromPrimitive, PartialEq)] @@ -90,18 +101,47 @@ pub enum TcpSocketOption { TCP_CONGESTION = 13, } +impl IpOption { + pub fn set(&self, socket: &Socket, opt: &[u8]) -> SyscallResult { + match self { + IpOption::IP_MULTICAST_IF => { + // 我们只会使用LOOPBACK作为多播接口 + Ok((0)) + } + IpOption::IP_MULTICAST_TTL => { + let mut inner = socket.inner.lock(); + match &mut *inner { + SocketInner::Udp(s) => { + let ttl = u8::from_ne_bytes(<[u8; 1]>::try_from(&opt[0..1]).unwrap()); + s.set_socket_ttl(ttl as u8); + Ok((0)) + } + _ => panic!("setsockopt IP_MULTICAST_TTL on a non-udp socket"), + } + } + IpOption::IP_MULTICAST_LOOP => Ok((0)), + IpOption::IP_ADD_MEMBERSHIP => { + let multicast_addr = IpAddr::v4(opt[0], opt[1], opt[2], opt[3]); + let interface_addr = IpAddr::v4(opt[4], opt[5], opt[6], opt[7]); + // TODO add membership error handling + add_membership(multicast_addr, interface_addr); + Ok((0)) + } + } + } +} + impl SocketOption { - pub fn set(&self, socket: &Socket, opt: &[u8]) { + pub fn set(&self, socket: &Socket, opt: &[u8]) -> SyscallResult { match self { SocketOption::SO_REUSEADDR => { + // unimplemented!("wait for implementation of SO_REUSEADDR"); if opt.len() < 4 { panic!("can't read a int from socket opt value"); } - let opt_value = i32::from_ne_bytes(<[u8; 4]>::try_from(&opt[0..4]).unwrap()); - socket.set_reuse_addr(opt_value != 0); - // socket.reuse_addr = opt_value != 0; + Ok((0)) } SocketOption::SO_DONTROUTE => { if opt.len() < 4 { @@ -112,6 +152,7 @@ impl SocketOption { socket.set_reuse_addr(opt_value != 0); // socket.reuse_addr = opt_value != 0; + Ok((0)) } SocketOption::SO_SNDBUF => { if opt.len() < 4 { @@ -122,6 +163,7 @@ impl SocketOption { socket.set_send_buf_size(opt_value as u64); // socket.send_buf_size = opt_value as usize; + Ok((0)) } SocketOption::SO_RCVBUF => { if opt.len() < 4 { @@ -132,6 +174,7 @@ impl SocketOption { socket.set_recv_buf_size(opt_value as u64); // socket.recv_buf_size = opt_value as usize; + Ok((0)) } SocketOption::SO_KEEPALIVE => { if opt.len() < 4 { @@ -162,6 +205,7 @@ impl SocketOption { drop(inner); socket.set_recv_buf_size(opt_value as u64); // socket.recv_buf_size = opt_value as usize; + Ok((0)) } SocketOption::SO_RCVTIMEO => { if opt.len() < size_of::() { @@ -174,10 +218,12 @@ impl SocketOption { } else { Some(timeout) }); + Ok((0)) } SocketOption::SO_ERROR => { panic!("can't set SO_ERROR"); } + SocketOption::SO_SNDTIMEO => Err(SyscallError::EPERM), } } @@ -282,6 +328,9 @@ impl SocketOption { SocketOption::SO_ERROR => { // 当前没有存储错误列表,因此不做处理 } + SocketOption::SO_SNDTIMEO => { + panic!("unimplemented!") + } } } } From 7d53241801b5f5d2656ed90f638fead6231c87fa Mon Sep 17 00:00:00 2001 From: YXalix <516875454@qq.com> Date: Sun, 28 Apr 2024 14:13:37 +0800 Subject: [PATCH 2/2] add udp reuseaddr support --- Cargo.toml | 3 -- api/axfeat/Cargo.toml | 2 +- modules/axnet/Cargo.toml | 4 +- modules/axnet/src/smoltcp_impl/mod.rs | 10 ++-- modules/axnet/src/smoltcp_impl/tcp.rs | 37 ++++++++------ modules/axnet/src/smoltcp_impl/udp.rs | 32 +++++++++++- modules/axprocess/src/signal.rs | 7 +++ ulib/axstarry/src/syscall_fs/ctype/epoll.rs | 10 +++- ulib/axstarry/src/syscall_fs/fs_syscall_id.rs | 3 ++ ulib/axstarry/src/syscall_fs/imp/epoll.rs | 4 ++ ulib/axstarry/src/syscall_fs/imp/poll.rs | 8 ++- ulib/axstarry/src/syscall_fs/mod.rs | 6 +++ ulib/axstarry/src/syscall_net/imp.rs | 3 +- ulib/axstarry/src/syscall_net/socket.rs | 50 +++++++++++-------- 14 files changed, 127 insertions(+), 52 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6be63c75d2..ae55d65676 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,6 +85,3 @@ lto = true [patch.crates-io] crate_interface = { path = "crates/crate_interface" } - -[patch."/~https://github.com/rcore-os/smoltcp.git"] -smoltcp = { git = "/~https://github.com/c0per/smoltcp", branch = "starryos" } diff --git a/api/axfeat/Cargo.toml b/api/axfeat/Cargo.toml index 8f3e50f37f..aa5d39099f 100644 --- a/api/axfeat/Cargo.toml +++ b/api/axfeat/Cargo.toml @@ -16,7 +16,7 @@ default = [] monolithic = ["axruntime/monolithic", "axhal/monolithic", "dep:axprocess"] # Signal -signal = ["axruntime/signal"] +signal = ["axruntime/signal", "axnet/signal"] # Futex support futex = ["axprocess/futex"] diff --git a/modules/axnet/Cargo.toml b/modules/axnet/Cargo.toml index ecfc518e34..f9e4a833aa 100644 --- a/modules/axnet/Cargo.toml +++ b/modules/axnet/Cargo.toml @@ -15,6 +15,8 @@ smoltcp = [] # 启用ip协议与否 ip = [] +signal = [] + default = ["smoltcp"] [dependencies] @@ -32,7 +34,7 @@ axio = { path = "../../crates/axio" } [dependencies.smoltcp] git = "/~https://github.com/rcore-os/smoltcp.git" -rev = "2ade274" +rev = "b7134a3" default-features = false features = [ "alloc", "log", # no std diff --git a/modules/axnet/src/smoltcp_impl/mod.rs b/modules/axnet/src/smoltcp_impl/mod.rs index 57026a790f..e66aedda16 100644 --- a/modules/axnet/src/smoltcp_impl/mod.rs +++ b/modules/axnet/src/smoltcp_impl/mod.rs @@ -92,11 +92,11 @@ impl<'a> SocketSetWrapper<'a> { pub fn new_udp_socket() -> socket::udp::Socket<'a> { let udp_rx_buffer = socket::udp::PacketBuffer::new( - vec![socket::udp::PacketMetadata::EMPTY; 8], + vec![socket::udp::PacketMetadata::EMPTY; 256], vec![0; UDP_RX_BUF_LEN], ); let udp_tx_buffer = socket::udp::PacketBuffer::new( - vec![socket::udp::PacketMetadata::EMPTY; 8], + vec![socket::udp::PacketMetadata::EMPTY; 256], vec![0; UDP_TX_BUF_LEN], ); socket::udp::Socket::new(udp_rx_buffer, udp_tx_buffer) @@ -131,14 +131,12 @@ impl<'a> SocketSetWrapper<'a> { f(socket) } - pub fn bind_check(&self, addr: IpAddress, port: u16) -> AxResult { + pub fn bind_check(&self, addr: IpAddress, _port: u16) -> AxResult { let mut sockets = self.0.lock(); - error!("checking addr: {:?}, port: {}", addr, port); for item in sockets.iter_mut() { match item.1 { Socket::Udp(s) => { - error!("{}", s.endpoint().port); - if s.endpoint().port == port { + if s.endpoint().addr == Some(addr) { return Err(AxError::AddrInUse); } } diff --git a/modules/axnet/src/smoltcp_impl/tcp.rs b/modules/axnet/src/smoltcp_impl/tcp.rs index 7521acc407..f259538a06 100644 --- a/modules/axnet/src/smoltcp_impl/tcp.rs +++ b/modules/axnet/src/smoltcp_impl/tcp.rs @@ -307,19 +307,19 @@ impl TcpSocket { let handle = unsafe { self.handle.get().read().unwrap() }; self.block_on(|| { SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() { - // not open - ax_err!(ConnectionRefused, "socket recv() failed") - } else if !socket.may_recv() { - // connection closed - Ok(0) - } else if socket.recv_queue() > 0 { + if socket.recv_queue() > 0 { // data available // TODO: use socket.recv(|buf| {...}) let len = socket .recv_slice(buf) .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; Ok(len) + } else if !socket.is_active() { + // not open + ax_err!(ConnectionRefused, "socket recv() failed") + } else if !socket.may_recv() { + // connection closed + Ok(0) } else { // no more data Err(AxError::WouldBlock) @@ -343,19 +343,19 @@ impl TcpSocket { let handle = unsafe { self.handle.get().read().unwrap() }; self.block_on(|| { SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() { - // not open - ax_err!(ConnectionRefused, "socket recv() failed") - } else if !socket.may_recv() { - // connection closed - Ok(0) - } else if socket.recv_queue() > 0 { + if socket.recv_queue() > 0 { // data available // TODO: use socket.recv(|buf| {...}) let len = socket .recv_slice(buf) .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; Ok(len) + } else if !socket.is_active() { + // not open + ax_err!(ConnectionRefused, "socket recv() failed") + } else if !socket.may_recv() { + // connection closed + Ok(0) } else { // no more data if current_ticks() > expire_at { @@ -609,6 +609,15 @@ impl TcpSocket { f() } else { loop { + #[cfg(feature = "signal")] + unsafe { + extern "Rust" { + fn current_have_signal() -> bool; + } + if current_have_signal() { + return Err(AxError::Interrupted); + } + } SOCKET_SET.poll_interfaces(); match f() { Ok(t) => return Ok(t), diff --git a/modules/axnet/src/smoltcp_impl/udp.rs b/modules/axnet/src/smoltcp_impl/udp.rs index 1e65914014..1da132d9ba 100644 --- a/modules/axnet/src/smoltcp_impl/udp.rs +++ b/modules/axnet/src/smoltcp_impl/udp.rs @@ -20,6 +20,7 @@ pub struct UdpSocket { local_addr: RwLock>, peer_addr: RwLock>, nonblock: AtomicBool, + reuse_addr: AtomicBool, } impl UdpSocket { @@ -33,6 +34,7 @@ impl UdpSocket { local_addr: RwLock::new(None), peer_addr: RwLock::new(None), nonblock: AtomicBool::new(false), + reuse_addr: AtomicBool::new(false), } } @@ -79,6 +81,22 @@ impl UdpSocket { }); } + /// Returns whether this socket is in reuse address mode. + #[inline] + pub fn is_reuse_addr(&self) -> bool { + self.reuse_addr.load(Ordering::Acquire) + } + + /// Moves this UDP socket into or out of reuse address mode. + /// + /// When a socket is bound, the `SO_REUSEADDR` option allows multiple sockets to be bound to the + /// same address if they are bound to different local addresses. This option must be set before + /// calling `bind`. + #[inline] + pub fn set_reuse_addr(&self, reuse_addr: bool) { + self.reuse_addr.store(reuse_addr, Ordering::Release); + } + /// Binds an unbound socket to the given address and port. /// /// It's must be called before [`send_to`](Self::send_to) and @@ -99,7 +117,10 @@ impl UdpSocket { port: local_endpoint.port, }; - SOCKET_SET.bind_check(local_endpoint.addr, local_endpoint.port)?; + if !self.is_reuse_addr() { + // Check if the address is already in use + SOCKET_SET.bind_check(local_endpoint.addr, local_endpoint.port)?; + } SOCKET_SET.with_socket_mut::(self.handle, |socket| { socket.bind(endpoint).or_else(|e| match e { @@ -295,6 +316,15 @@ impl UdpSocket { f() } else { loop { + #[cfg(feature = "signal")] + unsafe { + extern "Rust" { + fn current_have_signal() -> bool; + } + if current_have_signal() { + return Err(AxError::Interrupted); + } + } SOCKET_SET.poll_interfaces(); match f() { Ok(t) => return Ok(t), diff --git a/modules/axprocess/src/signal.rs b/modules/axprocess/src/signal.rs index 44a3796634..6c5eac3181 100644 --- a/modules/axprocess/src/signal.rs +++ b/modules/axprocess/src/signal.rs @@ -330,3 +330,10 @@ impl SignalCaller for SignalCallerImpl { send_signal_to_thread(tid, signum).unwrap(); } } + +/// check if the current task has a signal pending +#[no_mangle] +#[cfg(feature = "signal")] +pub extern "Rust" fn current_have_signal() -> bool { + current_process().have_signals().is_some() +} diff --git a/ulib/axstarry/src/syscall_fs/ctype/epoll.rs b/ulib/axstarry/src/syscall_fs/ctype/epoll.rs index ca0e35ad9f..6e274279f2 100644 --- a/ulib/axstarry/src/syscall_fs/ctype/epoll.rs +++ b/ulib/axstarry/src/syscall_fs/ctype/epoll.rs @@ -44,6 +44,9 @@ pub struct EpollEvent { pub event_type: EpollEventType, /// 事件中使用到的数据,如fd等 pub data: u64, + pub fd: i32, + pub data_u32: u32, + pub data_u64: u64, } numeric_enum_macro::numeric_enum! { @@ -105,7 +108,9 @@ impl EpollFile { // 添加事件 EpollCtl::ADD => { if inner.monitor_list.contains_key(&fd) { - return Err(SyscallError::EEXIST); + // return Err(SyscallError::EEXIST); + // TODO : fd close callback ? + inner.monitor_list.insert(fd, event); } inner.monitor_list.insert(fd, event); } @@ -181,6 +186,9 @@ impl EpollFile { ret_events.push(EpollEvent { event_type: EpollEventType::EPOLLERR, data: req_event.data, + fd: -1, + data_u32: 0, + data_u64: 0, }); } } diff --git a/ulib/axstarry/src/syscall_fs/fs_syscall_id.rs b/ulib/axstarry/src/syscall_fs/fs_syscall_id.rs index 1bd7c9c845..83ebb8cf7b 100644 --- a/ulib/axstarry/src/syscall_fs/fs_syscall_id.rs +++ b/ulib/axstarry/src/syscall_fs/fs_syscall_id.rs @@ -115,6 +115,7 @@ numeric_enum_macro::numeric_enum! { SELECT = 23, PSELECT6 = 270, READLINK = 89, + CHMOD = 90, PREADLINKAT = 267, FSTAT = 5, LSTAT = 6, @@ -124,5 +125,7 @@ numeric_enum_macro::numeric_enum! { RENAMEAT = 264, RENAMEAT2 = 316, COPYFILERANGE = 326, + EPOLL_CREATE1 = 291, + EPOLL_PWAIT = 281, } } diff --git a/ulib/axstarry/src/syscall_fs/imp/epoll.rs b/ulib/axstarry/src/syscall_fs/imp/epoll.rs index df41ae372f..bb260cbe48 100644 --- a/ulib/axstarry/src/syscall_fs/imp/epoll.rs +++ b/ulib/axstarry/src/syscall_fs/imp/epoll.rs @@ -91,6 +91,10 @@ pub fn syscall_epoll_wait(args: [usize; 6]) -> SyscallResult { let max_event = max_event as usize; let process = current_process(); let start: VirtAddr = (event as usize).into(); + // FIXME: this is a temporary solution + // the memory will out of mapped memory if the max_event is too large + // maybe give the max_event a limit is a better solution + let max_event = core::cmp::min(max_event, 400); let end = start + max_event * core::mem::size_of::(); if process.manual_alloc_range_for_lazy(start, end).is_err() { return Err(SyscallError::EFAULT); diff --git a/ulib/axstarry/src/syscall_fs/imp/poll.rs b/ulib/axstarry/src/syscall_fs/imp/poll.rs index 400378dc78..b5072eb4b4 100644 --- a/ulib/axstarry/src/syscall_fs/imp/poll.rs +++ b/ulib/axstarry/src/syscall_fs/imp/poll.rs @@ -1,6 +1,7 @@ use axfs::api::FileIO; use axhal::{mem::VirtAddr, time::current_ticks}; use axprocess::{current_process, yield_now_task}; +use axsignal::signal_no::SignalNo; use bitflags::bitflags; extern crate alloc; use crate::{SyscallError, SyscallResult, TimeSecs, TimeVal}; @@ -397,9 +398,12 @@ pub fn syscall_pselect6(args: [usize; 6]) -> SyscallResult { if current_ticks() as usize > expire_time { return Ok(0); } + // TODO: fix this and use mask to ignore specific signal #[cfg(feature = "signal")] - if process.have_signals().is_some() { - return Err(SyscallError::EINTR); + if let Some(signalno) = process.have_signals() { + if signalno == SignalNo::SIGKILL as usize { + return Err(SyscallError::EINTR); + } } } } diff --git a/ulib/axstarry/src/syscall_fs/mod.rs b/ulib/axstarry/src/syscall_fs/mod.rs index 86cb143665..e27906c833 100644 --- a/ulib/axstarry/src/syscall_fs/mod.rs +++ b/ulib/axstarry/src/syscall_fs/mod.rs @@ -92,5 +92,11 @@ pub fn fs_syscall(syscall_id: fs_syscall_id::FsSyscallId, args: [usize; 6]) -> S READLINK => syscall_readlink(args), #[cfg(target_arch = "x86_64")] CREAT => Err(axerrno::LinuxError::EPERM), + #[cfg(target_arch = "x86_64")] + EPOLL_CREATE1 => unimplemented!("epoll_create1"), + #[cfg(target_arch = "x86_64")] + EPOLL_PWAIT => unimplemented!("epoll_ctl"), + #[cfg(target_arch = "x86_64")] + CHMOD => Ok(0), } } diff --git a/ulib/axstarry/src/syscall_net/imp.rs b/ulib/axstarry/src/syscall_net/imp.rs index d211731b09..08d14cc140 100644 --- a/ulib/axstarry/src/syscall_net/imp.rs +++ b/ulib/axstarry/src/syscall_net/imp.rs @@ -481,8 +481,7 @@ pub fn syscall_set_sock_opt(args: [usize; 6]) -> SyscallResult { return Ok(0); }; - option.set(socket, opt); - Ok(0) + option.set(socket, opt) } } } diff --git a/ulib/axstarry/src/syscall_net/socket.rs b/ulib/axstarry/src/syscall_net/socket.rs index 35b57e099a..161bf771c2 100644 --- a/ulib/axstarry/src/syscall_net/socket.rs +++ b/ulib/axstarry/src/syscall_net/socket.rs @@ -106,26 +106,26 @@ impl IpOption { match self { IpOption::IP_MULTICAST_IF => { // 我们只会使用LOOPBACK作为多播接口 - Ok((0)) + Ok(0) } IpOption::IP_MULTICAST_TTL => { let mut inner = socket.inner.lock(); match &mut *inner { SocketInner::Udp(s) => { let ttl = u8::from_ne_bytes(<[u8; 1]>::try_from(&opt[0..1]).unwrap()); - s.set_socket_ttl(ttl as u8); - Ok((0)) + s.set_socket_ttl(ttl); + Ok(0) } _ => panic!("setsockopt IP_MULTICAST_TTL on a non-udp socket"), } } - IpOption::IP_MULTICAST_LOOP => Ok((0)), + IpOption::IP_MULTICAST_LOOP => Ok(0), IpOption::IP_ADD_MEMBERSHIP => { let multicast_addr = IpAddr::v4(opt[0], opt[1], opt[2], opt[3]); let interface_addr = IpAddr::v4(opt[4], opt[5], opt[6], opt[7]); // TODO add membership error handling add_membership(multicast_addr, interface_addr); - Ok((0)) + Ok(0) } } } @@ -135,13 +135,12 @@ impl SocketOption { pub fn set(&self, socket: &Socket, opt: &[u8]) -> SyscallResult { match self { SocketOption::SO_REUSEADDR => { - // unimplemented!("wait for implementation of SO_REUSEADDR"); if opt.len() < 4 { panic!("can't read a int from socket opt value"); } let opt_value = i32::from_ne_bytes(<[u8; 4]>::try_from(&opt[0..4]).unwrap()); socket.set_reuse_addr(opt_value != 0); - Ok((0)) + Ok(0) } SocketOption::SO_DONTROUTE => { if opt.len() < 4 { @@ -152,7 +151,7 @@ impl SocketOption { socket.set_reuse_addr(opt_value != 0); // socket.reuse_addr = opt_value != 0; - Ok((0)) + Ok(0) } SocketOption::SO_SNDBUF => { if opt.len() < 4 { @@ -163,7 +162,7 @@ impl SocketOption { socket.set_send_buf_size(opt_value as u64); // socket.send_buf_size = opt_value as usize; - Ok((0)) + Ok(0) } SocketOption::SO_RCVBUF => { if opt.len() < 4 { @@ -174,7 +173,7 @@ impl SocketOption { socket.set_recv_buf_size(opt_value as u64); // socket.recv_buf_size = opt_value as usize; - Ok((0)) + Ok(0) } SocketOption::SO_KEEPALIVE => { if opt.len() < 4 { @@ -205,7 +204,7 @@ impl SocketOption { drop(inner); socket.set_recv_buf_size(opt_value as u64); // socket.recv_buf_size = opt_value as usize; - Ok((0)) + Ok(0) } SocketOption::SO_RCVTIMEO => { if opt.len() < size_of::() { @@ -218,7 +217,7 @@ impl SocketOption { } else { Some(timeout) }); - Ok((0)) + Ok(0) } SocketOption::SO_ERROR => { panic!("can't set SO_ERROR"); @@ -336,7 +335,7 @@ impl SocketOption { } impl TcpSocketOption { - pub fn set(&self, raw_socket: &Socket, opt: &[u8]) { + pub fn set(&self, raw_socket: &Socket, opt: &[u8]) -> SyscallResult { let mut inner = raw_socket.inner.lock(); let socket = match &mut *inner { SocketInner::Tcp(ref mut s) => s, @@ -352,10 +351,15 @@ impl TcpSocketOption { let _ = socket.set_nagle_enabled(opt_value == 0); let _ = socket.flush(); + Ok(0) + } + TcpSocketOption::TCP_INFO => { + // TODO: support the protocal + Ok(0) } - TcpSocketOption::TCP_INFO => panic!("[setsockopt()] try to set TCP_INFO"), TcpSocketOption::TCP_CONGESTION => { - raw_socket.set_congestion(String::from_utf8(Vec::from(opt)).unwrap()) + raw_socket.set_congestion(String::from_utf8(Vec::from(opt)).unwrap()); + Ok(0) } _ => { unimplemented!() @@ -425,7 +429,6 @@ pub struct Socket { recv_timeout: Mutex>, // fake options - reuse_addr: AtomicBool, dont_route: bool, send_buf_size: AtomicU64, recv_buf_size: AtomicU64, @@ -445,7 +448,11 @@ impl Socket { *self.recv_timeout.lock() } fn get_reuse_addr(&self) -> bool { - self.reuse_addr.load(core::sync::atomic::Ordering::Acquire) + let inner = self.inner.lock(); + match &*inner { + SocketInner::Tcp(s) => unimplemented!("get_reuse_addr on other socket"), + SocketInner::Udp(s) => s.is_reuse_addr(), + } } fn get_send_buf_size(&self) -> u64 { @@ -467,8 +474,11 @@ impl Socket { } fn set_reuse_addr(&self, flag: bool) { - self.reuse_addr - .store(flag, core::sync::atomic::Ordering::Release) + let inner = self.inner.lock(); + match &*inner { + SocketInner::Tcp(s) => (), + SocketInner::Udp(s) => s.set_reuse_addr(flag), + } } fn set_send_buf_size(&self, size: u64) { @@ -500,7 +510,6 @@ impl Socket { inner: Mutex::new(inner), close_exec: false, recv_timeout: Mutex::new(None), - reuse_addr: AtomicBool::new(false), dont_route: false, send_buf_size: AtomicU64::new(64 * 1024), recv_buf_size: AtomicU64::new(64 * 1024), @@ -604,7 +613,6 @@ impl Socket { inner: Mutex::new(SocketInner::Tcp(new_socket)), close_exec: false, recv_timeout: Mutex::new(None), - reuse_addr: AtomicBool::new(false), dont_route: false, send_buf_size: AtomicU64::new(64 * 1024), recv_buf_size: AtomicU64::new(64 * 1024),