Receive the TCP MSS option and act on it.
This commit is contained in:
parent
bc1d65ea89
commit
d6b7623c37
|
@ -245,6 +245,8 @@ pub struct TcpSocket<'a> {
|
|||
/// The speculative remote window size.
|
||||
/// I.e. the actual remote window size minus the count of in-flight octets.
|
||||
remote_win_len: usize,
|
||||
/// The maximum number of data octets that the remote side may receive.
|
||||
remote_mss: usize,
|
||||
retransmit: Retransmit,
|
||||
rx_buffer: SocketBuffer<'a>,
|
||||
tx_buffer: SocketBuffer<'a>,
|
||||
|
@ -271,6 +273,7 @@ impl<'a> TcpSocket<'a> {
|
|||
remote_last_seq: TcpSeqNumber(0),
|
||||
remote_last_ack: TcpSeqNumber(0),
|
||||
remote_win_len: 0,
|
||||
remote_mss: 536,
|
||||
retransmit: Retransmit::new(),
|
||||
tx_buffer: tx_buffer.into(),
|
||||
rx_buffer: rx_buffer.into(),
|
||||
|
@ -688,7 +691,8 @@ impl<'a> TcpSocket<'a> {
|
|||
|
||||
// SYN packets in the LISTEN state change it to SYN-RECEIVED.
|
||||
(State::Listen, TcpRepr {
|
||||
src_port, dst_port, control: TcpControl::Syn, seq_number, ack_number: None, ..
|
||||
src_port, dst_port, control: TcpControl::Syn, seq_number, ack_number: None,
|
||||
max_seg_size, ..
|
||||
}) => {
|
||||
net_trace!("[{}]{}: received SYN",
|
||||
self.debug_id, self.local_endpoint);
|
||||
|
@ -698,6 +702,9 @@ impl<'a> TcpSocket<'a> {
|
|||
self.local_seq_no = TcpSeqNumber(-seq_number.0);
|
||||
self.remote_last_seq = self.local_seq_no + 1;
|
||||
self.remote_seq_no = seq_number + 1;
|
||||
if let Some(max_seg_size) = max_seg_size {
|
||||
self.remote_mss = max_seg_size as usize
|
||||
}
|
||||
self.set_state(State::SynReceived);
|
||||
self.retransmit.reset();
|
||||
}
|
||||
|
@ -897,8 +904,8 @@ impl<'a> TcpSocket<'a> {
|
|||
let mut size = self.tx_buffer.len();
|
||||
// Clamp to remote window length.
|
||||
if size > self.remote_win_len { size = self.remote_win_len }
|
||||
// Clamp to MSS. Currently we only support the default MSS value.
|
||||
if size > 536 { size = 536 }
|
||||
// Clamp to MSS.
|
||||
if size > self.remote_mss { size = self.remote_mss }
|
||||
// Extract data from the buffer. This may return less than what we want,
|
||||
// in case it's not possible to extract a contiguous slice.
|
||||
let offset = self.remote_last_seq - self.local_seq_no;
|
||||
|
@ -2248,4 +2255,37 @@ mod test {
|
|||
..RECV_TEMPL
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_segment_size() {
|
||||
let mut s = socket_listen();
|
||||
s.tx_buffer = SocketBuffer::new(vec![0; 32767]);
|
||||
send!(s, TcpRepr {
|
||||
control: TcpControl::Syn,
|
||||
seq_number: REMOTE_SEQ,
|
||||
ack_number: None,
|
||||
max_seg_size: Some(1000),
|
||||
..SEND_TEMPL
|
||||
});
|
||||
recv!(s, [TcpRepr {
|
||||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
send!(s, TcpRepr {
|
||||
seq_number: REMOTE_SEQ + 1,
|
||||
ack_number: Some(LOCAL_SEQ + 1),
|
||||
window_len: 32767,
|
||||
..SEND_TEMPL
|
||||
});
|
||||
s.send_slice(&[0; 1200][..]).unwrap();
|
||||
recv!(s, [TcpRepr {
|
||||
seq_number: LOCAL_SEQ + 1,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
payload: &[0; 1000][..],
|
||||
..RECV_TEMPL
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue