TcpRepr::push → TcpControl::Psh.
This is done for simplification. FIN implies PSH, RST doesn't have any meaning with PSH, and SYN|PSH only makes sense in the context of TCP Fast Open, in the context of which, any data in the original SYN already implies PSH.
This commit is contained in:
parent
5396687d52
commit
afdf73ffef
|
@ -57,11 +57,11 @@ The TCP protocol is supported over IPv4. Server and client sockets are supported
|
||||||
* TCP urgent pointer is **not** supported; any urgent octets will be received alongside
|
* TCP urgent pointer is **not** supported; any urgent octets will be received alongside
|
||||||
data octets.
|
data octets.
|
||||||
* Reassembly of out-of-order segments is **not** supported.
|
* Reassembly of out-of-order segments is **not** supported.
|
||||||
* The status of TCP options is:
|
* The status of TCP options or extensions is:
|
||||||
* Maximum segment size option is supported.
|
* Maximum segment size option is supported.
|
||||||
* Window scaling is **not** supported, and the maximum buffer size is 65536.
|
* Window scaling is **not** supported, and the maximum buffer size is 65536.
|
||||||
* Timestamping is **not** supported.
|
* Timestamping is **not** supported.
|
||||||
* Fast open is **not** supported.
|
* Fast open is **not** supported when smoltcp initiates connection.
|
||||||
* Keepalive is **not** supported.
|
* Keepalive is **not** supported.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
|
@ -696,7 +696,6 @@ impl<'a> TcpSocket<'a> {
|
||||||
src_port: repr.dst_port,
|
src_port: repr.dst_port,
|
||||||
dst_port: repr.src_port,
|
dst_port: repr.src_port,
|
||||||
control: TcpControl::None,
|
control: TcpControl::None,
|
||||||
push: false,
|
|
||||||
seq_number: TcpSeqNumber(0),
|
seq_number: TcpSeqNumber(0),
|
||||||
ack_number: None,
|
ack_number: None,
|
||||||
window_len: 0,
|
window_len: 0,
|
||||||
|
@ -1103,7 +1102,6 @@ impl<'a> TcpSocket<'a> {
|
||||||
src_port: self.local_endpoint.port,
|
src_port: self.local_endpoint.port,
|
||||||
dst_port: self.remote_endpoint.port,
|
dst_port: self.remote_endpoint.port,
|
||||||
control: TcpControl::None,
|
control: TcpControl::None,
|
||||||
push: false,
|
|
||||||
seq_number: self.remote_next_seq,
|
seq_number: self.remote_next_seq,
|
||||||
ack_number: Some(self.remote_seq_no + self.rx_buffer.len()),
|
ack_number: Some(self.remote_seq_no + self.rx_buffer.len()),
|
||||||
window_len: self.rx_buffer.window() as u16,
|
window_len: self.rx_buffer.window() as u16,
|
||||||
|
@ -1146,7 +1144,7 @@ impl<'a> TcpSocket<'a> {
|
||||||
State::FinWait1 | State::LastAck =>
|
State::FinWait1 | State::LastAck =>
|
||||||
repr.control = TcpControl::Fin,
|
repr.control = TcpControl::Fin,
|
||||||
State::Established | State::CloseWait =>
|
State::Established | State::CloseWait =>
|
||||||
repr.push = true,
|
repr.control = TcpControl::Psh,
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1188,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
(TcpControl::Syn, Some(_)) => "SYN|ACK",
|
(TcpControl::Syn, Some(_)) => "SYN|ACK",
|
||||||
(TcpControl::Fin, Some(_)) => "FIN|ACK",
|
(TcpControl::Fin, Some(_)) => "FIN|ACK",
|
||||||
(TcpControl::Rst, Some(_)) => "RST|ACK",
|
(TcpControl::Rst, Some(_)) => "RST|ACK",
|
||||||
(TcpControl::None, _) => "ACK",
|
(TcpControl::Psh, Some(_)) => "PSH|ACK",
|
||||||
|
(TcpControl::None, Some(_)) => "ACK",
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
if repr.payload.len() > 0 {
|
if repr.payload.len() > 0 {
|
||||||
|
@ -1346,14 +1345,14 @@ mod test {
|
||||||
|
|
||||||
const SEND_TEMPL: TcpRepr<'static> = TcpRepr {
|
const SEND_TEMPL: TcpRepr<'static> = TcpRepr {
|
||||||
src_port: REMOTE_PORT, dst_port: LOCAL_PORT,
|
src_port: REMOTE_PORT, dst_port: LOCAL_PORT,
|
||||||
control: TcpControl::None, push: false,
|
control: TcpControl::None,
|
||||||
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
||||||
window_len: 256, max_seg_size: None,
|
window_len: 256, max_seg_size: None,
|
||||||
payload: &[]
|
payload: &[]
|
||||||
};
|
};
|
||||||
const RECV_TEMPL: TcpRepr<'static> = TcpRepr {
|
const RECV_TEMPL: TcpRepr<'static> = TcpRepr {
|
||||||
src_port: LOCAL_PORT, dst_port: REMOTE_PORT,
|
src_port: LOCAL_PORT, dst_port: REMOTE_PORT,
|
||||||
control: TcpControl::None, push: false,
|
control: TcpControl::None,
|
||||||
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
seq_number: TcpSeqNumber(0), ack_number: Some(TcpSeqNumber(0)),
|
||||||
window_len: 64, max_seg_size: None,
|
window_len: 64, max_seg_size: None,
|
||||||
payload: &[]
|
payload: &[]
|
||||||
|
@ -1426,10 +1425,15 @@ mod test {
|
||||||
($socket:ident, $result:expr) =>
|
($socket:ident, $result:expr) =>
|
||||||
(recv!($socket, time 0, $result));
|
(recv!($socket, time 0, $result));
|
||||||
($socket:ident, time $time:expr, $result:expr) =>
|
($socket:ident, time $time:expr, $result:expr) =>
|
||||||
(recv(&mut $socket, $time, |repr| {
|
(recv(&mut $socket, $time, |result| {
|
||||||
// Most of the time we don't care about the PSH flag.
|
// Most of the time we don't care about the PSH flag.
|
||||||
let repr = repr.map(|r| TcpRepr { push: false, ..r });
|
let result = result.map(|mut repr| {
|
||||||
assert_eq!(repr, $result)
|
if repr.control == TcpControl::Psh {
|
||||||
|
repr.control = TcpControl::None;
|
||||||
|
}
|
||||||
|
repr
|
||||||
|
});
|
||||||
|
assert_eq!(result, $result)
|
||||||
}));
|
}));
|
||||||
($socket:ident, time $time:expr, $result:expr, exact) =>
|
($socket:ident, time $time:expr, $result:expr, exact) =>
|
||||||
(recv(&mut $socket, $time, |repr| assert_eq!(repr, $result)));
|
(recv(&mut $socket, $time, |repr| assert_eq!(repr, $result)));
|
||||||
|
@ -2893,16 +2897,16 @@ mod test {
|
||||||
s.send_slice(b"abcdef").unwrap();
|
s.send_slice(b"abcdef").unwrap();
|
||||||
s.send_slice(b"123456").unwrap();
|
s.send_slice(b"123456").unwrap();
|
||||||
recv!(s, time 0, Ok(TcpRepr {
|
recv!(s, time 0, Ok(TcpRepr {
|
||||||
|
control: TcpControl::None,
|
||||||
seq_number: LOCAL_SEQ + 1,
|
seq_number: LOCAL_SEQ + 1,
|
||||||
ack_number: Some(REMOTE_SEQ + 1),
|
ack_number: Some(REMOTE_SEQ + 1),
|
||||||
push: false,
|
|
||||||
payload: &b"abcdef"[..],
|
payload: &b"abcdef"[..],
|
||||||
..RECV_TEMPL
|
..RECV_TEMPL
|
||||||
}), exact);
|
}), exact);
|
||||||
recv!(s, time 0, Ok(TcpRepr {
|
recv!(s, time 0, Ok(TcpRepr {
|
||||||
|
control: TcpControl::Psh,
|
||||||
seq_number: LOCAL_SEQ + 1 + 6,
|
seq_number: LOCAL_SEQ + 1 + 6,
|
||||||
ack_number: Some(REMOTE_SEQ + 1),
|
ack_number: Some(REMOTE_SEQ + 1),
|
||||||
push: true,
|
|
||||||
payload: &b"123456"[..],
|
payload: &b"123456"[..],
|
||||||
..RECV_TEMPL
|
..RECV_TEMPL
|
||||||
}), exact);
|
}), exact);
|
||||||
|
|
|
@ -603,6 +603,7 @@ impl<'a> TcpOption<'a> {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Control {
|
pub enum Control {
|
||||||
None,
|
None,
|
||||||
|
Psh,
|
||||||
Syn,
|
Syn,
|
||||||
Fin,
|
Fin,
|
||||||
Rst
|
Rst
|
||||||
|
@ -613,7 +614,7 @@ impl Control {
|
||||||
pub fn len(self) -> usize {
|
pub fn len(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Control::Syn | Control::Fin => 1,
|
Control::Syn | Control::Fin => 1,
|
||||||
Control::Rst | Control::None => 0
|
_ => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,7 +625,6 @@ pub struct Repr<'a> {
|
||||||
pub src_port: u16,
|
pub src_port: u16,
|
||||||
pub dst_port: u16,
|
pub dst_port: u16,
|
||||||
pub control: Control,
|
pub control: Control,
|
||||||
pub push: bool,
|
|
||||||
pub seq_number: SeqNumber,
|
pub seq_number: SeqNumber,
|
||||||
pub ack_number: Option<SeqNumber>,
|
pub ack_number: Option<SeqNumber>,
|
||||||
pub window_len: u16,
|
pub window_len: u16,
|
||||||
|
@ -645,11 +645,12 @@ impl<'a> Repr<'a> {
|
||||||
if !packet.verify_checksum(src_addr, dst_addr) { return Err(Error::Checksum) }
|
if !packet.verify_checksum(src_addr, dst_addr) { return Err(Error::Checksum) }
|
||||||
|
|
||||||
let control =
|
let control =
|
||||||
match (packet.syn(), packet.fin(), packet.rst()) {
|
match (packet.syn(), packet.fin(), packet.rst(), packet.psh()) {
|
||||||
(false, false, false) => Control::None,
|
(false, false, false, false) => Control::None,
|
||||||
(true, false, false) => Control::Syn,
|
(false, false, false, true) => Control::Psh,
|
||||||
(false, true, false) => Control::Fin,
|
(true, false, false, _) => Control::Syn,
|
||||||
(false, false, true ) => Control::Rst,
|
(false, true, false, _) => Control::Fin,
|
||||||
|
(false, false, true , _) => Control::Rst,
|
||||||
_ => return Err(Error::Malformed)
|
_ => return Err(Error::Malformed)
|
||||||
};
|
};
|
||||||
let ack_number =
|
let ack_number =
|
||||||
|
@ -680,7 +681,6 @@ impl<'a> Repr<'a> {
|
||||||
src_port: packet.src_port(),
|
src_port: packet.src_port(),
|
||||||
dst_port: packet.dst_port(),
|
dst_port: packet.dst_port(),
|
||||||
control: control,
|
control: control,
|
||||||
push: packet.psh(),
|
|
||||||
seq_number: packet.seq_number(),
|
seq_number: packet.seq_number(),
|
||||||
ack_number: ack_number,
|
ack_number: ack_number,
|
||||||
window_len: packet.window_len(),
|
window_len: packet.window_len(),
|
||||||
|
@ -716,11 +716,11 @@ impl<'a> Repr<'a> {
|
||||||
packet.clear_flags();
|
packet.clear_flags();
|
||||||
match self.control {
|
match self.control {
|
||||||
Control::None => (),
|
Control::None => (),
|
||||||
|
Control::Psh => packet.set_psh(true),
|
||||||
Control::Syn => packet.set_syn(true),
|
Control::Syn => packet.set_syn(true),
|
||||||
Control::Fin => packet.set_fin(true),
|
Control::Fin => packet.set_fin(true),
|
||||||
Control::Rst => packet.set_rst(true)
|
Control::Rst => packet.set_rst(true)
|
||||||
}
|
}
|
||||||
packet.set_psh(self.push);
|
|
||||||
packet.set_ack(self.ack_number.is_some());
|
packet.set_ack(self.ack_number.is_some());
|
||||||
{
|
{
|
||||||
let mut options = packet.options_mut();
|
let mut options = packet.options_mut();
|
||||||
|
@ -795,11 +795,9 @@ impl<'a> fmt::Display for Repr<'a> {
|
||||||
Control::Syn => write!(f, " syn")?,
|
Control::Syn => write!(f, " syn")?,
|
||||||
Control::Fin => write!(f, " fin")?,
|
Control::Fin => write!(f, " fin")?,
|
||||||
Control::Rst => write!(f, " rst")?,
|
Control::Rst => write!(f, " rst")?,
|
||||||
|
Control::Psh => write!(f, " psh")?,
|
||||||
Control::None => ()
|
Control::None => ()
|
||||||
}
|
}
|
||||||
if self.push {
|
|
||||||
write!(f, " psh")?;
|
|
||||||
}
|
|
||||||
write!(f, " seq={}", self.seq_number)?;
|
write!(f, " seq={}", self.seq_number)?;
|
||||||
if let Some(ack_number) = self.ack_number {
|
if let Some(ack_number) = self.ack_number {
|
||||||
write!(f, " ack={}", ack_number)?;
|
write!(f, " ack={}", ack_number)?;
|
||||||
|
@ -913,8 +911,8 @@ mod test {
|
||||||
[0xbf, 0x00, 0x00, 0x50,
|
[0xbf, 0x00, 0x00, 0x50,
|
||||||
0x01, 0x23, 0x45, 0x67,
|
0x01, 0x23, 0x45, 0x67,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x50, 0x0a, 0x01, 0x23,
|
0x50, 0x02, 0x01, 0x23,
|
||||||
0x7a, 0x85, 0x00, 0x00,
|
0x7a, 0x8d, 0x00, 0x00,
|
||||||
0xaa, 0x00, 0x00, 0xff];
|
0xaa, 0x00, 0x00, 0xff];
|
||||||
|
|
||||||
fn packet_repr() -> Repr<'static> {
|
fn packet_repr() -> Repr<'static> {
|
||||||
|
@ -925,7 +923,6 @@ mod test {
|
||||||
ack_number: None,
|
ack_number: None,
|
||||||
window_len: 0x0123,
|
window_len: 0x0123,
|
||||||
control: Control::Syn,
|
control: Control::Syn,
|
||||||
push: true,
|
|
||||||
max_seg_size: None,
|
max_seg_size: None,
|
||||||
payload: &PAYLOAD_BYTES
|
payload: &PAYLOAD_BYTES
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue