Expose TCP RTT

PiperOrigin-RevId: 211504634
Change-Id: I9a7bcbbdd40e5036894930f709278725ef477293
This commit is contained in:
Tamir Duberstein
2018-09-04 12:39:47 -07:00
committed by Shentubot
parent c09f9acd7c
commit 3794cb6bff
4 changed files with 45 additions and 14 deletions
+4 -1
View File
@@ -430,7 +430,10 @@ type TimestampOption int
// TCPInfoOption is used by GetSockOpt to expose TCP statistics.
//
// TODO: Add and populate stat fields.
type TCPInfoOption struct{}
type TCPInfoOption struct {
RTT time.Duration
RTTVar time.Duration
}
// Route is a row in the routing table. It specifies through which NIC (and
// gateway) sets of packets should be routed. A row is considered viable if the
+4 -1
View File
@@ -129,7 +129,10 @@ func (c *cubicState) Update(packetsAcked int) {
return
}
} else {
c.s.sndCwnd = c.getCwnd(packetsAcked, c.s.sndCwnd, c.s.srtt)
c.s.rtt.Lock()
srtt := c.s.rtt.srtt
c.s.rtt.Unlock()
c.s.sndCwnd = c.getCwnd(packetsAcked, c.s.sndCwnd, srtt)
}
}
+13 -1
View File
@@ -788,6 +788,16 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error {
case *tcpip.TCPInfoOption:
*o = tcpip.TCPInfoOption{}
e.mu.RLock()
snd := e.snd
e.mu.RUnlock()
if snd != nil {
snd.rtt.Lock()
o.RTT = snd.rtt.srtt
o.RTTVar = snd.rtt.rttvar
snd.rtt.Unlock()
}
return nil
}
@@ -1463,13 +1473,15 @@ func (e *endpoint) completeState() stack.TCPEndpointState {
RTTMeasureSeqNum: e.snd.rttMeasureSeqNum,
RTTMeasureTime: e.snd.rttMeasureTime,
Closed: e.snd.closed,
SRTT: e.snd.srtt,
RTO: e.snd.rto,
SRTTInited: e.snd.srttInited,
MaxPayloadSize: e.snd.maxPayloadSize,
SndWndScale: e.snd.sndWndScale,
MaxSentAck: e.snd.maxSentAck,
}
e.snd.rtt.Lock()
s.Sender.SRTT = e.snd.rtt.srtt
e.snd.rtt.Unlock()
if cubic, ok := e.snd.cc.(*cubicState); ok {
s.Sender.Cubic = stack.TCPCubicState{
+24 -11
View File
@@ -16,6 +16,7 @@ package tcp
import (
"math"
"sync"
"time"
"gvisor.googlesource.com/gvisor/pkg/sleep"
@@ -116,11 +117,10 @@ type sender struct {
resendTimer timer `state:"nosave"`
resendWaker sleep.Waker `state:"nosave"`
// srtt, rttvar & rto are the "smoothed round-trip time", "round-trip
// time variation" and "retransmit timeout", as defined in section 2 of
// RFC 6298.
srtt time.Duration
rttvar time.Duration
// rtt.srtt, rtt.rttvar, and rto are the "smoothed round-trip time",
// "round-trip time variation" and "retransmit timeout", as defined in
// section 2 of RFC 6298.
rtt rtt
rto time.Duration
srttInited bool
@@ -139,6 +139,17 @@ type sender struct {
cc congestionControl
}
// rtt is a synchronization wrapper used to appease stateify. See the comment
// in sender, where it is used.
//
// +stateify savable
type rtt struct {
sync.Mutex `state:"nosave"`
srtt time.Duration
rttvar time.Duration
}
// fastRecovery holds information related to fast recovery from a packet loss.
//
// +stateify savable
@@ -265,20 +276,22 @@ func (s *sender) sendAck() {
// updateRTO updates the retransmit timeout when a new roud-trip time is
// available. This is done in accordance with section 2 of RFC 6298.
func (s *sender) updateRTO(rtt time.Duration) {
s.rtt.Lock()
if !s.srttInited {
s.rttvar = rtt / 2
s.srtt = rtt
s.rtt.rttvar = rtt / 2
s.rtt.srtt = rtt
s.srttInited = true
} else {
diff := s.srtt - rtt
diff := s.rtt.srtt - rtt
if diff < 0 {
diff = -diff
}
s.rttvar = (3*s.rttvar + diff) / 4
s.srtt = (7*s.srtt + rtt) / 8
s.rtt.rttvar = (3*s.rtt.rttvar + diff) / 4
s.rtt.srtt = (7*s.rtt.srtt + rtt) / 8
}
s.rto = s.srtt + 4*s.rttvar
s.rto = s.rtt.srtt + 4*s.rtt.rttvar
s.rtt.Unlock()
if s.rto < minRTO {
s.rto = minRTO
}