1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
//! 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. use Error; use wire::IpRepr; mod udp; mod tcp; mod set; pub use self::udp::PacketBuffer as UdpPacketBuffer; pub use self::udp::SocketBuffer as UdpSocketBuffer; pub use self::udp::UdpSocket; pub use self::tcp::SocketBuffer as TcpSocketBuffer; pub use self::tcp::State as TcpState; pub use self::tcp::TcpSocket; pub use self::set::{Set as SocketSet, Handle as SocketHandle}; pub use self::set::{Iter as SocketSetIter, IterMut as SocketSetIterMut}; /// A network socket. /// /// 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<_>>()`. /// /// 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, /// the packet length is already known and no allocation is required; on the other hand, /// `process` 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. #[derive(Debug)] pub enum Socket<'a, 'b: 'a> { Udp(UdpSocket<'a, 'b>), Tcp(TcpSocket<'a>), #[doc(hidden)] __Nonexhaustive } macro_rules! dispatch_socket { ($self_:expr, |$socket:ident [$( $mut_:tt )*]| $code:expr) => ({ match $self_ { &$( $mut_ )* Socket::Udp(ref $( $mut_ )* $socket) => $code, &$( $mut_ )* Socket::Tcp(ref $( $mut_ )* $socket) => $code, &$( $mut_ )* Socket::__Nonexhaustive => unreachable!() } }) } impl<'a, 'b> Socket<'a, 'b> { /// 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)) } /// 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. pub fn process(&mut self, timestamp: u64, ip_repr: &IpRepr, payload: &[u8]) -> Result<(), Error> { dispatch_socket!(self, |socket [mut]| socket.process(timestamp, ip_repr, payload)) } /// 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. pub fn dispatch<F, R>(&mut self, timestamp: u64, mtu: usize, emit: &mut F) -> Result<R, Error> where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> { dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, mtu, emit)) } } /// An IP-encapsulated packet representation. /// /// This trait abstracts the various types of packets layered under the IP protocol, /// and serves as an accessory to [trait Socket](trait.Socket.html). pub trait IpPayload { /// Return the length of the buffer required to serialize this high-level representation. fn buffer_len(&self) -> usize; /// Emit this high-level representation into a sequence of octets. fn emit(&self, ip_repr: &IpRepr, payload: &mut [u8]); } /// 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, 'b> AsSocket<UdpSocket<'a, 'b>> for Socket<'a, 'b> { fn as_socket(&mut self) -> &mut UdpSocket<'a, 'b> { match self { &mut Socket::Udp(ref mut socket) => socket, _ => panic!(".as_socket::<UdpSocket> called on wrong socket type") } } } impl<'a, 'b> AsSocket<TcpSocket<'a>> for Socket<'a, 'b> { fn as_socket(&mut self) -> &mut TcpSocket<'a> { match self { &mut Socket::Tcp(ref mut socket) => socket, _ => panic!(".as_socket::<TcpSocket> called on wrong socket type") } } }