2023-10-08 09:40:58 +00:00
|
|
|
use crate::events::IoEvents;
|
|
|
|
|
use crate::prelude::*;
|
|
|
|
|
use crate::process::signal::{Pollee, Poller};
|
2023-05-31 02:47:52 +00:00
|
|
|
|
|
|
|
|
use super::Iface;
|
|
|
|
|
use super::{IpAddress, IpEndpoint};
|
|
|
|
|
|
|
|
|
|
pub type RawTcpSocket = smoltcp::socket::tcp::Socket<'static>;
|
|
|
|
|
pub type RawUdpSocket = smoltcp::socket::udp::Socket<'static>;
|
|
|
|
|
pub type RawSocketHandle = smoltcp::iface::SocketHandle;
|
|
|
|
|
|
|
|
|
|
pub struct AnyUnboundSocket {
|
|
|
|
|
socket_family: AnyRawSocket,
|
|
|
|
|
pollee: Pollee,
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-04 03:04:42 +00:00
|
|
|
#[allow(clippy::large_enum_variant)]
|
2023-05-31 02:47:52 +00:00
|
|
|
pub(super) enum AnyRawSocket {
|
|
|
|
|
Tcp(RawTcpSocket),
|
|
|
|
|
Udp(RawUdpSocket),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) enum SocketFamily {
|
|
|
|
|
Tcp,
|
|
|
|
|
Udp,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AnyUnboundSocket {
|
|
|
|
|
pub fn new_tcp() -> Self {
|
|
|
|
|
let raw_tcp_socket = {
|
|
|
|
|
let rx_buffer = smoltcp::socket::tcp::SocketBuffer::new(vec![0u8; RECV_BUF_LEN]);
|
|
|
|
|
let tx_buffer = smoltcp::socket::tcp::SocketBuffer::new(vec![0u8; SEND_BUF_LEN]);
|
|
|
|
|
RawTcpSocket::new(rx_buffer, tx_buffer)
|
|
|
|
|
};
|
|
|
|
|
let pollee = Pollee::new(IoEvents::empty());
|
|
|
|
|
AnyUnboundSocket {
|
|
|
|
|
socket_family: AnyRawSocket::Tcp(raw_tcp_socket),
|
|
|
|
|
pollee,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_udp() -> Self {
|
|
|
|
|
let raw_udp_socket = {
|
|
|
|
|
let metadata = smoltcp::socket::udp::PacketMetadata::EMPTY;
|
|
|
|
|
let rx_buffer = smoltcp::socket::udp::PacketBuffer::new(
|
|
|
|
|
vec![metadata; UDP_METADATA_LEN],
|
|
|
|
|
vec![0u8; UDP_RECEIVE_PAYLOAD_LEN],
|
|
|
|
|
);
|
|
|
|
|
let tx_buffer = smoltcp::socket::udp::PacketBuffer::new(
|
|
|
|
|
vec![metadata; UDP_METADATA_LEN],
|
|
|
|
|
vec![0u8; UDP_RECEIVE_PAYLOAD_LEN],
|
|
|
|
|
);
|
|
|
|
|
RawUdpSocket::new(rx_buffer, tx_buffer)
|
|
|
|
|
};
|
|
|
|
|
AnyUnboundSocket {
|
|
|
|
|
socket_family: AnyRawSocket::Udp(raw_udp_socket),
|
|
|
|
|
pollee: Pollee::new(IoEvents::empty()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn raw_socket_family(self) -> AnyRawSocket {
|
|
|
|
|
self.socket_family
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn socket_family(&self) -> SocketFamily {
|
|
|
|
|
match &self.socket_family {
|
|
|
|
|
AnyRawSocket::Tcp(_) => SocketFamily::Tcp,
|
|
|
|
|
AnyRawSocket::Udp(_) => SocketFamily::Udp,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
|
|
|
|
self.pollee.poll(mask, poller)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn pollee(&self) -> Pollee {
|
|
|
|
|
self.pollee.clone()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct AnyBoundSocket {
|
|
|
|
|
iface: Arc<dyn Iface>,
|
|
|
|
|
handle: smoltcp::iface::SocketHandle,
|
|
|
|
|
port: u16,
|
|
|
|
|
pollee: Pollee,
|
|
|
|
|
socket_family: SocketFamily,
|
|
|
|
|
weak_self: Weak<Self>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AnyBoundSocket {
|
|
|
|
|
pub(super) fn new(
|
|
|
|
|
iface: Arc<dyn Iface>,
|
|
|
|
|
handle: smoltcp::iface::SocketHandle,
|
|
|
|
|
port: u16,
|
|
|
|
|
pollee: Pollee,
|
|
|
|
|
socket_family: SocketFamily,
|
|
|
|
|
) -> Arc<Self> {
|
|
|
|
|
Arc::new_cyclic(|weak_self| Self {
|
|
|
|
|
iface,
|
|
|
|
|
handle,
|
|
|
|
|
port,
|
|
|
|
|
pollee,
|
|
|
|
|
socket_family,
|
|
|
|
|
weak_self: weak_self.clone(),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn local_endpoint(&self) -> Option<IpEndpoint> {
|
|
|
|
|
let ip_addr = {
|
|
|
|
|
let ipv4_addr = self.iface.ipv4_addr()?;
|
|
|
|
|
IpAddress::Ipv4(ipv4_addr)
|
|
|
|
|
};
|
|
|
|
|
Some(IpEndpoint::new(ip_addr, self.port))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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.sockets();
|
|
|
|
|
let socket = sockets.get_mut::<T>(self.handle);
|
|
|
|
|
f(socket)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Try to connect to a remote endpoint. Tcp socket only.
|
|
|
|
|
pub fn do_connect(&self, remote_endpoint: IpEndpoint) -> Result<()> {
|
|
|
|
|
let mut sockets = self.iface.sockets();
|
|
|
|
|
let socket = sockets.get_mut::<RawTcpSocket>(self.handle);
|
|
|
|
|
let port = self.port;
|
|
|
|
|
let mut iface_inner = self.iface.iface_inner();
|
|
|
|
|
let cx = iface_inner.context();
|
|
|
|
|
socket
|
|
|
|
|
.connect(cx, remote_endpoint, port)
|
|
|
|
|
.map_err(|_| Error::with_message(Errno::ENOBUFS, "send connection request failed"))?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn update_socket_state(&self) {
|
|
|
|
|
let handle = &self.handle;
|
|
|
|
|
let pollee = &self.pollee;
|
|
|
|
|
let sockets = self.iface().sockets();
|
|
|
|
|
match self.socket_family {
|
|
|
|
|
SocketFamily::Tcp => {
|
|
|
|
|
let socket = sockets.get::<RawTcpSocket>(*handle);
|
|
|
|
|
update_tcp_socket_state(socket, pollee);
|
|
|
|
|
}
|
|
|
|
|
SocketFamily::Udp => {
|
|
|
|
|
let udp_socket = sockets.get::<RawUdpSocket>(*handle);
|
|
|
|
|
update_udp_socket_state(udp_socket, pollee);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn iface(&self) -> &Arc<dyn Iface> {
|
|
|
|
|
&self.iface
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
|
|
|
|
self.pollee.poll(mask, poller)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn weak_ref(&self) -> Weak<Self> {
|
|
|
|
|
self.weak_self.clone()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn close(&self) {
|
|
|
|
|
match self.socket_family {
|
|
|
|
|
SocketFamily::Tcp => self.raw_with(|socket: &mut RawTcpSocket| socket.close()),
|
|
|
|
|
SocketFamily::Udp => self.raw_with(|socket: &mut RawUdpSocket| socket.close()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for AnyBoundSocket {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
self.close();
|
2023-08-28 09:37:59 +00:00
|
|
|
self.iface.poll();
|
2023-05-31 02:47:52 +00:00
|
|
|
self.iface.common().remove_socket(self.handle);
|
|
|
|
|
self.iface.common().release_port(self.port);
|
|
|
|
|
self.iface.common().remove_bound_socket(self.weak_ref());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn update_tcp_socket_state(socket: &RawTcpSocket, pollee: &Pollee) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn update_udp_socket_state(socket: &RawUdpSocket, pollee: &Pollee) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For TCP
|
|
|
|
|
const RECV_BUF_LEN: usize = 65536;
|
|
|
|
|
const SEND_BUF_LEN: usize = 65536;
|
|
|
|
|
|
|
|
|
|
// For UDP
|
|
|
|
|
const UDP_METADATA_LEN: usize = 256;
|
|
|
|
|
const UDP_SEND_PAYLOAD_LEN: usize = 65536;
|
|
|
|
|
const UDP_RECEIVE_PAYLOAD_LEN: usize = 65536;
|