summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp/rcv.go
diff options
context:
space:
mode:
authorRahat Mahmood <rahat@google.com>2019-08-01 13:57:41 -0700
committergVisor bot <gvisor-bot@google.com>2019-08-01 13:58:48 -0700
commit79511e8a50facd509b8180d0160762b510dd6196 (patch)
treeef7dbd6a36361a9e84a7287d6e54fcbae7a4edd6 /pkg/tcpip/transport/tcp/rcv.go
parent0a246fab80581351309cdfe39ffeeffa00f811b1 (diff)
Implement getsockopt(TCP_INFO).
Export some readily-available fields for TCP_INFO and stub out the rest. PiperOrigin-RevId: 261191548
Diffstat (limited to 'pkg/tcpip/transport/tcp/rcv.go')
-rw-r--r--pkg/tcpip/transport/tcp/rcv.go27
1 files changed, 17 insertions, 10 deletions
diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go
index e90f9a7d9..a8f490c4a 100644
--- a/pkg/tcpip/transport/tcp/rcv.go
+++ b/pkg/tcpip/transport/tcp/rcv.go
@@ -220,25 +220,24 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
return true
}
-// updateRTT updates the receiver RTT measurement based on the sequence number
-// of the received segment.
-func (r *receiver) updateRTT() {
+// updateRTTLocked updates the receiver RTT measurement based on the sequence
+// number of the received segment.
+//
+// Precondition: Caller must hold r.ep.rcvListMu.
+func (r *receiver) updateRTTLocked() {
// From: https://public.lanl.gov/radiant/pubs/drs/sc2001-poster.pdf
//
// A system that is only transmitting acknowledgements can still
// estimate the round-trip time by observing the time between when a byte
// is first acknowledged and the receipt of data that is at least one
// window beyond the sequence number that was acknowledged.
- r.ep.rcvListMu.Lock()
if r.ep.rcvAutoParams.rttMeasureTime.IsZero() {
// New measurement.
r.ep.rcvAutoParams.rttMeasureTime = time.Now()
r.ep.rcvAutoParams.rttMeasureSeqNumber = r.rcvNxt.Add(r.rcvWnd)
- r.ep.rcvListMu.Unlock()
return
}
if r.rcvNxt.LessThan(r.ep.rcvAutoParams.rttMeasureSeqNumber) {
- r.ep.rcvListMu.Unlock()
return
}
rtt := time.Since(r.ep.rcvAutoParams.rttMeasureTime)
@@ -250,7 +249,6 @@ func (r *receiver) updateRTT() {
}
r.ep.rcvAutoParams.rttMeasureTime = time.Now()
r.ep.rcvAutoParams.rttMeasureSeqNumber = r.rcvNxt.Add(r.rcvWnd)
- r.ep.rcvListMu.Unlock()
}
// handleRcvdSegment handles TCP segments directed at the connection managed by
@@ -291,11 +289,20 @@ func (r *receiver) handleRcvdSegment(s *segment) {
return
}
- // Since we consumed a segment update the receiver's RTT estimate
- // if required.
+ r.ep.rcvListMu.Lock()
+ // FIXME(b/137581805): Using the runtime clock here is incorrect as it
+ // doesn't account for potentially virtualized time.
+ now := time.Now().UnixNano()
+ if s.flagIsSet(header.TCPFlagAck) {
+ r.ep.rcvLastAckNanos = now
+ }
if segLen > 0 {
- r.updateRTT()
+ // Since we consumed a segment update the receiver's RTT estimate if
+ // required.
+ r.ep.rcvLastDataNanos = now
+ r.updateRTTLocked()
}
+ r.ep.rcvListMu.Unlock()
// By consuming the current segment, we may have filled a gap in the
// sequence number domain that allows pending segments to be consumed