mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Move packet dispatch out of smoltcp
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
f793259512
commit
ee1656ba35
@ -8,4 +8,5 @@ pub use init::{init, IFACES};
|
||||
pub use poll::{lazy_init, poll_ifaces};
|
||||
|
||||
pub type Iface = dyn aster_bigtcp::iface::Iface<ext::IfaceExt>;
|
||||
pub type AnyBoundSocket = aster_bigtcp::socket::AnyBoundSocket<ext::IfaceExt>;
|
||||
pub type BoundTcpSocket = aster_bigtcp::socket::BoundTcpSocket<ext::IfaceExt>;
|
||||
pub type BoundUdpSocket = aster_bigtcp::socket::BoundUdpSocket<ext::IfaceExt>;
|
||||
|
@ -3,12 +3,11 @@
|
||||
use aster_bigtcp::{
|
||||
errors::BindError,
|
||||
iface::BindPortConfig,
|
||||
socket::AnyUnboundSocket,
|
||||
wire::{IpAddress, IpEndpoint},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
net::iface::{AnyBoundSocket, Iface, IFACES},
|
||||
net::iface::{Iface, IFACES},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@ -46,11 +45,16 @@ fn get_ephemeral_iface(remote_ip_addr: &IpAddress) -> Arc<Iface> {
|
||||
ifaces[0].clone()
|
||||
}
|
||||
|
||||
pub(super) fn bind_socket(
|
||||
unbound_socket: Box<AnyUnboundSocket>,
|
||||
pub(super) fn bind_socket<S, T>(
|
||||
unbound_socket: Box<S>,
|
||||
endpoint: &IpEndpoint,
|
||||
can_reuse: bool,
|
||||
) -> core::result::Result<AnyBoundSocket, (Error, Box<AnyUnboundSocket>)> {
|
||||
bind: impl FnOnce(
|
||||
Arc<Iface>,
|
||||
Box<S>,
|
||||
BindPortConfig,
|
||||
) -> core::result::Result<T, (BindError, Box<S>)>,
|
||||
) -> core::result::Result<T, (Error, Box<S>)> {
|
||||
let iface = match get_iface_to_bind(&endpoint.addr) {
|
||||
Some(iface) => iface,
|
||||
None => {
|
||||
@ -64,9 +68,7 @@ pub(super) fn bind_socket(
|
||||
|
||||
let bind_port_config = BindPortConfig::new(endpoint.port, can_reuse);
|
||||
|
||||
iface
|
||||
.bind_socket(unbound_socket, bind_port_config)
|
||||
.map_err(|(err, unbound)| (err.into(), unbound))
|
||||
bind(iface, unbound_socket, bind_port_config).map_err(|(err, unbound)| (err.into(), unbound))
|
||||
}
|
||||
|
||||
impl From<BindError> for Error {
|
||||
|
@ -2,25 +2,24 @@
|
||||
|
||||
use aster_bigtcp::{
|
||||
errors::udp::{RecvError, SendError},
|
||||
socket::RawUdpSocket,
|
||||
wire::IpEndpoint,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
net::{iface::AnyBoundSocket, socket::util::send_recv_flags::SendRecvFlags},
|
||||
net::{iface::BoundUdpSocket, socket::util::send_recv_flags::SendRecvFlags},
|
||||
prelude::*,
|
||||
process::signal::Pollee,
|
||||
util::{MultiRead, MultiWrite},
|
||||
};
|
||||
|
||||
pub struct BoundDatagram {
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundUdpSocket,
|
||||
remote_endpoint: Option<IpEndpoint>,
|
||||
}
|
||||
|
||||
impl BoundDatagram {
|
||||
pub fn new(bound_socket: AnyBoundSocket) -> Self {
|
||||
pub fn new(bound_socket: BoundUdpSocket) -> Self {
|
||||
Self {
|
||||
bound_socket,
|
||||
remote_endpoint: None,
|
||||
@ -44,12 +43,10 @@ impl BoundDatagram {
|
||||
writer: &mut dyn MultiWrite,
|
||||
_flags: SendRecvFlags,
|
||||
) -> Result<(usize, IpEndpoint)> {
|
||||
let result = self.bound_socket.raw_with(|socket: &mut RawUdpSocket| {
|
||||
socket.recv().map(|(packet, udp_metadata)| {
|
||||
let copied_res = writer.write(&mut VmReader::from(packet));
|
||||
let endpoint = udp_metadata.endpoint;
|
||||
(copied_res, endpoint)
|
||||
})
|
||||
let result = self.bound_socket.recv(|packet, udp_metadata| {
|
||||
let copied_res = writer.write(&mut VmReader::from(packet));
|
||||
let endpoint = udp_metadata.endpoint;
|
||||
(copied_res, endpoint)
|
||||
});
|
||||
|
||||
match result {
|
||||
@ -59,7 +56,7 @@ impl BoundDatagram {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the receive buffer is empty")
|
||||
}
|
||||
Err(RecvError::Truncated) => {
|
||||
unreachable!("`Socket::recv` should never fail with `RecvError::Truncated`")
|
||||
unreachable!("`recv` should never fail with `RecvError::Truncated`")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,32 +67,31 @@ impl BoundDatagram {
|
||||
remote: &IpEndpoint,
|
||||
_flags: SendRecvFlags,
|
||||
) -> Result<usize> {
|
||||
let reader_len = reader.sum_lens();
|
||||
let result = self
|
||||
.bound_socket
|
||||
.send(reader.sum_lens(), *remote, |socket_buffer| {
|
||||
// FIXME: If copy failed, we should not send any packet.
|
||||
// But current smoltcp API seems not to support this behavior.
|
||||
reader
|
||||
.read(&mut VmWriter::from(socket_buffer))
|
||||
.map_err(|e| {
|
||||
warn!("unexpected UDP packet will be sent");
|
||||
e
|
||||
})
|
||||
});
|
||||
|
||||
self.bound_socket.raw_with(|socket: &mut RawUdpSocket| {
|
||||
if socket.payload_send_capacity() < reader_len {
|
||||
match result {
|
||||
Ok(inner) => inner,
|
||||
Err(SendError::TooLarge) => {
|
||||
return_errno_with_message!(Errno::EMSGSIZE, "the message is too large");
|
||||
}
|
||||
|
||||
let socket_buffer = match socket.send(reader_len, *remote) {
|
||||
Ok(socket_buffer) => socket_buffer,
|
||||
Err(SendError::BufferFull) => {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the send buffer is full")
|
||||
}
|
||||
Err(SendError::Unaddressable) => {
|
||||
return_errno_with_message!(Errno::EINVAL, "the destination address is invalid")
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: If copy failed, we should not send any packet.
|
||||
// But current smoltcp API seems not to support this behavior.
|
||||
reader
|
||||
.read(&mut VmWriter::from(socket_buffer))
|
||||
.map_err(|e| {
|
||||
warn!("unexpected UDP packet will be sent");
|
||||
e
|
||||
})
|
||||
})
|
||||
Err(SendError::Unaddressable) => {
|
||||
return_errno_with_message!(Errno::EINVAL, "the destination address is invalid");
|
||||
}
|
||||
Err(SendError::BufferFull) => {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the send buffer is full");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn init_pollee(&self, pollee: &Pollee) {
|
||||
@ -104,7 +100,7 @@ impl BoundDatagram {
|
||||
}
|
||||
|
||||
pub(super) fn update_io_events(&self, pollee: &Pollee) {
|
||||
self.bound_socket.raw_with(|socket: &mut RawUdpSocket| {
|
||||
self.bound_socket.raw_with(|socket| {
|
||||
if socket.can_recv() {
|
||||
pollee.add_events(IoEvents::IN);
|
||||
} else {
|
||||
|
@ -154,13 +154,9 @@ impl DatagramSocket {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the socket is not bound");
|
||||
};
|
||||
|
||||
let received =
|
||||
bound_datagram
|
||||
.try_recv(writer, flags)
|
||||
.map(|(recv_bytes, remote_endpoint)| {
|
||||
bound_datagram.update_io_events(&self.pollee);
|
||||
(recv_bytes, remote_endpoint.into())
|
||||
});
|
||||
let received = bound_datagram
|
||||
.try_recv(writer, flags)
|
||||
.map(|(recv_bytes, remote_endpoint)| (recv_bytes, remote_endpoint.into()));
|
||||
|
||||
drop(inner);
|
||||
poll_ifaces();
|
||||
@ -192,12 +188,7 @@ impl DatagramSocket {
|
||||
return_errno_with_message!(Errno::EAGAIN, "the socket is not bound")
|
||||
};
|
||||
|
||||
let sent_bytes = bound_datagram
|
||||
.try_send(reader, remote, flags)
|
||||
.map(|sent_bytes| {
|
||||
bound_datagram.update_io_events(&self.pollee);
|
||||
sent_bytes
|
||||
});
|
||||
let sent_bytes = bound_datagram.try_send(reader, remote, flags);
|
||||
|
||||
drop(inner);
|
||||
poll_ifaces();
|
||||
|
@ -3,7 +3,7 @@
|
||||
use alloc::sync::Weak;
|
||||
|
||||
use aster_bigtcp::{
|
||||
socket::{AnyUnboundSocket, RawUdpSocket, SocketEventObserver},
|
||||
socket::{SocketEventObserver, UnboundUdpSocket},
|
||||
wire::IpEndpoint,
|
||||
};
|
||||
|
||||
@ -13,13 +13,13 @@ use crate::{
|
||||
};
|
||||
|
||||
pub struct UnboundDatagram {
|
||||
unbound_socket: Box<AnyUnboundSocket>,
|
||||
unbound_socket: Box<UnboundUdpSocket>,
|
||||
}
|
||||
|
||||
impl UnboundDatagram {
|
||||
pub fn new(observer: Weak<dyn SocketEventObserver>) -> Self {
|
||||
Self {
|
||||
unbound_socket: Box::new(AnyUnboundSocket::new_udp(observer)),
|
||||
unbound_socket: Box::new(UnboundUdpSocket::new(observer)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,15 +28,18 @@ impl UnboundDatagram {
|
||||
endpoint: &IpEndpoint,
|
||||
can_reuse: bool,
|
||||
) -> core::result::Result<BoundDatagram, (Error, Self)> {
|
||||
let bound_socket = match bind_socket(self.unbound_socket, endpoint, can_reuse) {
|
||||
let bound_socket = match bind_socket(
|
||||
self.unbound_socket,
|
||||
endpoint,
|
||||
can_reuse,
|
||||
|iface, socket, config| iface.bind_udp(socket, config),
|
||||
) {
|
||||
Ok(bound_socket) => bound_socket,
|
||||
Err((err, unbound_socket)) => return Err((err, Self { unbound_socket })),
|
||||
};
|
||||
|
||||
let bound_endpoint = bound_socket.local_endpoint().unwrap();
|
||||
bound_socket.raw_with(|socket: &mut RawUdpSocket| {
|
||||
socket.bind(bound_endpoint).unwrap();
|
||||
});
|
||||
bound_socket.bind(bound_endpoint).unwrap();
|
||||
|
||||
Ok(BoundDatagram::new(bound_socket))
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ use alloc::sync::Weak;
|
||||
|
||||
use aster_bigtcp::{
|
||||
errors::tcp::{RecvError, SendError},
|
||||
socket::{RawTcpSocket, SocketEventObserver},
|
||||
socket::SocketEventObserver,
|
||||
wire::IpEndpoint,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
net::{
|
||||
iface::AnyBoundSocket,
|
||||
iface::BoundTcpSocket,
|
||||
socket::util::{send_recv_flags::SendRecvFlags, shutdown_cmd::SockShutdownCmd},
|
||||
},
|
||||
prelude::*,
|
||||
@ -20,7 +20,7 @@ use crate::{
|
||||
};
|
||||
|
||||
pub struct ConnectedStream {
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
remote_endpoint: IpEndpoint,
|
||||
/// Indicates whether this connection is "new" in a `connect()` system call.
|
||||
///
|
||||
@ -37,7 +37,7 @@ pub struct ConnectedStream {
|
||||
|
||||
impl ConnectedStream {
|
||||
pub fn new(
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
remote_endpoint: IpEndpoint,
|
||||
is_new_connection: bool,
|
||||
) -> Self {
|
||||
@ -50,20 +50,16 @@ impl ConnectedStream {
|
||||
|
||||
pub fn shutdown(&self, _cmd: SockShutdownCmd) -> Result<()> {
|
||||
// TODO: deal with cmd
|
||||
self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
|
||||
socket.close();
|
||||
});
|
||||
self.bound_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)),
|
||||
},
|
||||
)
|
||||
let result = self.bound_socket.recv(|socket_buffer| {
|
||||
match writer.write(&mut VmReader::from(&*socket_buffer)) {
|
||||
Ok(len) => (len, Ok(len)),
|
||||
Err(e) => (0, Err(e)),
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
@ -78,13 +74,11 @@ impl ConnectedStream {
|
||||
}
|
||||
|
||||
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)),
|
||||
},
|
||||
)
|
||||
let result = self.bound_socket.send(|socket_buffer| {
|
||||
match reader.read(&mut VmWriter::from(socket_buffer)) {
|
||||
Ok(len) => (len, Ok(len)),
|
||||
Err(e) => (0, Err(e)),
|
||||
}
|
||||
});
|
||||
|
||||
match result {
|
||||
@ -123,7 +117,7 @@ impl ConnectedStream {
|
||||
}
|
||||
|
||||
pub(super) fn update_io_events(&self, pollee: &Pollee) {
|
||||
self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
|
||||
self.bound_socket.raw_with(|socket| {
|
||||
if socket.can_recv() {
|
||||
pollee.add_events(IoEvents::IN);
|
||||
} else {
|
||||
|
@ -1,12 +1,12 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use aster_bigtcp::{socket::RawTcpSocket, wire::IpEndpoint};
|
||||
use aster_bigtcp::wire::IpEndpoint;
|
||||
|
||||
use super::{connected::ConnectedStream, init::InitStream};
|
||||
use crate::{net::iface::AnyBoundSocket, prelude::*, process::signal::Pollee};
|
||||
use crate::{net::iface::BoundTcpSocket, prelude::*, process::signal::Pollee};
|
||||
|
||||
pub struct ConnectingStream {
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
remote_endpoint: IpEndpoint,
|
||||
conn_result: RwLock<Option<ConnResult>>,
|
||||
}
|
||||
@ -24,15 +24,15 @@ pub enum NonConnectedStream {
|
||||
|
||||
impl ConnectingStream {
|
||||
pub fn new(
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
remote_endpoint: IpEndpoint,
|
||||
) -> core::result::Result<Self, (Error, AnyBoundSocket)> {
|
||||
) -> core::result::Result<Self, (Error, BoundTcpSocket)> {
|
||||
// The only reason this method might fail is because we're trying to connect to an
|
||||
// unspecified address (i.e. 0.0.0.0). We currently have no support for binding to,
|
||||
// listening on, or connecting to the unspecified address.
|
||||
//
|
||||
// We assume the remote will just refuse to connect, so we return `ECONNREFUSED`.
|
||||
if bound_socket.do_connect(remote_endpoint).is_err() {
|
||||
if bound_socket.connect(remote_endpoint).is_err() {
|
||||
return Err((
|
||||
Error::with_message(
|
||||
Errno::ECONNREFUSED,
|
||||
@ -91,7 +91,7 @@ impl ConnectingStream {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.bound_socket.raw_with(|socket: &mut RawTcpSocket| {
|
||||
self.bound_socket.raw_with(|socket| {
|
||||
let mut result = self.conn_result.write();
|
||||
if result.is_some() {
|
||||
return false;
|
||||
|
@ -3,7 +3,7 @@
|
||||
use alloc::sync::Weak;
|
||||
|
||||
use aster_bigtcp::{
|
||||
socket::{AnyUnboundSocket, SocketEventObserver},
|
||||
socket::{SocketEventObserver, UnboundTcpSocket},
|
||||
wire::IpEndpoint,
|
||||
};
|
||||
|
||||
@ -11,7 +11,7 @@ use super::{connecting::ConnectingStream, listen::ListenStream};
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
net::{
|
||||
iface::AnyBoundSocket,
|
||||
iface::BoundTcpSocket,
|
||||
socket::ip::common::{bind_socket, get_ephemeral_endpoint},
|
||||
},
|
||||
prelude::*,
|
||||
@ -19,16 +19,16 @@ use crate::{
|
||||
};
|
||||
|
||||
pub enum InitStream {
|
||||
Unbound(Box<AnyUnboundSocket>),
|
||||
Bound(AnyBoundSocket),
|
||||
Unbound(Box<UnboundTcpSocket>),
|
||||
Bound(BoundTcpSocket),
|
||||
}
|
||||
|
||||
impl InitStream {
|
||||
pub fn new(observer: Weak<dyn SocketEventObserver>) -> Self {
|
||||
InitStream::Unbound(Box::new(AnyUnboundSocket::new_tcp(observer)))
|
||||
InitStream::Unbound(Box::new(UnboundTcpSocket::new(observer)))
|
||||
}
|
||||
|
||||
pub fn new_bound(bound_socket: AnyBoundSocket) -> Self {
|
||||
pub fn new_bound(bound_socket: BoundTcpSocket) -> Self {
|
||||
InitStream::Bound(bound_socket)
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ impl InitStream {
|
||||
self,
|
||||
endpoint: &IpEndpoint,
|
||||
can_reuse: bool,
|
||||
) -> core::result::Result<AnyBoundSocket, (Error, Self)> {
|
||||
) -> core::result::Result<BoundTcpSocket, (Error, Self)> {
|
||||
let unbound_socket = match self {
|
||||
InitStream::Unbound(unbound_socket) => unbound_socket,
|
||||
InitStream::Bound(bound_socket) => {
|
||||
@ -46,7 +46,12 @@ impl InitStream {
|
||||
));
|
||||
}
|
||||
};
|
||||
let bound_socket = match bind_socket(unbound_socket, endpoint, can_reuse) {
|
||||
let bound_socket = match bind_socket(
|
||||
unbound_socket,
|
||||
endpoint,
|
||||
can_reuse,
|
||||
|iface, socket, config| iface.bind_tcp(socket, config),
|
||||
) {
|
||||
Ok(bound_socket) => bound_socket,
|
||||
Err((err, unbound_socket)) => return Err((err, InitStream::Unbound(unbound_socket))),
|
||||
};
|
||||
@ -56,7 +61,7 @@ impl InitStream {
|
||||
fn bind_to_ephemeral_endpoint(
|
||||
self,
|
||||
remote_endpoint: &IpEndpoint,
|
||||
) -> core::result::Result<AnyBoundSocket, (Error, Self)> {
|
||||
) -> core::result::Result<BoundTcpSocket, (Error, Self)> {
|
||||
let endpoint = get_ephemeral_endpoint(remote_endpoint);
|
||||
self.bind(&endpoint, false)
|
||||
}
|
||||
|
@ -1,28 +1,25 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use aster_bigtcp::{
|
||||
errors::tcp::ListenError,
|
||||
iface::BindPortConfig,
|
||||
socket::{AnyUnboundSocket, RawTcpSocket},
|
||||
wire::IpEndpoint,
|
||||
errors::tcp::ListenError, iface::BindPortConfig, socket::UnboundTcpSocket, wire::IpEndpoint,
|
||||
};
|
||||
|
||||
use super::connected::ConnectedStream;
|
||||
use crate::{events::IoEvents, net::iface::AnyBoundSocket, prelude::*, process::signal::Pollee};
|
||||
use crate::{events::IoEvents, net::iface::BoundTcpSocket, prelude::*, process::signal::Pollee};
|
||||
|
||||
pub struct ListenStream {
|
||||
backlog: usize,
|
||||
/// A bound socket held to ensure the TCP port cannot be released
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
/// Backlog sockets listening at the local endpoint
|
||||
backlog_sockets: RwLock<Vec<BacklogSocket>>,
|
||||
}
|
||||
|
||||
impl ListenStream {
|
||||
pub fn new(
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
backlog: usize,
|
||||
) -> core::result::Result<Self, (Error, AnyBoundSocket)> {
|
||||
) -> core::result::Result<Self, (Error, BoundTcpSocket)> {
|
||||
const SOMAXCONN: usize = 4096;
|
||||
let somaxconn = SOMAXCONN.min(backlog);
|
||||
|
||||
@ -102,30 +99,28 @@ impl ListenStream {
|
||||
}
|
||||
|
||||
struct BacklogSocket {
|
||||
bound_socket: AnyBoundSocket,
|
||||
bound_socket: BoundTcpSocket,
|
||||
}
|
||||
|
||||
impl BacklogSocket {
|
||||
// FIXME: All of the error codes below seem to have no Linux equivalents, and I see no reason
|
||||
// why the error may occur. Perhaps it is better to call `unwrap()` directly?
|
||||
fn new(bound_socket: &AnyBoundSocket) -> Result<Self> {
|
||||
fn new(bound_socket: &BoundTcpSocket) -> Result<Self> {
|
||||
let local_endpoint = bound_socket.local_endpoint().ok_or(Error::with_message(
|
||||
Errno::EINVAL,
|
||||
"the socket is not bound",
|
||||
))?;
|
||||
|
||||
let unbound_socket = Box::new(AnyUnboundSocket::new_tcp(Weak::<()>::new()));
|
||||
let unbound_socket = Box::new(UnboundTcpSocket::new(bound_socket.observer()));
|
||||
let bound_socket = {
|
||||
let iface = bound_socket.iface();
|
||||
let bind_port_config = BindPortConfig::new(local_endpoint.port, true);
|
||||
iface
|
||||
.bind_socket(unbound_socket, bind_port_config)
|
||||
.bind_tcp(unbound_socket, bind_port_config)
|
||||
.map_err(|(err, _)| err)?
|
||||
};
|
||||
|
||||
let result = bound_socket
|
||||
.raw_with(|raw_tcp_socket: &mut RawTcpSocket| raw_tcp_socket.listen(local_endpoint));
|
||||
match result {
|
||||
match bound_socket.listen(local_endpoint) {
|
||||
Ok(()) => Ok(Self { bound_socket }),
|
||||
Err(ListenError::Unaddressable) => {
|
||||
return_errno_with_message!(Errno::EINVAL, "the listening address is invalid")
|
||||
@ -137,16 +132,15 @@ impl BacklogSocket {
|
||||
}
|
||||
|
||||
fn is_active(&self) -> bool {
|
||||
self.bound_socket
|
||||
.raw_with(|socket: &mut RawTcpSocket| socket.is_active())
|
||||
self.bound_socket.raw_with(|socket| socket.is_active())
|
||||
}
|
||||
|
||||
fn remote_endpoint(&self) -> Option<IpEndpoint> {
|
||||
self.bound_socket
|
||||
.raw_with(|socket: &mut RawTcpSocket| socket.remote_endpoint())
|
||||
.raw_with(|socket| socket.remote_endpoint())
|
||||
}
|
||||
|
||||
fn into_bound_socket(self) -> AnyBoundSocket {
|
||||
fn into_bound_socket(self) -> BoundTcpSocket {
|
||||
self.bound_socket
|
||||
}
|
||||
}
|
||||
|
@ -230,18 +230,13 @@ impl StreamSocket {
|
||||
return_errno_with_message!(Errno::EINVAL, "the socket is not listening");
|
||||
};
|
||||
|
||||
let accepted = listen_stream.try_accept().map(|connected_stream| {
|
||||
listen_stream.try_accept().map(|connected_stream| {
|
||||
listen_stream.update_io_events(&self.pollee);
|
||||
|
||||
let remote_endpoint = connected_stream.remote_endpoint();
|
||||
let accepted_socket = Self::new_connected(connected_stream);
|
||||
(accepted_socket as _, remote_endpoint.into())
|
||||
});
|
||||
|
||||
drop(state);
|
||||
poll_ifaces();
|
||||
|
||||
accepted
|
||||
})
|
||||
}
|
||||
|
||||
fn try_recv(
|
||||
@ -262,8 +257,6 @@ impl StreamSocket {
|
||||
};
|
||||
|
||||
let received = connected_stream.try_recv(writer, flags).map(|recv_bytes| {
|
||||
connected_stream.update_io_events(&self.pollee);
|
||||
|
||||
let remote_endpoint = connected_stream.remote_endpoint();
|
||||
(recv_bytes, remote_endpoint.into())
|
||||
});
|
||||
@ -302,10 +295,7 @@ impl StreamSocket {
|
||||
}
|
||||
};
|
||||
|
||||
let sent_bytes = connected_stream.try_send(reader, flags).map(|sent_bytes| {
|
||||
connected_stream.update_io_events(&self.pollee);
|
||||
sent_bytes
|
||||
});
|
||||
let sent_bytes = connected_stream.try_send(reader, flags);
|
||||
|
||||
drop(state);
|
||||
poll_ifaces();
|
||||
@ -658,3 +648,11 @@ impl SocketEventObserver for StreamSocket {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for StreamSocket {
|
||||
fn drop(&mut self) {
|
||||
self.state.write().take();
|
||||
|
||||
poll_ifaces();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user