mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
netstack: atomically update buffer sizes
Previously, two calls to set the send or receive buffer size could have raced and left state wherein: - The actual size depended on one call - The value returned by getsockopt() depended on the other PiperOrigin-RevId: 384508720
This commit is contained in:
committed by
gVisor bot
parent
b4caeaf78f
commit
1fe6db8c54
+31
-17
@@ -17,7 +17,6 @@ package tcpip
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -208,16 +207,24 @@ type SocketOptions struct {
|
||||
// will not change.
|
||||
getSendBufferLimits GetSendBufferLimits `state:"manual"`
|
||||
|
||||
// sendBufSizeMu protects sendBufferSize and calls to
|
||||
// handler.OnSetSendBufferSize.
|
||||
sendBufSizeMu sync.Mutex `state:"nosave"`
|
||||
|
||||
// sendBufferSize determines the send buffer size for this socket.
|
||||
sendBufferSize atomicbitops.AlignedAtomicInt64
|
||||
sendBufferSize int64
|
||||
|
||||
// getReceiveBufferLimits provides the handler to get the min, default and
|
||||
// max size for receive buffer. It is initialized at the creation time and
|
||||
// will not change.
|
||||
getReceiveBufferLimits GetReceiveBufferLimits `state:"manual"`
|
||||
|
||||
// receiveBufSizeMu protects receiveBufferSize and calls to
|
||||
// handler.OnSetReceiveBufferSize.
|
||||
receiveBufSizeMu sync.Mutex `state:"nosave"`
|
||||
|
||||
// receiveBufferSize determines the receive buffer size for this socket.
|
||||
receiveBufferSize atomicbitops.AlignedAtomicInt64
|
||||
receiveBufferSize int64
|
||||
|
||||
// mu protects the access to the below fields.
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
@@ -607,11 +614,6 @@ func (so *SocketOptions) SetBindToDevice(bindToDevice int32) Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSendBufferSize gets value for SO_SNDBUF option.
|
||||
func (so *SocketOptions) GetSendBufferSize() int64 {
|
||||
return so.sendBufferSize.Load()
|
||||
}
|
||||
|
||||
// SendBufferLimits returns the [min, max) range of allowable send buffer
|
||||
// sizes.
|
||||
func (so *SocketOptions) SendBufferLimits() (min, max int64) {
|
||||
@@ -619,18 +621,22 @@ func (so *SocketOptions) SendBufferLimits() (min, max int64) {
|
||||
return int64(limits.Min), int64(limits.Max)
|
||||
}
|
||||
|
||||
// GetSendBufferSize gets value for SO_SNDBUF option.
|
||||
func (so *SocketOptions) GetSendBufferSize() int64 {
|
||||
so.sendBufSizeMu.Lock()
|
||||
defer so.sendBufSizeMu.Unlock()
|
||||
return so.sendBufferSize
|
||||
}
|
||||
|
||||
// SetSendBufferSize sets value for SO_SNDBUF option. notify indicates if the
|
||||
// stack handler should be invoked to set the send buffer size.
|
||||
func (so *SocketOptions) SetSendBufferSize(sendBufferSize int64, notify bool) {
|
||||
so.sendBufSizeMu.Lock()
|
||||
defer so.sendBufSizeMu.Unlock()
|
||||
if notify {
|
||||
sendBufferSize = so.handler.OnSetSendBufferSize(sendBufferSize)
|
||||
}
|
||||
so.sendBufferSize.Store(sendBufferSize)
|
||||
}
|
||||
|
||||
// GetReceiveBufferSize gets value for SO_RCVBUF option.
|
||||
func (so *SocketOptions) GetReceiveBufferSize() int64 {
|
||||
return so.receiveBufferSize.Load()
|
||||
so.sendBufferSize = sendBufferSize
|
||||
}
|
||||
|
||||
// ReceiveBufferLimits returns the [min, max) range of allowable receive buffer
|
||||
@@ -640,12 +646,20 @@ func (so *SocketOptions) ReceiveBufferLimits() (min, max int64) {
|
||||
return int64(limits.Min), int64(limits.Max)
|
||||
}
|
||||
|
||||
// GetReceiveBufferSize gets value for SO_RCVBUF option.
|
||||
func (so *SocketOptions) GetReceiveBufferSize() int64 {
|
||||
so.receiveBufSizeMu.Lock()
|
||||
defer so.receiveBufSizeMu.Unlock()
|
||||
return so.receiveBufferSize
|
||||
}
|
||||
|
||||
// SetReceiveBufferSize sets the value of the SO_RCVBUF option, optionally
|
||||
// notifying the owning endpoint.
|
||||
func (so *SocketOptions) SetReceiveBufferSize(receiveBufferSize int64, notify bool) {
|
||||
so.receiveBufSizeMu.Lock()
|
||||
defer so.receiveBufSizeMu.Unlock()
|
||||
if notify {
|
||||
oldSz := so.receiveBufferSize.Load()
|
||||
receiveBufferSize = so.handler.OnSetReceiveBufferSize(receiveBufferSize, oldSz)
|
||||
receiveBufferSize = so.handler.OnSetReceiveBufferSize(receiveBufferSize, so.receiveBufferSize)
|
||||
}
|
||||
so.receiveBufferSize.Store(receiveBufferSize)
|
||||
so.receiveBufferSize = receiveBufferSize
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user