tcp: do not scale window in SYN packets.
This commit is contained in:
parent
4045dee3f9
commit
9101e039d5
|
@ -1515,7 +1515,11 @@ impl<'a> TcpSocket<'a> {
|
||||||
|
|
||||||
// RFC 1323: The window field (SEG.WND) in the header of every incoming segment, with the
|
// RFC 1323: The window field (SEG.WND) in the header of every incoming segment, with the
|
||||||
// exception of SYN segments, is left-shifted by Snd.Wind.Scale bits before updating SND.WND.
|
// exception of SYN segments, is left-shifted by Snd.Wind.Scale bits before updating SND.WND.
|
||||||
self.remote_win_len = (repr.window_len as usize) << (self.remote_win_scale.unwrap_or(0) as usize);
|
let scale = match repr.control {
|
||||||
|
TcpControl::Syn => 0,
|
||||||
|
_ => self.remote_win_scale.unwrap_or(0),
|
||||||
|
};
|
||||||
|
self.remote_win_len = (repr.window_len as usize) << (scale as usize);
|
||||||
|
|
||||||
if ack_len > 0 {
|
if ack_len > 0 {
|
||||||
// Dequeue acknowledged octets.
|
// Dequeue acknowledged octets.
|
||||||
|
@ -1746,7 +1750,7 @@ impl<'a> TcpSocket<'a> {
|
||||||
fn window_to_update(&self) -> bool {
|
fn window_to_update(&self) -> bool {
|
||||||
match self.state {
|
match self.state {
|
||||||
State::SynSent | State::SynReceived | State::Established | State::FinWait1 | State::FinWait2 =>
|
State::SynSent | State::SynReceived | State::Established | State::FinWait1 | State::FinWait2 =>
|
||||||
(self.rx_buffer.window() >> self.remote_win_shift) as u16 > self.remote_last_win,
|
self.scaled_window() > self.remote_last_win,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1858,6 +1862,8 @@ impl<'a> TcpSocket<'a> {
|
||||||
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
||||||
State::SynSent | State::SynReceived => {
|
State::SynSent | State::SynReceived => {
|
||||||
repr.control = TcpControl::Syn;
|
repr.control = TcpControl::Syn;
|
||||||
|
// window len must NOT be scaled in SYNs.
|
||||||
|
repr.window_len = self.rx_buffer.window().min((1<<16)-1) as u16;
|
||||||
if self.state == State::SynSent {
|
if self.state == State::SynSent {
|
||||||
repr.ack_number = None;
|
repr.ack_number = None;
|
||||||
repr.window_scale = Some(self.remote_win_shift);
|
repr.window_scale = Some(self.remote_win_shift);
|
||||||
|
@ -2503,7 +2509,7 @@ mod test {
|
||||||
ack_number: Some(REMOTE_SEQ + 1),
|
ack_number: Some(REMOTE_SEQ + 1),
|
||||||
max_seg_size: Some(BASE_MSS),
|
max_seg_size: Some(BASE_MSS),
|
||||||
window_scale: Some(*shift_amt),
|
window_scale: Some(*shift_amt),
|
||||||
window_len: cmp::min(*buffer_size >> *shift_amt, 65535) as u16,
|
window_len: cmp::min(*buffer_size, 65535) as u16,
|
||||||
..RECV_TEMPL
|
..RECV_TEMPL
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
|
@ -2932,7 +2938,7 @@ mod test {
|
||||||
ack_number: None,
|
ack_number: None,
|
||||||
max_seg_size: Some(BASE_MSS),
|
max_seg_size: Some(BASE_MSS),
|
||||||
window_scale: Some(*shift_amt),
|
window_scale: Some(*shift_amt),
|
||||||
window_len: cmp::min(*buffer_size >> *shift_amt, 65535) as u16,
|
window_len: cmp::min(*buffer_size, 65535) as u16,
|
||||||
sack_permitted: true,
|
sack_permitted: true,
|
||||||
..RECV_TEMPL
|
..RECV_TEMPL
|
||||||
}]);
|
}]);
|
||||||
|
@ -2947,7 +2953,8 @@ mod test {
|
||||||
seq_number: LOCAL_SEQ,
|
seq_number: LOCAL_SEQ,
|
||||||
ack_number: None,
|
ack_number: None,
|
||||||
max_seg_size: Some(BASE_MSS),
|
max_seg_size: Some(BASE_MSS),
|
||||||
window_len: 32768,
|
// scaling does NOT apply to the window value in SYN packets
|
||||||
|
window_len: 65535,
|
||||||
window_scale: Some(5),
|
window_scale: Some(5),
|
||||||
sack_permitted: true,
|
sack_permitted: true,
|
||||||
..RECV_TEMPL
|
..RECV_TEMPL
|
||||||
|
@ -2965,6 +2972,7 @@ mod test {
|
||||||
assert_eq!(s.state, State::Established);
|
assert_eq!(s.state, State::Established);
|
||||||
assert_eq!(s.remote_win_shift, 0);
|
assert_eq!(s.remote_win_shift, 0);
|
||||||
assert_eq!(s.remote_win_scale, None);
|
assert_eq!(s.remote_win_scale, None);
|
||||||
|
assert_eq!(s.remote_win_len, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -2990,6 +2998,8 @@ mod test {
|
||||||
});
|
});
|
||||||
assert_eq!(s.state, State::Established);
|
assert_eq!(s.state, State::Established);
|
||||||
assert_eq!(s.remote_win_scale, Some(7));
|
assert_eq!(s.remote_win_scale, Some(7));
|
||||||
|
// scaling does NOT apply to the window value in SYN packets
|
||||||
|
assert_eq!(s.remote_win_len, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================================//
|
// =========================================================================================//
|
||||||
|
|
Loading…
Reference in New Issue