diff options
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 82 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/snd.go | 5 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/tcp_state_autogen.go | 126 |
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) } |