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-26 19:20:20 +08:00
|
|
|
use wire::IpRepr;
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-raw")] mod raw;
|
|
|
|
#[cfg(feature = "socket-udp")] mod udp;
|
|
|
|
#[cfg(feature = "socket-tcp")] mod tcp;
|
2017-01-11 12:05:41 +08:00
|
|
|
mod set;
|
2016-12-15 01:39:44 +08:00
|
|
|
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
|
|
|
pub use self::raw::{PacketBuffer as RawPacketBuffer,
|
|
|
|
SocketBuffer as RawSocketBuffer,
|
|
|
|
RawSocket};
|
2017-06-18 18:14:20 +08:00
|
|
|
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
|
|
|
pub use self::udp::{PacketBuffer as UdpPacketBuffer,
|
|
|
|
SocketBuffer as UdpSocketBuffer,
|
|
|
|
UdpSocket};
|
2016-12-15 13:15:00 +08:00
|
|
|
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
|
|
|
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};
|
|
|
|
|
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.
|
|
|
|
/// To downcast a `Socket` value down to a concrete socket, use
|
|
|
|
/// the [AsSocket](trait.AsSocket.html) trait, and call e.g. `socket.as_socket::<UdpSocket<_>>()`.
|
2016-12-15 13:15:00 +08:00
|
|
|
///
|
2016-12-28 01:49:40 +08:00
|
|
|
/// The `process` and `dispatch` functions are fundamentally asymmetric and thus differ in
|
|
|
|
/// their use of the [trait PacketRepr](trait.PacketRepr.html). When `process` is called,
|
2016-12-15 13:15:00 +08:00
|
|
|
/// the packet length is already known and no allocation is required; on the other hand,
|
2016-12-28 01:49:40 +08:00
|
|
|
/// `process` would have to downcast a `&PacketRepr` to e.g. an `&UdpRepr` through `Any`,
|
2016-12-15 13:15:00 +08:00
|
|
|
/// which is rather inelegant. Conversely, when `dispatch` is called, the packet length is
|
|
|
|
/// not yet known and the packet storage has to be allocated; but the `&PacketRepr` is sufficient
|
|
|
|
/// since the lower layers treat the packet as an opaque octet sequence.
|
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-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-06-18 18:14:20 +08:00
|
|
|
Raw(RawSocket<'a, 'b>),
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2016-12-23 15:30:57 +08:00
|
|
|
Udp(UdpSocket<'a, 'b>),
|
2017-09-25 08:12:58 +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-01-17 07:35:21 +08:00
|
|
|
macro_rules! dispatch_socket {
|
|
|
|
($self_:expr, |$socket:ident [$( $mut_:tt )*]| $code:expr) => ({
|
|
|
|
match $self_ {
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-06-18 18:14:20 +08:00
|
|
|
&$( $mut_ )* Socket::Raw(ref $( $mut_ )* $socket) => $code,
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2017-01-17 07:35:21 +08:00
|
|
|
&$( $mut_ )* Socket::Udp(ref $( $mut_ )* $socket) => $code,
|
2017-09-25 08:12:58 +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-01-17 07:35:21 +08:00
|
|
|
/// Return the debug identifier.
|
|
|
|
pub fn debug_id(&self) -> usize {
|
|
|
|
dispatch_socket!(self, |socket []| socket.debug_id())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Set the debug identifier.
|
|
|
|
///
|
|
|
|
/// The debug identifier is a number printed in socket trace messages.
|
|
|
|
/// It could as well be used by the user code.
|
|
|
|
pub fn set_debug_id(&mut self, id: usize) {
|
|
|
|
dispatch_socket!(self, |socket [mut]| socket.set_debug_id(id))
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2016-12-17 13:12:45 +08:00
|
|
|
/// A conversion trait for network sockets.
|
|
|
|
///
|
|
|
|
/// This trait is used to concisely downcast [Socket](trait.Socket.html) values to their
|
|
|
|
/// concrete types.
|
|
|
|
pub trait AsSocket<T> {
|
|
|
|
fn as_socket(&mut self) -> &mut T;
|
2017-06-18 18:14:20 +08:00
|
|
|
fn try_as_socket(&mut self) -> Option<&mut T>;
|
|
|
|
}
|
|
|
|
|
2017-07-25 01:00:00 +08:00
|
|
|
macro_rules! as_socket {
|
|
|
|
($socket:ty, $variant:ident) => {
|
|
|
|
impl<'a, 'b> AsSocket<$socket> for Socket<'a, 'b> {
|
|
|
|
fn as_socket(&mut self) -> &mut $socket {
|
|
|
|
match self {
|
|
|
|
&mut Socket::$variant(ref mut socket) => socket,
|
|
|
|
_ => panic!(concat!(".as_socket::<",
|
|
|
|
stringify!($socket),
|
|
|
|
"> called on wrong socket type"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn try_as_socket(&mut self) -> Option<&mut $socket> {
|
|
|
|
match self {
|
|
|
|
&mut Socket::$variant(ref mut socket) => Some(socket),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
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-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-raw")]
|
2017-07-25 01:00:00 +08:00
|
|
|
as_socket!(RawSocket<'a, 'b>, Raw);
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-udp")]
|
2017-07-25 01:00:00 +08:00
|
|
|
as_socket!(UdpSocket<'a, 'b>, Udp);
|
2017-09-25 08:12:58 +08:00
|
|
|
#[cfg(feature = "socket-tcp")]
|
2017-07-25 01:00:00 +08:00
|
|
|
as_socket!(TcpSocket<'a>, Tcp);
|