asterinas/kernel/libs/aster-bigtcp/src/socket/bound.rs

167 lines
5.0 KiB
Rust
Raw Normal View History

2024-01-03 03:22:36 +00:00
// SPDX-License-Identifier: MPL-2.0
2024-09-06 10:49:37 +00:00
use alloc::sync::{Arc, Weak};
2023-05-31 02:47:52 +00:00
2024-09-06 10:49:37 +00:00
use ostd::sync::RwLock;
use smoltcp::{
socket::tcp::ConnectError,
wire::{IpAddress, IpEndpoint},
};
2023-05-31 02:47:52 +00:00
2024-09-06 10:49:37 +00:00
use super::{event::SocketEventObserver, RawTcpSocket, RawUdpSocket};
use crate::iface::Iface;
2023-05-31 02:47:52 +00:00
2024-09-06 10:49:37 +00:00
pub(crate) enum SocketFamily {
2023-05-31 02:47:52 +00:00
Tcp,
Udp,
}
2024-09-06 10:49:37 +00:00
pub struct AnyBoundSocket<E>(Arc<AnyBoundSocketInner<E>>);
2023-05-31 02:47:52 +00:00
2024-09-05 15:49:14 +00:00
impl<E> AnyBoundSocket<E> {
2024-09-06 10:49:37 +00:00
pub(crate) fn new(
2024-09-05 15:49:14 +00:00
iface: Arc<dyn Iface<E>>,
2023-05-31 02:47:52 +00:00
handle: smoltcp::iface::SocketHandle,
port: u16,
socket_family: SocketFamily,
2024-09-06 10:49:37 +00:00
observer: Weak<dyn SocketEventObserver>,
2024-07-23 15:03:10 +00:00
) -> Self {
Self(Arc::new(AnyBoundSocketInner {
2023-05-31 02:47:52 +00:00
iface,
handle,
port,
socket_family,
2024-01-07 15:55:23 +00:00
observer: RwLock::new(observer),
2024-07-23 15:03:10 +00:00
}))
2023-05-31 02:47:52 +00:00
}
2024-09-06 10:49:37 +00:00
pub(crate) fn inner(&self) -> &Arc<AnyBoundSocketInner<E>> {
2024-07-23 15:03:10 +00:00
&self.0
}
2024-09-06 10:49:37 +00:00
/// Sets the observer whose `on_events` will be called when certain iface events happen. After
/// setting, the new observer will fire once immediately to avoid missing any events.
///
/// If there is an existing observer, due to race conditions, this function does not guarantee
/// that the old observer will never be called after the setting. Users should be aware of this
/// and proactively handle the race conditions if necessary.
2024-09-06 10:49:37 +00:00
pub fn set_observer(&self, new_observer: Weak<dyn SocketEventObserver>) {
*self.0.observer.write() = new_observer;
2024-07-23 15:03:10 +00:00
self.0.on_iface_events();
}
2023-05-31 02:47:52 +00:00
pub fn local_endpoint(&self) -> Option<IpEndpoint> {
let ip_addr = {
2024-07-23 15:03:10 +00:00
let ipv4_addr = self.0.iface.ipv4_addr()?;
2023-05-31 02:47:52 +00:00
IpAddress::Ipv4(ipv4_addr)
};
2024-07-23 15:03:10 +00:00
Some(IpEndpoint::new(ip_addr, self.0.port))
2023-05-31 02:47:52 +00:00
}
pub fn raw_with<T: smoltcp::socket::AnySocket<'static>, R, F: FnMut(&mut T) -> R>(
&self,
2024-07-23 15:03:10 +00:00
f: F,
2023-05-31 02:47:52 +00:00
) -> R {
2024-07-23 15:03:10 +00:00
self.0.raw_with(f)
2023-05-31 02:47:52 +00:00
}
/// Connects to a remote endpoint.
///
/// # Panics
///
/// This method will panic if the socket is not a TCP socket.
2024-09-06 10:49:37 +00:00
pub fn do_connect(&self, remote_endpoint: IpEndpoint) -> Result<(), ConnectError> {
let common = self.iface().common();
let mut sockets = common.sockets();
2024-07-23 15:03:10 +00:00
let socket = sockets.get_mut::<RawTcpSocket>(self.0.handle);
let mut iface = common.interface();
let cx = iface.context();
2024-09-06 10:49:37 +00:00
socket.connect(cx, remote_endpoint, self.0.port)
2023-05-31 02:47:52 +00:00
}
2024-09-05 15:49:14 +00:00
pub fn iface(&self) -> &Arc<dyn Iface<E>> {
2024-07-23 15:03:10 +00:00
&self.0.iface
2023-05-31 02:47:52 +00:00
}
2024-07-23 15:03:10 +00:00
}
2023-05-31 02:47:52 +00:00
2024-09-05 15:49:14 +00:00
impl<E> Drop for AnyBoundSocket<E> {
2024-07-23 15:03:10 +00:00
fn drop(&mut self) {
if self.0.start_closing() {
self.0.iface.common().remove_bound_socket_now(&self.0);
} else {
self.0
.iface
.common()
.remove_bound_socket_when_closed(&self.0);
}
2023-05-31 02:47:52 +00:00
}
2024-07-23 15:03:10 +00:00
}
2023-05-31 02:47:52 +00:00
2024-09-06 10:49:37 +00:00
pub(crate) struct AnyBoundSocketInner<E> {
2024-09-05 15:49:14 +00:00
iface: Arc<dyn Iface<E>>,
2024-07-23 15:03:10 +00:00
handle: smoltcp::iface::SocketHandle,
port: u16,
socket_family: SocketFamily,
2024-09-06 10:49:37 +00:00
observer: RwLock<Weak<dyn SocketEventObserver>>,
2024-07-23 15:03:10 +00:00
}
2024-09-05 15:49:14 +00:00
impl<E> AnyBoundSocketInner<E> {
2024-09-06 10:49:37 +00:00
pub(crate) fn on_iface_events(&self) {
2024-07-23 15:03:10 +00:00
if let Some(observer) = Weak::upgrade(&*self.observer.read()) {
2024-09-06 10:49:37 +00:00
observer.on_events();
2024-07-23 15:03:10 +00:00
}
}
2024-09-06 10:49:37 +00:00
pub(crate) fn is_closed(&self) -> bool {
2024-07-23 15:03:10 +00:00
match self.socket_family {
SocketFamily::Tcp => self.raw_with(|socket: &mut RawTcpSocket| {
socket.state() == smoltcp::socket::tcp::State::Closed
}),
SocketFamily::Udp => true,
}
}
/// Starts closing the socket and returns whether the socket is closed.
///
/// For sockets that can be closed immediately, such as UDP sockets and TCP listening sockets,
/// this method will always return `true`.
///
/// For other sockets, such as TCP connected sockets, they cannot be closed immediately because
/// we at least need to send the FIN packet and wait for the remote end to send an ACK packet.
/// In this case, this method will return `false` and [`Self::is_closed`] can be used to
/// determine if the closing process is complete.
fn start_closing(&self) -> bool {
2023-05-31 02:47:52 +00:00
match self.socket_family {
2024-07-23 15:03:10 +00:00
SocketFamily::Tcp => self.raw_with(|socket: &mut RawTcpSocket| {
socket.close();
socket.state() == smoltcp::socket::tcp::State::Closed
}),
SocketFamily::Udp => {
self.raw_with(|socket: &mut RawUdpSocket| socket.close());
true
}
2023-05-31 02:47:52 +00:00
}
}
2024-07-23 15:03:10 +00:00
pub fn raw_with<T: smoltcp::socket::AnySocket<'static>, R, F: FnMut(&mut T) -> R>(
&self,
mut f: F,
) -> R {
let mut sockets = self.iface.common().sockets();
2024-07-23 15:03:10 +00:00
let socket = sockets.get_mut::<T>(self.handle);
f(socket)
}
2023-05-31 02:47:52 +00:00
}
2024-09-05 15:49:14 +00:00
impl<E> Drop for AnyBoundSocketInner<E> {
2023-05-31 02:47:52 +00:00
fn drop(&mut self) {
2024-07-23 15:03:10 +00:00
let iface_common = self.iface.common();
iface_common.remove_socket(self.handle);
iface_common.release_port(self.port);
2023-05-31 02:47:52 +00:00
}
}