Skip to content

Commit 550deb3

Browse files
committedSep 5, 2017
Don't instantly ACK every received TCP segment.
This is prohibited by RFC 1122. Instead, aggregate them, and respond once in the egress function. However, still instantly send challenge ACKs to trigger fast retransmit.
1 parent 962180b commit 550deb3

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed
 

‎src/socket/tcp.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -856,10 +856,18 @@ impl<'a> TcpSocket<'a> {
856856
_ => {
857857
let mut send_challenge_ack = false;
858858

859-
let window_start = self.remote_seq_no;
860-
let window_end = window_start + self.rx_buffer.capacity();
859+
let window_start = self.remote_seq_no + self.rx_buffer.len();
860+
let window_end = self.remote_seq_no + self.rx_buffer.capacity();
861861
let segment_start = repr.seq_number;
862-
let segment_end = segment_start + repr.segment_len();
862+
let segment_end = repr.seq_number + repr.segment_len();
863+
864+
if window_start == window_end && segment_start != segment_end {
865+
net_debug!("[{}]{}:{}: non-zero-length segment with zero receive window, \
866+
will only send an ACK",
867+
self.debug_id, self.local_endpoint, self.remote_endpoint);
868+
send_challenge_ack = true;
869+
}
870+
863871
if !((window_start <= segment_start && segment_start <= window_end) ||
864872
(window_start <= segment_end && segment_end <= window_end)) {
865873
net_debug!("[{}]{}:{}: segment not in receive window \
@@ -870,11 +878,11 @@ impl<'a> TcpSocket<'a> {
870878
}
871879

872880
// For now, do not actually try to reassemble out-of-order segments.
873-
if segment_start != window_start + self.rx_buffer.len() {
881+
if segment_start != window_start {
874882
net_debug!("[{}]{}:{}: out-of-order SEQ ({} not equal to {}), \
875883
will send challenge ACK",
876884
self.debug_id, self.local_endpoint, self.remote_endpoint,
877-
segment_start, window_start + self.rx_buffer.len());
885+
segment_start, window_start);
878886
// Some segments between what we have last received and this segment
879887
// went missing. Send a duplicate ACK; RFC 793 does not specify the behavior
880888
// required when receiving a duplicate ACK, but in practice (see RFC 1122
@@ -1092,16 +1100,9 @@ impl<'a> TcpSocket<'a> {
10921100
self.debug_id, self.local_endpoint, self.remote_endpoint,
10931101
repr.payload.len(), self.rx_buffer.len() + repr.payload.len());
10941102
self.rx_buffer.enqueue_slice(repr.payload);
1095-
1096-
// Send an acknowledgement.
1097-
self.remote_last_ack = Some(self.remote_seq_no + self.rx_buffer.len());
1098-
self.remote_last_win = self.rx_buffer.window() as u16;
1099-
Ok(Some(self.ack_reply(ip_repr, &repr)))
1100-
} else {
1101-
// No data to acknowledge; the logic to acknowledge SYN and FIN flags
1102-
// resides in dispatch().
1103-
Ok(None)
11041103
}
1104+
1105+
Ok(None)
11051106
}
11061107

11071108
fn seq_to_transmit(&self, control: TcpControl) -> bool {
@@ -1664,12 +1665,13 @@ mod test {
16641665
ack_number: Some(LOCAL_SEQ + 1),
16651666
payload: &b"abcdef"[..],
16661667
..SEND_TEMPL
1667-
}, Ok(Some(TcpRepr {
1668+
});
1669+
recv!(s, [TcpRepr {
16681670
seq_number: LOCAL_SEQ + 1,
16691671
ack_number: Some(REMOTE_SEQ + 1 + 6 + 1),
16701672
window_len: 58,
16711673
..RECV_TEMPL
1672-
})));
1674+
}]);
16731675
assert_eq!(s.state, State::CloseWait);
16741676
sanity!(s, TcpSocket {
16751677
remote_last_ack: Some(REMOTE_SEQ + 1 + 6 + 1),
@@ -1881,12 +1883,13 @@ mod test {
18811883
ack_number: Some(LOCAL_SEQ + 1),
18821884
payload: &b"abcdef"[..],
18831885
..SEND_TEMPL
1884-
}, Ok(Some(TcpRepr {
1886+
});
1887+
recv!(s, [TcpRepr {
18851888
seq_number: LOCAL_SEQ + 1,
18861889
ack_number: Some(REMOTE_SEQ + 1 + 6),
18871890
window_len: 58,
18881891
..RECV_TEMPL
1889-
})));
1892+
}]);
18901893
assert_eq!(s.rx_buffer.dequeue(6), &b"abcdef"[..]);
18911894
}
18921895

