2018-01-06 03:38:23 +08:00
|
|
|
/*! Communication between endpoints.
|
|
|
|
|
|
|
|
The `socket` module deals with *network endpoints* and *buffering*.
|
|
|
|
It provides interfaces for accessing buffers of data, and protocol state machines
|
|
|
|
for filling and emptying these buffers.
|
|
|
|
|
|
|
|
The programming interface implemented here differs greatly from the common Berkeley socket
|
|
|
|
interface. Specifically, in the Berkeley interface the buffering is implicit:
|
|
|
|
the operating system decides on the good size for a buffer and manages it.
|
|
|
|
The interface implemented by this module uses explicit buffering: you decide on the good
|
|
|
|
size for a buffer, allocate it, and let the networking stack use it.
|
|
|
|
*/
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2020-12-27 07:11:30 +08:00
|
|
|
use crate::time::Instant;
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2017-12-18 18:57:26 +08:00
|
|
|
mod meta;
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
|
|
|
mod raw;
|
2018-05-09 21:27:51 +08:00
|
|
|
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
|
2017-10-30 08:19:34 +08:00
|
|
|
mod icmp;
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
|
|
|
mod udp;
|
|
|
|
#[cfg(feature = "socket-tcp")]
|
|
|
|
mod tcp;
|
2017-01-11 12:05:41 +08:00
|
|
|
mod set;
|
2017-09-11 04:18:12 +08:00
|
|
|
mod ref_;
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2020-10-20 19:22:46 +08:00
|
|
|
#[cfg(feature = "async")]
|
|
|
|
mod waker;
|
|
|
|
|
2017-12-18 18:57:26 +08:00
|
|
|
pub(crate) use self::meta::Meta as SocketMeta;
|
2020-10-20 19:22:46 +08:00
|
|
|
#[cfg(feature = "async")]
|
|
|
|
pub(crate) use self::waker::WakerRegistration;
|
2017-12-18 18:57:26 +08:00
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2018-02-22 20:05:36 +08:00
|
|
|
pub use self::raw::{RawPacketMetadata,
|
|
|
|
RawSocketBuffer,
|
2017-09-25 08:12:58 +08:00
|
|
|
RawSocket};
|
2017-06-18 18:14:20 +08:00
|
|
|
|
2018-05-09 21:27:51 +08:00
|
|
|
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
|
2018-02-22 20:23:35 +08:00
|
|
|
pub use self::icmp::{IcmpPacketMetadata,
|
|
|
|
IcmpSocketBuffer,
|
2017-10-30 08:19:34 +08:00
|
|
|
Endpoint as IcmpEndpoint,
|
|
|
|
IcmpSocket};
|
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2018-02-22 19:34:58 +08:00
|
|
|
pub use self::udp::{UdpPacketMetadata,
|
|
|
|
UdpSocketBuffer,
|
2017-09-25 08:12:58 +08:00
|
|
|
UdpSocket};
|
2016-12-15 13:15:00 +08:00
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
2017-09-25 08:12:58 +08:00
|
|
|
pub use self::tcp::{SocketBuffer as TcpSocketBuffer,
|
|
|
|
State as TcpState,
|
|
|
|
TcpSocket};
|
2016-12-19 03:40:11 +08:00
|
|
|
|
2017-06-21 11:57:13 +08:00
|
|
|
pub use self::set::{Set as SocketSet, Item as SocketSetItem, Handle as SocketHandle};
|
2017-01-11 12:05:41 +08:00
|
|
|
pub use self::set::{Iter as SocketSetIter, IterMut as SocketSetIterMut};
|
|
|
|
|
2017-09-11 04:18:12 +08:00
|
|
|
pub use self::ref_::Ref as SocketRef;
|
|
|
|
pub(crate) use self::ref_::Session as SocketSession;
|
|
|
|
|
2018-05-18 00:27:56 +08:00
|
|
|
/// Gives an indication on the next time the socket should be polled.
|
2018-05-17 03:11:04 +08:00
|
|
|
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
|
|
|
|
pub(crate) enum PollAt {
|
2018-05-18 00:27:56 +08:00
|
|
|
/// The socket needs to be polled immidiately.
|
2018-05-17 03:11:04 +08:00
|
|
|
Now,
|
2018-05-18 00:27:56 +08:00
|
|
|
/// The socket needs to be polled at given [Instant][struct.Instant].
|
2018-05-17 03:11:04 +08:00
|
|
|
Time(Instant),
|
2018-05-18 00:27:56 +08:00
|
|
|
/// The socket does not need to be polled unless there are external changes.
|
2018-05-17 03:11:04 +08:00
|
|
|
Ingress,
|
|
|
|
}
|
|
|
|
|
2016-12-15 13:15:00 +08:00
|
|
|
/// A network socket.
|
|
|
|
///
|
2016-12-17 13:12:45 +08:00
|
|
|
/// This enumeration abstracts the various types of sockets based on the IP protocol.
|
2017-09-11 04:18:12 +08:00
|
|
|
/// To downcast a `Socket` value to a concrete socket, use the [AnySocket] trait,
|
|
|
|
/// e.g. to get `UdpSocket`, call `UdpSocket::downcast(socket)`.
|
|
|
|
///
|
|
|
|
/// It is usually more convenient to use [SocketSet::get] instead.
|
2016-12-15 13:15:00 +08:00
|
|
|
///
|
2017-09-11 04:18:12 +08:00
|
|
|
/// [AnySocket]: trait.AnySocket.html
|
|
|
|
/// [SocketSet::get]: struct.SocketSet.html#method.get
|
2017-01-12 12:28:34 +08:00
|
|
|
#[derive(Debug)]
|
2021-01-09 08:52:08 +08:00
|
|
|
pub enum Socket<'a> {
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2021-01-09 08:52:08 +08:00
|
|
|
Raw(RawSocket<'a>),
|
2018-05-09 21:27:51 +08:00
|
|
|
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
|
2021-01-09 08:52:08 +08:00
|
|
|
Icmp(IcmpSocket<'a>),
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2021-01-09 08:52:08 +08:00
|
|
|
Udp(UdpSocket<'a>),
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
2016-12-23 15:30:57 +08:00
|
|
|
Tcp(TcpSocket<'a>),
|
2016-12-17 13:12:45 +08:00
|
|
|
}
|
|
|
|
|
2017-01-17 07:35:21 +08:00
|
|
|
macro_rules! dispatch_socket {
|
2018-01-08 12:52:28 +08:00
|
|
|
($self_:expr, |$socket:ident| $code:expr) => {
|
|
|
|
dispatch_socket!(@inner $self_, |$socket| $code);
|
|
|
|
};
|
|
|
|
(mut $self_:expr, |$socket:ident| $code:expr) => {
|
|
|
|
dispatch_socket!(@inner mut $self_, |$socket| $code);
|
|
|
|
};
|
|
|
|
(@inner $( $mut_:ident )* $self_:expr, |$socket:ident| $code:expr) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
match $self_ {
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-06-18 18:14:20 +08:00
|
|
|
&$( $mut_ )* Socket::Raw(ref $( $mut_ )* $socket) => $code,
|
2018-05-09 21:27:51 +08:00
|
|
|
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
|
2017-10-30 08:19:34 +08:00
|
|
|
&$( $mut_ )* Socket::Icmp(ref $( $mut_ )* $socket) => $code,
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2017-01-17 07:35:21 +08:00
|
|
|
&$( $mut_ )* Socket::Udp(ref $( $mut_ )* $socket) => $code,
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
2017-01-17 07:35:21 +08:00
|
|
|
&$( $mut_ )* Socket::Tcp(ref $( $mut_ )* $socket) => $code,
|
|
|
|
}
|
2018-01-08 12:52:28 +08:00
|
|
|
};
|
2017-01-17 07:35:21 +08:00
|
|
|
}
|
|
|
|
|
2021-01-09 08:52:08 +08:00
|
|
|
impl<'a> Socket<'a> {
|
2017-10-05 11:02:41 +08:00
|
|
|
/// Return the socket handle.
|
2017-11-22 15:20:31 +08:00
|
|
|
#[inline]
|
2017-10-05 11:02:41 +08:00
|
|
|
pub fn handle(&self) -> SocketHandle {
|
2017-11-22 11:50:09 +08:00
|
|
|
self.meta().handle
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn meta(&self) -> &SocketMeta {
|
2018-01-08 12:52:28 +08:00
|
|
|
dispatch_socket!(self, |socket| &socket.meta)
|
2017-01-17 07:35:21 +08:00
|
|
|
}
|
|
|
|
|
2017-11-22 11:50:09 +08:00
|
|
|
pub(crate) fn meta_mut(&mut self) -> &mut SocketMeta {
|
2018-01-08 12:52:28 +08:00
|
|
|
dispatch_socket!(mut self, |socket| &mut socket.meta)
|
2017-01-17 07:35:21 +08:00
|
|
|
}
|
2017-08-30 03:35:09 +08:00
|
|
|
|
2018-05-17 03:11:04 +08:00
|
|
|
pub(crate) fn poll_at(&self) -> PollAt {
|
2018-01-08 12:52:28 +08:00
|
|
|
dispatch_socket!(self, |socket| socket.poll_at())
|
2017-08-30 03:35:09 +08:00
|
|
|
}
|
2016-12-26 18:06:49 +08:00
|
|
|
}
|
|
|
|
|
2021-01-09 08:52:08 +08:00
|
|
|
impl<'a> SocketSession for Socket<'a> {
|
2017-09-11 04:18:12 +08:00
|
|
|
fn finish(&mut self) {
|
2018-01-08 12:52:28 +08:00
|
|
|
dispatch_socket!(mut self, |socket| socket.finish())
|
2017-09-11 04:18:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-17 13:12:45 +08:00
|
|
|
/// A conversion trait for network sockets.
|
2021-01-09 08:52:08 +08:00
|
|
|
pub trait AnySocket<'a>: SocketSession + Sized {
|
|
|
|
fn downcast<'c>(socket_ref: SocketRef<'c, Socket<'a>>) ->
|
2017-09-11 04:18:12 +08:00
|
|
|
Option<SocketRef<'c, Self>>;
|
2017-06-18 18:14:20 +08:00
|
|
|
}
|
|
|
|
|
2017-09-11 04:18:12 +08:00
|
|
|
macro_rules! from_socket {
|
2017-07-25 01:00:00 +08:00
|
|
|
($socket:ty, $variant:ident) => {
|
2021-01-09 08:52:08 +08:00
|
|
|
impl<'a> AnySocket<'a> for $socket {
|
|
|
|
fn downcast<'c>(ref_: SocketRef<'c, Socket<'a>>) ->
|
2017-09-11 04:18:12 +08:00
|
|
|
Option<SocketRef<'c, Self>> {
|
2021-01-09 07:55:28 +08:00
|
|
|
if let Socket::$variant(ref mut socket) = SocketRef::into_inner(ref_) {
|
|
|
|
Some(SocketRef::new(socket))
|
|
|
|
} else {
|
|
|
|
None
|
2017-10-25 09:28:57 +08:00
|
|
|
}
|
2017-07-25 01:00:00 +08:00
|
|
|
}
|
2017-06-18 18:14:20 +08:00
|
|
|
}
|
|
|
|
}
|
2016-12-15 13:15:00 +08:00
|
|
|
}
|
2016-12-21 03:51:52 +08:00
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2021-01-09 08:52:08 +08:00
|
|
|
from_socket!(RawSocket<'a>, Raw);
|
2018-05-09 21:27:51 +08:00
|
|
|
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
|
2021-01-09 08:52:08 +08:00
|
|
|
from_socket!(IcmpSocket<'a>, Icmp);
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2021-01-09 08:52:08 +08:00
|
|
|
from_socket!(UdpSocket<'a>, Udp);
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
2017-09-11 04:18:12 +08:00
|
|
|
from_socket!(TcpSocket<'a>, Tcp);
|