Fix the TCP SEQ acceptability check.

It has nothing to do with the last ACK transmitted.
This commit is contained in:
whitequark 2017-08-30 21:10:23 +00:00
parent c2bc20e9bf
commit 41ceeea9ac
1 changed files with 16 additions and 13 deletions

View File

@ -830,30 +830,33 @@ impl<'a> TcpSocket<'a> {
} }
} }
match (self.state, repr) { match self.state {
// In LISTEN and SYN-SENT states, we have not yet synchronized with the remote end. // In LISTEN and SYN-SENT states, we have not yet synchronized with the remote end.
(State::Listen, _) => (), State::Listen => (),
(State::SynSent, _) => (), State::SynSent => (),
// In all other states, segments must occupy a valid portion of the receive window. // In all other states, segments must occupy a valid portion of the receive window.
(_, &TcpRepr { seq_number, .. }) => { _ => {
let mut send_challenge_ack = false; let mut send_challenge_ack = false;
let window_start = self.remote_last_ack; let window_start = self.remote_seq_no;
let window_end = window_start + self.rx_buffer.capacity(); let window_end = window_start + self.rx_buffer.capacity();
if seq_number < window_start || seq_number > window_end { let segment_start = repr.seq_number;
net_debug!("[{}]{}:{}: SEQ not in receive window ({} not in {}..{}), \ let segment_end = segment_start + repr.segment_len();
will send challenge ACK", if !((window_start <= segment_start && segment_start <= window_end) ||
(window_start <= segment_end && segment_end <= window_end)) {
net_debug!("[{}]{}:{}: segment not in receive window \
({}..{} not intersecting {}..{}), will send challenge ACK",
self.debug_id, self.local_endpoint, self.remote_endpoint, self.debug_id, self.local_endpoint, self.remote_endpoint,
seq_number, window_start, window_end); segment_start, segment_end, window_start, window_end);
send_challenge_ack = true; send_challenge_ack = true;
} }
// For now, do not actually try to reassemble out-of-order segments. // For now, do not actually try to reassemble out-of-order segments.
if seq_number != self.remote_last_ack { if segment_start != window_start + self.rx_buffer.len() {
net_debug!("[{}]{}:{}: out-of-order SEQ ({} not in ..{}), \ net_debug!("[{}]{}:{}: out-of-order SEQ ({} not equal to {}), \
will send challenge ACK", will send challenge ACK",
self.debug_id, self.local_endpoint, self.remote_endpoint, self.debug_id, self.local_endpoint, self.remote_endpoint,
seq_number, self.remote_last_ack); segment_start, window_start + self.rx_buffer.len());
// Some segments between what we have last received and this segment // Some segments between what we have last received and this segment
// went missing. Send a duplicate ACK; RFC 793 does not specify the behavior // 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 // required when receiving a duplicate ACK, but in practice (see RFC 1122