diff options
Diffstat (limited to 'pkg/tcpip/transport')
-rw-r--r-- | pkg/tcpip/transport/icmp/endpoint.go | 18 | ||||
-rw-r--r-- | pkg/tcpip/transport/icmp/endpoint_state.go | 1 | ||||
-rw-r--r-- | pkg/tcpip/transport/icmp/icmp_state_autogen.go | 23 | ||||
-rw-r--r-- | pkg/tcpip/transport/packet/endpoint.go | 43 | ||||
-rw-r--r-- | pkg/tcpip/transport/packet/endpoint_state.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/transport/packet/packet_state_autogen.go | 26 | ||||
-rw-r--r-- | pkg/tcpip/transport/raw/endpoint.go | 42 | ||||
-rw-r--r-- | pkg/tcpip/transport/raw/endpoint_state.go | 1 | ||||
-rw-r--r-- | pkg/tcpip/transport/raw/raw_state_autogen.go | 26 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 76 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint_state.go | 6 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/tcp_state_autogen.go | 91 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 37 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint_state.go | 1 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/udp_state_autogen.go | 70 |
15 files changed, 179 insertions, 284 deletions
diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index af00ed548..85b497365 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -69,8 +69,7 @@ type endpoint struct { rcvClosed bool // The following fields are protected by the mu mutex. - mu sync.RWMutex `state:"nosave"` - sndBufSize int + mu sync.RWMutex `state:"nosave"` // shutdownFlags represent the current shutdown state of the endpoint. shutdownFlags tcpip.ShutdownFlags state endpointState @@ -94,11 +93,17 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProt }, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, - sndBufSize: 32 * 1024, state: stateInitial, uniqueID: s.UniqueID(), } - ep.ops.InitHandler(ep) + ep.ops.InitHandler(ep, ep.stack) + ep.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits) + + // Override with stack defaults. + var ss tcpip.SendBufferSizeOption + if err := s.Option(&ss); err == nil { + ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits) + } return ep, nil } @@ -363,11 +368,6 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { } e.rcvMu.Unlock() return v, nil - case tcpip.SendBufferSizeOption: - e.mu.Lock() - v := e.sndBufSize - e.mu.Unlock() - return v, nil case tcpip.ReceiveBufferSizeOption: e.rcvMu.Lock() diff --git a/pkg/tcpip/transport/icmp/endpoint_state.go b/pkg/tcpip/transport/icmp/endpoint_state.go index 9d263c0ec..9335cbc5a 100644 --- a/pkg/tcpip/transport/icmp/endpoint_state.go +++ b/pkg/tcpip/transport/icmp/endpoint_state.go @@ -69,6 +69,7 @@ func (e *endpoint) afterLoad() { // Resume implements tcpip.ResumableEndpoint.Resume. func (e *endpoint) Resume(s *stack.Stack) { e.stack = s + e.ops.InitHandler(e, e.stack) if e.state != stateBound && e.state != stateConnected { return diff --git a/pkg/tcpip/transport/icmp/icmp_state_autogen.go b/pkg/tcpip/transport/icmp/icmp_state_autogen.go index 28a734f05..fe5af3d97 100644 --- a/pkg/tcpip/transport/icmp/icmp_state_autogen.go +++ b/pkg/tcpip/transport/icmp/icmp_state_autogen.go @@ -55,7 +55,6 @@ func (e *endpoint) StateFields() []string { "rcvBufSizeMax", "rcvBufSize", "rcvClosed", - "sndBufSize", "shutdownFlags", "state", "ttl", @@ -76,12 +75,11 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(5, &e.rcvList) stateSinkObject.Save(7, &e.rcvBufSize) stateSinkObject.Save(8, &e.rcvClosed) - stateSinkObject.Save(9, &e.sndBufSize) - stateSinkObject.Save(10, &e.shutdownFlags) - stateSinkObject.Save(11, &e.state) - stateSinkObject.Save(12, &e.ttl) - stateSinkObject.Save(13, &e.owner) - stateSinkObject.Save(14, &e.ops) + stateSinkObject.Save(9, &e.shutdownFlags) + stateSinkObject.Save(10, &e.state) + stateSinkObject.Save(11, &e.ttl) + stateSinkObject.Save(12, &e.owner) + stateSinkObject.Save(13, &e.ops) } func (e *endpoint) StateLoad(stateSourceObject state.Source) { @@ -93,12 +91,11 @@ func (e *endpoint) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(5, &e.rcvList) stateSourceObject.Load(7, &e.rcvBufSize) stateSourceObject.Load(8, &e.rcvClosed) - stateSourceObject.Load(9, &e.sndBufSize) - stateSourceObject.Load(10, &e.shutdownFlags) - stateSourceObject.Load(11, &e.state) - stateSourceObject.Load(12, &e.ttl) - stateSourceObject.Load(13, &e.owner) - stateSourceObject.Load(14, &e.ops) + stateSourceObject.Load(9, &e.shutdownFlags) + stateSourceObject.Load(10, &e.state) + stateSourceObject.Load(11, &e.ttl) + stateSourceObject.Load(12, &e.owner) + stateSourceObject.Load(13, &e.ops) stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) }) stateSourceObject.AfterLoad(e.afterLoad) } diff --git a/pkg/tcpip/transport/packet/endpoint.go b/pkg/tcpip/transport/packet/endpoint.go index 6fd116a98..9ca9c9780 100644 --- a/pkg/tcpip/transport/packet/endpoint.go +++ b/pkg/tcpip/transport/packet/endpoint.go @@ -79,13 +79,11 @@ type endpoint struct { rcvClosed bool // The following fields are protected by mu. - mu sync.RWMutex `state:"nosave"` - sndBufSize int - sndBufSizeMax int - closed bool - stats tcpip.TransportEndpointStats `state:"nosave"` - bound bool - boundNIC tcpip.NICID + mu sync.RWMutex `state:"nosave"` + closed bool + stats tcpip.TransportEndpointStats `state:"nosave"` + bound bool + boundNIC tcpip.NICID // lastErrorMu protects lastError. lastErrorMu sync.Mutex `state:"nosave"` @@ -106,14 +104,13 @@ func NewEndpoint(s *stack.Stack, cooked bool, netProto tcpip.NetworkProtocolNumb netProto: netProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, - sndBufSize: 32 * 1024, } - ep.ops.InitHandler(ep) + ep.ops.InitHandler(ep, ep.stack) // Override with stack defaults. - var ss stack.SendBufferSizeOption + var ss tcpip.SendBufferSizeOption if err := s.Option(&ss); err == nil { - ep.sndBufSizeMax = ss.Default + ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits) } var rs stack.ReceiveBufferSizeOption @@ -320,24 +317,6 @@ func (ep *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { // SetSockOptInt implements tcpip.Endpoint.SetSockOptInt. func (ep *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { switch opt { - case tcpip.SendBufferSizeOption: - // Make sure the send buffer size is within the min and max - // allowed. - var ss stack.SendBufferSizeOption - if err := ep.stack.Option(&ss); err != nil { - panic(fmt.Sprintf("s.Option(%#v) = %s", ss, err)) - } - if v > ss.Max { - v = ss.Max - } - if v < ss.Min { - v = ss.Min - } - ep.mu.Lock() - ep.sndBufSizeMax = v - ep.mu.Unlock() - return nil - case tcpip.ReceiveBufferSizeOption: // Make sure the receive buffer size is within the min and max // allowed. @@ -395,12 +374,6 @@ func (ep *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { ep.rcvMu.Unlock() return v, nil - case tcpip.SendBufferSizeOption: - ep.mu.Lock() - v := ep.sndBufSizeMax - ep.mu.Unlock() - return v, nil - case tcpip.ReceiveBufferSizeOption: ep.rcvMu.Lock() v := ep.rcvBufSizeMax diff --git a/pkg/tcpip/transport/packet/endpoint_state.go b/pkg/tcpip/transport/packet/endpoint_state.go index e2fa96d17..61221be71 100644 --- a/pkg/tcpip/transport/packet/endpoint_state.go +++ b/pkg/tcpip/transport/packet/endpoint_state.go @@ -63,8 +63,8 @@ func (ep *endpoint) loadRcvBufSizeMax(max int) { // afterLoad is invoked by stateify. func (ep *endpoint) afterLoad() { - // StackFromEnv is a stack used specifically for save/restore. ep.stack = stack.StackFromEnv + ep.ops.InitHandler(ep, ep.stack) // TODO(gvisor.dev/173): Once bind is supported, choose the right NIC. if err := ep.stack.RegisterPacketEndpoint(0, ep.netProto, ep); err != nil { diff --git a/pkg/tcpip/transport/packet/packet_state_autogen.go b/pkg/tcpip/transport/packet/packet_state_autogen.go index ccb66800b..4a62f1e4b 100644 --- a/pkg/tcpip/transport/packet/packet_state_autogen.go +++ b/pkg/tcpip/transport/packet/packet_state_autogen.go @@ -58,8 +58,6 @@ func (ep *endpoint) StateFields() []string { "rcvBufSizeMax", "rcvBufSize", "rcvClosed", - "sndBufSize", - "sndBufSizeMax", "closed", "bound", "boundNIC", @@ -73,7 +71,7 @@ func (ep *endpoint) StateSave(stateSinkObject state.Sink) { var rcvBufSizeMaxValue int = ep.saveRcvBufSizeMax() stateSinkObject.SaveValue(6, rcvBufSizeMaxValue) var lastErrorValue string = ep.saveLastError() - stateSinkObject.SaveValue(14, lastErrorValue) + stateSinkObject.SaveValue(12, lastErrorValue) stateSinkObject.Save(0, &ep.TransportEndpointInfo) stateSinkObject.Save(1, &ep.DefaultSocketOptionsHandler) stateSinkObject.Save(2, &ep.netProto) @@ -82,12 +80,10 @@ func (ep *endpoint) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(5, &ep.rcvList) stateSinkObject.Save(7, &ep.rcvBufSize) stateSinkObject.Save(8, &ep.rcvClosed) - stateSinkObject.Save(9, &ep.sndBufSize) - stateSinkObject.Save(10, &ep.sndBufSizeMax) - stateSinkObject.Save(11, &ep.closed) - stateSinkObject.Save(12, &ep.bound) - stateSinkObject.Save(13, &ep.boundNIC) - stateSinkObject.Save(15, &ep.ops) + stateSinkObject.Save(9, &ep.closed) + stateSinkObject.Save(10, &ep.bound) + stateSinkObject.Save(11, &ep.boundNIC) + stateSinkObject.Save(13, &ep.ops) } func (ep *endpoint) StateLoad(stateSourceObject state.Source) { @@ -99,14 +95,12 @@ func (ep *endpoint) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(5, &ep.rcvList) stateSourceObject.Load(7, &ep.rcvBufSize) stateSourceObject.Load(8, &ep.rcvClosed) - stateSourceObject.Load(9, &ep.sndBufSize) - stateSourceObject.Load(10, &ep.sndBufSizeMax) - stateSourceObject.Load(11, &ep.closed) - stateSourceObject.Load(12, &ep.bound) - stateSourceObject.Load(13, &ep.boundNIC) - stateSourceObject.Load(15, &ep.ops) + stateSourceObject.Load(9, &ep.closed) + stateSourceObject.Load(10, &ep.bound) + stateSourceObject.Load(11, &ep.boundNIC) + stateSourceObject.Load(13, &ep.ops) stateSourceObject.LoadValue(6, new(int), func(y interface{}) { ep.loadRcvBufSizeMax(y.(int)) }) - stateSourceObject.LoadValue(14, new(string), func(y interface{}) { ep.loadLastError(y.(string)) }) + stateSourceObject.LoadValue(12, new(string), func(y interface{}) { ep.loadLastError(y.(string)) }) stateSourceObject.AfterLoad(ep.afterLoad) } diff --git a/pkg/tcpip/transport/raw/endpoint.go b/pkg/tcpip/transport/raw/endpoint.go index 2dacf5a64..f038097e4 100644 --- a/pkg/tcpip/transport/raw/endpoint.go +++ b/pkg/tcpip/transport/raw/endpoint.go @@ -76,12 +76,10 @@ type endpoint struct { rcvClosed bool // The following fields are protected by mu. - mu sync.RWMutex `state:"nosave"` - sndBufSize int - sndBufSizeMax int - closed bool - connected bool - bound bool + mu sync.RWMutex `state:"nosave"` + closed bool + connected bool + bound bool // route is the route to a remote network endpoint. It is set via // Connect(), and is valid only when conneted is true. route *stack.Route `state:"manual"` @@ -112,16 +110,16 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProt }, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, - sndBufSizeMax: 32 * 1024, associated: associated, } - e.ops.InitHandler(e) + e.ops.InitHandler(e, e.stack) e.ops.SetHeaderIncluded(!associated) + e.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits) // Override with stack defaults. - var ss stack.SendBufferSizeOption + var ss tcpip.SendBufferSizeOption if err := s.Option(&ss); err == nil { - e.sndBufSizeMax = ss.Default + e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits) } var rs stack.ReceiveBufferSizeOption @@ -511,24 +509,6 @@ func (e *endpoint) SetSockOpt(opt tcpip.SettableSocketOption) *tcpip.Error { // SetSockOptInt implements tcpip.Endpoint.SetSockOptInt. func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { switch opt { - case tcpip.SendBufferSizeOption: - // Make sure the send buffer size is within the min and max - // allowed. - var ss stack.SendBufferSizeOption - if err := e.stack.Option(&ss); err != nil { - panic(fmt.Sprintf("s.Option(%#v) = %s", ss, err)) - } - if v > ss.Max { - v = ss.Max - } - if v < ss.Min { - v = ss.Min - } - e.mu.Lock() - e.sndBufSizeMax = v - e.mu.Unlock() - return nil - case tcpip.ReceiveBufferSizeOption: // Make sure the receive buffer size is within the min and max // allowed. @@ -570,12 +550,6 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { e.rcvMu.Unlock() return v, nil - case tcpip.SendBufferSizeOption: - e.mu.Lock() - v := e.sndBufSizeMax - e.mu.Unlock() - return v, nil - case tcpip.ReceiveBufferSizeOption: e.rcvMu.Lock() v := e.rcvBufSizeMax diff --git a/pkg/tcpip/transport/raw/endpoint_state.go b/pkg/tcpip/transport/raw/endpoint_state.go index 4a7e1c039..e11ab38d5 100644 --- a/pkg/tcpip/transport/raw/endpoint_state.go +++ b/pkg/tcpip/transport/raw/endpoint_state.go @@ -69,6 +69,7 @@ func (e *endpoint) afterLoad() { // Resume implements tcpip.ResumableEndpoint.Resume. func (e *endpoint) Resume(s *stack.Stack) { e.stack = s + e.ops.InitHandler(e, e.stack) // If the endpoint is connected, re-connect. if e.connected { diff --git a/pkg/tcpip/transport/raw/raw_state_autogen.go b/pkg/tcpip/transport/raw/raw_state_autogen.go index a7ecccb20..db4b393a7 100644 --- a/pkg/tcpip/transport/raw/raw_state_autogen.go +++ b/pkg/tcpip/transport/raw/raw_state_autogen.go @@ -54,8 +54,6 @@ func (e *endpoint) StateFields() []string { "rcvBufSize", "rcvBufSizeMax", "rcvClosed", - "sndBufSize", - "sndBufSizeMax", "closed", "connected", "bound", @@ -75,13 +73,11 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(4, &e.rcvList) stateSinkObject.Save(5, &e.rcvBufSize) stateSinkObject.Save(7, &e.rcvClosed) - stateSinkObject.Save(8, &e.sndBufSize) - stateSinkObject.Save(9, &e.sndBufSizeMax) - stateSinkObject.Save(10, &e.closed) - stateSinkObject.Save(11, &e.connected) - stateSinkObject.Save(12, &e.bound) - stateSinkObject.Save(13, &e.owner) - stateSinkObject.Save(14, &e.ops) + stateSinkObject.Save(8, &e.closed) + stateSinkObject.Save(9, &e.connected) + stateSinkObject.Save(10, &e.bound) + stateSinkObject.Save(11, &e.owner) + stateSinkObject.Save(12, &e.ops) } func (e *endpoint) StateLoad(stateSourceObject state.Source) { @@ -92,13 +88,11 @@ func (e *endpoint) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(4, &e.rcvList) stateSourceObject.Load(5, &e.rcvBufSize) stateSourceObject.Load(7, &e.rcvClosed) - stateSourceObject.Load(8, &e.sndBufSize) - stateSourceObject.Load(9, &e.sndBufSizeMax) - stateSourceObject.Load(10, &e.closed) - stateSourceObject.Load(11, &e.connected) - stateSourceObject.Load(12, &e.bound) - stateSourceObject.Load(13, &e.owner) - stateSourceObject.Load(14, &e.ops) + stateSourceObject.Load(8, &e.closed) + stateSourceObject.Load(9, &e.connected) + stateSourceObject.Load(10, &e.bound) + stateSourceObject.Load(11, &e.owner) + stateSourceObject.Load(12, &e.ops) stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) }) stateSourceObject.AfterLoad(e.afterLoad) } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 05c431e83..8e43fec81 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -557,7 +557,6 @@ type endpoint struct { // When the send side is closed, the protocol goroutine is notified via // sndCloseWaker, and sndClosed is set to true. sndBufMu sync.Mutex `state:"nosave"` - sndBufSize int sndBufUsed int sndClosed bool sndBufInQueue seqnum.Size @@ -869,7 +868,6 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue waiterQueue: waiterQueue, state: StateInitial, rcvBufSize: DefaultReceiveBufferSize, - sndBufSize: DefaultSendBufferSize, sndMTU: int(math.MaxInt32), keepalive: keepalive{ // Linux defaults. @@ -882,13 +880,14 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue windowClamp: DefaultReceiveBufferSize, maxSynRetries: DefaultSynRetries, } - e.ops.InitHandler(e) + e.ops.InitHandler(e, e.stack) e.ops.SetMulticastLoop(true) e.ops.SetQuickAck(true) + e.ops.SetSendBufferSize(DefaultSendBufferSize, false /* notify */, GetTCPSendBufferLimits) var ss tcpip.TCPSendBufferSizeRangeOption if err := s.TransportProtocolOption(ProtocolNumber, &ss); err == nil { - e.sndBufSize = ss.Default + e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, GetTCPSendBufferLimits) } var rs tcpip.TCPReceiveBufferSizeRangeOption @@ -967,7 +966,8 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // Determine if the endpoint is writable if requested. if (mask & waiter.EventOut) != 0 { e.sndBufMu.Lock() - if e.sndClosed || e.sndBufUsed < e.sndBufSize { + sndBufSize := e.getSendBufferSize() + if e.sndClosed || e.sndBufUsed < sndBufSize { result |= waiter.EventOut } e.sndBufMu.Unlock() @@ -1499,7 +1499,8 @@ func (e *endpoint) isEndpointWritableLocked() (int, *tcpip.Error) { return 0, tcpip.ErrClosedForSend } - avail := e.sndBufSize - e.sndBufUsed + sndBufSize := e.getSendBufferSize() + avail := sndBufSize - e.sndBufUsed if avail <= 0 { return 0, tcpip.ErrWouldBlock } @@ -1692,6 +1693,14 @@ func (e *endpoint) OnCorkOptionSet(v bool) { } } +func (e *endpoint) getSendBufferSize() int { + sndBufSize, err := e.ops.GetSendBufferSize() + if err != nil { + panic(fmt.Sprintf("e.ops.GetSendBufferSize() = %s", err)) + } + return int(sndBufSize) +} + // SetSockOptInt sets a socket option. func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { // Lower 2 bits represents ECN bits. RFC 3168, section 23.1 @@ -1785,31 +1794,6 @@ func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { e.rcvListMu.Unlock() e.UnlockUser() - case tcpip.SendBufferSizeOption: - // Make sure the send buffer size is within the min and max - // allowed. - var ss tcpip.TCPSendBufferSizeRangeOption - if err := e.stack.TransportProtocolOption(ProtocolNumber, &ss); err != nil { - panic(fmt.Sprintf("e.stack.TransportProtocolOption(%d, %#v) = %s", ProtocolNumber, &ss, err)) - } - - if v > ss.Max { - v = ss.Max - } - - if v < math.MaxInt32/SegOverheadFactor { - v *= SegOverheadFactor - if v < ss.Min { - v = ss.Min - } - } else { - v = math.MaxInt32 - } - - e.sndBufMu.Lock() - e.sndBufSize = v - e.sndBufMu.Unlock() - case tcpip.TTLOption: e.LockUser() e.ttl = uint8(v) @@ -1995,12 +1979,6 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { case tcpip.ReceiveQueueSizeOption: return e.readyReceiveSize() - case tcpip.SendBufferSizeOption: - e.sndBufMu.Lock() - v := e.sndBufSize - e.sndBufMu.Unlock() - return v, nil - case tcpip.ReceiveBufferSizeOption: e.rcvListMu.Lock() v := e.rcvBufSize @@ -2749,13 +2727,14 @@ func (e *endpoint) HandleControlPacket(typ stack.ControlType, extra uint32, pkt // updateSndBufferUsage is called by the protocol goroutine when room opens up // in the send buffer. The number of newly available bytes is v. func (e *endpoint) updateSndBufferUsage(v int) { + sendBufferSize := e.getSendBufferSize() e.sndBufMu.Lock() - notify := e.sndBufUsed >= e.sndBufSize>>1 + notify := e.sndBufUsed >= sendBufferSize>>1 e.sndBufUsed -= v - // We only notify when there is half the sndBufSize available after + // We only notify when there is half the sendBufferSize available after // a full buffer event occurs. This ensures that we don't wake up // writers to queue just 1-2 segments and go back to sleep. - notify = notify && e.sndBufUsed < e.sndBufSize>>1 + notify = notify && e.sndBufUsed < int(sendBufferSize)>>1 e.sndBufMu.Unlock() if notify { @@ -2967,8 +2946,9 @@ func (e *endpoint) completeState() stack.TCPEndpointState { s.SACK.ReceivedBlocks, s.SACK.MaxSACKED = e.scoreboard.Copy() // Copy endpoint send state. + sndBufSize := e.getSendBufferSize() e.sndBufMu.Lock() - s.SndBufSize = e.sndBufSize + s.SndBufSize = sndBufSize s.SndBufUsed = e.sndBufUsed s.SndClosed = e.sndClosed s.SndBufInQueue = e.sndBufInQueue @@ -3113,3 +3093,17 @@ func (e *endpoint) Wait() { func (e *endpoint) SocketOptions() *tcpip.SocketOptions { return &e.ops } + +// GetTCPSendBufferLimits is used to get send buffer size limits for TCP. +func GetTCPSendBufferLimits(s tcpip.StackHandler) tcpip.SendBufferSizeOption { + var ss tcpip.TCPSendBufferSizeRangeOption + if err := s.TransportProtocolOption(header.TCPProtocolNumber, &ss); err != nil { + panic(fmt.Sprintf("s.TransportProtocolOption(%d, %#v) = %s", header.TCPProtocolNumber, ss, err)) + } + + return tcpip.SendBufferSizeOption{ + Min: ss.Min, + Default: ss.Default, + Max: ss.Max, + } +} diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index ba67176b5..19c1dc67a 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -179,14 +179,16 @@ func (e *endpoint) afterLoad() { // Resume implements tcpip.ResumableEndpoint.Resume. func (e *endpoint) Resume(s *stack.Stack) { e.stack = s + e.ops.InitHandler(e, e.stack) e.segmentQueue.thaw() epState := e.origEndpointState switch epState { case StateInitial, StateBound, StateListen, StateConnecting, StateEstablished: var ss tcpip.TCPSendBufferSizeRangeOption if err := e.stack.TransportProtocolOption(ProtocolNumber, &ss); err == nil { - if e.sndBufSize < ss.Min || e.sndBufSize > ss.Max { - panic(fmt.Sprintf("endpoint.sndBufSize %d is outside the min and max allowed [%d, %d]", e.sndBufSize, ss.Min, ss.Max)) + sendBufferSize := e.getSendBufferSize() + if sendBufferSize < ss.Min || sendBufferSize > ss.Max { + panic(fmt.Sprintf("endpoint sendBufferSize %d is outside the min and max allowed [%d, %d]", sendBufferSize, ss.Min, ss.Max)) } } diff --git a/pkg/tcpip/transport/tcp/tcp_state_autogen.go b/pkg/tcpip/transport/tcp/tcp_state_autogen.go index 6131d151a..c9926f8ca 100644 --- a/pkg/tcpip/transport/tcp/tcp_state_autogen.go +++ b/pkg/tcpip/transport/tcp/tcp_state_autogen.go @@ -195,7 +195,6 @@ func (e *endpoint) StateFields() []string { "userMSS", "maxSynRetries", "windowClamp", - "sndBufSize", "sndBufUsed", "sndClosed", "sndBufInQueue", @@ -232,7 +231,7 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { var recentTSTimeValue unixTime = e.saveRecentTSTime() stateSinkObject.SaveValue(26, recentTSTimeValue) var acceptedChanValue []*endpoint = e.saveAcceptedChan() - stateSinkObject.SaveValue(50, acceptedChanValue) + stateSinkObject.SaveValue(49, acceptedChanValue) stateSinkObject.Save(0, &e.EndpointInfo) stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler) stateSinkObject.Save(2, &e.waiterQueue) @@ -268,28 +267,27 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { 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.ops) + stateSinkObject.Save(39, &e.sndBufUsed) + stateSinkObject.Save(40, &e.sndClosed) + stateSinkObject.Save(41, &e.sndBufInQueue) + stateSinkObject.Save(42, &e.sndQueue) + stateSinkObject.Save(43, &e.cc) + stateSinkObject.Save(44, &e.packetTooBigCount) + stateSinkObject.Save(45, &e.sndMTU) + stateSinkObject.Save(46, &e.keepalive) + stateSinkObject.Save(47, &e.userTimeout) + stateSinkObject.Save(48, &e.deferAccept) + stateSinkObject.Save(50, &e.rcv) + stateSinkObject.Save(51, &e.snd) + stateSinkObject.Save(52, &e.connectingAddress) + stateSinkObject.Save(53, &e.amss) + stateSinkObject.Save(54, &e.sendTOS) + stateSinkObject.Save(55, &e.gso) + stateSinkObject.Save(56, &e.tcpLingerTimeout) + stateSinkObject.Save(57, &e.closed) + stateSinkObject.Save(58, &e.txHash) + stateSinkObject.Save(59, &e.owner) + stateSinkObject.Save(60, &e.ops) } func (e *endpoint) StateLoad(stateSourceObject state.Source) { @@ -328,33 +326,32 @@ func (e *endpoint) StateLoad(stateSourceObject state.Source) { 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.ops) + stateSourceObject.Load(39, &e.sndBufUsed) + stateSourceObject.Load(40, &e.sndClosed) + stateSourceObject.Load(41, &e.sndBufInQueue) + stateSourceObject.LoadWait(42, &e.sndQueue) + stateSourceObject.Load(43, &e.cc) + stateSourceObject.Load(44, &e.packetTooBigCount) + stateSourceObject.Load(45, &e.sndMTU) + stateSourceObject.Load(46, &e.keepalive) + stateSourceObject.Load(47, &e.userTimeout) + stateSourceObject.Load(48, &e.deferAccept) + stateSourceObject.LoadWait(50, &e.rcv) + stateSourceObject.LoadWait(51, &e.snd) + stateSourceObject.Load(52, &e.connectingAddress) + stateSourceObject.Load(53, &e.amss) + stateSourceObject.Load(54, &e.sendTOS) + stateSourceObject.Load(55, &e.gso) + stateSourceObject.Load(56, &e.tcpLingerTimeout) + stateSourceObject.Load(57, &e.closed) + stateSourceObject.Load(58, &e.txHash) + stateSourceObject.Load(59, &e.owner) + stateSourceObject.Load(60, &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(50, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) }) + stateSourceObject.LoadValue(49, new([]*endpoint), func(y interface{}) { e.loadAcceptedChan(y.([]*endpoint)) }) stateSourceObject.AfterLoad(e.afterLoad) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 8544fcb08..ee7e43b97 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -97,9 +97,7 @@ type endpoint struct { rcvClosed bool // The following fields are protected by the mu mutex. - mu sync.RWMutex `state:"nosave"` - sndBufSize int - sndBufSizeMax int + mu sync.RWMutex `state:"nosave"` // state must be read/set using the EndpointState()/setEndpointState() // methods. state EndpointState @@ -176,18 +174,18 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue // Linux defaults to TTL=1. multicastTTL: 1, rcvBufSizeMax: 32 * 1024, - sndBufSizeMax: 32 * 1024, multicastMemberships: make(map[multicastMembership]struct{}), state: StateInitial, uniqueID: s.UniqueID(), } - e.ops.InitHandler(e) + e.ops.InitHandler(e, e.stack) e.ops.SetMulticastLoop(true) + e.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits) // Override with stack defaults. - var ss stack.SendBufferSizeOption + var ss tcpip.SendBufferSizeOption if err := s.Option(&ss); err == nil { - e.sndBufSizeMax = ss.Default + e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits) } var rs stack.ReceiveBufferSizeOption @@ -632,25 +630,6 @@ func (e *endpoint) SetSockOptInt(opt tcpip.SockOptInt, v int) *tcpip.Error { e.rcvBufSizeMax = v e.mu.Unlock() return nil - case tcpip.SendBufferSizeOption: - // Make sure the send buffer size is within the min and max - // allowed. - var ss stack.SendBufferSizeOption - if err := e.stack.Option(&ss); err != nil { - panic(fmt.Sprintf("e.stack.Option(%#v) = %s", ss, err)) - } - - if v < ss.Min { - v = ss.Min - } - if v > ss.Max { - v = ss.Max - } - - e.mu.Lock() - e.sndBufSizeMax = v - e.mu.Unlock() - return nil } return nil @@ -811,12 +790,6 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, *tcpip.Error) { e.rcvMu.Unlock() return v, nil - case tcpip.SendBufferSizeOption: - e.mu.Lock() - v := e.sndBufSizeMax - e.mu.Unlock() - return v, nil - case tcpip.ReceiveBufferSizeOption: e.rcvMu.Lock() v := e.rcvBufSizeMax diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 13b72dc88..903397f1c 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -91,6 +91,7 @@ func (e *endpoint) Resume(s *stack.Stack) { defer e.mu.Unlock() e.stack = s + e.ops.InitHandler(e, e.stack) for m := range e.multicastMemberships { if err := e.stack.JoinGroup(e.NetProto, m.nicID, m.multicastAddr); err != nil { diff --git a/pkg/tcpip/transport/udp/udp_state_autogen.go b/pkg/tcpip/transport/udp/udp_state_autogen.go index 2b7726097..6f61505c9 100644 --- a/pkg/tcpip/transport/udp/udp_state_autogen.go +++ b/pkg/tcpip/transport/udp/udp_state_autogen.go @@ -64,8 +64,6 @@ func (e *endpoint) StateFields() []string { "rcvBufSizeMax", "rcvBufSize", "rcvClosed", - "sndBufSize", - "sndBufSizeMax", "state", "dstPort", "ttl", @@ -90,7 +88,7 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { var rcvBufSizeMaxValue int = e.saveRcvBufSizeMax() stateSinkObject.SaveValue(6, rcvBufSizeMaxValue) var lastErrorValue string = e.saveLastError() - stateSinkObject.SaveValue(18, lastErrorValue) + stateSinkObject.SaveValue(16, lastErrorValue) stateSinkObject.Save(0, &e.TransportEndpointInfo) stateSinkObject.Save(1, &e.DefaultSocketOptionsHandler) stateSinkObject.Save(2, &e.waiterQueue) @@ -99,23 +97,21 @@ func (e *endpoint) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(5, &e.rcvList) stateSinkObject.Save(7, &e.rcvBufSize) stateSinkObject.Save(8, &e.rcvClosed) - stateSinkObject.Save(9, &e.sndBufSize) - stateSinkObject.Save(10, &e.sndBufSizeMax) - stateSinkObject.Save(11, &e.state) - stateSinkObject.Save(12, &e.dstPort) - stateSinkObject.Save(13, &e.ttl) - stateSinkObject.Save(14, &e.multicastTTL) - stateSinkObject.Save(15, &e.multicastAddr) - stateSinkObject.Save(16, &e.multicastNICID) - stateSinkObject.Save(17, &e.portFlags) - stateSinkObject.Save(19, &e.boundBindToDevice) - stateSinkObject.Save(20, &e.boundPortFlags) - stateSinkObject.Save(21, &e.sendTOS) - stateSinkObject.Save(22, &e.shutdownFlags) - stateSinkObject.Save(23, &e.multicastMemberships) - stateSinkObject.Save(24, &e.effectiveNetProtos) - stateSinkObject.Save(25, &e.owner) - stateSinkObject.Save(26, &e.ops) + stateSinkObject.Save(9, &e.state) + stateSinkObject.Save(10, &e.dstPort) + stateSinkObject.Save(11, &e.ttl) + stateSinkObject.Save(12, &e.multicastTTL) + stateSinkObject.Save(13, &e.multicastAddr) + stateSinkObject.Save(14, &e.multicastNICID) + stateSinkObject.Save(15, &e.portFlags) + stateSinkObject.Save(17, &e.boundBindToDevice) + stateSinkObject.Save(18, &e.boundPortFlags) + stateSinkObject.Save(19, &e.sendTOS) + stateSinkObject.Save(20, &e.shutdownFlags) + stateSinkObject.Save(21, &e.multicastMemberships) + stateSinkObject.Save(22, &e.effectiveNetProtos) + stateSinkObject.Save(23, &e.owner) + stateSinkObject.Save(24, &e.ops) } func (e *endpoint) StateLoad(stateSourceObject state.Source) { @@ -127,25 +123,23 @@ func (e *endpoint) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(5, &e.rcvList) stateSourceObject.Load(7, &e.rcvBufSize) stateSourceObject.Load(8, &e.rcvClosed) - stateSourceObject.Load(9, &e.sndBufSize) - stateSourceObject.Load(10, &e.sndBufSizeMax) - stateSourceObject.Load(11, &e.state) - stateSourceObject.Load(12, &e.dstPort) - stateSourceObject.Load(13, &e.ttl) - stateSourceObject.Load(14, &e.multicastTTL) - stateSourceObject.Load(15, &e.multicastAddr) - stateSourceObject.Load(16, &e.multicastNICID) - stateSourceObject.Load(17, &e.portFlags) - stateSourceObject.Load(19, &e.boundBindToDevice) - stateSourceObject.Load(20, &e.boundPortFlags) - stateSourceObject.Load(21, &e.sendTOS) - stateSourceObject.Load(22, &e.shutdownFlags) - stateSourceObject.Load(23, &e.multicastMemberships) - stateSourceObject.Load(24, &e.effectiveNetProtos) - stateSourceObject.Load(25, &e.owner) - stateSourceObject.Load(26, &e.ops) + stateSourceObject.Load(9, &e.state) + stateSourceObject.Load(10, &e.dstPort) + stateSourceObject.Load(11, &e.ttl) + stateSourceObject.Load(12, &e.multicastTTL) + stateSourceObject.Load(13, &e.multicastAddr) + stateSourceObject.Load(14, &e.multicastNICID) + stateSourceObject.Load(15, &e.portFlags) + stateSourceObject.Load(17, &e.boundBindToDevice) + stateSourceObject.Load(18, &e.boundPortFlags) + stateSourceObject.Load(19, &e.sendTOS) + stateSourceObject.Load(20, &e.shutdownFlags) + stateSourceObject.Load(21, &e.multicastMemberships) + stateSourceObject.Load(22, &e.effectiveNetProtos) + stateSourceObject.Load(23, &e.owner) + stateSourceObject.Load(24, &e.ops) stateSourceObject.LoadValue(6, new(int), func(y interface{}) { e.loadRcvBufSizeMax(y.(int)) }) - stateSourceObject.LoadValue(18, new(string), func(y interface{}) { e.loadLastError(y.(string)) }) + stateSourceObject.LoadValue(16, new(string), func(y interface{}) { e.loadLastError(y.(string)) }) stateSourceObject.AfterLoad(e.afterLoad) } |