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.
|
|
|
|
|
2016-12-15 13:15:00 +08:00
|
|
|
use Error;
|
|
|
|
use wire::{InternetAddress as Address, InternetProtocolType as ProtocolType};
|
2016-12-15 01:39:44 +08:00
|
|
|
|
|
|
|
mod udp;
|
|
|
|
|
|
|
|
pub use self::udp::Buffer as UdpBuffer;
|
2016-12-16 01:07:56 +08:00
|
|
|
pub use self::udp::BufferElem as UdpBufferElem;
|
2016-12-15 13:15:00 +08:00
|
|
|
pub use self::udp::UdpSocket as UdpSocket;
|
|
|
|
|
|
|
|
/// A packet representation.
|
|
|
|
///
|
|
|
|
/// This interface abstracts the various types of packets layered under the IP protocol,
|
|
|
|
/// and serves as an accessory to [trait Socket](trait.Socket.html).
|
|
|
|
pub trait PacketRepr {
|
|
|
|
/// Return the length required to serialize this high-level representation.
|
|
|
|
fn len(&self) -> usize;
|
|
|
|
|
|
|
|
/// Emit this high-level representation into a sequence of octets.
|
|
|
|
fn emit(&self, src_addr: &Address, dst_addr: &Address, payload: &mut [u8]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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
|
|
|
///
|
|
|
|
/// The `collect` and `dispatch` functions are fundamentally asymmetric and thus differ in
|
|
|
|
/// their use of the [trait PacketRepr](trait.PacketRepr.html). When `collect` is called,
|
|
|
|
/// the packet length is already known and no allocation is required; on the other hand,
|
|
|
|
/// `collect` would have to downcast a `&PacketRepr` to e.g. an `&UdpRepr` through `Any`,
|
|
|
|
/// 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.
|
2016-12-17 13:12:45 +08:00
|
|
|
pub enum Socket<'a> {
|
|
|
|
Udp(UdpSocket<'a>),
|
|
|
|
#[doc(hidden)]
|
|
|
|
__Nonexhaustive
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Socket<'a> {
|
2016-12-15 13:15:00 +08:00
|
|
|
/// Process a packet received from a network interface.
|
|
|
|
///
|
|
|
|
/// This function checks if the packet contained in the payload matches the socket endpoint,
|
|
|
|
/// and if it does, copies it into the internal buffer, otherwise, `Err(Error::Rejected)`
|
|
|
|
/// is returned.
|
|
|
|
///
|
|
|
|
/// This function is used internally by the networking stack.
|
2016-12-17 13:12:45 +08:00
|
|
|
pub fn collect(&mut self, src_addr: &Address, dst_addr: &Address,
|
|
|
|
protocol: ProtocolType, payload: &[u8])
|
|
|
|
-> Result<(), Error> {
|
|
|
|
match self {
|
|
|
|
&mut Socket::Udp(ref mut socket) =>
|
|
|
|
socket.collect(src_addr, dst_addr, protocol, payload),
|
|
|
|
&mut Socket::__Nonexhaustive => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
2016-12-15 13:15:00 +08:00
|
|
|
|
|
|
|
/// Prepare a packet to be transmitted to a network interface.
|
|
|
|
///
|
|
|
|
/// This function checks if the internal buffer is empty, and if it is not, calls `f` with
|
|
|
|
/// the representation of the packet to be transmitted, otherwise, `Err(Error::Exhausted)`
|
|
|
|
/// is returned.
|
|
|
|
///
|
|
|
|
/// This function is used internally by the networking stack.
|
2016-12-17 13:12:45 +08:00
|
|
|
pub fn dispatch(&mut self, f: &mut FnMut(&Address, &Address,
|
|
|
|
ProtocolType, &PacketRepr) -> Result<(), Error>)
|
|
|
|
-> Result<(), Error> {
|
|
|
|
match self {
|
|
|
|
&mut Socket::Udp(ref mut socket) =>
|
|
|
|
socket.dispatch(f),
|
|
|
|
&mut Socket::__Nonexhaustive => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> AsSocket<UdpSocket<'a>> for Socket<'a> {
|
|
|
|
fn as_socket(&mut self) -> &mut UdpSocket<'a> {
|
|
|
|
match self {
|
|
|
|
&mut Socket::Udp(ref mut socket) => socket,
|
|
|
|
_ => panic!(".as_socket::<UdpSocket> called on wrong socket type")
|
|
|
|
}
|
|
|
|
}
|
2016-12-15 13:15:00 +08:00
|
|
|
}
|