2016-12-15 01:39:44 +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.
|
|
|
|
|
2017-09-25 08:12:58 +08:00
|
|
|
use core::marker::PhantomData;
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
|
|
|
mod raw;
|
2017-10-30 08:19:34 +08:00
|
|
|
#[cfg(feature = "socket-icmp")]
|
|
|
|
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
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-09-25 08:12:58 +08:00
|
|
|
pub use self::raw::{PacketBuffer as RawPacketBuffer,
|
|
|
|
SocketBuffer as RawSocketBuffer,
|
|
|
|
RawSocket};
|
2017-06-18 18:14:20 +08:00
|
|
|
|
2017-10-30 08:19:34 +08:00
|
|
|
#[cfg(feature = "socket-icmp")]
|
|
|
|
pub use self::icmp::{PacketBuffer as IcmpPacketBuffer,
|
|
|
|
SocketBuffer as IcmpSocketBuffer,
|
|
|
|
Endpoint as IcmpEndpoint,
|
|
|
|
IcmpSocket};
|
|
|
|
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2017-09-25 08:12:58 +08:00
|
|
|
pub use self::udp::{PacketBuffer as UdpPacketBuffer,
|
|
|
|
SocketBuffer as UdpSocketBuffer,
|
|
|
|
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;
|
|
|
|
|
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)]
|
2016-12-17 14:27:08 +08:00
|
|
|
pub enum Socket<'a, 'b: 'a> {
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-06-18 18:14:20 +08:00
|
|
|
Raw(RawSocket<'a, 'b>),
|
2017-10-30 08:19:34 +08:00
|
|
|
#[cfg(feature = "socket-icmp")]
|
|
|
|
Icmp(IcmpSocket<'a, 'b>),
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2016-12-23 15:30:57 +08:00
|
|
|
Udp(UdpSocket<'a, 'b>),
|
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
|
|
|
#[doc(hidden)]
|
2017-09-25 08:12:58 +08:00
|
|
|
__Nonexhaustive(PhantomData<(&'a (), &'b ())>)
|
2016-12-17 13:12:45 +08:00
|
|
|
}
|
|
|
|
|
2017-11-22 11:50:09 +08:00
|
|
|
/// Network socket metadata.
|
|
|
|
///
|
|
|
|
/// This includes things that only external (to the socket, that is) code
|
|
|
|
/// is interested in, but which are more conveniently stored inside the socket itself.
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub(crate) struct SocketMeta {
|
|
|
|
handle: SocketHandle,
|
|
|
|
}
|
|
|
|
|
2017-01-17 07:35:21 +08:00
|
|
|
macro_rules! dispatch_socket {
|
|
|
|
($self_:expr, |$socket:ident [$( $mut_:tt )*]| $code:expr) => ({
|
|
|
|
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,
|
2017-10-30 08:19:34 +08:00
|
|
|
#[cfg(feature = "socket-icmp")]
|
|
|
|
&$( $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,
|
2017-09-25 08:12:58 +08:00
|
|
|
&$( $mut_ )* Socket::__Nonexhaustive(_) => unreachable!()
|
2017-01-17 07:35:21 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-12-17 14:27:08 +08:00
|
|
|
impl<'a, 'b> Socket<'a, 'b> {
|
2017-10-05 11:02:41 +08:00
|
|
|
/// Return the socket handle.
|
|
|
|
pub fn handle(&self) -> SocketHandle {
|
2017-11-22 11:50:09 +08:00
|
|
|
self.meta().handle
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn meta(&self) -> &SocketMeta {
|
|
|
|
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 {
|
|
|
|
dispatch_socket!(self, |socket [mut]| &mut socket.meta)
|
2017-01-17 07:35:21 +08:00
|
|
|
}
|
2017-08-30 03:35:09 +08:00
|
|
|
|
|
|
|
pub(crate) fn poll_at(&self) -> Option<u64> {
|
|
|
|
dispatch_socket!(self, |socket []| socket.poll_at())
|
|
|
|
}
|
2016-12-26 18:06:49 +08:00
|
|
|
}
|
|
|
|
|
2017-09-11 04:18:12 +08:00
|
|
|
impl<'a, 'b> SocketSession for Socket<'a, 'b> {
|
|
|
|
fn finish(&mut self) {
|
|
|
|
dispatch_socket!(self, |socket [mut]| socket.finish())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-17 13:12:45 +08:00
|
|
|
/// A conversion trait for network sockets.
|
2017-09-11 04:18:12 +08:00
|
|
|
pub trait AnySocket<'a, 'b>: SocketSession + Sized {
|
|
|
|
fn downcast<'c>(socket_ref: SocketRef<'c, Socket<'a, 'b>>) ->
|
|
|
|
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) => {
|
2017-09-11 04:18:12 +08:00
|
|
|
impl<'a, 'b> AnySocket<'a, 'b> for $socket {
|
|
|
|
fn downcast<'c>(ref_: SocketRef<'c, Socket<'a, 'b>>) ->
|
|
|
|
Option<SocketRef<'c, Self>> {
|
2017-10-25 10:16:23 +08:00
|
|
|
match SocketRef::into_inner(ref_) {
|
|
|
|
&mut Socket::$variant(ref mut socket) => Some(SocketRef::new(socket)),
|
2017-10-25 09:28:57 +08:00
|
|
|
_ => None,
|
|
|
|
}
|
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")]
|
2017-09-11 04:18:12 +08:00
|
|
|
from_socket!(RawSocket<'a, 'b>, Raw);
|
2017-10-30 08:19:34 +08:00
|
|
|
#[cfg(feature = "socket-icmp")]
|
|
|
|
from_socket!(IcmpSocket<'a, 'b>, Icmp);
|
2017-11-06 17:51:03 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2017-09-11 04:18:12 +08:00
|
|
|
from_socket!(UdpSocket<'a, 'b>, 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);
|