2017-06-26 16:09:27 +08:00
|
|
|
// Heads up! Before working on this file you should read, at least, RFC 793 and
|
|
|
|
// the parts of RFC 1122 that discuss TCP.
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
use core::fmt;
|
2017-01-10 19:04:00 +08:00
|
|
|
use managed::Managed;
|
2016-12-23 15:30:57 +08:00
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
use {Error, Result};
|
2017-03-07 18:56:48 +08:00
|
|
|
use phy::DeviceLimits;
|
2016-12-26 21:54:26 +08:00
|
|
|
use wire::{IpProtocol, IpAddress, IpEndpoint};
|
2016-12-28 02:34:13 +08:00
|
|
|
use wire::{TcpSeqNumber, TcpPacket, TcpRepr, TcpControl};
|
2016-12-26 18:06:49 +08:00
|
|
|
use socket::{Socket, IpRepr, IpPayload};
|
2016-12-19 03:40:11 +08:00
|
|
|
|
|
|
|
/// A TCP stream ring buffer.
|
|
|
|
#[derive(Debug)]
|
2016-12-23 15:30:57 +08:00
|
|
|
pub struct SocketBuffer<'a> {
|
2016-12-19 03:40:11 +08:00
|
|
|
storage: Managed<'a, [u8]>,
|
|
|
|
read_at: usize,
|
|
|
|
length: usize
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
impl<'a> SocketBuffer<'a> {
|
2016-12-19 03:40:11 +08:00
|
|
|
/// Create a packet buffer with the given storage.
|
2016-12-23 15:30:57 +08:00
|
|
|
pub fn new<T>(storage: T) -> SocketBuffer<'a>
|
2016-12-19 03:40:11 +08:00
|
|
|
where T: Into<Managed<'a, [u8]>> {
|
2016-12-23 15:30:57 +08:00
|
|
|
SocketBuffer {
|
2016-12-19 03:40:11 +08:00
|
|
|
storage: storage.into(),
|
|
|
|
read_at: 0,
|
|
|
|
length: 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
fn clear(&mut self) {
|
|
|
|
self.read_at = 0;
|
|
|
|
self.length = 0;
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
fn capacity(&self) -> usize {
|
2016-12-25 17:22:49 +08:00
|
|
|
self.storage.len()
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
fn len(&self) -> usize {
|
2016-12-23 15:30:57 +08:00
|
|
|
self.length
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
fn window(&self) -> usize {
|
2016-12-25 17:22:49 +08:00
|
|
|
self.capacity() - self.len()
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
|
|
|
|
2017-01-14 14:51:29 +08:00
|
|
|
fn empty(&self) -> bool {
|
2017-01-15 19:00:04 +08:00
|
|
|
self.len() == 0
|
2017-01-14 14:51:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn full(&self) -> bool {
|
|
|
|
self.window() == 0
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
fn clamp_writer(&self, mut size: usize) -> (usize, usize) {
|
2016-12-19 03:40:11 +08:00
|
|
|
let write_at = (self.read_at + self.length) % self.storage.len();
|
|
|
|
// We can't enqueue more than there is free space.
|
|
|
|
let free = self.storage.len() - self.length;
|
|
|
|
if size > free { size = free }
|
|
|
|
// We can't contiguously enqueue past the beginning of the storage.
|
|
|
|
let until_end = self.storage.len() - write_at;
|
|
|
|
if size > until_end { size = until_end }
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
(write_at, size)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn enqueue(&mut self, size: usize) -> &mut [u8] {
|
|
|
|
let (write_at, size) = self.clamp_writer(size);
|
2016-12-19 03:40:11 +08:00
|
|
|
self.length += size;
|
|
|
|
&mut self.storage[write_at..write_at + size]
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
fn enqueue_slice(&mut self, data: &[u8]) {
|
|
|
|
let data = {
|
|
|
|
let mut dest = self.enqueue(data.len());
|
|
|
|
let (data, rest) = data.split_at(dest.len());
|
|
|
|
dest.copy_from_slice(data);
|
|
|
|
rest
|
|
|
|
};
|
|
|
|
// Retry, in case we had a wraparound.
|
|
|
|
let mut dest = self.enqueue(data.len());
|
|
|
|
let (data, _) = data.split_at(dest.len());
|
|
|
|
dest.copy_from_slice(data);
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:59:39 +08:00
|
|
|
fn clamp_reader(&self, offset: usize, mut size: usize) -> (usize, usize) {
|
|
|
|
let read_at = (self.read_at + offset) % self.storage.len();
|
2016-12-28 04:08:50 +08:00
|
|
|
// We can't read past the end of the queued data.
|
|
|
|
if offset > self.length { return (read_at, 0) }
|
2016-12-19 03:40:11 +08:00
|
|
|
// We can't dequeue more than was queued.
|
2016-12-28 04:08:50 +08:00
|
|
|
let clamped_length = self.length - offset;
|
|
|
|
if size > clamped_length { size = clamped_length }
|
2016-12-19 03:40:11 +08:00
|
|
|
// We can't contiguously dequeue past the end of the storage.
|
2016-12-25 19:09:50 +08:00
|
|
|
let until_end = self.storage.len() - read_at;
|
2016-12-19 03:40:11 +08:00
|
|
|
if size > until_end { size = until_end }
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
(read_at, size)
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:59:39 +08:00
|
|
|
fn dequeue(&mut self, size: usize) -> &[u8] {
|
|
|
|
let (read_at, size) = self.clamp_reader(0, size);
|
|
|
|
self.read_at = (self.read_at + size) % self.storage.len();
|
|
|
|
self.length -= size;
|
2016-12-25 19:09:50 +08:00
|
|
|
&self.storage[read_at..read_at + size]
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:59:39 +08:00
|
|
|
fn peek(&self, offset: usize, size: usize) -> &[u8] {
|
|
|
|
let (read_at, size) = self.clamp_reader(offset, size);
|
|
|
|
&self.storage[read_at..read_at + size]
|
2016-12-25 19:09:50 +08:00
|
|
|
}
|
|
|
|
|
2016-12-27 00:59:39 +08:00
|
|
|
fn advance(&mut self, size: usize) {
|
2016-12-28 04:08:50 +08:00
|
|
|
if size > self.length {
|
|
|
|
panic!("advancing {} octets into free space", size - self.length)
|
|
|
|
}
|
2016-12-19 03:40:11 +08:00
|
|
|
self.read_at = (self.read_at + size) % self.storage.len();
|
|
|
|
self.length -= size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
impl<'a> Into<SocketBuffer<'a>> for Managed<'a, [u8]> {
|
|
|
|
fn into(self) -> SocketBuffer<'a> {
|
|
|
|
SocketBuffer::new(self)
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-28 01:49:40 +08:00
|
|
|
/// The state of a TCP socket, according to [RFC 793][rfc793].
|
|
|
|
/// [rfc793]: https://tools.ietf.org/html/rfc793
|
2016-12-23 15:30:57 +08:00
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
|
|
pub enum State {
|
|
|
|
Closed,
|
|
|
|
Listen,
|
|
|
|
SynSent,
|
|
|
|
SynReceived,
|
|
|
|
Established,
|
|
|
|
FinWait1,
|
|
|
|
FinWait2,
|
|
|
|
CloseWait,
|
|
|
|
Closing,
|
|
|
|
LastAck,
|
|
|
|
TimeWait
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
impl fmt::Display for State {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
&State::Closed => write!(f, "CLOSED"),
|
|
|
|
&State::Listen => write!(f, "LISTEN"),
|
2016-12-28 07:28:57 +08:00
|
|
|
&State::SynSent => write!(f, "SYN-SENT"),
|
|
|
|
&State::SynReceived => write!(f, "SYN-RECEIVED"),
|
2016-12-23 15:30:57 +08:00
|
|
|
&State::Established => write!(f, "ESTABLISHED"),
|
2016-12-28 07:28:57 +08:00
|
|
|
&State::FinWait1 => write!(f, "FIN-WAIT-1"),
|
|
|
|
&State::FinWait2 => write!(f, "FIN-WAIT-2"),
|
|
|
|
&State::CloseWait => write!(f, "CLOSE-WAIT"),
|
2016-12-23 15:30:57 +08:00
|
|
|
&State::Closing => write!(f, "CLOSING"),
|
2016-12-28 07:28:57 +08:00
|
|
|
&State::LastAck => write!(f, "LAST-ACK"),
|
|
|
|
&State::TimeWait => write!(f, "TIME-WAIT")
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
}
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
2016-12-21 06:57:21 +08:00
|
|
|
|
2017-01-14 20:56:58 +08:00
|
|
|
#[derive(Debug, PartialEq)]
|
2016-12-23 15:30:57 +08:00
|
|
|
struct Retransmit {
|
2016-12-31 16:35:07 +08:00
|
|
|
resend_at: u64,
|
|
|
|
delay: u64
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
impl Retransmit {
|
|
|
|
fn new() -> Retransmit {
|
2016-12-31 16:35:07 +08:00
|
|
|
Retransmit { resend_at: 0, delay: 0 }
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
fn reset(&mut self) {
|
2016-12-31 16:35:07 +08:00
|
|
|
self.resend_at = 0;
|
|
|
|
self.delay = 0;
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
|
|
|
|
2016-12-31 16:35:07 +08:00
|
|
|
fn may_send_old(&mut self, timestamp: u64) -> bool {
|
|
|
|
if self.delay == 0 {
|
|
|
|
// We haven't transmitted anything yet.
|
|
|
|
false
|
|
|
|
} else if timestamp < self.resend_at {
|
|
|
|
// We may not retransmit yet.
|
|
|
|
false
|
|
|
|
} else {
|
|
|
|
// We may retransmit!
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn may_send_new(&mut self, timestamp: u64) -> bool {
|
|
|
|
if self.delay == 0 {
|
|
|
|
// We've something new to transmit, do it unconditionally.
|
|
|
|
self.delay = 100; // ms
|
|
|
|
self.resend_at = timestamp + self.delay;
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-23 13:09:38 +08:00
|
|
|
fn commit(&mut self, timestamp: u64) -> Option<u64> {
|
2016-12-31 16:35:07 +08:00
|
|
|
if self.delay == 0 {
|
|
|
|
self.delay = 100; // ms
|
|
|
|
self.resend_at = timestamp + self.delay;
|
2017-07-23 13:09:38 +08:00
|
|
|
None
|
2016-12-31 16:35:07 +08:00
|
|
|
} else if timestamp >= self.resend_at {
|
2017-07-23 13:09:38 +08:00
|
|
|
let actual_delay = (timestamp - self.resend_at) + self.delay;
|
2016-12-31 16:35:07 +08:00
|
|
|
self.resend_at = timestamp + self.delay;
|
|
|
|
self.delay *= 2;
|
2017-07-23 13:09:38 +08:00
|
|
|
Some(actual_delay)
|
2017-01-17 00:34:24 +08:00
|
|
|
} else {
|
2017-07-23 13:09:38 +08:00
|
|
|
None
|
2016-12-31 16:35:07 +08:00
|
|
|
}
|
2016-12-21 06:57:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-28 01:49:40 +08:00
|
|
|
/// A Transmission Control Protocol socket.
|
|
|
|
///
|
|
|
|
/// A TCP socket may passively listen for connections or actively connect to another endpoint.
|
|
|
|
/// Note that, for listening sockets, there is no "backlog"; to be able to simultaneously
|
|
|
|
/// accept several connections, as many sockets must be allocated, or any new connection
|
|
|
|
/// attempts will be reset.
|
2016-12-21 03:51:52 +08:00
|
|
|
#[derive(Debug)]
|
2016-12-23 15:30:57 +08:00
|
|
|
pub struct TcpSocket<'a> {
|
2017-07-28 06:55:30 +08:00
|
|
|
debug_id: usize,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// State of the socket.
|
2016-12-25 17:22:49 +08:00
|
|
|
state: State,
|
2016-12-28 12:56:49 +08:00
|
|
|
/// Address passed to listen(). Listen address is set when listen() is called and
|
|
|
|
/// used every time the socket is reset back to the LISTEN state.
|
2016-12-26 21:54:26 +08:00
|
|
|
listen_address: IpAddress,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// Current local endpoint. This is used for both filtering the incoming packets and
|
|
|
|
/// setting the source address. When listening or initiating connection on/from
|
|
|
|
/// an unspecified address, this field is updated with the chosen source address before
|
|
|
|
/// any packets are sent.
|
2016-12-25 17:22:49 +08:00
|
|
|
local_endpoint: IpEndpoint,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// Current remote endpoint. This is used for both filtering the incoming packets and
|
2016-12-28 12:56:49 +08:00
|
|
|
/// setting the destination address. If the remote endpoint is unspecified, it means that
|
|
|
|
/// aborting the connection will not send an RST, and, in TIME-WAIT state, will not
|
|
|
|
/// send an ACK.
|
2016-12-25 17:22:49 +08:00
|
|
|
remote_endpoint: IpEndpoint,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// The sequence number corresponding to the beginning of the transmit buffer.
|
|
|
|
/// I.e. an ACK(local_seq_no+n) packet removes n bytes from the transmit buffer.
|
2016-12-28 02:34:13 +08:00
|
|
|
local_seq_no: TcpSeqNumber,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// The sequence number corresponding to the beginning of the receive buffer.
|
|
|
|
/// I.e. userspace reading n bytes adds n to remote_seq_no.
|
2016-12-28 02:34:13 +08:00
|
|
|
remote_seq_no: TcpSeqNumber,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// The last sequence number sent.
|
|
|
|
/// I.e. in an idle socket, local_seq_no+tx_buffer.len().
|
2016-12-28 02:34:13 +08:00
|
|
|
remote_last_seq: TcpSeqNumber,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// The last acknowledgement number sent.
|
|
|
|
/// I.e. in an idle socket, remote_seq_no+rx_buffer.len().
|
2016-12-28 02:34:13 +08:00
|
|
|
remote_last_ack: TcpSeqNumber,
|
2016-12-27 00:59:39 +08:00
|
|
|
/// The speculative remote window size.
|
|
|
|
/// I.e. the actual remote window size minus the count of in-flight octets.
|
2016-12-25 19:09:50 +08:00
|
|
|
remote_win_len: usize,
|
2017-01-27 11:06:52 +08:00
|
|
|
/// The maximum number of data octets that the remote side may receive.
|
|
|
|
remote_mss: usize,
|
2017-04-22 00:01:49 +08:00
|
|
|
/// The retransmit timeout.
|
2016-12-25 17:22:49 +08:00
|
|
|
retransmit: Retransmit,
|
2017-04-22 00:01:49 +08:00
|
|
|
/// The TIME-WAIT timeout.
|
|
|
|
time_wait_since: u64,
|
2016-12-25 17:22:49 +08:00
|
|
|
rx_buffer: SocketBuffer<'a>,
|
2017-01-17 07:35:21 +08:00
|
|
|
tx_buffer: SocketBuffer<'a>,
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
const DEFAULT_MSS: usize = 536;
|
2017-04-22 00:01:49 +08:00
|
|
|
const TIME_WAIT_TIMEOUT: u64 = 10_000;
|
2017-03-05 11:52:47 +08:00
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
impl<'a> TcpSocket<'a> {
|
|
|
|
/// Create a socket using the given buffers.
|
|
|
|
pub fn new<T>(rx_buffer: T, tx_buffer: T) -> Socket<'a, 'static>
|
|
|
|
where T: Into<SocketBuffer<'a>> {
|
|
|
|
let rx_buffer = rx_buffer.into();
|
|
|
|
if rx_buffer.capacity() > <u16>::max_value() as usize {
|
|
|
|
panic!("buffers larger than {} require window scaling, which is not implemented",
|
|
|
|
<u16>::max_value())
|
|
|
|
}
|
|
|
|
|
|
|
|
Socket::Tcp(TcpSocket {
|
2017-07-28 06:55:30 +08:00
|
|
|
debug_id: 0,
|
2016-12-25 17:22:49 +08:00
|
|
|
state: State::Closed,
|
2016-12-26 21:54:26 +08:00
|
|
|
listen_address: IpAddress::default(),
|
2016-12-25 17:22:49 +08:00
|
|
|
local_endpoint: IpEndpoint::default(),
|
|
|
|
remote_endpoint: IpEndpoint::default(),
|
2016-12-28 02:34:13 +08:00
|
|
|
local_seq_no: TcpSeqNumber(0),
|
|
|
|
remote_seq_no: TcpSeqNumber(0),
|
|
|
|
remote_last_seq: TcpSeqNumber(0),
|
|
|
|
remote_last_ack: TcpSeqNumber(0),
|
2016-12-27 00:59:39 +08:00
|
|
|
remote_win_len: 0,
|
2017-03-05 11:52:47 +08:00
|
|
|
remote_mss: DEFAULT_MSS,
|
2016-12-25 17:22:49 +08:00
|
|
|
retransmit: Retransmit::new(),
|
2017-04-22 00:01:49 +08:00
|
|
|
time_wait_since: 0,
|
2016-12-25 17:22:49 +08:00
|
|
|
tx_buffer: tx_buffer.into(),
|
2017-01-17 07:35:21 +08:00
|
|
|
rx_buffer: rx_buffer.into(),
|
2016-12-23 15:30:57 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-01-17 07:35:21 +08:00
|
|
|
/// Return the debug identifier.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-17 07:35:21 +08:00
|
|
|
pub fn debug_id(&self) -> usize {
|
|
|
|
self.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) {
|
|
|
|
self.debug_id = id
|
|
|
|
}
|
|
|
|
|
2016-12-21 03:51:52 +08:00
|
|
|
/// Return the local endpoint.
|
2016-12-31 00:55:31 +08:00
|
|
|
#[inline]
|
2016-12-23 15:30:57 +08:00
|
|
|
pub fn local_endpoint(&self) -> IpEndpoint {
|
2016-12-25 17:22:49 +08:00
|
|
|
self.local_endpoint
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the remote endpoint.
|
2016-12-31 00:55:31 +08:00
|
|
|
#[inline]
|
2016-12-23 15:30:57 +08:00
|
|
|
pub fn remote_endpoint(&self) -> IpEndpoint {
|
2016-12-25 17:22:49 +08:00
|
|
|
self.remote_endpoint
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
2016-12-21 06:57:21 +08:00
|
|
|
|
2017-01-17 08:21:03 +08:00
|
|
|
/// Return the connection state, in terms of the TCP state machine.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-17 08:21:03 +08:00
|
|
|
pub fn state(&self) -> State {
|
|
|
|
self.state
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
fn reset(&mut self) {
|
2017-04-22 00:01:49 +08:00
|
|
|
self.state = State::Closed;
|
2017-03-05 11:52:47 +08:00
|
|
|
self.listen_address = IpAddress::default();
|
|
|
|
self.local_endpoint = IpEndpoint::default();
|
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
|
|
|
self.local_seq_no = TcpSeqNumber(0);
|
|
|
|
self.remote_seq_no = TcpSeqNumber(0);
|
|
|
|
self.remote_last_seq = TcpSeqNumber(0);
|
|
|
|
self.remote_last_ack = TcpSeqNumber(0);
|
|
|
|
self.remote_win_len = 0;
|
|
|
|
self.remote_mss = DEFAULT_MSS;
|
|
|
|
self.retransmit.reset();
|
|
|
|
self.tx_buffer.clear();
|
|
|
|
self.rx_buffer.clear();
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
/// Start listening on the given endpoint.
|
|
|
|
///
|
2017-07-30 09:17:48 +08:00
|
|
|
/// This function returns `Err(Error::Illegal)` if the socket was already open
|
|
|
|
/// (see [is_open](#method.is_open)), and `Err(Error::Unaddressable)`
|
|
|
|
/// if the port in the given endpoint is zero.
|
2017-07-27 21:51:02 +08:00
|
|
|
pub fn listen<T>(&mut self, local_endpoint: T) -> Result<()>
|
2017-03-05 11:52:47 +08:00
|
|
|
where T: Into<IpEndpoint> {
|
|
|
|
let local_endpoint = local_endpoint.into();
|
2017-07-27 22:53:06 +08:00
|
|
|
if local_endpoint.port == 0 { return Err(Error::Unaddressable) }
|
2017-03-05 11:52:47 +08:00
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
if self.is_open() { return Err(Error::Illegal) }
|
2016-12-23 15:59:38 +08:00
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
self.reset();
|
|
|
|
self.listen_address = local_endpoint.addr;
|
|
|
|
self.local_endpoint = local_endpoint;
|
2016-12-25 17:22:49 +08:00
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
2016-12-23 15:59:38 +08:00
|
|
|
self.set_state(State::Listen);
|
2016-12-28 01:49:40 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
/// Connect to a given endpoint.
|
|
|
|
///
|
|
|
|
/// The local port must be provided explicitly. Assuming `fn get_ephemeral_port() -> u16`
|
2017-07-24 07:07:55 +08:00
|
|
|
/// allocates a port between 49152 and 65535, a connection may be established as follows:
|
2017-03-05 11:52:47 +08:00
|
|
|
///
|
|
|
|
/// ```rust,ignore
|
|
|
|
/// socket.connect((IpAddress::v4(10, 0, 0, 1), 80), get_ephemeral_port())
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The local address may optionally be provided.
|
|
|
|
///
|
|
|
|
/// This function returns an error if the socket was open; see [is_open](#method.is_open).
|
2017-07-27 19:26:39 +08:00
|
|
|
/// It also returns an error if the local or remote port is zero, or if the remote address
|
|
|
|
/// is unspecified.
|
2017-07-27 21:51:02 +08:00
|
|
|
pub fn connect<T, U>(&mut self, remote_endpoint: T, local_endpoint: U) -> Result<()>
|
2017-03-05 11:52:47 +08:00
|
|
|
where T: Into<IpEndpoint>, U: Into<IpEndpoint> {
|
|
|
|
let remote_endpoint = remote_endpoint.into();
|
|
|
|
let local_endpoint = local_endpoint.into();
|
|
|
|
|
2017-07-27 20:27:33 +08:00
|
|
|
if self.is_open() { return Err(Error::Illegal) }
|
|
|
|
if !remote_endpoint.is_specified() { return Err(Error::Unaddressable) }
|
|
|
|
if local_endpoint.port == 0 { return Err(Error::Unaddressable) }
|
2017-07-24 07:07:55 +08:00
|
|
|
|
|
|
|
// If local address is not provided, use an unspecified address but a specified protocol.
|
|
|
|
// This lets us lower IpRepr later to determine IP header size and calculate MSS,
|
|
|
|
// but without committing to a specific address right away.
|
|
|
|
let local_addr = match remote_endpoint.addr {
|
2017-07-27 20:27:33 +08:00
|
|
|
IpAddress::Unspecified => return Err(Error::Unaddressable),
|
2017-07-27 19:26:07 +08:00
|
|
|
_ => remote_endpoint.addr.to_unspecified(),
|
2017-07-24 07:07:55 +08:00
|
|
|
};
|
|
|
|
let local_endpoint = IpEndpoint { addr: local_addr, ..local_endpoint };
|
2017-03-05 11:52:47 +08:00
|
|
|
|
|
|
|
// Carry over the local sequence number.
|
|
|
|
let local_seq_no = self.local_seq_no;
|
|
|
|
|
|
|
|
self.reset();
|
|
|
|
self.local_endpoint = local_endpoint;
|
|
|
|
self.remote_endpoint = remote_endpoint;
|
|
|
|
self.local_seq_no = local_seq_no;
|
|
|
|
self.set_state(State::SynSent);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
/// Close the transmit half of the full-duplex connection.
|
|
|
|
///
|
|
|
|
/// Note that there is no corresponding function for the receive half of the full-duplex
|
|
|
|
/// connection; only the remote end can close it. If you no longer wish to receive any
|
|
|
|
/// data and would like to reuse the socket right away, use [abort](#method.abort).
|
|
|
|
pub fn close(&mut self) {
|
|
|
|
match self.state {
|
|
|
|
// In the LISTEN state there is no established connection.
|
|
|
|
State::Listen =>
|
|
|
|
self.set_state(State::Closed),
|
2016-12-28 07:28:57 +08:00
|
|
|
// In the SYN-SENT state the remote endpoint is not yet synchronized and, upon
|
2016-12-28 06:43:16 +08:00
|
|
|
// receiving an RST, will abort the connection.
|
|
|
|
State::SynSent =>
|
|
|
|
self.set_state(State::Closed),
|
2016-12-28 07:28:57 +08:00
|
|
|
// In the SYN-RECEIVED, ESTABLISHED and CLOSE-WAIT states the transmit half
|
2016-12-28 06:43:16 +08:00
|
|
|
// of the connection is open, and needs to be explicitly closed with a FIN.
|
2016-12-28 07:27:33 +08:00
|
|
|
State::SynReceived | State::Established => {
|
|
|
|
self.retransmit.reset();
|
|
|
|
self.set_state(State::FinWait1);
|
|
|
|
}
|
|
|
|
State::CloseWait => {
|
|
|
|
self.retransmit.reset();
|
|
|
|
self.set_state(State::LastAck);
|
|
|
|
}
|
2016-12-28 07:28:57 +08:00
|
|
|
// In the FIN-WAIT-1, FIN-WAIT-2, CLOSING, LAST-ACK, TIME-WAIT and CLOSED states,
|
2016-12-28 06:43:16 +08:00
|
|
|
// the transmit half of the connection is already closed, and no further
|
|
|
|
// action is needed.
|
|
|
|
State::FinWait1 | State::FinWait2 | State::Closing |
|
|
|
|
State::TimeWait | State::LastAck | State::Closed => ()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-17 09:24:51 +08:00
|
|
|
/// Aborts the connection, if any.
|
|
|
|
///
|
|
|
|
/// This function instantly closes the socket. One reset packet will be sent to the remote
|
|
|
|
/// endpoint.
|
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket may be in any state and is moved to
|
|
|
|
/// the `CLOSED` state.
|
|
|
|
pub fn abort(&mut self) {
|
|
|
|
self.set_state(State::Closed);
|
|
|
|
}
|
|
|
|
|
2017-01-15 19:00:04 +08:00
|
|
|
/// Return whether the socket is passively listening for incoming connections.
|
2017-01-17 08:21:03 +08:00
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket must be in the `LISTEN` state.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-15 19:00:04 +08:00
|
|
|
pub fn is_listening(&self) -> bool {
|
|
|
|
match self.state {
|
|
|
|
State::Listen => true,
|
|
|
|
_ => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-28 02:54:45 +08:00
|
|
|
/// Return whether the socket is open.
|
2016-12-28 01:49:40 +08:00
|
|
|
///
|
|
|
|
/// This function returns true if the socket will process incoming or dispatch outgoing
|
|
|
|
/// packets. Note that this does not mean that it is possible to send or receive data through
|
|
|
|
/// the socket; for that, use [can_send](#method.can_send) or [can_recv](#method.can_recv).
|
2017-01-17 08:21:03 +08:00
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket must be in the `CLOSED` or `TIME-WAIT` state.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2016-12-28 01:49:40 +08:00
|
|
|
pub fn is_open(&self) -> bool {
|
|
|
|
match self.state {
|
|
|
|
State::Closed => false,
|
|
|
|
State::TimeWait => false,
|
|
|
|
_ => true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-14 17:13:25 +08:00
|
|
|
/// Return whether a connection is active.
|
2016-12-28 02:54:45 +08:00
|
|
|
///
|
|
|
|
/// This function returns true if the socket is actively exchanging packets with
|
|
|
|
/// a remote endpoint. Note that this does not mean that it is possible to send or receive
|
|
|
|
/// data through the socket; for that, use [can_send](#method.can_send) or
|
|
|
|
/// [can_recv](#method.can_recv).
|
|
|
|
///
|
|
|
|
/// If a connection is established, [abort](#method.close) will send a reset to
|
|
|
|
/// the remote endpoint.
|
2017-01-17 08:21:03 +08:00
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket must be in the `CLOSED`, `TIME-WAIT`,
|
|
|
|
/// or `LISTEN` state.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-14 17:13:25 +08:00
|
|
|
pub fn is_active(&self) -> bool {
|
2016-12-28 02:54:45 +08:00
|
|
|
match self.state {
|
|
|
|
State::Closed => false,
|
|
|
|
State::TimeWait => false,
|
|
|
|
State::Listen => false,
|
|
|
|
_ => true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-28 01:49:40 +08:00
|
|
|
/// Return whether the transmit half of the full-duplex connection is open.
|
|
|
|
///
|
|
|
|
/// This function returns true if it's possible to send data and have it arrive
|
|
|
|
/// to the remote endpoint. However, it does not make any guarantees about the state
|
|
|
|
/// of the transmit buffer, and even if it returns true, [send](#method.send) may
|
|
|
|
/// not be able to enqueue any octets.
|
2017-01-17 08:21:03 +08:00
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket must be in the `ESTABLISHED` or
|
|
|
|
/// `CLOSE-WAIT` state.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-14 14:51:29 +08:00
|
|
|
pub fn may_send(&self) -> bool {
|
2016-12-28 01:49:40 +08:00
|
|
|
match self.state {
|
|
|
|
State::Established => true,
|
2016-12-28 07:28:57 +08:00
|
|
|
// In CLOSE-WAIT, the remote endpoint has closed our receive half of the connection
|
2016-12-28 01:49:40 +08:00
|
|
|
// but we still can transmit indefinitely.
|
|
|
|
State::CloseWait => true,
|
|
|
|
_ => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return whether the receive half of the full-duplex connection is open.
|
|
|
|
///
|
|
|
|
/// This function returns true if it's possible to receive data from the remote endpoint.
|
|
|
|
/// It will return true while there is data in the receive buffer, and if there isn't,
|
|
|
|
/// as long as the remote endpoint has not closed the connection.
|
2017-01-17 08:21:03 +08:00
|
|
|
///
|
|
|
|
/// In terms of the TCP state machine, the socket must be in the `ESTABLISHED`,
|
|
|
|
/// `FIN-WAIT-1`, or `FIN-WAIT-2` state, or have data in the receive buffer instead.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-14 14:51:29 +08:00
|
|
|
pub fn may_recv(&self) -> bool {
|
2016-12-28 01:49:40 +08:00
|
|
|
match self.state {
|
|
|
|
State::Established => true,
|
2016-12-28 07:28:57 +08:00
|
|
|
// In FIN-WAIT-1/2, we have closed our transmit half of the connection but
|
2016-12-28 01:49:40 +08:00
|
|
|
// we still can receive indefinitely.
|
|
|
|
State::FinWait1 | State::FinWait2 => true,
|
2016-12-28 04:17:46 +08:00
|
|
|
// If we have something in the receive buffer, we can receive that.
|
|
|
|
_ if self.rx_buffer.len() > 0 => true,
|
2016-12-28 01:49:40 +08:00
|
|
|
_ => false
|
|
|
|
}
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
|
|
|
|
2017-01-17 08:21:03 +08:00
|
|
|
/// Check whether the transmit half of the full-duplex connection is open
|
|
|
|
/// (see [may_send](#method.may_send), and the transmit buffer is not full.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-14 14:51:29 +08:00
|
|
|
pub fn can_send(&self) -> bool {
|
2017-01-14 14:55:29 +08:00
|
|
|
if !self.may_send() { return false }
|
|
|
|
|
2017-01-14 14:51:29 +08:00
|
|
|
!self.tx_buffer.full()
|
|
|
|
}
|
|
|
|
|
2017-01-17 08:21:03 +08:00
|
|
|
/// Check whether the receive half of the full-duplex connection buffer is open
|
|
|
|
/// (see [may_recv](#method.may_recv), and the receive buffer is not empty.
|
2017-07-05 02:46:36 +08:00
|
|
|
#[inline]
|
2017-01-14 14:51:29 +08:00
|
|
|
pub fn can_recv(&self) -> bool {
|
2017-01-14 14:55:29 +08:00
|
|
|
if !self.may_recv() { return false }
|
|
|
|
|
2017-01-14 14:51:29 +08:00
|
|
|
!self.rx_buffer.empty()
|
|
|
|
}
|
|
|
|
|
2016-12-26 22:50:12 +08:00
|
|
|
/// Enqueue a sequence of octets to be sent, and return a pointer to it.
|
|
|
|
///
|
|
|
|
/// This function may return a slice smaller than the requested size in case
|
|
|
|
/// there is not enough contiguous free space in the transmit buffer, down to
|
|
|
|
/// an empty slice.
|
2016-12-28 01:49:40 +08:00
|
|
|
///
|
2017-07-27 21:51:02 +08:00
|
|
|
/// This function returns `Err(Error::Illegal) if the transmit half of
|
|
|
|
/// the connection is not open; see [may_send](#method.may_send).
|
|
|
|
pub fn send(&mut self, size: usize) -> Result<&mut [u8]> {
|
|
|
|
if !self.may_send() { return Err(Error::Illegal) }
|
2016-12-28 01:49:40 +08:00
|
|
|
|
2017-01-23 04:29:45 +08:00
|
|
|
#[cfg(any(test, feature = "verbose"))]
|
2016-12-28 04:08:50 +08:00
|
|
|
let old_length = self.tx_buffer.len();
|
2016-12-26 22:50:12 +08:00
|
|
|
let buffer = self.tx_buffer.enqueue(size);
|
|
|
|
if buffer.len() > 0 {
|
2017-01-19 20:23:32 +08:00
|
|
|
#[cfg(any(test, feature = "verbose"))]
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: tx buffer: enqueueing {} octets (now {})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-28 04:08:50 +08:00
|
|
|
buffer.len(), old_length + buffer.len());
|
2016-12-31 16:35:07 +08:00
|
|
|
self.retransmit.reset();
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
2016-12-28 01:49:40 +08:00
|
|
|
Ok(buffer)
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Enqueue a sequence of octets to be sent, and fill it from a slice.
|
|
|
|
///
|
|
|
|
/// This function returns the amount of bytes actually enqueued, which is limited
|
|
|
|
/// by the amount of free space in the transmit buffer; down to zero.
|
|
|
|
///
|
|
|
|
/// See also [send](#method.send).
|
2017-07-27 21:51:02 +08:00
|
|
|
pub fn send_slice(&mut self, data: &[u8]) -> Result<usize> {
|
2017-06-25 00:34:32 +08:00
|
|
|
let buffer = self.send(data.len())?;
|
2016-12-27 00:29:33 +08:00
|
|
|
let data = &data[..buffer.len()];
|
2016-12-26 22:50:12 +08:00
|
|
|
buffer.copy_from_slice(data);
|
2016-12-28 01:49:40 +08:00
|
|
|
Ok(buffer.len())
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Dequeue a sequence of received octets, and return a pointer to it.
|
|
|
|
///
|
|
|
|
/// This function may return a slice smaller than the requested size in case
|
|
|
|
/// there are not enough octets queued in the receive buffer, down to
|
|
|
|
/// an empty slice.
|
2017-07-27 21:51:02 +08:00
|
|
|
///
|
|
|
|
/// This function returns `Err(Error::Illegal) if the receive half of
|
|
|
|
/// the connection is not open; see [may_recv](#method.may_recv).
|
|
|
|
pub fn recv(&mut self, size: usize) -> Result<&[u8]> {
|
2017-01-27 06:04:05 +08:00
|
|
|
// We may have received some data inside the initial SYN, but until the connection
|
|
|
|
// is fully open we must not dequeue any data, as it may be overwritten by e.g.
|
|
|
|
// another (stale) SYN.
|
2017-07-27 21:51:02 +08:00
|
|
|
if !self.may_recv() { return Err(Error::Illegal) }
|
2016-12-28 01:49:40 +08:00
|
|
|
|
2017-01-23 04:29:45 +08:00
|
|
|
#[cfg(any(test, feature = "verbose"))]
|
2016-12-28 04:08:50 +08:00
|
|
|
let old_length = self.rx_buffer.len();
|
2016-12-26 22:50:12 +08:00
|
|
|
let buffer = self.rx_buffer.dequeue(size);
|
2016-12-28 02:34:13 +08:00
|
|
|
self.remote_seq_no += buffer.len();
|
2016-12-26 22:50:12 +08:00
|
|
|
if buffer.len() > 0 {
|
2017-01-19 20:23:32 +08:00
|
|
|
#[cfg(any(test, feature = "verbose"))]
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: rx buffer: dequeueing {} octets (now {})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-28 04:08:50 +08:00
|
|
|
buffer.len(), old_length - buffer.len());
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
2016-12-28 01:49:40 +08:00
|
|
|
Ok(buffer)
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Dequeue a sequence of received octets, and fill a slice from it.
|
|
|
|
///
|
|
|
|
/// This function returns the amount of bytes actually dequeued, which is limited
|
|
|
|
/// by the amount of free space in the transmit buffer; down to zero.
|
|
|
|
///
|
|
|
|
/// See also [recv](#method.recv).
|
2017-07-27 21:51:02 +08:00
|
|
|
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize> {
|
2017-06-25 00:34:32 +08:00
|
|
|
let buffer = self.recv(data.len())?;
|
2016-12-27 00:29:33 +08:00
|
|
|
let data = &mut data[..buffer.len()];
|
|
|
|
data.copy_from_slice(buffer);
|
2016-12-28 01:49:40 +08:00
|
|
|
Ok(buffer.len())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_state(&mut self, state: State) {
|
|
|
|
if self.state != state {
|
|
|
|
if self.remote_endpoint.addr.is_unspecified() {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}: state={}=>{}",
|
|
|
|
self.debug_id, self.local_endpoint,
|
|
|
|
self.state, state);
|
2016-12-28 01:49:40 +08:00
|
|
|
} else {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: state={}=>{}",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
|
|
|
self.state, state);
|
2016-12-28 01:49:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.state = state
|
2016-12-26 22:50:12 +08:00
|
|
|
}
|
|
|
|
|
2017-07-01 04:54:58 +08:00
|
|
|
pub(crate) fn process(&mut self, timestamp: u64, ip_repr: &IpRepr,
|
2017-07-27 21:51:02 +08:00
|
|
|
payload: &[u8]) -> Result<()> {
|
2017-07-01 03:17:14 +08:00
|
|
|
debug_assert!(ip_repr.protocol() == IpProtocol::Tcp);
|
2017-01-17 08:24:47 +08:00
|
|
|
|
2017-07-01 03:17:14 +08:00
|
|
|
if self.state == State::Closed { return Err(Error::Rejected) }
|
2016-12-21 03:51:52 +08:00
|
|
|
|
2017-06-25 00:34:32 +08:00
|
|
|
let packet = TcpPacket::new_checked(&payload[..ip_repr.payload_len()])?;
|
|
|
|
let repr = TcpRepr::parse(&packet, &ip_repr.src_addr(), &ip_repr.dst_addr())?;
|
2016-12-21 03:51:52 +08:00
|
|
|
|
2016-12-25 17:22:49 +08:00
|
|
|
// Reject packets with a wrong destination.
|
|
|
|
if self.local_endpoint.port != repr.dst_port { return Err(Error::Rejected) }
|
|
|
|
if !self.local_endpoint.addr.is_unspecified() &&
|
2016-12-26 19:20:20 +08:00
|
|
|
self.local_endpoint.addr != ip_repr.dst_addr() { return Err(Error::Rejected) }
|
2016-12-23 15:30:57 +08:00
|
|
|
|
2016-12-25 17:22:49 +08:00
|
|
|
// Reject packets from a source to which we aren't connected.
|
|
|
|
if self.remote_endpoint.port != 0 &&
|
|
|
|
self.remote_endpoint.port != repr.src_port { return Err(Error::Rejected) }
|
|
|
|
if !self.remote_endpoint.addr.is_unspecified() &&
|
2016-12-26 19:20:20 +08:00
|
|
|
self.remote_endpoint.addr != ip_repr.src_addr() { return Err(Error::Rejected) }
|
2016-12-23 15:30:57 +08:00
|
|
|
|
2017-01-24 05:02:28 +08:00
|
|
|
// Consider how much the sequence number space differs from the transmit buffer space.
|
|
|
|
let (sent_syn, sent_fin) = match self.state {
|
|
|
|
// In SYN-SENT or SYN-RECEIVED, we've just sent a SYN.
|
|
|
|
State::SynSent | State::SynReceived => (true, false),
|
|
|
|
// In FIN-WAIT-1, LAST-ACK, or CLOSING, we've just sent a FIN.
|
|
|
|
State::FinWait1 | State::LastAck | State::Closing => (false, true),
|
|
|
|
// In all other states we've already got acknowledgemetns for
|
|
|
|
// all of the control flags we sent.
|
|
|
|
_ => (false, false)
|
|
|
|
};
|
|
|
|
let control_len = (sent_syn as usize) + (sent_fin as usize);
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
// Reject unacceptable acknowledgements.
|
2016-12-23 15:30:57 +08:00
|
|
|
match (self.state, repr) {
|
2016-12-26 21:54:26 +08:00
|
|
|
// The initial SYN (or whatever) cannot contain an acknowledgement.
|
2017-01-17 12:43:51 +08:00
|
|
|
// It may be destined to another socket though.
|
2016-12-26 20:51:47 +08:00
|
|
|
(State::Listen, TcpRepr { ack_number: Some(_), .. }) => {
|
2017-01-17 12:43:51 +08:00
|
|
|
return Err(Error::Rejected)
|
2016-12-26 20:51:47 +08:00
|
|
|
}
|
|
|
|
(State::Listen, TcpRepr { ack_number: None, .. }) => (),
|
2016-12-28 04:08:50 +08:00
|
|
|
// An RST received in response to initial SYN is acceptable if it acknowledges
|
2016-12-26 21:10:39 +08:00
|
|
|
// the initial SYN.
|
|
|
|
(State::SynSent, TcpRepr { control: TcpControl::Rst, ack_number: None, .. }) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: unacceptable RST (expecting RST|ACK) \
|
2016-12-26 21:10:39 +08:00
|
|
|
in response to initial SYN",
|
2017-01-17 07:35:21 +08:00
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-26 21:10:39 +08:00
|
|
|
return Err(Error::Malformed)
|
|
|
|
}
|
|
|
|
(State::SynSent, TcpRepr {
|
|
|
|
control: TcpControl::Rst, ack_number: Some(ack_number), ..
|
|
|
|
}) => {
|
2017-03-05 13:31:12 +08:00
|
|
|
if ack_number != self.local_seq_no + 1 {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: unacceptable RST|ACK in response to initial SYN",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-26 21:10:39 +08:00
|
|
|
return Err(Error::Malformed)
|
|
|
|
}
|
|
|
|
}
|
2016-12-28 04:17:35 +08:00
|
|
|
// Any other RST need only have a valid sequence number.
|
|
|
|
(_, TcpRepr { control: TcpControl::Rst, .. }) => (),
|
2016-12-25 17:22:49 +08:00
|
|
|
// Every packet after the initial SYN must be an acknowledgement.
|
|
|
|
(_, TcpRepr { ack_number: None, .. }) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: expecting an ACK",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-25 17:22:49 +08:00
|
|
|
return Err(Error::Malformed)
|
|
|
|
}
|
2016-12-25 19:09:50 +08:00
|
|
|
// Every acknowledgement must be for transmitted but unacknowledged data.
|
2017-01-24 05:02:28 +08:00
|
|
|
(_, TcpRepr { ack_number: Some(ack_number), .. }) => {
|
2016-12-28 02:34:13 +08:00
|
|
|
let unacknowledged = self.tx_buffer.len() + control_len;
|
2017-06-26 16:09:27 +08:00
|
|
|
if ack_number < self.local_seq_no {
|
|
|
|
net_trace!("[{}]{}:{}: duplicate ACK ({} not in {}...{})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
|
|
|
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
|
|
|
|
// FIXME: instead of waiting for the retransmit timer to kick in,
|
|
|
|
// reset it here.
|
|
|
|
return Err(Error::Dropped)
|
|
|
|
}
|
|
|
|
if ack_number > self.local_seq_no + unacknowledged {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: unacceptable ACK ({} not in {}...{})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-25 17:22:49 +08:00
|
|
|
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
|
2017-01-17 00:58:45 +08:00
|
|
|
return Err(Error::Dropped)
|
2016-12-25 17:22:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-23 15:30:57 +08:00
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
match (self.state, repr) {
|
2016-12-28 07:28:57 +08:00
|
|
|
// In LISTEN and SYN-SENT states, we have not yet synchronized with the remote end.
|
2016-12-26 21:54:26 +08:00
|
|
|
(State::Listen, _) => (),
|
|
|
|
(State::SynSent, _) => (),
|
|
|
|
// In all other states, segments must occupy a valid portion of the receive window.
|
|
|
|
// For now, do not try to reassemble out-of-order segments.
|
2016-12-27 01:24:37 +08:00
|
|
|
(_, TcpRepr { seq_number, .. }) => {
|
2016-12-28 02:34:13 +08:00
|
|
|
let next_remote_seq = self.remote_seq_no + self.rx_buffer.len();
|
2017-06-26 16:09:27 +08:00
|
|
|
let mut send_ack_again = false;
|
2016-12-28 02:34:13 +08:00
|
|
|
if seq_number > next_remote_seq {
|
2017-06-26 16:09:27 +08:00
|
|
|
net_trace!("[{}]{}:{}: unacceptable SEQ ({} not in {}..), \
|
|
|
|
will send duplicate ACK",
|
2017-01-17 07:35:21 +08:00
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-26 21:54:26 +08:00
|
|
|
seq_number, next_remote_seq);
|
2017-06-26 16:09:27 +08:00
|
|
|
// Some segments between what we have last received and this segment
|
|
|
|
// went missing. Send a duplicate ACK; RFC 793 does not specify the behavior
|
|
|
|
// required when receiving a duplicate ACK, but in practice (see RFC 1122
|
|
|
|
// section 4.2.2.21) most congestion control algorithms implement what's called
|
|
|
|
// a "fast retransmit", where a threshold amount of duplicate ACKs triggers
|
|
|
|
// retransmission.
|
|
|
|
send_ack_again = true;
|
2016-12-28 02:34:13 +08:00
|
|
|
} else if seq_number != next_remote_seq {
|
2017-06-26 16:09:27 +08:00
|
|
|
net_trace!("[{}]{}:{}: duplicate SEQ ({} in ..{}), \
|
|
|
|
will re-send ACK",
|
2017-01-17 07:35:21 +08:00
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-26 21:54:26 +08:00
|
|
|
seq_number, next_remote_seq);
|
2016-12-31 09:24:55 +08:00
|
|
|
// If we've seen this sequence number already but the remote end is not aware
|
|
|
|
// of that, make sure we send the acknowledgement again.
|
2017-06-26 16:09:27 +08:00
|
|
|
send_ack_again = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if send_ack_again {
|
2016-12-31 09:24:55 +08:00
|
|
|
self.remote_last_ack = next_remote_seq - 1;
|
2016-12-31 16:35:07 +08:00
|
|
|
self.retransmit.reset();
|
2017-06-26 16:09:27 +08:00
|
|
|
// If we're in the TIME-WAIT state, restart the TIME-WAIT timeout, since
|
|
|
|
// the remote end may not realize we've closed the connection.
|
2017-04-22 00:01:49 +08:00
|
|
|
if self.state == State::TimeWait {
|
|
|
|
self.time_wait_since = timestamp;
|
|
|
|
}
|
2017-01-17 00:58:45 +08:00
|
|
|
return Err(Error::Dropped)
|
2016-12-26 21:54:26 +08:00
|
|
|
}
|
2016-12-25 19:09:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-07 18:17:30 +08:00
|
|
|
// Compute the amount of acknowledged octets, removing the SYN and FIN bits
|
|
|
|
// from the sequence space.
|
|
|
|
let mut ack_len = 0;
|
|
|
|
let mut ack_of_fin = false;
|
|
|
|
if repr.control != TcpControl::Rst {
|
|
|
|
if let Some(ack_number) = repr.ack_number {
|
|
|
|
ack_len = ack_number - self.local_seq_no;
|
|
|
|
// There could have been no data sent before the SYN, so we always remove it
|
|
|
|
// from the sequence space.
|
|
|
|
if sent_syn {
|
|
|
|
ack_len -= 1
|
|
|
|
}
|
|
|
|
// We could've sent data before the FIN, so only remove FIN from the sequence
|
|
|
|
// space if all of that data is acknowledged.
|
|
|
|
if sent_fin && self.tx_buffer.len() + 1 == ack_len {
|
|
|
|
ack_len -= 1;
|
|
|
|
net_trace!("[{}]{}:{}: received ACK of FIN",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
|
|
|
ack_of_fin = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
// Validate and update the state.
|
2016-12-25 17:22:49 +08:00
|
|
|
match (self.state, repr) {
|
2016-12-26 21:54:26 +08:00
|
|
|
// RSTs are ignored in the LISTEN state.
|
|
|
|
(State::Listen, TcpRepr { control: TcpControl::Rst, .. }) =>
|
2017-01-17 12:33:37 +08:00
|
|
|
return Err(Error::Rejected),
|
2016-12-26 21:54:26 +08:00
|
|
|
|
2016-12-28 07:28:57 +08:00
|
|
|
// RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
|
2016-12-26 21:54:26 +08:00
|
|
|
(State::SynReceived, TcpRepr { control: TcpControl::Rst, .. }) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: received RST",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-26 21:54:26 +08:00
|
|
|
self.local_endpoint.addr = self.listen_address;
|
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
|
|
|
self.set_state(State::Listen);
|
|
|
|
return Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
// RSTs in any other state close the socket.
|
|
|
|
(_, TcpRepr { control: TcpControl::Rst, .. }) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: received RST",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2017-01-17 00:34:24 +08:00
|
|
|
self.set_state(State::Closed);
|
2016-12-26 21:54:26 +08:00
|
|
|
self.local_endpoint = IpEndpoint::default();
|
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
|
|
|
return Ok(())
|
|
|
|
}
|
|
|
|
|
2016-12-28 07:28:57 +08:00
|
|
|
// SYN packets in the LISTEN state change it to SYN-RECEIVED.
|
2016-12-23 15:30:57 +08:00
|
|
|
(State::Listen, TcpRepr {
|
2017-01-27 11:06:52 +08:00
|
|
|
src_port, dst_port, control: TcpControl::Syn, seq_number, ack_number: None,
|
|
|
|
max_seg_size, ..
|
2016-12-23 15:30:57 +08:00
|
|
|
}) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}: received SYN",
|
|
|
|
self.debug_id, self.local_endpoint);
|
2016-12-26 19:20:20 +08:00
|
|
|
self.local_endpoint = IpEndpoint::new(ip_repr.dst_addr(), dst_port);
|
|
|
|
self.remote_endpoint = IpEndpoint::new(ip_repr.src_addr(), src_port);
|
2016-12-28 02:34:13 +08:00
|
|
|
// FIXME: use something more secure here
|
|
|
|
self.local_seq_no = TcpSeqNumber(-seq_number.0);
|
2016-12-27 22:04:30 +08:00
|
|
|
self.remote_last_seq = self.local_seq_no + 1;
|
2016-12-25 19:09:50 +08:00
|
|
|
self.remote_seq_no = seq_number + 1;
|
2017-01-27 11:06:52 +08:00
|
|
|
if let Some(max_seg_size) = max_seg_size {
|
|
|
|
self.remote_mss = max_seg_size as usize
|
|
|
|
}
|
2016-12-23 15:59:38 +08:00
|
|
|
self.set_state(State::SynReceived);
|
2016-12-28 12:02:43 +08:00
|
|
|
self.retransmit.reset();
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 07:28:57 +08:00
|
|
|
// ACK packets in the SYN-RECEIVED state change it to ESTABLISHED.
|
2016-12-25 19:09:50 +08:00
|
|
|
(State::SynReceived, TcpRepr { control: TcpControl::None, .. }) => {
|
2016-12-23 16:05:50 +08:00
|
|
|
self.set_state(State::Established);
|
2016-12-28 12:02:43 +08:00
|
|
|
self.retransmit.reset();
|
2016-12-25 19:09:50 +08:00
|
|
|
}
|
2016-12-23 16:05:50 +08:00
|
|
|
|
2017-07-24 07:51:56 +08:00
|
|
|
// FIN packets in the SYN-RECEIVED state change it to CLOSE-WAIT.
|
|
|
|
// It's not obvious from RFC 793 that this is permitted, but
|
|
|
|
// 7th and 8th steps in the "SEGMENT ARRIVES" event describe this behavior.
|
|
|
|
(State::SynReceived, TcpRepr { control: TcpControl::Fin, .. }) => {
|
|
|
|
self.remote_seq_no += 1;
|
|
|
|
self.set_state(State::CloseWait);
|
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
// SYN|ACK packets in the SYN-SENT state change it to ESTABLISHED.
|
|
|
|
(State::SynSent, TcpRepr {
|
|
|
|
control: TcpControl::Syn, seq_number, ack_number: Some(_),
|
|
|
|
max_seg_size, ..
|
|
|
|
}) => {
|
|
|
|
net_trace!("[{}]{}:{}: received SYN|ACK",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2017-07-24 07:07:55 +08:00
|
|
|
self.local_endpoint = IpEndpoint::new(ip_repr.dst_addr(), repr.dst_port);
|
2017-03-05 11:52:47 +08:00
|
|
|
self.remote_last_seq = self.local_seq_no + 1;
|
|
|
|
self.remote_seq_no = seq_number + 1;
|
|
|
|
self.remote_last_ack = seq_number;
|
|
|
|
if let Some(max_seg_size) = max_seg_size {
|
|
|
|
self.remote_mss = max_seg_size as usize;
|
|
|
|
}
|
|
|
|
self.set_state(State::Established);
|
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
|
|
|
|
2017-01-25 13:42:02 +08:00
|
|
|
// ACK packets in ESTABLISHED state reset the retransmit timer.
|
|
|
|
(State::Established, TcpRepr { control: TcpControl::None, .. }) => {
|
|
|
|
self.retransmit.reset()
|
|
|
|
},
|
2016-12-25 19:09:50 +08:00
|
|
|
|
2016-12-27 21:34:48 +08:00
|
|
|
// FIN packets in ESTABLISHED state indicate the remote side has closed.
|
|
|
|
(State::Established, TcpRepr { control: TcpControl::Fin, .. }) => {
|
2016-12-27 22:04:30 +08:00
|
|
|
self.remote_seq_no += 1;
|
2016-12-27 21:34:48 +08:00
|
|
|
self.set_state(State::CloseWait);
|
2016-12-28 12:02:43 +08:00
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
|
|
|
|
2017-01-25 13:36:42 +08:00
|
|
|
// ACK packets in FIN-WAIT-1 state change it to FIN-WAIT-2, if we've already
|
2017-03-07 18:17:30 +08:00
|
|
|
// sent everything in the transmit buffer. If not, they reset the retransmit timer.
|
2016-12-28 12:02:43 +08:00
|
|
|
(State::FinWait1, TcpRepr { control: TcpControl::None, .. }) => {
|
2017-03-07 18:17:30 +08:00
|
|
|
if ack_of_fin {
|
2017-01-25 13:36:42 +08:00
|
|
|
self.set_state(State::FinWait2);
|
2017-01-25 14:01:58 +08:00
|
|
|
} else {
|
|
|
|
self.retransmit.reset();
|
2017-01-25 13:36:42 +08:00
|
|
|
}
|
2016-12-28 12:02:43 +08:00
|
|
|
}
|
|
|
|
|
2017-04-22 00:01:49 +08:00
|
|
|
// FIN packets in FIN-WAIT-1 state change it to CLOSING, or to TIME-WAIT
|
|
|
|
// if they also acknowledge our FIN.
|
2016-12-28 12:10:17 +08:00
|
|
|
(State::FinWait1, TcpRepr { control: TcpControl::Fin, .. }) => {
|
2016-12-28 12:02:43 +08:00
|
|
|
self.remote_seq_no += 1;
|
2017-03-07 18:17:30 +08:00
|
|
|
if ack_of_fin {
|
2017-04-22 00:01:49 +08:00
|
|
|
self.time_wait_since = timestamp;
|
2017-03-07 18:17:30 +08:00
|
|
|
self.set_state(State::TimeWait);
|
|
|
|
} else {
|
|
|
|
self.set_state(State::Closing);
|
|
|
|
}
|
2016-12-28 12:02:43 +08:00
|
|
|
self.retransmit.reset();
|
2016-12-27 21:34:48 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 12:10:17 +08:00
|
|
|
// FIN packets in FIN-WAIT-2 state change it to TIME-WAIT.
|
|
|
|
(State::FinWait2, TcpRepr { control: TcpControl::Fin, .. }) => {
|
|
|
|
self.remote_seq_no += 1;
|
2017-04-22 00:01:49 +08:00
|
|
|
self.time_wait_since = timestamp;
|
2016-12-28 12:10:17 +08:00
|
|
|
self.set_state(State::TimeWait);
|
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:56:49 +08:00
|
|
|
// ACK packets in CLOSING state change it to TIME-WAIT.
|
|
|
|
(State::Closing, TcpRepr { control: TcpControl::None, .. }) => {
|
2017-03-07 18:17:30 +08:00
|
|
|
if ack_of_fin {
|
2017-04-22 00:01:49 +08:00
|
|
|
self.time_wait_since = timestamp;
|
2017-03-07 18:17:30 +08:00
|
|
|
self.set_state(State::TimeWait);
|
|
|
|
} else {
|
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
2016-12-28 12:56:49 +08:00
|
|
|
}
|
|
|
|
|
2017-01-25 13:42:02 +08:00
|
|
|
// ACK packets in CLOSE-WAIT state reset the retransmit timer.
|
|
|
|
(State::CloseWait, TcpRepr { control: TcpControl::None, .. }) => {
|
|
|
|
self.retransmit.reset();
|
|
|
|
}
|
2016-12-27 22:13:42 +08:00
|
|
|
|
2016-12-28 07:28:57 +08:00
|
|
|
// ACK packets in LAST-ACK state change it to CLOSED.
|
2016-12-28 07:27:33 +08:00
|
|
|
(State::LastAck, TcpRepr { control: TcpControl::None, .. }) => {
|
|
|
|
// Clear the remote endpoint, or we'll send an RST there.
|
2017-01-17 00:34:24 +08:00
|
|
|
self.set_state(State::Closed);
|
2016-12-28 07:27:33 +08:00
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
_ => {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: unexpected packet {}",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint, repr);
|
2016-12-25 19:09:50 +08:00
|
|
|
return Err(Error::Malformed)
|
2016-12-23 16:05:50 +08:00
|
|
|
}
|
2016-12-25 19:09:50 +08:00
|
|
|
}
|
2016-12-23 16:05:50 +08:00
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
// Dequeue acknowledged octets.
|
2017-03-07 18:17:30 +08:00
|
|
|
if ack_len > 0 {
|
|
|
|
net_trace!("[{}]{}:{}: tx buffer: dequeueing {} octets (now {})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
|
|
|
ack_len, self.tx_buffer.len() - ack_len);
|
2017-01-24 05:02:28 +08:00
|
|
|
self.tx_buffer.advance(ack_len);
|
2017-03-07 18:17:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// We've processed everything in the incoming segment, so advance the local
|
|
|
|
// sequence number past it.
|
|
|
|
if let Some(ack_number) = repr.ack_number {
|
2016-12-25 19:09:50 +08:00
|
|
|
self.local_seq_no = ack_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enqueue payload octets, which is guaranteed to be in order, unless we already did.
|
|
|
|
if repr.payload.len() > 0 {
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: rx buffer: enqueueing {} octets (now {})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2016-12-28 04:08:50 +08:00
|
|
|
repr.payload.len(), self.rx_buffer.len() + repr.payload.len());
|
2016-12-25 19:09:50 +08:00
|
|
|
self.rx_buffer.enqueue_slice(repr.payload)
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
2016-12-25 19:09:50 +08:00
|
|
|
|
|
|
|
// Update window length.
|
|
|
|
self.remote_win_len = repr.window_len as usize;
|
|
|
|
|
|
|
|
Ok(())
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
2016-12-21 03:51:52 +08:00
|
|
|
|
2017-07-01 04:54:58 +08:00
|
|
|
pub(crate) fn dispatch<F, R>(&mut self, timestamp: u64, limits: &DeviceLimits,
|
2017-07-27 21:51:02 +08:00
|
|
|
emit: &mut F) -> Result<R>
|
|
|
|
where F: FnMut(&IpRepr, &IpPayload) -> Result<R> {
|
2017-07-27 20:27:33 +08:00
|
|
|
if !self.remote_endpoint.is_specified() { return Err(Error::Exhausted) }
|
2016-12-28 12:56:49 +08:00
|
|
|
|
2016-12-23 15:30:57 +08:00
|
|
|
let mut repr = TcpRepr {
|
2017-01-27 09:09:34 +08:00
|
|
|
src_port: self.local_endpoint.port,
|
|
|
|
dst_port: self.remote_endpoint.port,
|
|
|
|
control: TcpControl::None,
|
2017-06-25 16:20:25 +08:00
|
|
|
push: false,
|
2017-01-27 09:09:34 +08:00
|
|
|
seq_number: self.local_seq_no,
|
|
|
|
ack_number: None,
|
|
|
|
window_len: self.rx_buffer.window() as u16,
|
|
|
|
max_seg_size: None,
|
|
|
|
payload: &[]
|
2016-12-23 15:30:57 +08:00
|
|
|
};
|
|
|
|
|
2017-01-17 09:24:51 +08:00
|
|
|
if self.state == State::Closed {
|
|
|
|
// If we have a specified local and remote endpoint, but are in the CLOSED state,
|
|
|
|
// we've ended up here after aborting a connection. Send exactly one RST packet.
|
|
|
|
net_trace!("[{}]{}:{}: sending RST",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
|
|
|
|
|
|
|
repr.control = TcpControl::Rst;
|
|
|
|
repr.ack_number = Some(self.remote_seq_no);
|
|
|
|
let ip_repr = IpRepr::Unspecified {
|
|
|
|
src_addr: self.local_endpoint.addr,
|
|
|
|
dst_addr: self.remote_endpoint.addr,
|
|
|
|
protocol: IpProtocol::Tcp,
|
|
|
|
payload_len: repr.buffer_len()
|
|
|
|
};
|
|
|
|
let result = emit(&ip_repr, &repr);
|
|
|
|
|
|
|
|
self.local_endpoint = IpEndpoint::default();
|
|
|
|
self.remote_endpoint = IpEndpoint::default();
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2017-04-22 00:01:49 +08:00
|
|
|
if self.state == State::TimeWait {
|
|
|
|
if timestamp >= self.time_wait_since + TIME_WAIT_TIMEOUT {
|
|
|
|
net_trace!("[{}]{}:{}: TIME-WAIT timeout",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
|
|
|
self.reset();
|
|
|
|
return Err(Error::Exhausted)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-31 16:35:07 +08:00
|
|
|
if self.retransmit.may_send_old(timestamp) {
|
2017-01-14 19:22:19 +08:00
|
|
|
// The retransmit timer has expired, so assume all in-flight data that
|
|
|
|
// has not been acknowledged is lost.
|
|
|
|
match self.state {
|
|
|
|
// Retransmission of SYN is handled elsewhere.
|
|
|
|
State::SynReceived => (),
|
|
|
|
_ => self.remote_last_seq = self.local_seq_no
|
|
|
|
}
|
2016-12-31 16:35:07 +08:00
|
|
|
} else if self.retransmit.may_send_new(timestamp) {
|
2017-06-25 16:05:37 +08:00
|
|
|
// The retransmit timer has been reset, and we can send something new.
|
2016-12-31 16:35:07 +08:00
|
|
|
} else {
|
|
|
|
// We don't have anything to send at this time.
|
|
|
|
return Err(Error::Exhausted)
|
|
|
|
}
|
|
|
|
|
2016-12-27 22:04:30 +08:00
|
|
|
let mut should_send = false;
|
2016-12-23 15:30:57 +08:00
|
|
|
match self.state {
|
2016-12-28 13:33:12 +08:00
|
|
|
// We never transmit anything in the CLOSED, LISTEN, or FIN-WAIT-2 states.
|
|
|
|
State::Closed | State::Listen | State::FinWait2 => {
|
2016-12-28 07:27:33 +08:00
|
|
|
return Err(Error::Exhausted)
|
|
|
|
}
|
2016-12-23 16:05:50 +08:00
|
|
|
|
2016-12-28 07:28:57 +08:00
|
|
|
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
|
|
|
// We transmit a SYN in the SYN-SENT state.
|
2017-01-27 10:49:06 +08:00
|
|
|
State::SynReceived | State::SynSent => {
|
2016-12-28 07:27:33 +08:00
|
|
|
repr.control = TcpControl::Syn;
|
2017-01-27 10:49:06 +08:00
|
|
|
net_trace!("[{}]{}:{}: sending SYN{}",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2017-03-05 11:16:15 +08:00
|
|
|
if self.state == State::SynReceived { "|ACK" } else { "" });
|
2016-12-28 07:27:33 +08:00
|
|
|
should_send = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We transmit data in the ESTABLISHED state,
|
2016-12-28 13:33:12 +08:00
|
|
|
// ACK in CLOSE-WAIT, CLOSING, and TIME-WAIT states,
|
2016-12-31 16:35:07 +08:00
|
|
|
// FIN in FIN-WAIT-1 and LAST-ACK states,
|
|
|
|
// but only if the receiver has a nonzero window.
|
2016-12-27 21:34:48 +08:00
|
|
|
State::Established |
|
2016-12-28 13:33:12 +08:00
|
|
|
State::CloseWait | State::Closing | State::TimeWait |
|
2016-12-31 16:35:07 +08:00
|
|
|
State::FinWait1 | State::LastAck
|
|
|
|
if self.remote_win_len > 0 => {
|
|
|
|
// We can send something, so let's try doing that.
|
|
|
|
let mut size = self.tx_buffer.len();
|
|
|
|
// Clamp to remote window length.
|
|
|
|
if size > self.remote_win_len { size = self.remote_win_len }
|
2017-01-27 11:06:52 +08:00
|
|
|
// Clamp to MSS.
|
|
|
|
if size > self.remote_mss { size = self.remote_mss }
|
2016-12-31 16:35:07 +08:00
|
|
|
// Extract data from the buffer. This may return less than what we want,
|
|
|
|
// in case it's not possible to extract a contiguous slice.
|
|
|
|
let offset = self.remote_last_seq - self.local_seq_no;
|
|
|
|
let data = self.tx_buffer.peek(offset, size);
|
2017-01-14 14:55:29 +08:00
|
|
|
if data.len() > 0 {
|
|
|
|
// Send the extracted data.
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: tx buffer: peeking at {} octets (from {})",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2017-01-14 14:55:29 +08:00
|
|
|
data.len(), offset);
|
|
|
|
repr.seq_number += offset;
|
|
|
|
repr.payload = data;
|
2017-06-26 07:12:25 +08:00
|
|
|
// If that was the last data we had buffered, set the PSH flag.
|
|
|
|
if offset + data.len() == self.tx_buffer.len() {
|
|
|
|
repr.push = true;
|
|
|
|
}
|
2017-01-14 14:55:29 +08:00
|
|
|
// Speculatively shrink the remote window. This will get updated
|
|
|
|
// the next time we receive a packet.
|
|
|
|
self.remote_win_len -= data.len();
|
|
|
|
// Advance the in-flight sequence number.
|
|
|
|
self.remote_last_seq += data.len();
|
|
|
|
should_send = true;
|
|
|
|
}
|
2017-01-23 20:07:07 +08:00
|
|
|
// The FIN control flag occupies the place in the sequence space after
|
|
|
|
// the data in the current segment. If we still have some data left for the next
|
|
|
|
// segment (e.g. the receiver window is too small), then don't send FIN just yet.
|
2017-01-25 14:20:57 +08:00
|
|
|
let all_data_sent = self.tx_buffer.len() == offset + data.len();
|
2016-12-28 07:27:33 +08:00
|
|
|
match self.state {
|
2017-01-23 20:07:07 +08:00
|
|
|
State::FinWait1 | State::LastAck if all_data_sent => {
|
2016-12-28 07:27:33 +08:00
|
|
|
// We should notify the other side that we've closed the transmit half
|
|
|
|
// of the connection.
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: sending FIN|ACK",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-28 07:27:33 +08:00
|
|
|
repr.control = TcpControl::Fin;
|
2017-03-07 18:17:30 +08:00
|
|
|
self.remote_last_seq += 1;
|
2016-12-28 07:27:33 +08:00
|
|
|
should_send = true;
|
2016-12-31 16:35:07 +08:00
|
|
|
}
|
2016-12-28 07:27:33 +08:00
|
|
|
_ => ()
|
|
|
|
}
|
|
|
|
}
|
2016-12-31 16:35:07 +08:00
|
|
|
|
|
|
|
// We don't transmit anything (except ACKs) if the receiver has a zero window.
|
|
|
|
State::Established |
|
|
|
|
State::CloseWait | State::Closing | State::TimeWait |
|
|
|
|
State::FinWait1 | State::LastAck => ()
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
2016-12-23 15:30:57 +08:00
|
|
|
|
2016-12-28 02:34:13 +08:00
|
|
|
let ack_number = self.remote_seq_no + self.rx_buffer.len();
|
2016-12-27 22:04:30 +08:00
|
|
|
if !should_send && self.remote_last_ack != ack_number {
|
2016-12-26 22:24:17 +08:00
|
|
|
// Acknowledge all data we have received, since it is all in order.
|
2017-01-17 07:35:21 +08:00
|
|
|
net_trace!("[{}]{}:{}: sending ACK",
|
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
2016-12-27 22:04:30 +08:00
|
|
|
should_send = true;
|
2016-12-26 22:24:17 +08:00
|
|
|
}
|
|
|
|
|
2016-12-27 22:04:30 +08:00
|
|
|
if should_send {
|
2017-07-23 13:09:38 +08:00
|
|
|
if let Some(actual_delay) = self.retransmit.commit(timestamp) {
|
|
|
|
net_trace!("[{}]{}:{}: retransmitting at t+{}ms ",
|
2017-01-17 07:35:21 +08:00
|
|
|
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
2017-07-23 13:09:38 +08:00
|
|
|
actual_delay);
|
2017-01-17 00:34:24 +08:00
|
|
|
}
|
2016-12-31 16:35:07 +08:00
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
if self.state != State::SynSent {
|
|
|
|
repr.ack_number = Some(ack_number);
|
|
|
|
self.remote_last_ack = ack_number;
|
|
|
|
}
|
2016-12-27 22:04:30 +08:00
|
|
|
|
2017-01-31 19:39:33 +08:00
|
|
|
// Remember the header length before enabling the MSS option, since that option
|
|
|
|
// only affects SYN packets.
|
|
|
|
let header_len = repr.header_len();
|
|
|
|
|
2017-01-27 11:35:22 +08:00
|
|
|
if repr.control == TcpControl::Syn {
|
|
|
|
// First enable the option, without assigning any value, to get a correct
|
2017-06-25 16:05:37 +08:00
|
|
|
// result for the payload_len field of ip_repr below.
|
2017-01-27 11:35:22 +08:00
|
|
|
repr.max_seg_size = Some(0);
|
|
|
|
}
|
|
|
|
|
2017-01-14 19:07:06 +08:00
|
|
|
let ip_repr = IpRepr::Unspecified {
|
2017-01-27 10:49:06 +08:00
|
|
|
src_addr: self.local_endpoint.addr,
|
|
|
|
dst_addr: self.remote_endpoint.addr,
|
|
|
|
protocol: IpProtocol::Tcp,
|
|
|
|
payload_len: repr.buffer_len()
|
2017-01-14 19:07:06 +08:00
|
|
|
};
|
2017-06-25 00:34:32 +08:00
|
|
|
let ip_repr = ip_repr.lower(&[])?;
|
2017-01-27 10:49:06 +08:00
|
|
|
|
2017-03-07 19:21:49 +08:00
|
|
|
let mut max_segment_size = limits.max_transmission_unit;
|
|
|
|
max_segment_size -= header_len;
|
|
|
|
max_segment_size -= ip_repr.buffer_len();
|
|
|
|
|
2017-01-27 10:49:06 +08:00
|
|
|
if repr.control == TcpControl::Syn {
|
2017-03-07 18:56:48 +08:00
|
|
|
repr.max_seg_size = Some(max_segment_size as u16);
|
2017-01-27 10:49:06 +08:00
|
|
|
}
|
|
|
|
|
2017-03-07 19:21:49 +08:00
|
|
|
if let Some(max_burst_size) = limits.max_burst_size {
|
|
|
|
let max_window_size = max_burst_size * max_segment_size;
|
|
|
|
if repr.window_len as usize > max_window_size {
|
|
|
|
repr.window_len = max_window_size as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-27 22:04:30 +08:00
|
|
|
emit(&ip_repr, &repr)
|
|
|
|
} else {
|
|
|
|
Err(Error::Exhausted)
|
|
|
|
}
|
2016-12-23 15:30:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-30 14:59:01 +08:00
|
|
|
impl<'a> fmt::Write for TcpSocket<'a> {
|
|
|
|
fn write_str(&mut self, slice: &str) -> fmt::Result {
|
|
|
|
let slice = slice.as_bytes();
|
|
|
|
if self.send_slice(slice) == Ok(slice.len()) {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(fmt::Error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-26 18:06:49 +08:00
|
|
|
impl<'a> IpPayload for TcpRepr<'a> {
|
2016-12-23 15:30:57 +08:00
|
|
|
fn buffer_len(&self) -> usize {
|
|
|
|
self.buffer_len()
|
|
|
|
}
|
|
|
|
|
2016-12-26 19:20:20 +08:00
|
|
|
fn emit(&self, ip_repr: &IpRepr, payload: &mut [u8]) {
|
Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.
This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
* `fn check_len(&self) -> Result<(), Error>`, purely a validator;
* `fn new(T) -> Self`, purely a wrapper;
* `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.
This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).
Fixes #17.
2017-06-24 17:15:22 +08:00
|
|
|
let mut packet = TcpPacket::new(payload);
|
2016-12-26 19:20:20 +08:00
|
|
|
self.emit(&mut packet, &ip_repr.src_addr(), &ip_repr.dst_addr())
|
2016-12-21 03:51:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-19 03:40:11 +08:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2016-12-28 08:08:01 +08:00
|
|
|
use wire::{IpAddress, Ipv4Address};
|
2016-12-19 03:40:11 +08:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_buffer() {
|
2016-12-23 15:30:57 +08:00
|
|
|
let mut buffer = SocketBuffer::new(vec![0; 8]); // ........
|
2016-12-19 03:40:11 +08:00
|
|
|
buffer.enqueue(6).copy_from_slice(b"foobar"); // foobar..
|
|
|
|
assert_eq!(buffer.dequeue(3), b"foo"); // ...bar..
|
|
|
|
buffer.enqueue(6).copy_from_slice(b"ba"); // ...barba
|
|
|
|
buffer.enqueue(4).copy_from_slice(b"zho"); // zhobarba
|
|
|
|
assert_eq!(buffer.dequeue(6), b"barba"); // zho.....
|
|
|
|
assert_eq!(buffer.dequeue(8), b"zho"); // ........
|
|
|
|
buffer.enqueue(8).copy_from_slice(b"gefug"); // ...gefug
|
|
|
|
}
|
2016-12-25 05:52:23 +08:00
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
#[test]
|
|
|
|
fn test_buffer_wraparound() {
|
|
|
|
let mut buffer = SocketBuffer::new(vec![0; 8]); // ........
|
|
|
|
buffer.enqueue_slice(&b"foobar"[..]); // foobar..
|
|
|
|
assert_eq!(buffer.dequeue(3), b"foo"); // ...bar..
|
|
|
|
buffer.enqueue_slice(&b"bazhoge"[..]); // zhobarba
|
|
|
|
}
|
|
|
|
|
2016-12-28 04:08:50 +08:00
|
|
|
#[test]
|
|
|
|
fn test_buffer_peek() {
|
|
|
|
let mut buffer = SocketBuffer::new(vec![0; 8]); // ........
|
|
|
|
buffer.enqueue_slice(&b"foobar"[..]); // foobar..
|
|
|
|
assert_eq!(buffer.peek(0, 8), &b"foobar"[..]);
|
|
|
|
assert_eq!(buffer.peek(3, 8), &b"bar"[..]);
|
|
|
|
}
|
|
|
|
|
2016-12-31 16:35:07 +08:00
|
|
|
#[test]
|
|
|
|
fn test_retransmit_may_send() {
|
|
|
|
fn may_send(r: &mut Retransmit, t: u64) -> (bool, bool) {
|
|
|
|
(r.may_send_old(t), r.may_send_new(t))
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut r = Retransmit::new();
|
|
|
|
assert_eq!(may_send(&mut r, 1000), (false, true));
|
|
|
|
r.commit(1000);
|
|
|
|
assert_eq!(may_send(&mut r, 1000), (false, false));
|
|
|
|
assert_eq!(may_send(&mut r, 1050), (false, false));
|
|
|
|
assert_eq!(may_send(&mut r, 1101), (true, false));
|
|
|
|
r.commit(1101);
|
|
|
|
assert_eq!(may_send(&mut r, 1150), (false, false));
|
|
|
|
assert_eq!(may_send(&mut r, 1200), (false, false));
|
|
|
|
assert_eq!(may_send(&mut r, 1301), (true, false));
|
|
|
|
r.reset();
|
|
|
|
assert_eq!(may_send(&mut r, 1350), (false, true));
|
|
|
|
}
|
|
|
|
|
2016-12-28 08:08:01 +08:00
|
|
|
const LOCAL_IP: IpAddress = IpAddress::Ipv4(Ipv4Address([10, 0, 0, 1]));
|
|
|
|
const REMOTE_IP: IpAddress = IpAddress::Ipv4(Ipv4Address([10, 0, 0, 2]));
|
2016-12-28 02:34:13 +08:00
|
|
|
const LOCAL_PORT: u16 = 80;
|
|
|
|
const REMOTE_PORT: u16 = 49500;
|
2016-12-28 08:08:01 +08:00
|
|
|
const LOCAL_END: IpEndpoint = IpEndpoint { addr: LOCAL_IP, port: LOCAL_PORT };
|
|
|
|
const REMOTE_END: IpEndpoint = IpEndpoint { addr: REMOTE_IP, port: REMOTE_PORT };
|
2016-12-28 02:34:13 +08:00
|
|
|
const LOCAL_SEQ: TcpSeqNumber = TcpSeqNumber(10000);
|
|
|
|
const REMOTE_SEQ: TcpSeqNumber = TcpSeqNumber(-10000);
|
2016-12-25 05:52:23 +08:00
|
|
|
|
|
|
|
const SEND_TEMPL: TcpRepr<'static> = TcpRepr {
|
|
|
|
src_port: REMOTE_PORT, dst_port: LOCAL_PORT,
|
2017-06-25 16:20:25 +08:00
|
|
|
control: TcpControl::None, push: false,
|
2016-12-28 02:34:13 +08:00
|
|
|
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
2017-01-27 09:09:34 +08:00
|
|
|
window_len: 256, max_seg_size: None,
|
|
|
|
payload: &[]
|
2016-12-25 05:52:23 +08:00
|
|
|
};
|
|
|
|
const RECV_TEMPL: TcpRepr<'static> = TcpRepr {
|
|
|
|
src_port: LOCAL_PORT, dst_port: REMOTE_PORT,
|
2017-06-25 16:20:25 +08:00
|
|
|
control: TcpControl::None, push: false,
|
2016-12-28 02:34:13 +08:00
|
|
|
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
2017-01-27 09:09:34 +08:00
|
|
|
window_len: 64, max_seg_size: None,
|
|
|
|
payload: &[]
|
2016-12-25 05:52:23 +08:00
|
|
|
};
|
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
fn send(socket: &mut TcpSocket, timestamp: u64, repr: &TcpRepr) -> Result<()> {
|
2016-12-27 22:04:30 +08:00
|
|
|
trace!("send: {}", repr);
|
2016-12-26 20:38:40 +08:00
|
|
|
let mut buffer = vec![0; repr.buffer_len()];
|
Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.
This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
* `fn check_len(&self) -> Result<(), Error>`, purely a validator;
* `fn new(T) -> Self`, purely a wrapper;
* `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.
This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).
Fixes #17.
2017-06-24 17:15:22 +08:00
|
|
|
let mut packet = TcpPacket::new(&mut buffer);
|
2016-12-26 20:38:40 +08:00
|
|
|
repr.emit(&mut packet, &REMOTE_IP, &LOCAL_IP);
|
|
|
|
let ip_repr = IpRepr::Unspecified {
|
2017-01-14 19:07:06 +08:00
|
|
|
src_addr: REMOTE_IP,
|
|
|
|
dst_addr: LOCAL_IP,
|
|
|
|
protocol: IpProtocol::Tcp,
|
|
|
|
payload_len: repr.buffer_len()
|
2016-12-26 20:38:40 +08:00
|
|
|
};
|
2016-12-31 16:35:07 +08:00
|
|
|
socket.process(timestamp, &ip_repr, &packet.into_inner()[..])
|
2016-12-26 20:38:40 +08:00
|
|
|
}
|
|
|
|
|
2016-12-31 16:35:07 +08:00
|
|
|
fn recv<F>(socket: &mut TcpSocket, timestamp: u64, mut f: F)
|
2017-07-27 21:51:02 +08:00
|
|
|
where F: FnMut(Result<TcpRepr>) {
|
2016-12-26 20:38:40 +08:00
|
|
|
let mut buffer = vec![];
|
2017-03-07 18:56:48 +08:00
|
|
|
let mut limits = DeviceLimits::default();
|
|
|
|
limits.max_transmission_unit = 1520;
|
|
|
|
let result = socket.dispatch(timestamp, &limits, &mut |ip_repr, payload| {
|
2017-07-24 07:07:55 +08:00
|
|
|
let ip_repr = ip_repr.lower(&[LOCAL_END.addr.into()]).unwrap();
|
|
|
|
|
2016-12-26 20:38:40 +08:00
|
|
|
assert_eq!(ip_repr.protocol(), IpProtocol::Tcp);
|
|
|
|
assert_eq!(ip_repr.src_addr(), LOCAL_IP);
|
|
|
|
assert_eq!(ip_repr.dst_addr(), REMOTE_IP);
|
|
|
|
|
|
|
|
buffer.resize(payload.buffer_len(), 0);
|
|
|
|
payload.emit(&ip_repr, &mut buffer[..]);
|
Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.
This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
* `fn check_len(&self) -> Result<(), Error>`, purely a validator;
* `fn new(T) -> Self`, purely a wrapper;
* `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.
This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).
Fixes #17.
2017-06-24 17:15:22 +08:00
|
|
|
let packet = TcpPacket::new(&buffer[..]);
|
2017-06-25 00:34:32 +08:00
|
|
|
let repr = TcpRepr::parse(&packet, &ip_repr.src_addr(), &ip_repr.dst_addr())?;
|
2016-12-27 22:04:30 +08:00
|
|
|
trace!("recv: {}", repr);
|
2016-12-26 20:38:40 +08:00
|
|
|
Ok(f(Ok(repr)))
|
|
|
|
});
|
|
|
|
// Appease borrow checker.
|
|
|
|
match result {
|
|
|
|
Ok(()) => (),
|
|
|
|
Err(e) => f(Err(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-25 05:52:23 +08:00
|
|
|
macro_rules! send {
|
2016-12-31 16:35:07 +08:00
|
|
|
($socket:ident, $repr:expr) =>
|
|
|
|
(send!($socket, time 0, $repr));
|
2016-12-26 20:38:40 +08:00
|
|
|
($socket:ident, $repr:expr, $result:expr) =>
|
2016-12-31 16:35:07 +08:00
|
|
|
(send!($socket, time 0, $repr, $result));
|
|
|
|
($socket:ident, time $time:expr, $repr:expr) =>
|
2017-04-22 00:01:49 +08:00
|
|
|
(send!($socket, time $time, $repr, Ok(())));
|
2016-12-31 16:35:07 +08:00
|
|
|
($socket:ident, time $time:expr, $repr:expr, $result:expr) =>
|
|
|
|
(assert_eq!(send(&mut $socket, $time, &$repr), $result));
|
2016-12-25 05:52:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! recv {
|
2016-12-26 20:38:40 +08:00
|
|
|
($socket:ident, [$( $repr:expr )*]) => ({
|
|
|
|
$( recv!($socket, Ok($repr)); )*
|
|
|
|
recv!($socket, Err(Error::Exhausted))
|
|
|
|
});
|
|
|
|
($socket:ident, $result:expr) =>
|
2016-12-31 16:35:07 +08:00
|
|
|
(recv!($socket, time 0, $result));
|
|
|
|
($socket:ident, time $time:expr, $result:expr) =>
|
2017-06-26 07:12:25 +08:00
|
|
|
(recv(&mut $socket, $time, |repr| {
|
|
|
|
// Most of the time we don't care about the PSH flag.
|
|
|
|
let repr = repr.map(|r| TcpRepr { push: false, ..r });
|
|
|
|
assert_eq!(repr, $result)
|
|
|
|
}));
|
|
|
|
($socket:ident, time $time:expr, $result:expr, exact) =>
|
2016-12-31 16:35:07 +08:00
|
|
|
(recv(&mut $socket, $time, |repr| assert_eq!(repr, $result)));
|
2016-12-25 05:52:23 +08:00
|
|
|
}
|
|
|
|
|
2017-01-14 20:56:58 +08:00
|
|
|
macro_rules! sanity {
|
|
|
|
($socket1:expr, $socket2:expr, retransmit: $retransmit:expr) => ({
|
|
|
|
let (s1, s2) = ($socket1, $socket2);
|
|
|
|
assert_eq!(s1.state, s2.state, "state");
|
|
|
|
assert_eq!(s1.listen_address, s2.listen_address, "listen_address");
|
|
|
|
assert_eq!(s1.local_endpoint, s2.local_endpoint, "local_endpoint");
|
|
|
|
assert_eq!(s1.remote_endpoint, s2.remote_endpoint, "remote_endpoint");
|
|
|
|
assert_eq!(s1.local_seq_no, s2.local_seq_no, "local_seq_no");
|
|
|
|
assert_eq!(s1.remote_seq_no, s2.remote_seq_no, "remote_seq_no");
|
|
|
|
assert_eq!(s1.remote_last_seq, s2.remote_last_seq, "remote_last_seq");
|
|
|
|
assert_eq!(s1.remote_last_ack, s2.remote_last_ack, "remote_last_ack");
|
|
|
|
assert_eq!(s1.remote_win_len, s2.remote_win_len, "remote_win_len");
|
2017-04-22 00:01:49 +08:00
|
|
|
assert_eq!(s1.time_wait_since, s2.time_wait_since, "time_wait_since");
|
2017-01-14 20:56:58 +08:00
|
|
|
if $retransmit {
|
|
|
|
assert_eq!(s1.retransmit, s2.retransmit, "retransmit");
|
|
|
|
} else {
|
|
|
|
let retransmit = Retransmit { resend_at: 100, delay: 100 };
|
|
|
|
assert_eq!(s1.retransmit, retransmit, "retransmit (delaying)");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
($socket1:expr, $socket2:expr) =>
|
|
|
|
(sanity!($socket1, $socket2, retransmit: true))
|
|
|
|
}
|
|
|
|
|
2016-12-25 05:52:23 +08:00
|
|
|
fn init_logger() {
|
|
|
|
extern crate log;
|
|
|
|
use std::boxed::Box;
|
|
|
|
|
|
|
|
struct Logger(());
|
|
|
|
|
|
|
|
impl log::Log for Logger {
|
|
|
|
fn enabled(&self, _metadata: &log::LogMetadata) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log(&self, record: &log::LogRecord) {
|
|
|
|
println!("{}", record.args());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let _ = log::set_logger(|max_level| {
|
|
|
|
max_level.set(log::LogLevelFilter::Trace);
|
|
|
|
Box::new(Logger(()))
|
|
|
|
});
|
|
|
|
|
|
|
|
println!("");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn socket() -> TcpSocket<'static> {
|
|
|
|
init_logger();
|
|
|
|
|
2016-12-27 00:29:33 +08:00
|
|
|
let rx_buffer = SocketBuffer::new(vec![0; 64]);
|
|
|
|
let tx_buffer = SocketBuffer::new(vec![0; 64]);
|
2016-12-25 05:52:23 +08:00
|
|
|
match TcpSocket::new(rx_buffer, tx_buffer) {
|
|
|
|
Socket::Tcp(socket) => socket,
|
|
|
|
_ => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for the CLOSED state.
|
|
|
|
// =========================================================================================//
|
2016-12-26 20:44:41 +08:00
|
|
|
#[test]
|
2017-01-17 00:58:45 +08:00
|
|
|
fn test_closed_reject() {
|
2016-12-26 20:44:41 +08:00
|
|
|
let mut s = socket();
|
2016-12-28 06:43:16 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
2016-12-26 20:44:41 +08:00
|
|
|
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Rejected));
|
|
|
|
}
|
|
|
|
|
2017-01-17 08:24:47 +08:00
|
|
|
#[test]
|
|
|
|
fn test_closed_reject_after_listen() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.listen(LOCAL_END).unwrap();
|
|
|
|
s.close();
|
|
|
|
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Rejected));
|
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_closed_close() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for the LISTEN state.
|
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_listen() -> TcpSocket<'static> {
|
2016-12-26 20:51:47 +08:00
|
|
|
let mut s = socket();
|
|
|
|
s.state = State::Listen;
|
|
|
|
s.local_endpoint = IpEndpoint::new(IpAddress::default(), LOCAL_PORT);
|
2016-12-26 21:54:26 +08:00
|
|
|
s
|
|
|
|
}
|
2016-12-25 05:52:23 +08:00
|
|
|
|
2017-01-14 20:56:58 +08:00
|
|
|
#[test]
|
|
|
|
fn test_listen_sanity() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.listen(LOCAL_PORT).unwrap();
|
|
|
|
sanity!(s, socket_listen());
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
#[test]
|
|
|
|
fn test_listen_validation() {
|
|
|
|
let mut s = socket();
|
2017-07-27 21:51:02 +08:00
|
|
|
assert_eq!(s.listen(0), Err(Error::Unaddressable));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_listen_twice() {
|
|
|
|
let mut s = socket();
|
|
|
|
assert_eq!(s.listen(80), Ok(()));
|
|
|
|
assert_eq!(s.listen(80), Err(Error::Illegal));
|
2017-03-05 11:52:47 +08:00
|
|
|
}
|
|
|
|
|
2017-01-14 20:56:58 +08:00
|
|
|
#[test]
|
|
|
|
fn test_listen_syn() {
|
|
|
|
let mut s = socket_listen();
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
sanity!(s, socket_syn_received());
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
#[test]
|
2017-01-17 12:43:51 +08:00
|
|
|
fn test_listen_syn_reject_ack() {
|
2016-12-26 21:54:26 +08:00
|
|
|
let mut s = socket_listen();
|
|
|
|
send!(s, TcpRepr {
|
2016-12-25 05:52:23 +08:00
|
|
|
control: TcpControl::Syn,
|
2016-12-25 19:09:50 +08:00
|
|
|
seq_number: REMOTE_SEQ,
|
2016-12-26 21:54:26 +08:00
|
|
|
ack_number: Some(LOCAL_SEQ),
|
2016-12-25 05:52:23 +08:00
|
|
|
..SEND_TEMPL
|
2017-01-17 12:43:51 +08:00
|
|
|
}, Err(Error::Rejected));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::Listen);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_listen_rst() {
|
|
|
|
let mut s = socket_listen();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: None,
|
2016-12-25 05:52:23 +08:00
|
|
|
..SEND_TEMPL
|
2017-01-17 12:33:37 +08:00
|
|
|
}, Err(Error::Rejected));
|
2016-12-25 05:52:23 +08:00
|
|
|
}
|
2016-12-25 19:09:50 +08:00
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_listen_close() {
|
|
|
|
let mut s = socket_listen();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the SYN-RECEIVED state.
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_syn_received() -> TcpSocket<'static> {
|
2016-12-26 20:44:41 +08:00
|
|
|
let mut s = socket();
|
2016-12-26 21:54:26 +08:00
|
|
|
s.state = State::SynReceived;
|
2016-12-26 20:44:41 +08:00
|
|
|
s.local_endpoint = LOCAL_END;
|
|
|
|
s.remote_endpoint = REMOTE_END;
|
2016-12-26 21:54:26 +08:00
|
|
|
s.local_seq_no = LOCAL_SEQ;
|
2017-01-14 19:22:19 +08:00
|
|
|
s.remote_seq_no = REMOTE_SEQ + 1;
|
|
|
|
s.remote_last_seq = LOCAL_SEQ + 1;
|
2017-01-14 20:56:58 +08:00
|
|
|
s.remote_win_len = 256;
|
2016-12-26 21:54:26 +08:00
|
|
|
s
|
2016-12-26 20:44:41 +08:00
|
|
|
}
|
|
|
|
|
2017-01-14 19:22:19 +08:00
|
|
|
#[test]
|
2017-07-24 07:51:56 +08:00
|
|
|
fn test_syn_received_ack() {
|
2017-01-14 19:22:19 +08:00
|
|
|
let mut s = socket_syn_received();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
2017-01-27 10:49:06 +08:00
|
|
|
max_seg_size: Some(1480),
|
2017-01-14 19:22:19 +08:00
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
2017-01-14 20:56:58 +08:00
|
|
|
assert_eq!(s.state, State::Established);
|
|
|
|
sanity!(s, socket_established());
|
2017-01-14 19:22:19 +08:00
|
|
|
}
|
|
|
|
|
2017-07-24 07:51:56 +08:00
|
|
|
#[test]
|
|
|
|
fn test_syn_received_fin() {
|
|
|
|
let mut s = socket_syn_received();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
max_seg_size: Some(1480),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.state, State::CloseWait);
|
|
|
|
sanity!(s, TcpSocket {
|
|
|
|
remote_last_ack: REMOTE_SEQ + 1,
|
|
|
|
..socket_close_wait()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-12-26 20:44:41 +08:00
|
|
|
#[test]
|
2016-12-26 21:54:26 +08:00
|
|
|
fn test_syn_received_rst() {
|
|
|
|
let mut s = socket_syn_received();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Rst,
|
2017-01-14 19:22:19 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
2016-12-26 20:51:47 +08:00
|
|
|
ack_number: Some(LOCAL_SEQ),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::Listen);
|
|
|
|
assert_eq!(s.local_endpoint, IpEndpoint::new(IpAddress::Unspecified, LOCAL_END.port));
|
|
|
|
assert_eq!(s.remote_endpoint, IpEndpoint::default());
|
2016-12-26 21:10:39 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_syn_received_close() {
|
|
|
|
let mut s = socket_syn_received();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the SYN-SENT state.
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_syn_sent() -> TcpSocket<'static> {
|
2016-12-26 21:10:39 +08:00
|
|
|
let mut s = socket();
|
|
|
|
s.state = State::SynSent;
|
2017-07-24 07:07:55 +08:00
|
|
|
s.local_endpoint = IpEndpoint::new(IpAddress::v4(0, 0, 0, 0), LOCAL_PORT);
|
2016-12-26 21:10:39 +08:00
|
|
|
s.remote_endpoint = REMOTE_END;
|
|
|
|
s.local_seq_no = LOCAL_SEQ;
|
2016-12-26 21:54:26 +08:00
|
|
|
s
|
|
|
|
}
|
2016-12-26 21:10:39 +08:00
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
#[test]
|
|
|
|
fn test_connect_validation() {
|
|
|
|
let mut s = socket();
|
2017-07-27 20:27:33 +08:00
|
|
|
assert_eq!(s.connect((IpAddress::v4(0, 0, 0, 0), 80), LOCAL_END),
|
|
|
|
Err(Error::Unaddressable));
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::v4(10, 0, 0, 0), 0)),
|
|
|
|
Err(Error::Unaddressable));
|
|
|
|
assert_eq!(s.connect((IpAddress::v4(10, 0, 0, 0), 0), LOCAL_END),
|
|
|
|
Err(Error::Unaddressable));
|
|
|
|
assert_eq!(s.connect((IpAddress::Unspecified, 80), LOCAL_END),
|
|
|
|
Err(Error::Unaddressable));
|
2017-03-05 11:52:47 +08:00
|
|
|
}
|
|
|
|
|
2017-07-24 07:07:55 +08:00
|
|
|
#[test]
|
|
|
|
fn test_connect() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.local_seq_no = LOCAL_SEQ;
|
|
|
|
s.connect(REMOTE_END, LOCAL_END.port).unwrap();
|
|
|
|
assert_eq!(s.local_endpoint, IpEndpoint::new(IpAddress::v4(0, 0, 0, 0), LOCAL_END.port));
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
max_seg_size: Some(1480),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
max_seg_size: Some(1400),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.local_endpoint, LOCAL_END);
|
|
|
|
}
|
|
|
|
|
2017-07-27 20:27:33 +08:00
|
|
|
#[test]
|
|
|
|
fn test_connect_unspecified_local() {
|
|
|
|
let mut s = socket();
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::v4(0, 0, 0, 0), 80)),
|
|
|
|
Ok(()));
|
|
|
|
s.abort();
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::Unspecified, 80)),
|
|
|
|
Ok(()));
|
|
|
|
s.abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_connect_specified_local() {
|
|
|
|
let mut s = socket();
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::v4(10, 0, 0, 2), 80)),
|
|
|
|
Ok(()));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_connect_twice() {
|
|
|
|
let mut s = socket();
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::Unspecified, 80)),
|
|
|
|
Ok(()));
|
|
|
|
assert_eq!(s.connect(REMOTE_END, (IpAddress::Unspecified, 80)),
|
|
|
|
Err(Error::Illegal));
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:52:47 +08:00
|
|
|
#[test]
|
|
|
|
fn test_syn_sent_sanity() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.local_seq_no = LOCAL_SEQ;
|
|
|
|
s.connect(REMOTE_END, LOCAL_END).unwrap();
|
|
|
|
sanity!(s, socket_syn_sent());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_syn_sent_syn_ack() {
|
|
|
|
let mut s = socket_syn_sent();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
max_seg_size: Some(1480),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
max_seg_size: Some(1400),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.state, State::Established);
|
2017-03-07 18:17:30 +08:00
|
|
|
sanity!(s, socket_established(), retransmit: false);
|
2017-03-05 11:52:47 +08:00
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
#[test]
|
|
|
|
fn test_syn_sent_rst() {
|
|
|
|
let mut s = socket_syn_sent();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: REMOTE_SEQ,
|
2017-03-05 13:31:12 +08:00
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
2016-12-26 21:54:26 +08:00
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_syn_sent_rst_no_ack() {
|
|
|
|
let mut s = socket_syn_sent();
|
2016-12-26 21:10:39 +08:00
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Malformed));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::SynSent);
|
2016-12-26 21:10:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-12-26 21:54:26 +08:00
|
|
|
fn test_syn_sent_rst_bad_ack() {
|
|
|
|
let mut s = socket_syn_sent();
|
2016-12-26 21:10:39 +08:00
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: REMOTE_SEQ,
|
2016-12-28 02:34:13 +08:00
|
|
|
ack_number: Some(TcpSeqNumber(1234)),
|
2016-12-26 21:10:39 +08:00
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Malformed));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::SynSent);
|
2016-12-26 20:51:47 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_syn_sent_close() {
|
|
|
|
let mut s = socket();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for the ESTABLISHED state.
|
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_established() -> TcpSocket<'static> {
|
2016-12-27 22:13:42 +08:00
|
|
|
let mut s = socket_syn_received();
|
2017-01-14 20:56:58 +08:00
|
|
|
s.state = State::Established;
|
2016-12-26 20:44:41 +08:00
|
|
|
s.local_seq_no = LOCAL_SEQ + 1;
|
2016-12-27 00:59:39 +08:00
|
|
|
s.remote_last_ack = REMOTE_SEQ + 1;
|
2016-12-26 21:54:26 +08:00
|
|
|
s
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-12-27 00:59:39 +08:00
|
|
|
fn test_established_recv() {
|
2016-12-26 21:54:26 +08:00
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
2016-12-27 00:29:33 +08:00
|
|
|
window_len: 58,
|
2016-12-26 21:54:26 +08:00
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.rx_buffer.dequeue(6), &b"abcdef"[..]);
|
|
|
|
}
|
2016-12-26 20:44:41 +08:00
|
|
|
|
2016-12-26 22:24:17 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_send() {
|
|
|
|
let mut s = socket_established();
|
2016-12-27 00:59:39 +08:00
|
|
|
// First roundtrip after establishing.
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"abcdef").unwrap();
|
2016-12-26 22:24:17 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.tx_buffer.len(), 6);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 22:24:17 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 22:24:17 +08:00
|
|
|
assert_eq!(s.tx_buffer.len(), 0);
|
2016-12-27 00:59:39 +08:00
|
|
|
// Second roundtrip.
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"foobar").unwrap();
|
2016-12-27 00:59:39 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"foobar"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-27 00:59:39 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 6),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-27 00:59:39 +08:00
|
|
|
assert_eq!(s.tx_buffer.len(), 0);
|
2016-12-26 22:24:17 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 04:39:46 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_send_no_ack_send() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"abcdef").unwrap();
|
2016-12-28 04:39:46 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"foobar").unwrap();
|
2016-12-28 04:39:46 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"foobar"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2016-12-28 04:08:50 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_send_buf_gt_win() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.remote_win_len = 16;
|
|
|
|
// First roundtrip after establishing.
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(&[0; 32][..]).unwrap();
|
2016-12-28 04:08:50 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &[0; 16][..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_no_ack() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: None,
|
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Malformed));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_established_bad_ack() {
|
|
|
|
let mut s = socket_established();
|
2016-12-26 20:44:41 +08:00
|
|
|
// Already acknowledged data.
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
2016-12-28 02:34:13 +08:00
|
|
|
ack_number: Some(TcpSeqNumber(LOCAL_SEQ.0 - 1)),
|
2016-12-26 20:44:41 +08:00
|
|
|
..SEND_TEMPL
|
2017-01-17 00:58:45 +08:00
|
|
|
}, Err(Error::Dropped));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
|
2016-12-26 20:44:41 +08:00
|
|
|
// Data not yet transmitted.
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 10),
|
|
|
|
..SEND_TEMPL
|
2017-01-17 00:58:45 +08:00
|
|
|
}, Err(Error::Dropped));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
|
2016-12-26 20:44:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-12-26 21:54:26 +08:00
|
|
|
fn test_established_bad_seq() {
|
|
|
|
let mut s = socket_established();
|
2016-12-26 20:44:41 +08:00
|
|
|
// Data outside of receive window.
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1 + 256,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2017-01-17 00:58:45 +08:00
|
|
|
}, Err(Error::Dropped));
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.remote_seq_no, REMOTE_SEQ + 1);
|
2016-12-26 20:44:41 +08:00
|
|
|
}
|
|
|
|
|
2016-12-27 21:34:48 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_fin() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-27 21:34:48 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-27 21:34:48 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2017-01-14 20:56:58 +08:00
|
|
|
assert_eq!(s.state, State::CloseWait);
|
|
|
|
sanity!(s, socket_close_wait(), retransmit: false);
|
2016-12-27 21:34:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_established_send_fin() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
send!(s, TcpRepr {
|
2016-12-27 21:34:48 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-27 21:34:48 +08:00
|
|
|
assert_eq!(s.state, State::CloseWait);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2016-12-25 19:09:50 +08:00
|
|
|
#[test]
|
2016-12-26 21:54:26 +08:00
|
|
|
fn test_established_rst() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Rst,
|
2016-12-25 19:09:50 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-28 04:17:35 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_rst_no_ack() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 04:17:35 +08:00
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: None,
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 04:17:35 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_close() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
2017-01-14 20:56:58 +08:00
|
|
|
sanity!(s, socket_fin_wait_1());
|
2016-12-28 06:43:16 +08:00
|
|
|
}
|
|
|
|
|
2017-01-17 09:24:51 +08:00
|
|
|
#[test]
|
|
|
|
fn test_established_abort() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.abort();
|
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Rst,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the FIN-WAIT-1 state.
|
2016-12-28 06:43:16 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_fin_wait_1() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.state = State::FinWait1;
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:02:43 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_1_fin_ack() {
|
|
|
|
let mut s = socket_fin_wait_1();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 12:02:43 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 12:02:43 +08:00
|
|
|
assert_eq!(s.state, State::FinWait2);
|
2017-03-07 18:17:30 +08:00
|
|
|
sanity!(s, TcpSocket {
|
|
|
|
remote_last_seq: LOCAL_SEQ + 1 + 1,
|
|
|
|
..socket_fin_wait_2()
|
|
|
|
}, retransmit: false);
|
2016-12-28 12:02:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_1_fin_fin() {
|
|
|
|
let mut s = socket_fin_wait_1();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 12:02:43 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 12:02:43 +08:00
|
|
|
assert_eq!(s.state, State::Closing);
|
2017-03-07 18:17:30 +08:00
|
|
|
sanity!(s, TcpSocket {
|
|
|
|
remote_last_seq: LOCAL_SEQ + 1 + 1,
|
|
|
|
..socket_closing()
|
|
|
|
});
|
2016-12-28 12:02:43 +08:00
|
|
|
}
|
|
|
|
|
2017-01-23 20:07:07 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_1_fin_with_data_queued() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.remote_win_len = 6;
|
|
|
|
s.send_slice(b"abcdef123456").unwrap();
|
|
|
|
s.close();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2017-01-25 13:36:42 +08:00
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
2017-01-23 20:07:07 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_1_close() {
|
|
|
|
let mut s = socket_fin_wait_1();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the FIN-WAIT-2 state.
|
2016-12-28 06:43:16 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_fin_wait_2() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_fin_wait_1();
|
|
|
|
s.state = State::FinWait2;
|
|
|
|
s.local_seq_no = LOCAL_SEQ + 1 + 1;
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:10:17 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_2_fin() {
|
|
|
|
let mut s = socket_fin_wait_2();
|
2017-04-22 00:01:49 +08:00
|
|
|
send!(s, time 1_000, TcpRepr {
|
2016-12-28 12:10:17 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 12:10:17 +08:00
|
|
|
assert_eq!(s.state, State::TimeWait);
|
2017-01-14 20:56:58 +08:00
|
|
|
sanity!(s, socket_time_wait(false));
|
2016-12-28 12:10:17 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_2_close() {
|
|
|
|
let mut s = socket_fin_wait_2();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for the CLOSING state.
|
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_closing() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_fin_wait_1();
|
|
|
|
s.state = State::Closing;
|
2016-12-28 13:33:12 +08:00
|
|
|
s.local_seq_no = LOCAL_SEQ + 1;
|
2016-12-28 06:43:16 +08:00
|
|
|
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:56:49 +08:00
|
|
|
#[test]
|
|
|
|
fn test_closing_ack_fin() {
|
|
|
|
let mut s = socket_closing();
|
|
|
|
recv!(s, [TcpRepr {
|
2016-12-28 13:33:12 +08:00
|
|
|
seq_number: LOCAL_SEQ + 1,
|
2016-12-28 12:56:49 +08:00
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2017-04-22 00:01:49 +08:00
|
|
|
send!(s, time 1_000, TcpRepr {
|
2016-12-28 12:56:49 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 12:56:49 +08:00
|
|
|
assert_eq!(s.state, State::TimeWait);
|
2017-03-07 18:17:30 +08:00
|
|
|
sanity!(s, socket_time_wait(true), retransmit: false);
|
2016-12-28 12:56:49 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_closing_close() {
|
|
|
|
let mut s = socket_closing();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::Closing);
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:10:17 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for the TIME-WAIT state.
|
|
|
|
// =========================================================================================//
|
2016-12-28 13:33:12 +08:00
|
|
|
fn socket_time_wait(from_closing: bool) -> TcpSocket<'static> {
|
2016-12-28 12:10:17 +08:00
|
|
|
let mut s = socket_fin_wait_2();
|
|
|
|
s.state = State::TimeWait;
|
|
|
|
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
|
2016-12-28 13:33:12 +08:00
|
|
|
if from_closing {
|
|
|
|
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
|
|
|
|
}
|
2017-04-22 00:01:49 +08:00
|
|
|
s.time_wait_since = 1_000;
|
2016-12-28 12:10:17 +08:00
|
|
|
s
|
|
|
|
}
|
|
|
|
|
2016-12-28 13:33:12 +08:00
|
|
|
#[test]
|
|
|
|
fn test_time_wait_from_fin_wait_2_ack() {
|
|
|
|
let mut s = socket_time_wait(false);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_time_wait_from_closing_no_ack() {
|
|
|
|
let mut s = socket_time_wait(true);
|
|
|
|
recv!(s, []);
|
|
|
|
}
|
|
|
|
|
2016-12-28 12:10:17 +08:00
|
|
|
#[test]
|
|
|
|
fn test_time_wait_close() {
|
2016-12-28 13:33:12 +08:00
|
|
|
let mut s = socket_time_wait(false);
|
2016-12-28 12:10:17 +08:00
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
}
|
|
|
|
|
2017-04-22 00:01:49 +08:00
|
|
|
#[test]
|
|
|
|
fn test_time_wait_retransmit() {
|
|
|
|
let mut s = socket_time_wait(false);
|
|
|
|
send!(s, time 5_000, TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
}, Err(Error::Dropped));
|
|
|
|
assert_eq!(s.time_wait_since, 5_000);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_time_wait_timeout() {
|
|
|
|
let mut s = socket_time_wait(false);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
recv!(s, time 60_000, Err(Error::Exhausted));
|
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-27 22:13:42 +08:00
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the CLOSE-WAIT state.
|
2016-12-27 22:13:42 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_close_wait() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.state = State::CloseWait;
|
|
|
|
s.remote_seq_no = REMOTE_SEQ + 1 + 1;
|
|
|
|
s.remote_last_ack = REMOTE_SEQ + 1 + 1;
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_close_wait_ack() {
|
|
|
|
let mut s = socket_close_wait();
|
2016-12-31 16:35:07 +08:00
|
|
|
s.send_slice(b"abcdef").unwrap();
|
2016-12-27 22:13:42 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-27 22:13:42 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-27 22:13:42 +08:00
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_close_wait_close() {
|
|
|
|
let mut s = socket_close_wait();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::LastAck);
|
2017-01-14 20:56:58 +08:00
|
|
|
sanity!(s, socket_last_ack());
|
2016-12-28 06:43:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// =========================================================================================//
|
2016-12-28 07:28:57 +08:00
|
|
|
// Tests for the LAST-ACK state.
|
2016-12-28 06:43:16 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_last_ack() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_close_wait();
|
|
|
|
s.state = State::LastAck;
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
2016-12-28 07:27:33 +08:00
|
|
|
#[test]
|
|
|
|
fn test_last_ack_fin_ack() {
|
|
|
|
let mut s = socket_last_ack();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.state, State::LastAck);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 07:27:33 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 07:27:33 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
2016-12-28 06:43:16 +08:00
|
|
|
#[test]
|
|
|
|
fn test_last_ack_close() {
|
|
|
|
let mut s = socket_last_ack();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::LastAck);
|
|
|
|
}
|
|
|
|
|
2016-12-26 21:54:26 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for transitioning through multiple states.
|
|
|
|
// =========================================================================================//
|
|
|
|
#[test]
|
|
|
|
fn test_listen() {
|
|
|
|
let mut s = socket();
|
2016-12-28 02:04:02 +08:00
|
|
|
s.listen(IpEndpoint::new(IpAddress::default(), LOCAL_PORT)).unwrap();
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state, State::Listen);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_three_way_handshake() {
|
2016-12-28 12:02:43 +08:00
|
|
|
let mut s = socket_listen();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state(), State::SynReceived);
|
|
|
|
assert_eq!(s.local_endpoint(), LOCAL_END);
|
|
|
|
assert_eq!(s.remote_endpoint(), REMOTE_END);
|
2016-12-26 20:38:40 +08:00
|
|
|
recv!(s, [TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
2017-01-27 10:49:06 +08:00
|
|
|
max_seg_size: Some(1480),
|
2016-12-25 19:19:50 +08:00
|
|
|
..RECV_TEMPL
|
2016-12-26 20:38:40 +08:00
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-26 21:54:26 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-26 21:54:26 +08:00
|
|
|
assert_eq!(s.state(), State::Established);
|
|
|
|
assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
|
|
|
|
assert_eq!(s.remote_seq_no, REMOTE_SEQ + 1);
|
2016-12-25 19:09:50 +08:00
|
|
|
}
|
2016-12-28 12:02:43 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_remote_close() {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 12:02:43 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 12:02:43 +08:00
|
|
|
assert_eq!(s.state, State::CloseWait);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::LastAck);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 12:02:43 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 13:33:12 +08:00
|
|
|
assert_eq!(s.state, State::Closed);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_local_close() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 13:33:12 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 13:33:12 +08:00
|
|
|
assert_eq!(s.state, State::FinWait2);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 13:33:12 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 13:33:12 +08:00
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_simultaneous_close() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
recv!(s, [TcpRepr { // this is logically located...
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 13:33:12 +08:00
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 13:33:12 +08:00
|
|
|
assert_eq!(s.state, State::Closing);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
// ... at this point
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-28 13:33:12 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-28 13:33:12 +08:00
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
recv!(s, []);
|
2016-12-28 12:02:43 +08:00
|
|
|
}
|
2016-12-31 09:24:55 +08:00
|
|
|
|
2017-01-25 11:58:03 +08:00
|
|
|
#[test]
|
|
|
|
fn test_simultaneous_close_combined_fin_ack() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
2017-01-14 19:22:19 +08:00
|
|
|
#[test]
|
|
|
|
fn test_fin_with_data() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.close();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}])
|
|
|
|
}
|
|
|
|
|
2017-01-24 05:02:28 +08:00
|
|
|
#[test]
|
2017-03-07 18:17:30 +08:00
|
|
|
fn test_mutual_close_with_data_1() {
|
2017-01-24 05:02:28 +08:00
|
|
|
let mut s = socket_established();
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-07 18:17:30 +08:00
|
|
|
#[test]
|
|
|
|
fn test_mutual_close_with_data_2() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.close();
|
|
|
|
assert_eq!(s.state, State::FinWait1);
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.state, State::FinWait2);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6 + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
assert_eq!(s.state, State::TimeWait);
|
|
|
|
}
|
|
|
|
|
2016-12-31 09:24:55 +08:00
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for retransmission on packet loss.
|
|
|
|
// =========================================================================================//
|
|
|
|
fn socket_recved() -> TcpSocket<'static> {
|
|
|
|
let mut s = socket_established();
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-31 09:24:55 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..SEND_TEMPL
|
2016-12-31 16:35:07 +08:00
|
|
|
});
|
2016-12-31 09:24:55 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
|
|
|
window_len: 58,
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
s
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_duplicate_seq_ack() {
|
|
|
|
let mut s = socket_recved();
|
|
|
|
// remote retransmission
|
2016-12-31 16:35:07 +08:00
|
|
|
send!(s, TcpRepr {
|
2016-12-31 09:24:55 +08:00
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..SEND_TEMPL
|
2017-06-26 16:09:27 +08:00
|
|
|
}, Err(Error::Dropped));
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
|
|
|
window_len: 58,
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_missing_segment() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
|
|
|
window_len: 58,
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1 + 6 + 6,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
payload: &b"mnopqr"[..],
|
|
|
|
..SEND_TEMPL
|
2017-01-17 00:58:45 +08:00
|
|
|
}, Err(Error::Dropped));
|
2016-12-31 09:24:55 +08:00
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 6),
|
|
|
|
window_len: 58,
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
}
|
2016-12-31 16:35:07 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_data_retransmit() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
recv!(s, time 1000, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
recv!(s, time 1050, Err(Error::Exhausted));
|
|
|
|
recv!(s, time 1100, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
}
|
2017-01-14 14:55:29 +08:00
|
|
|
|
|
|
|
#[test]
|
2017-01-14 19:22:19 +08:00
|
|
|
fn test_send_data_after_syn_ack_retransmit() {
|
|
|
|
let mut s = socket_syn_received();
|
|
|
|
recv!(s, time 50, Ok(TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
2017-01-27 10:49:06 +08:00
|
|
|
max_seg_size: Some(1480),
|
2017-01-14 19:22:19 +08:00
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
recv!(s, time 150, Ok(TcpRepr { // retransmit
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
2017-01-27 10:49:06 +08:00
|
|
|
max_seg_size: Some(1480),
|
2017-01-14 19:22:19 +08:00
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
assert_eq!(s.state(), State::Established);
|
2017-01-14 14:55:29 +08:00
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}])
|
|
|
|
}
|
2017-01-14 19:22:19 +08:00
|
|
|
|
2017-01-23 19:34:30 +08:00
|
|
|
#[test]
|
2017-01-25 13:42:02 +08:00
|
|
|
fn test_established_retransmit_reset_after_ack() {
|
2017-01-23 19:34:30 +08:00
|
|
|
let mut s = socket_established();
|
|
|
|
s.remote_win_len = 6;
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.send_slice(b"123456").unwrap();
|
|
|
|
s.send_slice(b"ABCDEF").unwrap();
|
|
|
|
recv!(s, time 1000, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1005, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1010, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"123456"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1015, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1020, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"ABCDEF"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
}
|
2017-01-25 13:42:02 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_close_wait_retransmit_reset_after_ack() {
|
|
|
|
let mut s = socket_close_wait();
|
|
|
|
s.remote_win_len = 6;
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.send_slice(b"123456").unwrap();
|
|
|
|
s.send_slice(b"ABCDEF").unwrap();
|
|
|
|
recv!(s, time 1000, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1005, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1010, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
payload: &b"123456"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1015, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1 + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1020, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1 + 1),
|
|
|
|
payload: &b"ABCDEF"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
}
|
2017-01-25 14:01:58 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_fin_wait_1_retransmit_reset_after_ack() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.remote_win_len = 6;
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.send_slice(b"123456").unwrap();
|
|
|
|
s.send_slice(b"ABCDEF").unwrap();
|
|
|
|
s.close();
|
|
|
|
recv!(s, time 1000, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1005, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1010, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"123456"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
send!(s, time 1015, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 1020, Ok(TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &b"ABCDEF"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}));
|
|
|
|
}
|
2017-01-27 11:06:52 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_maximum_segment_size() {
|
|
|
|
let mut s = socket_listen();
|
|
|
|
s.tx_buffer = SocketBuffer::new(vec![0; 32767]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: REMOTE_SEQ,
|
|
|
|
ack_number: None,
|
|
|
|
max_seg_size: Some(1000),
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
control: TcpControl::Syn,
|
|
|
|
seq_number: LOCAL_SEQ,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
max_seg_size: Some(1480),
|
|
|
|
..RECV_TEMPL
|
|
|
|
}]);
|
|
|
|
send!(s, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1),
|
|
|
|
window_len: 32767,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
s.send_slice(&[0; 1200][..]).unwrap();
|
|
|
|
recv!(s, [TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
payload: &[0; 1000][..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}])
|
|
|
|
}
|
2017-03-07 19:21:49 +08:00
|
|
|
|
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for window management.
|
|
|
|
// =========================================================================================//
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_window_size_clamp() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.rx_buffer = SocketBuffer::new(vec![0; 32767]);
|
|
|
|
|
|
|
|
let mut limits = DeviceLimits::default();
|
|
|
|
limits.max_transmission_unit = 1520;
|
|
|
|
|
|
|
|
limits.max_burst_size = None;
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.dispatch(0, &limits, &mut |ip_repr, payload| {
|
|
|
|
let mut buffer = vec![0; payload.buffer_len()];
|
|
|
|
payload.emit(&ip_repr, &mut buffer[..]);
|
Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.
This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
* `fn check_len(&self) -> Result<(), Error>`, purely a validator;
* `fn new(T) -> Self`, purely a wrapper;
* `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.
This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).
Fixes #17.
2017-06-24 17:15:22 +08:00
|
|
|
let packet = TcpPacket::new(&buffer[..]);
|
2017-03-07 19:21:49 +08:00
|
|
|
assert_eq!(packet.window_len(), 32767);
|
|
|
|
Ok(())
|
|
|
|
}).unwrap();
|
|
|
|
|
|
|
|
limits.max_burst_size = Some(4);
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.dispatch(0, &limits, &mut |ip_repr, payload| {
|
|
|
|
let mut buffer = vec![0; payload.buffer_len()];
|
|
|
|
payload.emit(&ip_repr, &mut buffer[..]);
|
Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.
This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
* `fn check_len(&self) -> Result<(), Error>`, purely a validator;
* `fn new(T) -> Self`, purely a wrapper;
* `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.
This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).
Fixes #17.
2017-06-24 17:15:22 +08:00
|
|
|
let packet = TcpPacket::new(&buffer[..]);
|
2017-03-07 19:21:49 +08:00
|
|
|
assert_eq!(packet.window_len(), 5920);
|
|
|
|
Ok(())
|
|
|
|
}).unwrap();
|
|
|
|
}
|
2017-06-26 07:12:25 +08:00
|
|
|
|
|
|
|
// =========================================================================================//
|
|
|
|
// Tests for flow control.
|
|
|
|
// =========================================================================================//
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_psh() {
|
|
|
|
let mut s = socket_established();
|
|
|
|
s.remote_win_len = 6;
|
|
|
|
s.send_slice(b"abcdef").unwrap();
|
|
|
|
s.send_slice(b"123456").unwrap();
|
|
|
|
s.close();
|
|
|
|
recv!(s, time 0, Ok(TcpRepr {
|
|
|
|
seq_number: LOCAL_SEQ + 1,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
push: false,
|
|
|
|
payload: &b"abcdef"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}), exact);
|
|
|
|
send!(s, time 0, TcpRepr {
|
|
|
|
seq_number: REMOTE_SEQ + 1,
|
|
|
|
ack_number: Some(LOCAL_SEQ + 1 + 6),
|
|
|
|
window_len: 6,
|
|
|
|
..SEND_TEMPL
|
|
|
|
});
|
|
|
|
recv!(s, time 0, Ok(TcpRepr {
|
|
|
|
control: TcpControl::Fin,
|
|
|
|
seq_number: LOCAL_SEQ + 1 + 6,
|
|
|
|
ack_number: Some(REMOTE_SEQ + 1),
|
|
|
|
push: true,
|
|
|
|
payload: &b"123456"[..],
|
|
|
|
..RECV_TEMPL
|
|
|
|
}), exact);
|
|
|
|
}
|
2016-12-19 03:40:11 +08:00
|
|
|
}
|