asterinas/kernel/src/net/socket/ip/stream/connected.rs

145 lines
4.7 KiB
Rust
Raw Normal View History

2024-01-03 03:22:36 +00:00
// SPDX-License-Identifier: MPL-2.0
2024-01-07 15:55:23 +00:00
use alloc::sync::Weak;
2023-06-13 09:49:44 +00:00
2024-09-06 10:49:37 +00:00
use aster_bigtcp::{
errors::tcp::{RecvError, SendError},
socket::{RawTcpSocket, SocketEventObserver},
wire::IpEndpoint,
};
2023-05-31 02:48:16 +00:00
use crate::{
2024-09-06 10:49:37 +00:00
events::IoEvents,
2023-05-31 02:48:16 +00:00
net::{
2024-09-06 10:49:37 +00:00
iface::AnyBoundSocket,
2023-05-31 02:48:16 +00:00
socket::util::{send_recv_flags::SendRecvFlags, shutdown_cmd::SockShutdownCmd},
},
prelude::*,
2024-01-07 15:55:23 +00:00
process::signal::Pollee,
util::{MultiRead, MultiWrite},
2023-05-31 02:48:16 +00:00
};
pub struct ConnectedStream {
2024-07-23 15:03:10 +00:00
bound_socket: AnyBoundSocket,
2023-05-31 02:48:16 +00:00
remote_endpoint: IpEndpoint,
2024-01-09 15:42:26 +00:00
/// Indicates whether this connection is "new" in a `connect()` system call.
///
/// If the connection is not new, `connect()` will fail with the error code `EISCONN`,
/// otherwise it will succeed. This means that `connect()` will succeed _exactly_ once,
/// regardless of whether the connection is established synchronously or asynchronously.
///
/// If the connection is established synchronously, the synchronous `connect()` will succeed
/// and any subsequent `connect()` will fail; otherwise, the first `connect()` after the
/// connection is established asynchronously will succeed and any subsequent `connect()` will
/// fail.
is_new_connection: bool,
2023-05-31 02:48:16 +00:00
}
impl ConnectedStream {
2024-01-09 15:42:26 +00:00
pub fn new(
2024-07-23 15:03:10 +00:00
bound_socket: AnyBoundSocket,
2024-01-09 15:42:26 +00:00
remote_endpoint: IpEndpoint,
is_new_connection: bool,
) -> Self {
2024-01-07 15:55:23 +00:00
Self {
2023-05-31 02:48:16 +00:00
bound_socket,
remote_endpoint,
2024-01-09 15:42:26 +00:00
is_new_connection,
2024-01-07 15:55:23 +00:00
}
2023-05-31 02:48:16 +00:00
}
pub fn shutdown(&self, _cmd: SockShutdownCmd) -> Result<()> {
2023-05-31 02:48:16 +00:00
// TODO: deal with cmd
self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
socket.close();
});
Ok(())
}
pub fn try_recv(&self, writer: &mut dyn MultiWrite, _flags: SendRecvFlags) -> Result<usize> {
let result = self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
socket.recv(
|socket_buffer| match writer.write(&mut VmReader::from(&*socket_buffer)) {
Ok(len) => (len, Ok(len)),
Err(e) => (0, Err(e)),
},
)
});
2024-03-20 03:25:18 +00:00
match result {
Ok(Ok(0)) => return_errno_with_message!(Errno::EAGAIN, "the receive buffer is empty"),
Ok(Ok(recv_bytes)) => Ok(recv_bytes),
Ok(Err(e)) => Err(e),
Err(RecvError::Finished) => Ok(0),
Err(RecvError::InvalidState) => {
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset")
}
2023-05-31 02:48:16 +00:00
}
}
pub fn try_send(&self, reader: &mut dyn MultiRead, _flags: SendRecvFlags) -> Result<usize> {
let result = self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
socket.send(
|socket_buffer| match reader.read(&mut VmWriter::from(socket_buffer)) {
Ok(len) => (len, Ok(len)),
Err(e) => (0, Err(e)),
},
)
});
2024-03-20 03:25:18 +00:00
match result {
Ok(Ok(0)) => return_errno_with_message!(Errno::EAGAIN, "the send buffer is full"),
Ok(Ok(sent_bytes)) => Ok(sent_bytes),
Ok(Err(e)) => Err(e),
Err(SendError::InvalidState) => {
// FIXME: `EPIPE` is another possibility, which means that the socket is shut down
// for writing. In that case, we should also trigger a `SIGPIPE` if `MSG_NOSIGNAL`
// is not specified.
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset");
}
2024-01-07 15:55:23 +00:00
}
}
2024-01-07 15:55:23 +00:00
pub fn local_endpoint(&self) -> IpEndpoint {
self.bound_socket.local_endpoint().unwrap()
2023-05-31 02:48:16 +00:00
}
2024-01-07 15:55:23 +00:00
pub fn remote_endpoint(&self) -> IpEndpoint {
self.remote_endpoint
2023-05-31 02:48:16 +00:00
}
2024-01-09 15:42:26 +00:00
pub fn check_new(&mut self) -> Result<()> {
if !self.is_new_connection {
return_errno_with_message!(Errno::EISCONN, "the socket is already connected");
}
self.is_new_connection = false;
Ok(())
}
2024-01-07 15:55:23 +00:00
pub(super) fn init_pollee(&self, pollee: &Pollee) {
pollee.reset_events();
self.update_io_events(pollee);
}
2024-01-07 15:55:23 +00:00
pub(super) fn update_io_events(&self, pollee: &Pollee) {
self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
if socket.can_recv() {
pollee.add_events(IoEvents::IN);
} else {
pollee.del_events(IoEvents::IN);
}
if socket.can_send() {
pollee.add_events(IoEvents::OUT);
} else {
pollee.del_events(IoEvents::OUT);
}
});
2023-05-31 02:48:16 +00:00
}
2023-06-13 09:49:44 +00:00
2024-09-06 10:49:37 +00:00
pub(super) fn set_observer(&self, observer: Weak<dyn SocketEventObserver>) {
2024-01-07 15:55:23 +00:00
self.bound_socket.set_observer(observer)
}
}