summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-11-26 08:46:41 +0000
committergVisor bot <gvisor-bot@google.com>2020-11-26 08:46:41 +0000
commitbf476d6586a7f00ff86d07fd0d6eaa9a1a2c86ef (patch)
tree55deafebcc68c292f3268a7e644b0ced7c4baf91 /pkg/tcpip/transport/tcp
parent55c38174d6d9c55faf274cc6fa80e5671f1adb1d (diff)
parentad83112423ecf8729df582dd79cbe5a7e29bd937 (diff)
Merge release-20201109.0-120-gad8311242 (automated)
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go82
-rw-r--r--pkg/tcpip/transport/tcp/snd.go5
-rw-r--r--pkg/tcpip/transport/tcp/tcp_state_autogen.go126
3 files changed, 76 insertions, 137 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index fb64851ae..d321869c4 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -497,24 +497,9 @@ type endpoint struct {
// delay is a boolean (0 is false) and must be accessed atomically.
delay uint32
- // cork holds back segments until full.
- //
- // cork is a boolean (0 is false) and must be accessed atomically.
- cork uint32
-
// scoreboard holds TCP SACK Scoreboard information for this endpoint.
scoreboard *SACKScoreboard
- // The options below aren't implemented, but we remember the user
- // settings because applications expect to be able to set/query these
- // options.
-
- // slowAck holds the negated state of quick ack. It is stubbed out and
- // does nothing.
- //
- // slowAck is a boolean (0 is false) and must be accessed atomically.
- slowAck uint32
-
// segmentQueue is used to hand received segments to the protocol
// goroutine. Segments are queued as long as the queue is not full,
// and dropped when it is.
@@ -874,6 +859,7 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue
}
e.ops.InitHandler(e)
e.ops.SetMulticastLoop(true)
+ e.ops.SetQuickAck(true)
var ss tcpip.TCPSendBufferSizeRangeOption
if err := s.TransportProtocolOption(ProtocolNumber, &ss); err == nil {
@@ -897,7 +883,7 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue
var de tcpip.TCPDelayEnabled
if err := s.TransportProtocolOption(ProtocolNumber, &de); err == nil && de {
- e.SetSockOptBool(tcpip.DelayOption, true)
+ e.ops.SetDelayOption(true)
}
var tcpLT tcpip.TCPLingerTimeoutOption
@@ -1640,41 +1626,20 @@ func (e *endpoint) OnKeepAliveSet(v bool) {
e.notifyProtocolGoroutine(notifyKeepaliveChanged)
}
-// SetSockOptBool sets a socket option.
-func (e *endpoint) SetSockOptBool(opt tcpip.SockOptBool, v bool) *tcpip.Error {
- switch opt {
-
- case tcpip.CorkOption:
- e.LockUser()
- if !v {
- atomic.StoreUint32(&e.cork, 0)
-
- // Handle the corked data.
- e.sndWaker.Assert()
- } else {
- atomic.StoreUint32(&e.cork, 1)
- }
- e.UnlockUser()
-
- case tcpip.DelayOption:
- if v {
- atomic.StoreUint32(&e.delay, 1)
- } else {
- atomic.StoreUint32(&e.delay, 0)
-
- // Handle delayed data.
- e.sndWaker.Assert()
- }
-
- case tcpip.QuickAckOption:
- o := uint32(1)
- if v {
- o = 0
- }
- atomic.StoreUint32(&e.slowAck, o)
+// OnDelayOptionSet implements tcpip.SocketOptionsHandler.OnDelayOptionSet.
+func (e *endpoint) OnDelayOptionSet(v bool) {
+ if !v {
+ // Handle delayed data.
+ e.sndWaker.Assert()
}
+}
- return nil
+// OnCorkOptionSet implements tcpip.SocketOptionsHandler.OnCorkOptionSet.
+func (e *endpoint) OnCorkOptionSet(v bool) {
+ if !v {
+ // Handle the corked data.
+ e.sndWaker.Assert()
+ }
}
// SetSockOptInt sets a socket option.
@@ -1956,25 +1921,6 @@ func (e *endpoint) readyReceiveSize() (int, *tcpip.Error) {
return e.rcvBufUsed, nil
}
-// GetSockOptBool implements tcpip.Endpoint.GetSockOptBool.
-func (e *endpoint) GetSockOptBool(opt tcpip.SockOptBool) (bool, *tcpip.Error) {
- switch opt {
-
- case tcpip.CorkOption:
- return atomic.LoadUint32(&e.cork) != 0, nil
-
- case tcpip.DelayOption:
- return atomic.LoadUint32(&e.delay) != 0, nil
-
- case tcpip.QuickAckOption:
- v := atomic.LoadUint32(&e.slowAck) == 0
- return v, nil
-
- default:
- return false, tcpip.ErrUnknownProtocolOption
- }
-}
-
// GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) {
switch opt {
diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go
index 5ed9f7ace..baec762e1 100644
--- a/pkg/tcpip/transport/tcp/snd.go
+++ b/pkg/tcpip/transport/tcp/snd.go
@@ -18,7 +18,6 @@ import (
"fmt"
"math"
"sort"
- "sync/atomic"
"time"
"gvisor.dev/gvisor/pkg/sleep"
@@ -813,7 +812,7 @@ func (s *sender) maybeSendSegment(seg *segment, limit int, end seqnum.Value) (se
}
if !nextTooBig && seg.data.Size() < available {
// Segment is not full.
- if s.outstanding > 0 && atomic.LoadUint32(&s.ep.delay) != 0 {
+ if s.outstanding > 0 && s.ep.ops.GetDelayOption() {
// Nagle's algorithm. From Wikipedia:
// Nagle's algorithm works by
// combining a number of small
@@ -832,7 +831,7 @@ func (s *sender) maybeSendSegment(seg *segment, limit int, end seqnum.Value) (se
// send space and MSS.
// TODO(gvisor.dev/issue/2833): Drain the held segments after a
// timeout.
- if seg.data.Size() < s.maxPayloadSize && atomic.LoadUint32(&s.ep.cork) != 0 {
+ if seg.data.Size() < s.maxPayloadSize && s.ep.ops.GetCorkOption() {
return false
}
}
diff --git a/pkg/tcpip/transport/tcp/tcp_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
index 590602fdf..6c4f93499 100644
--- a/pkg/tcpip/transport/tcp/tcp_state_autogen.go
+++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go
@@ -166,9 +166,7 @@ func (e *endpoint) StateFields() []string {
"sack",
"bindToDevice",
"delay",
- "cork",
"scoreboard",
- "slowAck",
"segmentQueue",
"synRcvdCount",
"userMSS",
@@ -212,7 +210,7 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) {
var recentTSTimeValue unixTime = e.saveRecentTSTime()
stateSinkObject.SaveValue(26, recentTSTimeValue)
var acceptedChanValue []*endpoint = e.saveAcceptedChan()
- stateSinkObject.SaveValue(52, acceptedChanValue)
+ stateSinkObject.SaveValue(50, acceptedChanValue)
stateSinkObject.Save(0, &e.TransportEndpointInfo)
stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler)
stateSinkObject.Save(2, &e.waiterQueue)
@@ -242,37 +240,35 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(30, &e.sack)
stateSinkObject.Save(31, &e.bindToDevice)
stateSinkObject.Save(32, &e.delay)
- stateSinkObject.Save(33, &e.cork)
- stateSinkObject.Save(34, &e.scoreboard)
- stateSinkObject.Save(35, &e.slowAck)
- stateSinkObject.Save(36, &e.segmentQueue)
- stateSinkObject.Save(37, &e.synRcvdCount)
- stateSinkObject.Save(38, &e.userMSS)
- stateSinkObject.Save(39, &e.maxSynRetries)
- stateSinkObject.Save(40, &e.windowClamp)
- stateSinkObject.Save(41, &e.sndBufSize)
- stateSinkObject.Save(42, &e.sndBufUsed)
- stateSinkObject.Save(43, &e.sndClosed)
- stateSinkObject.Save(44, &e.sndBufInQueue)
- stateSinkObject.Save(45, &e.sndQueue)
- stateSinkObject.Save(46, &e.cc)
- stateSinkObject.Save(47, &e.packetTooBigCount)
- stateSinkObject.Save(48, &e.sndMTU)
- stateSinkObject.Save(49, &e.keepalive)
- stateSinkObject.Save(50, &e.userTimeout)
- stateSinkObject.Save(51, &e.deferAccept)
- stateSinkObject.Save(53, &e.rcv)
- stateSinkObject.Save(54, &e.snd)
- stateSinkObject.Save(55, &e.connectingAddress)
- stateSinkObject.Save(56, &e.amss)
- stateSinkObject.Save(57, &e.sendTOS)
- stateSinkObject.Save(58, &e.gso)
- stateSinkObject.Save(59, &e.tcpLingerTimeout)
- stateSinkObject.Save(60, &e.closed)
- stateSinkObject.Save(61, &e.txHash)
- stateSinkObject.Save(62, &e.owner)
- stateSinkObject.Save(63, &e.linger)
- stateSinkObject.Save(64, &e.ops)
+ stateSinkObject.Save(33, &e.scoreboard)
+ stateSinkObject.Save(34, &e.segmentQueue)
+ stateSinkObject.Save(35, &e.synRcvdCount)
+ stateSinkObject.Save(36, &e.userMSS)
+ stateSinkObject.Save(37, &e.maxSynRetries)
+ stateSinkObject.Save(38, &e.windowClamp)
+ stateSinkObject.Save(39, &e.sndBufSize)
+ stateSinkObject.Save(40, &e.sndBufUsed)
+ stateSinkObject.Save(41, &e.sndClosed)
+ stateSinkObject.Save(42, &e.sndBufInQueue)
+ stateSinkObject.Save(43, &e.sndQueue)
+ stateSinkObject.Save(44, &e.cc)
+ stateSinkObject.Save(45, &e.packetTooBigCount)
+ stateSinkObject.Save(46, &e.sndMTU)
+ stateSinkObject.Save(47, &e.keepalive)
+ stateSinkObject.Save(48, &e.userTimeout)
+ stateSinkObject.Save(49, &e.deferAccept)
+ stateSinkObject.Save(51, &e.rcv)
+ stateSinkObject.Save(52, &e.snd)
+ stateSinkObject.Save(53, &e.connectingAddress)
+ stateSinkObject.Save(54, &e.amss)
+ stateSinkObject.Save(55, &e.sendTOS)
+ stateSinkObject.Save(56, &e.gso)
+ stateSinkObject.Save(57, &e.tcpLingerTimeout)
+ stateSinkObject.Save(58, &e.closed)
+ stateSinkObject.Save(59, &e.txHash)
+ stateSinkObject.Save(60, &e.owner)
+ stateSinkObject.Save(61, &e.linger)
+ stateSinkObject.Save(62, &e.ops)
}
func (e *endpoint) StateLoad(stateSourceObject state.Source) {
@@ -305,42 +301,40 @@ func (e *endpoint) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(30, &e.sack)
stateSourceObject.Load(31, &e.bindToDevice)
stateSourceObject.Load(32, &e.delay)
- stateSourceObject.Load(33, &e.cork)
- stateSourceObject.Load(34, &e.scoreboard)
- stateSourceObject.Load(35, &e.slowAck)
- stateSourceObject.LoadWait(36, &e.segmentQueue)
- stateSourceObject.Load(37, &e.synRcvdCount)
- stateSourceObject.Load(38, &e.userMSS)
- stateSourceObject.Load(39, &e.maxSynRetries)
- stateSourceObject.Load(40, &e.windowClamp)
- stateSourceObject.Load(41, &e.sndBufSize)
- stateSourceObject.Load(42, &e.sndBufUsed)
- stateSourceObject.Load(43, &e.sndClosed)
- stateSourceObject.Load(44, &e.sndBufInQueue)
- stateSourceObject.LoadWait(45, &e.sndQueue)
- stateSourceObject.Load(46, &e.cc)
- stateSourceObject.Load(47, &e.packetTooBigCount)
- stateSourceObject.Load(48, &e.sndMTU)
- stateSourceObject.Load(49, &e.keepalive)
- stateSourceObject.Load(50, &e.userTimeout)
- stateSourceObject.Load(51, &e.deferAccept)
- stateSourceObject.LoadWait(53, &e.rcv)
- stateSourceObject.LoadWait(54, &e.snd)
- stateSourceObject.Load(55, &e.connectingAddress)
- stateSourceObject.Load(56, &e.amss)
- stateSourceObject.Load(57, &e.sendTOS)
- stateSourceObject.Load(58, &e.gso)
- stateSourceObject.Load(59, &e.tcpLingerTimeout)
- stateSourceObject.Load(60, &e.closed)
- stateSourceObject.Load(61, &e.txHash)
- stateSourceObject.Load(62, &e.owner)
- stateSourceObject.Load(63, &e.linger)
- stateSourceObject.Load(64, &e.ops)
+ stateSourceObject.Load(33, &e.scoreboard)
+ stateSourceObject.LoadWait(34, &e.segmentQueue)
+ stateSourceObject.Load(35, &e.synRcvdCount)
+ stateSourceObject.Load(36, &e.userMSS)
+ stateSourceObject.Load(37, &e.maxSynRetries)
+ stateSourceObject.Load(38, &e.windowClamp)
+ stateSourceObject.Load(39, &e.sndBufSize)
+ stateSourceObject.Load(40, &e.sndBufUsed)
+ stateSourceObject.Load(41, &e.sndClosed)
+ stateSourceObject.Load(42, &e.sndBufInQueue)
+ stateSourceObject.LoadWait(43, &e.sndQueue)
+ stateSourceObject.Load(44, &e.cc)
+ stateSourceObject.Load(45, &e.packetTooBigCount)
+ stateSourceObject.Load(46, &e.sndMTU)
+ stateSourceObject.Load(47, &e.keepalive)
+ stateSourceObject.Load(48, &e.userTimeout)
+ stateSourceObject.Load(49, &e.deferAccept)
+ stateSourceObject.LoadWait(51, &e.rcv)
+ stateSourceObject.LoadWait(52, &e.snd)
+ stateSourceObject.Load(53, &e.connectingAddress)
+ stateSourceObject.Load(54, &e.amss)
+ stateSourceObject.Load(55, &e.sendTOS)
+ stateSourceObject.Load(56, &e.gso)
+ stateSourceObject.Load(57, &e.tcpLingerTimeout)
+ stateSourceObject.Load(58, &e.closed)
+ stateSourceObject.Load(59, &e.txHash)
+ stateSourceObject.Load(60, &e.owner)
+ stateSourceObject.Load(61, &e.linger)
+ stateSourceObject.Load(62, &e.ops)
stateSourceObject.LoadValue(4, new(string), func(y interface{}) { e.loadHardError(y.(string)) })
stateSourceObject.LoadValue(5, new(string), func(y interface{}) { e.loadLastError(y.(string)) })
stateSourceObject.LoadValue(13, new(EndpointState), func(y interface{}) { e.loadState(y.(EndpointState)) })
stateSourceObject.LoadValue(26, new(unixTime), func(y interface{}) { e.loadRecentTSTime(y.(unixTime)) })
- stateSourceObject.LoadValue(52, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) })
+ stateSourceObject.LoadValue(50, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) })
stateSourceObject.AfterLoad(e.afterLoad)
}