TCP: Fix Zero Window Probes.
I did some tcpdump recording, and I believe we confuse the receiver with our Zero Window Probe, because we don't resent even though it only ACKs the previous segment, and we keep sending things after it: * we send the last segment before window is closed, next seg = N, * we get ACK for N, with window=0 * we send Zero Window Probe with 1 byte, next seg = N+1, * we eventually get a window>0 ACK still at N, * we start sending stuff again, but starting from N+1, * receiver keeps ACKing N because it never accepted it. It seems sending either 1 or 0 byte is valid for a ZWP, although I'm not entirely sure. At least it's easier to handle 0 than 1, and it seems to work. Wireshark shows them as duplicate ACKs, but they get the thing going. References: * RFC 793: https://tools.ietf.org/html/rfc793#section-3.7 * RFC 6429: https://tools.ietf.org/html/rfc6429 * Wireshark wiki: https://www.wireshark.org/docs/wsug_html_chunked/ChAdvTCPAnalysis.html Should fix #13769. Change-Id: I95264ebbbb8c66c23411dfce6fc41871e0427166 Reviewed-on: https://review.haiku-os.org/c/haiku/+/1188 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
934ad06cf1
commit
f0ba8f6aca
@ -2084,12 +2084,6 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
||||
} else
|
||||
sendWindow -= consumedWindow;
|
||||
|
||||
if (force && sendWindow == 0 && fSendNext <= fSendQueue.LastSequence()) {
|
||||
// send one byte of data to ask for a window update
|
||||
// (triggered by the persist timer)
|
||||
sendWindow = 1;
|
||||
}
|
||||
|
||||
uint32 length = min_c(fSendQueue.Available(fSendNext), sendWindow);
|
||||
bool shouldStartRetransmitTimer = fSendNext == fSendUnacknowledged;
|
||||
bool retransmit = fSendNext < fSendMax;
|
||||
@ -2104,7 +2098,7 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
||||
- tcp_options_length(segment);
|
||||
uint32 segmentLength = min_c(length, segmentMaxSize);
|
||||
|
||||
if (fSendNext + segmentLength == fSendQueue.LastSequence()) {
|
||||
if (fSendNext + segmentLength == fSendQueue.LastSequence() && !force) {
|
||||
if (state_needs_finish(fState))
|
||||
segment.flags |= TCP_FLAG_FINISH;
|
||||
if (length > 0)
|
||||
|
Loading…
Reference in New Issue
Block a user