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:
whitequark 2017-08-25 06:03:54 +00:00
parent 5396687d52
commit afdf73ffef
3 changed files with 29 additions and 28 deletions

View File

@ -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

View File

@ -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);

View File

@ -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
} }