diff --git a/kernel/aster-nix/src/net/socket/ip/stream/connected.rs b/kernel/aster-nix/src/net/socket/ip/stream/connected.rs index e26e3d9de..3a70f2c97 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/connected.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/connected.rs @@ -68,6 +68,26 @@ impl ConnectedStream { self.update_io_events(pollee); } + pub fn register_observer( + &self, + pollee: &Pollee, + observer: Weak>, + mask: IoEvents, + ) -> Result<()> { + pollee.register_observer(observer, mask); + Ok(()) + } + + pub fn unregister_observer( + &self, + pollee: &Pollee, + observer: &Weak>, + ) -> Result>> { + pollee + .unregister_observer(observer) + .ok_or_else(|| Error::with_message(Errno::EINVAL, "fails to unregister observer")) + } + pub(super) fn update_io_events(&self, pollee: &Pollee) { self.bound_socket.raw_with(|socket: &mut RawTcpSocket| { if socket.can_recv() { diff --git a/kernel/aster-nix/src/net/socket/ip/stream/connecting.rs b/kernel/aster-nix/src/net/socket/ip/stream/connecting.rs index d1ac85383..2af4eb24f 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/connecting.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/connecting.rs @@ -2,7 +2,7 @@ use super::{connected::ConnectedStream, init::InitStream}; use crate::{ - events::IoEvents, + events::{IoEvents, Observer}, net::iface::{AnyBoundSocket, IpEndpoint, RawTcpSocket}, prelude::*, process::signal::Pollee, @@ -71,6 +71,26 @@ impl ConnectingStream { self.update_io_events(pollee); } + pub fn register_observer( + &self, + pollee: &Pollee, + observer: Weak>, + mask: IoEvents, + ) -> Result<()> { + pollee.register_observer(observer, mask); + Ok(()) + } + + pub fn unregister_observer( + &self, + pollee: &Pollee, + observer: &Weak>, + ) -> Result>> { + pollee + .unregister_observer(observer) + .ok_or_else(|| Error::with_message(Errno::EINVAL, "fails to unregister observer")) + } + pub(super) fn update_io_events(&self, pollee: &Pollee) { if self.conn_result.read().is_some() { return; diff --git a/kernel/aster-nix/src/net/socket/ip/stream/init.rs b/kernel/aster-nix/src/net/socket/ip/stream/init.rs index 352237a9c..3f8626b32 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/init.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/init.rs @@ -4,12 +4,13 @@ use alloc::sync::Weak; use super::{connecting::ConnectingStream, listen::ListenStream}; use crate::{ - events::Observer, + events::{IoEvents, Observer}, net::{ iface::{AnyBoundSocket, AnyUnboundSocket, IpEndpoint}, socket::ip::common::{bind_socket, get_ephemeral_endpoint}, }, prelude::*, + process::signal::Pollee, }; pub enum InitStream { @@ -90,4 +91,24 @@ impl InitStream { InitStream::Bound(bound_socket) => Ok(bound_socket.local_endpoint().unwrap()), } } + + pub fn register_observer( + &self, + pollee: &Pollee, + observer: Weak>, + mask: IoEvents, + ) -> Result<()> { + pollee.register_observer(observer, mask); + Ok(()) + } + + pub fn unregister_observer( + &self, + pollee: &Pollee, + observer: &Weak>, + ) -> Result>> { + pollee + .unregister_observer(observer) + .ok_or_else(|| Error::with_message(Errno::EINVAL, "fails to unregister observer")) + } } diff --git a/kernel/aster-nix/src/net/socket/ip/stream/listen.rs b/kernel/aster-nix/src/net/socket/ip/stream/listen.rs index a970eaea1..239d9ae9b 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/listen.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/listen.rs @@ -2,7 +2,7 @@ use super::connected::ConnectedStream; use crate::{ - events::IoEvents, + events::{IoEvents, Observer}, net::iface::{AnyBoundSocket, AnyUnboundSocket, BindPortConfig, IpEndpoint, RawTcpSocket}, prelude::*, process::signal::Pollee, @@ -92,6 +92,26 @@ impl ListenStream { pollee.del_events(IoEvents::IN); } } + + pub fn register_observer( + &self, + pollee: &Pollee, + observer: Weak>, + mask: IoEvents, + ) -> Result<()> { + pollee.register_observer(observer, mask); + Ok(()) + } + + pub fn unregister_observer( + &self, + pollee: &Pollee, + observer: &Weak>, + ) -> Result>> { + pollee + .unregister_observer(observer) + .ok_or_else(|| Error::with_message(Errno::EINVAL, "fails to unregister observer")) + } } struct BacklogSocket { diff --git a/kernel/aster-nix/src/net/socket/ip/stream/mod.rs b/kernel/aster-nix/src/net/socket/ip/stream/mod.rs index 32b95e52a..8091fcd78 100644 --- a/kernel/aster-nix/src/net/socket/ip/stream/mod.rs +++ b/kernel/aster-nix/src/net/socket/ip/stream/mod.rs @@ -275,6 +275,36 @@ impl FileLike for StreamSocket { fn as_socket(self: Arc) -> Option> { Some(self) } + + fn register_observer( + &self, + observer: Weak>, + mask: IoEvents, + ) -> Result<()> { + let state = self.state.read(); + match state.as_ref() { + State::Init(init) => init.register_observer(&self.pollee, observer, mask), + State::Connecting(connecting) => { + connecting.register_observer(&self.pollee, observer, mask) + } + State::Connected(connected) => { + connected.register_observer(&self.pollee, observer, mask) + } + State::Listen(listen) => listen.register_observer(&self.pollee, observer, mask), + } + } + + fn unregister_observer( + &self, + observer: &Weak>, + ) -> Result>> { + match self.state.read().as_ref() { + State::Init(init) => init.unregister_observer(&self.pollee, observer), + State::Connecting(connecting) => connecting.unregister_observer(&self.pollee, observer), + State::Connected(connected) => connected.unregister_observer(&self.pollee, observer), + State::Listen(listen) => listen.unregister_observer(&self.pollee, observer), + } + } } impl Socket for StreamSocket { diff --git a/kernel/aster-nix/src/net/socket/options/mod.rs b/kernel/aster-nix/src/net/socket/options/mod.rs index 0332180c2..b5df5a857 100644 --- a/kernel/aster-nix/src/net/socket/options/mod.rs +++ b/kernel/aster-nix/src/net/socket/options/mod.rs @@ -19,4 +19,5 @@ impl_socket_options!( pub struct RecvBuf(u32); pub struct Error(Option); pub struct Linger(LingerOption); + pub struct KeepAlive(bool); ); diff --git a/kernel/aster-nix/src/net/socket/util/options.rs b/kernel/aster-nix/src/net/socket/util/options.rs index 023c080d3..b72ea92ca 100644 --- a/kernel/aster-nix/src/net/socket/util/options.rs +++ b/kernel/aster-nix/src/net/socket/util/options.rs @@ -17,6 +17,7 @@ pub struct SocketOptionSet { send_buf: u32, recv_buf: u32, linger: LingerOption, + keep_alive: bool, } impl SocketOptionSet { @@ -29,6 +30,7 @@ impl SocketOptionSet { send_buf: SEND_BUF_LEN as u32, recv_buf: RECV_BUF_LEN as u32, linger: LingerOption::default(), + keep_alive: false, } } } diff --git a/kernel/aster-nix/src/util/net/options/socket.rs b/kernel/aster-nix/src/util/net/options/socket.rs index 79ed26ecb..7c1ac1b8d 100644 --- a/kernel/aster-nix/src/util/net/options/socket.rs +++ b/kernel/aster-nix/src/util/net/options/socket.rs @@ -5,7 +5,9 @@ use aster_rights::Full; use super::RawSocketOption; use crate::{ impl_raw_sock_option_get_only, impl_raw_socket_option, - net::socket::options::{Error, Linger, RecvBuf, ReuseAddr, ReusePort, SendBuf, SocketOption}, + net::socket::options::{ + Error, KeepAlive, Linger, RecvBuf, ReuseAddr, ReusePort, SendBuf, SocketOption, + }, prelude::*, vm::vmar::Vmar, }; @@ -48,6 +50,7 @@ pub fn new_socket_option(name: i32) -> Result> { CSocketOptionName::ERROR => Ok(Box::new(Error::new())), CSocketOptionName::REUSEPORT => Ok(Box::new(ReusePort::new())), CSocketOptionName::LINGER => Ok(Box::new(Linger::new())), + CSocketOptionName::KEEPALIVE => Ok(Box::new(KeepAlive::new())), _ => todo!(), } } @@ -58,3 +61,4 @@ impl_raw_socket_option!(ReuseAddr); impl_raw_sock_option_get_only!(Error); impl_raw_socket_option!(ReusePort); impl_raw_socket_option!(Linger); +impl_raw_socket_option!(KeepAlive);