diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-01-15 23:35:16 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-15 23:35:16 +0000 |
commit | 0b4604d503bfac4dfccd6f0b7e34b55dc2c9e36d (patch) | |
tree | b9266d74221158cdbd0393379c4be4475a5bd1b4 /pkg/tcpip/transport/tcp | |
parent | 05c07164804f4721cba4df0dad040082286ef37c (diff) | |
parent | f37ace6661dfed8acae7e22ed0eb9ad78bdeab34 (diff) |
Merge release-20210112.0-36-gf37ace666 (automated)
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-rw-r--r-- | pkg/tcpip/transport/tcp/rack.go | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/pkg/tcpip/transport/tcp/rack.go b/pkg/tcpip/transport/tcp/rack.go index 5a4ee70f5..307bacca5 100644 --- a/pkg/tcpip/transport/tcp/rack.go +++ b/pkg/tcpip/transport/tcp/rack.go @@ -197,18 +197,42 @@ func (s *sender) probeTimerExpired() *tcpip.Error { if !s.rc.probeTimer.checkExpiration() { return nil } - // TODO(gvisor.dev/issue/5084): Implement this pseudo algorithm. - // If an unsent segment exists AND - // the receive window allows new data to be sent: - // Transmit the lowest-sequence unsent segment of up to SMSS - // Increment FlightSize by the size of the newly-sent segment - // Else if TLPRxtOut is not set: - // Retransmit the highest-sequence segment sent so far - // TLPRxtOut = true - // TLPHighRxt = SND.NXT - // The cwnd remains unchanged - // If FlightSize != 0: - // Arm RTO timer only. + + var dataSent bool + if s.writeNext != nil && s.writeNext.xmitCount == 0 && s.outstanding < s.sndCwnd { + dataSent = s.maybeSendSegment(s.writeNext, int(s.ep.scoreboard.SMSS()), s.sndUna.Add(s.sndWnd)) + if dataSent { + s.outstanding += s.pCount(s.writeNext, s.maxPayloadSize) + s.writeNext = s.writeNext.Next() + } + } + + if !dataSent && !s.rc.tlpRxtOut { + var highestSeqXmit *segment + for highestSeqXmit = s.writeList.Front(); highestSeqXmit != nil; highestSeqXmit = highestSeqXmit.Next() { + if highestSeqXmit.xmitCount == 0 { + // Nothing in writeList is transmitted, no need to send a probe. + highestSeqXmit = nil + break + } + if highestSeqXmit.Next() == nil || highestSeqXmit.Next().xmitCount == 0 { + // Either everything in writeList has been transmitted or the next + // sequence has not been transmitted. Either way this is the highest + // sequence segment that was transmitted. + break + } + } + + if highestSeqXmit != nil { + dataSent = s.maybeSendSegment(highestSeqXmit, int(s.ep.scoreboard.SMSS()), s.sndUna.Add(s.sndWnd)) + if dataSent { + s.rc.tlpRxtOut = true + s.rc.tlpHighRxt = s.sndNxt + } + } + } + + s.postXmit(dataSent) return nil } |