Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 30cafe310621
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c43446ff3ae7
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Sep 22, 2017

  1. Copy the full SHA
    968255e View commit details
  2. Do not clear remote_last_ts in TcpSocket::set_timeout().

    After this change, if an 1s timeout is set on a socket that received
    no packet for 2s, it will be instantly aborted, which seems
    more reasonable. Also, this makes the `self.remote_last_ts.is_none()`
    branch in TcpSocket::dispatch() actually behave as described.
    whitequark committed Sep 22, 2017
    Copy the full SHA
    c43446f View commit details
Showing with 26 additions and 28 deletions.
  1. +26 −28 src/socket/tcp.rs
54 changes: 26 additions & 28 deletions src/socket/tcp.rs
Original file line number Diff line number Diff line change
@@ -280,8 +280,7 @@ impl<'a> TcpSocket<'a> {
/// * After enabling [keep-alive](#method.set_keep_alive), the remote endpoint exceeds
/// the specified duration between any two packets it sends.
pub fn set_timeout(&mut self, duration: Option<u64>) {
self.timeout = duration;
self.remote_last_ts = None;
self.timeout = duration
}

/// Return the keep-alive interval.
@@ -1172,6 +1171,17 @@ impl<'a> TcpSocket<'a> {
}
}

// Construct the lowered IP representation.
// We might need this to calculate the MSS, so do it early.
let mut ip_repr = IpRepr::Unspecified {
src_addr: self.local_endpoint.addr,
dst_addr: self.remote_endpoint.addr,
protocol: IpProtocol::Tcp,
payload_len: 0
}.lower(&[])?;

// Construct the basic TCP representation, an empty ACK packet.
// We'll adjust this to be more specific as needed.
let mut repr = TcpRepr {
src_port: self.local_endpoint.port,
dst_port: self.remote_endpoint.port,
@@ -1290,33 +1300,21 @@ impl<'a> TcpSocket<'a> {
is_keep_alive = false;
}

// Remember the header length before enabling the MSS option, since that option
// only affects SYN packets.
let header_len = repr.header_len();

if repr.control == TcpControl::Syn {
// First enable the option, without assigning any value, to get a correct
// result for the payload_len field of ip_repr below.
repr.max_seg_size = Some(0);
}

// Then, construct the IP representation, since we know the final length
// of the TCP header.
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()
}.lower(&[])?;

// Finally, compute the maximum segment size, deriving it from from the underlying
// maximum transmission unit and the header sizes we just determined.
let mut max_segment_size = limits.max_transmission_unit;
max_segment_size -= header_len;
max_segment_size -= ip_repr.buffer_len();

if repr.control == TcpControl::Syn {
// And fill in the actual option, if it's a SYN packet.
// Compute the maximum segment size, deriving it from from the underlying
// maximum transmission unit and the IP and TCP header sizes.
//
// Note that what we actually *want* is for the other party to limit
// the total length of the TCP segment, but what we *get* is limiting
// the amount of data in the TCP segment. As a result, if they interpret
// the requirement naively and send us a TCP packet with both some options
// and an MSS-sized payload, that packet's last few bytes will get split
// into a tiny fragment.
//
// TCP is not a well-designed protocol.
let mut max_segment_size = limits.max_transmission_unit;
max_segment_size -= ip_repr.buffer_len();
max_segment_size -= repr.header_len();
repr.max_seg_size = Some(max_segment_size as u16);
}