Send the TCP MSS option.
parent
077513fda6
commit
bc1d65ea89
|
@ -353,10 +353,11 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
|||
let src_protocol_addrs = self.protocol_addrs.as_ref();
|
||||
let arp_cache = &mut self.arp_cache;
|
||||
let device = &mut self.device;
|
||||
let mtu = device.mtu() - EthernetFrame::<&[u8]>::header_len();
|
||||
|
||||
let mut nothing_to_transmit = true;
|
||||
for socket in sockets.iter_mut() {
|
||||
let result = socket.dispatch(timestamp, &mut |repr, payload| {
|
||||
let result = socket.dispatch(timestamp, mtu, &mut |repr, payload| {
|
||||
let repr = try!(repr.lower(src_protocol_addrs));
|
||||
|
||||
let dst_hardware_addr =
|
||||
|
|
|
@ -92,9 +92,10 @@ impl<'a, 'b> Socket<'a, 'b> {
|
|||
/// is returned.
|
||||
///
|
||||
/// This function is used internally by the networking stack.
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, emit: &mut F) -> Result<R, Error>
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, mtu: usize,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, emit))
|
||||
dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, mtu, emit))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -816,7 +816,8 @@ impl<'a> TcpSocket<'a> {
|
|||
}
|
||||
|
||||
/// See [Socket::dispatch](enum.Socket.html#method.dispatch).
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, emit: &mut F) -> Result<R, Error>
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, mtu: usize,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
if self.remote_endpoint.is_unspecified() { return Err(Error::Exhausted) }
|
||||
|
||||
|
@ -875,19 +876,12 @@ impl<'a> TcpSocket<'a> {
|
|||
}
|
||||
|
||||
// We transmit a SYN|ACK in the SYN-RECEIVED state.
|
||||
State::SynReceived => {
|
||||
repr.control = TcpControl::Syn;
|
||||
net_trace!("[{}]{}:{}: sending SYN|ACK",
|
||||
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||
should_send = true;
|
||||
}
|
||||
|
||||
// We transmit a SYN in the SYN-SENT state.
|
||||
State::SynSent => {
|
||||
State::SynReceived | State::SynSent => {
|
||||
repr.control = TcpControl::Syn;
|
||||
repr.ack_number = None;
|
||||
net_trace!("[{}]{}:{}: sending SYN",
|
||||
self.debug_id, self.local_endpoint, self.remote_endpoint);
|
||||
net_trace!("[{}]{}:{}: sending SYN{}",
|
||||
self.debug_id, self.local_endpoint, self.remote_endpoint,
|
||||
if repr.ack_number.is_some() { "|ACK" } else { "" });
|
||||
should_send = true;
|
||||
}
|
||||
|
||||
|
@ -965,11 +959,18 @@ impl<'a> TcpSocket<'a> {
|
|||
self.remote_last_ack = ack_number;
|
||||
|
||||
let ip_repr = IpRepr::Unspecified {
|
||||
src_addr: self.local_endpoint.addr,
|
||||
dst_addr: self.remote_endpoint.addr,
|
||||
protocol: IpProtocol::Tcp,
|
||||
payload_len: repr.buffer_len()
|
||||
src_addr: self.local_endpoint.addr,
|
||||
dst_addr: self.remote_endpoint.addr,
|
||||
protocol: IpProtocol::Tcp,
|
||||
payload_len: repr.buffer_len()
|
||||
};
|
||||
let ip_repr = try!(ip_repr.lower(&[]));
|
||||
|
||||
if repr.control == TcpControl::Syn {
|
||||
let mtu = mtu - repr.header_len() - ip_repr.buffer_len();
|
||||
repr.max_seg_size = Some(mtu as u16);
|
||||
}
|
||||
|
||||
emit(&ip_repr, &repr)
|
||||
} else {
|
||||
Err(Error::Exhausted)
|
||||
|
@ -1082,7 +1083,7 @@ mod test {
|
|||
fn recv<F>(socket: &mut TcpSocket, timestamp: u64, mut f: F)
|
||||
where F: FnMut(Result<TcpRepr, Error>) {
|
||||
let mut buffer = vec![];
|
||||
let result = socket.dispatch(timestamp, &mut |ip_repr, payload| {
|
||||
let result = socket.dispatch(timestamp, 1520, &mut |ip_repr, payload| {
|
||||
assert_eq!(ip_repr.protocol(), IpProtocol::Tcp);
|
||||
assert_eq!(ip_repr.src_addr(), LOCAL_IP);
|
||||
assert_eq!(ip_repr.dst_addr(), REMOTE_IP);
|
||||
|
@ -1295,6 +1296,7 @@ mod test {
|
|||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
send!(s, TcpRepr {
|
||||
|
@ -1871,6 +1873,7 @@ mod test {
|
|||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}]);
|
||||
send!(s, TcpRepr {
|
||||
|
@ -2102,12 +2105,14 @@ mod test {
|
|||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}));
|
||||
recv!(s, time 150, Ok(TcpRepr { // retransmit
|
||||
control: TcpControl::Syn,
|
||||
seq_number: LOCAL_SEQ,
|
||||
ack_number: Some(REMOTE_SEQ + 1),
|
||||
max_seg_size: Some(1480),
|
||||
..RECV_TEMPL
|
||||
}));
|
||||
send!(s, TcpRepr {
|
||||
|
|
|
@ -232,7 +232,8 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
|||
}
|
||||
|
||||
/// See [Socket::dispatch](enum.Socket.html#method.dispatch).
|
||||
pub fn dispatch<F, R>(&mut self, _timestamp: u64, emit: &mut F) -> Result<R, Error>
|
||||
pub fn dispatch<F, R>(&mut self, _timestamp: u64, _mtu: usize,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
let packet_buf = try!(self.tx_buffer.dequeue().map_err(|()| Error::Exhausted));
|
||||
net_trace!("[{}]{}:{}: sending {} octets",
|
||||
|
|
|
@ -96,6 +96,11 @@ impl<T: AsRef<[u8]>> Frame<T> {
|
|||
self.buffer
|
||||
}
|
||||
|
||||
/// Return the length of a frame header.
|
||||
pub fn header_len() -> usize {
|
||||
field::PAYLOAD.start
|
||||
}
|
||||
|
||||
/// Return the length of a buffer required to hold a packet with the payload
|
||||
/// of a given length.
|
||||
pub fn buffer_len(payload_len: usize) -> usize {
|
||||
|
|
Loading…
Reference in New Issue