@@ -2610,12 +2613,13 @@ mod test {
26102613
ack_number: Some(LOCAL_SEQ + 1),
26112614
payload: &b"abcdef"[..],
26122615
..SEND_TEMPL
2613-
}, Ok(Some(TcpRepr {
2616+
});
2617+
recv!(s, [TcpRepr {
26142618
seq_number: LOCAL_SEQ + 1,
26152619
ack_number: Some(REMOTE_SEQ + 1 + 6),
26162620
window_len: 58,
26172621
..RECV_TEMPL
2618-
})));
2622+
}]);
26192623
s
26202624
}
26212625

@@ -2644,12 +2648,13 @@ mod test {
26442648
ack_number: Some(LOCAL_SEQ + 1),
26452649
payload: &b"abcdef"[..],
26462650
..SEND_TEMPL
2647-
}, Ok(Some(TcpRepr {
2651+
});
2652+
recv!(s, [TcpRepr {
26482653
seq_number: LOCAL_SEQ + 1,
26492654
ack_number: Some(REMOTE_SEQ + 1 + 6),
26502655
window_len: 58,
26512656
..RECV_TEMPL
2652-
})));
2657+
}]);
26532658
send!(s, TcpRepr {
26542659
seq_number: REMOTE_SEQ + 1 + 6 + 6,
26552660
ack_number: Some(LOCAL_SEQ + 1),
@@ -2950,12 +2955,13 @@ mod test {
29502955
ack_number: Some(LOCAL_SEQ + 1),
29512956
payload: &b"abcdef"[..],
29522957
..SEND_TEMPL
2953-
}, Ok(Some(TcpRepr {
2958+
});
2959+
recv!(s, [TcpRepr {
29542960
seq_number: LOCAL_SEQ + 1,
29552961
ack_number: Some(REMOTE_SEQ + 1 + 6),
29562962
window_len: 58,
29572963
..RECV_TEMPL
2958-
})));
2964+
}]);
29592965
}
29602966

29612967
#[test]
@@ -2967,12 +2973,13 @@ mod test {
29672973
ack_number: Some(LOCAL_SEQ + 1),
29682974
payload: &b"abcdef"[..],
29692975
..SEND_TEMPL
2970-
}, Ok(Some(TcpRepr {
2976+
});
2977+
recv!(s, [TcpRepr {
29712978
seq_number: LOCAL_SEQ + 1,
29722979
ack_number: Some(REMOTE_SEQ + 1 + 6),
29732980
window_len: 0,
29742981
..RECV_TEMPL
2975-
})));
2982+
}]);
29762983
send!(s, TcpRepr {
29772984
seq_number: REMOTE_SEQ + 1 + 6,
29782985
ack_number: Some(LOCAL_SEQ + 1),
@@ -2995,12 +3002,13 @@ mod test {
29953002
ack_number: Some(LOCAL_SEQ + 1),
29963003
payload: &b"abcdef"[..],
29973004
..SEND_TEMPL
2998-
}, Ok(Some(TcpRepr {
3005+
});
3006+
recv!(s, [TcpRepr {
29993007
seq_number: LOCAL_SEQ + 1,
30003008
ack_number: Some(REMOTE_SEQ + 1 + 6),
30013009
window_len: 0,
30023010
..RECV_TEMPL
3003-
})));
3011+
}]);
30043012
recv!(s, time 0, Err(Error::Exhausted));
30053013
assert_eq!(s.recv(3), Ok(&b"abc"[..]));
30063014
recv!(s, time 0, Ok(TcpRepr {

0 commit comments

Comments
 (0)
Please sign in to comment.