Skip to content

Commit ac32e64

Browse files
authored
Merge pull request #1079 from lrh2000/tcp-rej-out-win
tcp: Reject bytes outside the receive window
2 parents 8203207 + 005c69e commit ac32e64

File tree

1 file changed

+73
-1
lines changed

1 file changed

+73
-1
lines changed

src/socket/tcp.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1677,7 +1677,11 @@ impl<'a> Socket<'a> {
16771677
}
16781678

16791679
let window_start = self.remote_seq_no + self.rx_buffer.len();
1680-
let window_end = self.remote_seq_no + self.rx_buffer.capacity();
1680+
let window_end = if let Some(last_ack) = self.remote_last_ack {
1681+
last_ack + ((self.remote_last_win as usize) << self.remote_win_shift)
1682+
} else {
1683+
window_start
1684+
};
16811685
let segment_start = repr.seq_number;
16821686
let segment_end = repr.seq_number + repr.payload.len();
16831687

@@ -6789,6 +6793,74 @@ mod test {
67896793
);
67906794
}
67916795

6796+
#[test]
6797+
fn test_recv_out_of_recv_win() {
6798+
let mut s = socket_established();
6799+
s.set_ack_delay(Some(ACK_DELAY_DEFAULT));
6800+
s.remote_mss = 32;
6801+
6802+
// No ACKs are sent due to the ACK delay.
6803+
send!(
6804+
s,
6805+
TcpRepr {
6806+
control: TcpControl::Psh,
6807+
seq_number: REMOTE_SEQ + 1,
6808+
ack_number: Some(LOCAL_SEQ + 1),
6809+
payload: &[0; 32],
6810+
..SEND_TEMPL
6811+
}
6812+
);
6813+
recv_nothing!(s);
6814+
6815+
// RMSS+1 bytes of data has been received, so ACK is sent without delay.
6816+
send!(
6817+
s,
6818+
TcpRepr {
6819+
control: TcpControl::Psh,
6820+
seq_number: REMOTE_SEQ + 33,
6821+
ack_number: Some(LOCAL_SEQ + 1),
6822+
payload: &[0; 1],
6823+
..SEND_TEMPL
6824+
}
6825+
);
6826+
recv!(
6827+
s,
6828+
Ok(TcpRepr {
6829+
seq_number: LOCAL_SEQ + 1,
6830+
ack_number: Some(REMOTE_SEQ + 34),
6831+
window_len: 31,
6832+
..RECV_TEMPL
6833+
})
6834+
);
6835+
6836+
// This frees up a byte in the receive buffer. However, the remote shouldn't be aware of
6837+
// this since no ACKs are sent.
6838+
s.recv_slice(&mut [0; 1]).unwrap();
6839+
recv_nothing!(s);
6840+
6841+
// Now, if the remote wants to send one byte outside of the receive window that we
6842+
// previously advertised, it should not succeed.
6843+
send!(
6844+
s,
6845+
TcpRepr {
6846+
control: TcpControl::Psh,
6847+
seq_number: REMOTE_SEQ + 34,
6848+
ack_number: Some(LOCAL_SEQ + 1),
6849+
payload: &[0; 32],
6850+
..SEND_TEMPL
6851+
}
6852+
);
6853+
recv!(
6854+
s,
6855+
Ok(TcpRepr {
6856+
seq_number: LOCAL_SEQ + 1,
6857+
ack_number: Some(REMOTE_SEQ + 65),
6858+
window_len: 1, // The last byte isn't accepted.
6859+
..RECV_TEMPL
6860+
})
6861+
);
6862+
}
6863+
67926864
#[test]
67936865
fn test_close_wait_no_window_update() {
67946866
let mut s = socket_established();

0 commit comments

Comments
 (0)