diff options
Diffstat (limited to 'pkg/tcpip/transport/tcp/endpoint.go')
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 0b395b5b0..96a546aa7 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -162,10 +162,19 @@ type endpoint struct { // sack holds TCP SACK related information for this endpoint. sack SACKInfo + // delay enables Nagle's algorithm. + // + // 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 + // The options below aren't implemented, but we remember the user // settings because applications expect to be able to set/query these // options. - noDelay bool reuseAddr bool // segmentQueue is used to hand received segments to the protocol @@ -276,7 +285,6 @@ func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waite rcvBufSize: DefaultBufferSize, sndBufSize: DefaultBufferSize, sndMTU: int(math.MaxInt32), - noDelay: false, reuseAddr: true, keepalive: keepalive{ // Linux defaults. @@ -643,10 +651,24 @@ func (e *endpoint) zeroReceiveWindow(scale uint8) bool { // SetSockOpt sets a socket option. func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { switch v := opt.(type) { - case tcpip.NoDelayOption: - e.mu.Lock() - e.noDelay = v != 0 - e.mu.Unlock() + case tcpip.DelayOption: + if v == 0 { + atomic.StoreUint32(&e.delay, 0) + } else { + atomic.StoreUint32(&e.delay, 1) + } + return nil + + case tcpip.CorkOption: + if v == 0 { + atomic.StoreUint32(&e.cork, 0) + } else { + atomic.StoreUint32(&e.cork, 1) + } + + // Handle the corked data. + e.sndWaker.Assert() + return nil case tcpip.ReuseAddressOption: @@ -812,13 +834,16 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = tcpip.ReceiveQueueSizeOption(v) return nil - case *tcpip.NoDelayOption: - e.mu.RLock() - v := e.noDelay - e.mu.RUnlock() + case *tcpip.DelayOption: + *o = 0 + if v := atomic.LoadUint32(&e.delay); v != 0 { + *o = 1 + } + return nil + case *tcpip.CorkOption: *o = 0 - if v { + if v := atomic.LoadUint32(&e.cork); v != 0 { *o = 1 } return nil |