// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tcpip

import (
	"gvisor.dev/gvisor/pkg/atomicbitops"
	"gvisor.dev/gvisor/pkg/sync"
)

// SocketOptionsHandler holds methods that help define endpoint specific
// behavior for socket level socket options. These must be implemented by
// endpoints to get notified when socket level options are set.
type SocketOptionsHandler interface {
	// OnReuseAddressSet is invoked when SO_REUSEADDR is set for an endpoint.
	OnReuseAddressSet(v bool)

	// OnReusePortSet is invoked when SO_REUSEPORT is set for an endpoint.
	OnReusePortSet(v bool)

	// OnKeepAliveSet is invoked when SO_KEEPALIVE is set for an endpoint.
	OnKeepAliveSet(v bool)

	// OnDelayOptionSet is invoked when TCP_NODELAY is set for an endpoint.
	// Note that v will be the inverse of TCP_NODELAY option.
	OnDelayOptionSet(v bool)

	// OnCorkOptionSet is invoked when TCP_CORK is set for an endpoint.
	OnCorkOptionSet(v bool)

	// LastError is invoked when SO_ERROR is read for an endpoint.
	LastError() Error

	// UpdateLastError updates the endpoint specific last error field.
	UpdateLastError(err Error)

	// HasNIC is invoked to check if the NIC is valid for SO_BINDTODEVICE.
	HasNIC(v int32) bool

	// OnSetSendBufferSize is invoked when the send buffer size for an endpoint is
	// changed. The handler is invoked with the new value for the socket send
	// buffer size. It also returns the newly set value.
	OnSetSendBufferSize(v int64) (newSz int64)

	// OnSetReceiveBufferSize is invoked by SO_RCVBUF and SO_RCVBUFFORCE. The
	// handler can optionally return a callback which will be called after
	// the buffer size is updated to newSz.
	OnSetReceiveBufferSize(v, oldSz int64) (newSz int64, postSet func())

	// WakeupWriters is invoked when the send buffer size for an endpoint is
	// changed. The handler notifies the writers if the send buffer size is
	// increased with setsockopt(2) for TCP endpoints.
	WakeupWriters()
}

// DefaultSocketOptionsHandler is an embeddable type that implements no-op
// implementations for SocketOptionsHandler methods.
type DefaultSocketOptionsHandler struct{}

var _ SocketOptionsHandler = (*DefaultSocketOptionsHandler)(nil)

// OnReuseAddressSet implements SocketOptionsHandler.OnReuseAddressSet.
func (*DefaultSocketOptionsHandler) OnReuseAddressSet(bool) {}

// OnReusePortSet implements SocketOptionsHandler.OnReusePortSet.
func (*DefaultSocketOptionsHandler) OnReusePortSet(bool) {}

// OnKeepAliveSet implements SocketOptionsHandler.OnKeepAliveSet.
func (*DefaultSocketOptionsHandler) OnKeepAliveSet(bool) {}

// OnDelayOptionSet implements SocketOptionsHandler.OnDelayOptionSet.
func (*DefaultSocketOptionsHandler) OnDelayOptionSet(bool) {}

// OnCorkOptionSet implements SocketOptionsHandler.OnCorkOptionSet.
func (*DefaultSocketOptionsHandler) OnCorkOptionSet(bool) {}

// LastError implements SocketOptionsHandler.LastError.
func (*DefaultSocketOptionsHandler) LastError() Error {
	return nil
}

// UpdateLastError implements SocketOptionsHandler.UpdateLastError.
func (*DefaultSocketOptionsHandler) UpdateLastError(Error) {}

// HasNIC implements SocketOptionsHandler.HasNIC.
func (*DefaultSocketOptionsHandler) HasNIC(int32) bool {
	return false
}

// OnSetSendBufferSize implements SocketOptionsHandler.OnSetSendBufferSize.
func (*DefaultSocketOptionsHandler) OnSetSendBufferSize(v int64) (newSz int64) {
	return v
}

// WakeupWriters implements SocketOptionsHandler.WakeupWriters.
func (*DefaultSocketOptionsHandler) WakeupWriters() {}

// OnSetReceiveBufferSize implements SocketOptionsHandler.OnSetReceiveBufferSize.
func (*DefaultSocketOptionsHandler) OnSetReceiveBufferSize(v, oldSz int64) (newSz int64, postSet func()) {
	return v, nil
}

// StackHandler holds methods to access the stack options. These must be
// implemented by the stack.
type StackHandler interface {
	// Option allows retrieving stack wide options.
	Option(option interface{}) Error

	// TransportProtocolOption allows retrieving individual protocol level
	// option values.
	TransportProtocolOption(proto TransportProtocolNumber, option GettableTransportProtocolOption) Error
}

// SocketOptions contains all the variables which store values for SOL_SOCKET,
// SOL_IP, SOL_IPV6 and SOL_TCP level options.
//
// +stateify savable
type SocketOptions struct {
	handler SocketOptionsHandler

	// StackHandler is initialized at the creation time and will not change.
	stackHandler StackHandler `state:"manual"`

	// These fields are accessed and modified using atomic operations.

	// broadcastEnabled determines whether datagram sockets are allowed to
	// send packets to a broadcast address.
	broadcastEnabled atomicbitops.Uint32

	// passCredEnabled determines whether SCM_CREDENTIALS socket control
	// messages are enabled.
	passCredEnabled atomicbitops.Uint32

	// noChecksumEnabled determines whether UDP checksum is disabled while
	// transmitting for this socket.
	noChecksumEnabled atomicbitops.Uint32

	// reuseAddressEnabled determines whether Bind() should allow reuse of
	// local address.
	reuseAddressEnabled atomicbitops.Uint32

	// reusePortEnabled determines whether to permit multiple sockets to be
	// bound to an identical socket address.
	reusePortEnabled atomicbitops.Uint32

	// keepAliveEnabled determines whether TCP keepalive is enabled for this
	// socket.
	keepAliveEnabled atomicbitops.Uint32

	// multicastLoopEnabled determines whether multicast packets sent over a
	// non-loopback interface will be looped back.
	multicastLoopEnabled atomicbitops.Uint32

	// receiveTOSEnabled is used to specify if the TOS ancillary message is
	// passed with incoming packets.
	receiveTOSEnabled atomicbitops.Uint32

	// receiveTTLEnabled is used to specify if the TTL ancillary message is passed
	// with incoming packets.
	receiveTTLEnabled atomicbitops.Uint32

	// receiveHopLimitEnabled is used to specify if the HopLimit ancillary message
	// is passed with incoming packets.
	receiveHopLimitEnabled atomicbitops.Uint32

	// receiveTClassEnabled is used to specify if the IPV6_TCLASS ancillary
	// message is passed with incoming packets.
	receiveTClassEnabled atomicbitops.Uint32

	// receivePacketInfoEnabled is used to specify if more information is
	// provided with incoming IPv4 packets.
	receivePacketInfoEnabled atomicbitops.Uint32

	// receivePacketInfoEnabled is used to specify if more information is
	// provided with incoming IPv6 packets.
	receiveIPv6PacketInfoEnabled atomicbitops.Uint32

	// hdrIncludeEnabled is used to indicate for a raw endpoint that all packets
	// being written have an IP header and the endpoint should not attach an IP
	// header.
	hdrIncludedEnabled atomicbitops.Uint32

	// v6OnlyEnabled is used to determine whether an IPv6 socket is to be
	// restricted to sending and receiving IPv6 packets only.
	v6OnlyEnabled atomicbitops.Uint32

	// quickAckEnabled is used to represent the value of TCP_QUICKACK option.
	// It currently does not have any effect on the TCP endpoint.
	quickAckEnabled atomicbitops.Uint32

	// delayOptionEnabled is used to specify if data should be sent out immediately
	// by the transport protocol. For TCP, it determines if the Nagle algorithm
	// is on or off.
	delayOptionEnabled atomicbitops.Uint32

	// corkOptionEnabled is used to specify if data should be held until segments
	// are full by the TCP transport protocol.
	corkOptionEnabled atomicbitops.Uint32

	// receiveOriginalDstAddress is used to specify if the original destination of
	// the incoming packet should be returned as an ancillary message.
	receiveOriginalDstAddress atomicbitops.Uint32

	// ipv4RecvErrEnabled determines whether extended reliable error message
	// passing is enabled for IPv4.
	ipv4RecvErrEnabled atomicbitops.Uint32

	// ipv6RecvErrEnabled determines whether extended reliable error message
	// passing is enabled for IPv6.
	ipv6RecvErrEnabled atomicbitops.Uint32

	// errQueue is the per-socket error queue. It is protected by errQueueMu.
	errQueueMu sync.Mutex `state:"nosave"`
	errQueue   sockErrorList

	// bindToDevice determines the device to which the socket is bound.
	bindToDevice atomicbitops.Int32

	// getSendBufferLimits provides the handler to get the min, default and max
	// size for send buffer. It is initialized at the creation time and will not
	// change.
	getSendBufferLimits GetSendBufferLimits `state:"manual"`

	// sendBufferSize determines the send buffer size for this socket.
	sendBufferSize atomicbitops.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"`

	// receiveBufferSize determines the receive buffer size for this socket.
	receiveBufferSize atomicbitops.Int64

	// mu protects the access to the below fields.
	mu sync.Mutex `state:"nosave"`

	// linger determines the amount of time the socket should linger before
	// close. We currently implement this option for TCP socket only.
	linger LingerOption

	// rcvlowat specifies the minimum number of bytes which should be
	// received to indicate the socket as readable.
	rcvlowat atomicbitops.Int32
}

// InitHandler initializes the handler. This must be called before using the
// socket options utility.
func (so *SocketOptions) InitHandler(handler SocketOptionsHandler, stack StackHandler, getSendBufferLimits GetSendBufferLimits, getReceiveBufferLimits GetReceiveBufferLimits) {
	so.handler = handler
	so.stackHandler = stack
	so.getSendBufferLimits = getSendBufferLimits
	so.getReceiveBufferLimits = getReceiveBufferLimits
}

func storeAtomicBool(addr *atomicbitops.Uint32, v bool) {
	var val uint32
	if v {
		val = 1
	}
	addr.Store(val)
}

// SetLastError sets the last error for a socket.
func (so *SocketOptions) SetLastError(err Error) {
	so.handler.UpdateLastError(err)
}

// GetBroadcast gets value for SO_BROADCAST option.
func (so *SocketOptions) GetBroadcast() bool {
	return so.broadcastEnabled.Load() != 0
}

// SetBroadcast sets value for SO_BROADCAST option.
func (so *SocketOptions) SetBroadcast(v bool) {
	storeAtomicBool(&so.broadcastEnabled, v)
}

// GetPassCred gets value for SO_PASSCRED option.
func (so *SocketOptions) GetPassCred() bool {
	return so.passCredEnabled.Load() != 0
}

// SetPassCred sets value for SO_PASSCRED option.
func (so *SocketOptions) SetPassCred(v bool) {
	storeAtomicBool(&so.passCredEnabled, v)
}

// GetNoChecksum gets value for SO_NO_CHECK option.
func (so *SocketOptions) GetNoChecksum() bool {
	return so.noChecksumEnabled.Load() != 0
}

// SetNoChecksum sets value for SO_NO_CHECK option.
func (so *SocketOptions) SetNoChecksum(v bool) {
	storeAtomicBool(&so.noChecksumEnabled, v)
}

// GetReuseAddress gets value for SO_REUSEADDR option.
func (so *SocketOptions) GetReuseAddress() bool {
	return so.reuseAddressEnabled.Load() != 0
}

// SetReuseAddress sets value for SO_REUSEADDR option.
func (so *SocketOptions) SetReuseAddress(v bool) {
	storeAtomicBool(&so.reuseAddressEnabled, v)
	so.handler.OnReuseAddressSet(v)
}

// GetReusePort gets value for SO_REUSEPORT option.
func (so *SocketOptions) GetReusePort() bool {
	return so.reusePortEnabled.Load() != 0
}

// SetReusePort sets value for SO_REUSEPORT option.
func (so *SocketOptions) SetReusePort(v bool) {
	storeAtomicBool(&so.reusePortEnabled, v)
	so.handler.OnReusePortSet(v)
}

// GetKeepAlive gets value for SO_KEEPALIVE option.
func (so *SocketOptions) GetKeepAlive() bool {
	return so.keepAliveEnabled.Load() != 0
}

// SetKeepAlive sets value for SO_KEEPALIVE option.
func (so *SocketOptions) SetKeepAlive(v bool) {
	storeAtomicBool(&so.keepAliveEnabled, v)
	so.handler.OnKeepAliveSet(v)
}

// GetMulticastLoop gets value for IP_MULTICAST_LOOP option.
func (so *SocketOptions) GetMulticastLoop() bool {
	return so.multicastLoopEnabled.Load() != 0
}

// SetMulticastLoop sets value for IP_MULTICAST_LOOP option.
func (so *SocketOptions) SetMulticastLoop(v bool) {
	storeAtomicBool(&so.multicastLoopEnabled, v)
}

// GetReceiveTOS gets value for IP_RECVTOS option.
func (so *SocketOptions) GetReceiveTOS() bool {
	return so.receiveTOSEnabled.Load() != 0
}

// SetReceiveTOS sets value for IP_RECVTOS option.
func (so *SocketOptions) SetReceiveTOS(v bool) {
	storeAtomicBool(&so.receiveTOSEnabled, v)
}

// GetReceiveTTL gets value for IP_RECVTTL option.
func (so *SocketOptions) GetReceiveTTL() bool {
	return so.receiveTTLEnabled.Load() != 0
}

// SetReceiveTTL sets value for IP_RECVTTL option.
func (so *SocketOptions) SetReceiveTTL(v bool) {
	storeAtomicBool(&so.receiveTTLEnabled, v)
}

// GetReceiveHopLimit gets value for IP_RECVHOPLIMIT option.
func (so *SocketOptions) GetReceiveHopLimit() bool {
	return so.receiveHopLimitEnabled.Load() != 0
}

// SetReceiveHopLimit sets value for IP_RECVHOPLIMIT option.
func (so *SocketOptions) SetReceiveHopLimit(v bool) {
	storeAtomicBool(&so.receiveHopLimitEnabled, v)
}

// GetReceiveTClass gets value for IPV6_RECVTCLASS option.
func (so *SocketOptions) GetReceiveTClass() bool {
	return so.receiveTClassEnabled.Load() != 0
}

// SetReceiveTClass sets value for IPV6_RECVTCLASS option.
func (so *SocketOptions) SetReceiveTClass(v bool) {
	storeAtomicBool(&so.receiveTClassEnabled, v)
}

// GetReceivePacketInfo gets value for IP_PKTINFO option.
func (so *SocketOptions) GetReceivePacketInfo() bool {
	return so.receivePacketInfoEnabled.Load() != 0
}

// SetReceivePacketInfo sets value for IP_PKTINFO option.
func (so *SocketOptions) SetReceivePacketInfo(v bool) {
	storeAtomicBool(&so.receivePacketInfoEnabled, v)
}

// GetIPv6ReceivePacketInfo gets value for IPV6_RECVPKTINFO option.
func (so *SocketOptions) GetIPv6ReceivePacketInfo() bool {
	return so.receiveIPv6PacketInfoEnabled.Load() != 0
}

// SetIPv6ReceivePacketInfo sets value for IPV6_RECVPKTINFO option.
func (so *SocketOptions) SetIPv6ReceivePacketInfo(v bool) {
	storeAtomicBool(&so.receiveIPv6PacketInfoEnabled, v)
}

// GetHeaderIncluded gets value for IP_HDRINCL option.
func (so *SocketOptions) GetHeaderIncluded() bool {
	return so.hdrIncludedEnabled.Load() != 0
}

// SetHeaderIncluded sets value for IP_HDRINCL option.
func (so *SocketOptions) SetHeaderIncluded(v bool) {
	storeAtomicBool(&so.hdrIncludedEnabled, v)
}

// GetV6Only gets value for IPV6_V6ONLY option.
func (so *SocketOptions) GetV6Only() bool {
	return so.v6OnlyEnabled.Load() != 0
}

// SetV6Only sets value for IPV6_V6ONLY option.
//
// Preconditions: the backing TCP or UDP endpoint must be in initial state.
func (so *SocketOptions) SetV6Only(v bool) {
	storeAtomicBool(&so.v6OnlyEnabled, v)
}

// GetQuickAck gets value for TCP_QUICKACK option.
func (so *SocketOptions) GetQuickAck() bool {
	return so.quickAckEnabled.Load() != 0
}

// SetQuickAck sets value for TCP_QUICKACK option.
func (so *SocketOptions) SetQuickAck(v bool) {
	storeAtomicBool(&so.quickAckEnabled, v)
}

// GetDelayOption gets inverted value for TCP_NODELAY option.
func (so *SocketOptions) GetDelayOption() bool {
	return so.delayOptionEnabled.Load() != 0
}

// SetDelayOption sets inverted value for TCP_NODELAY option.
func (so *SocketOptions) SetDelayOption(v bool) {
	storeAtomicBool(&so.delayOptionEnabled, v)
	so.handler.OnDelayOptionSet(v)
}

// GetCorkOption gets value for TCP_CORK option.
func (so *SocketOptions) GetCorkOption() bool {
	return so.corkOptionEnabled.Load() != 0
}

// SetCorkOption sets value for TCP_CORK option.
func (so *SocketOptions) SetCorkOption(v bool) {
	storeAtomicBool(&so.corkOptionEnabled, v)
	so.handler.OnCorkOptionSet(v)
}

// GetReceiveOriginalDstAddress gets value for IP(V6)_RECVORIGDSTADDR option.
func (so *SocketOptions) GetReceiveOriginalDstAddress() bool {
	return so.receiveOriginalDstAddress.Load() != 0
}

// SetReceiveOriginalDstAddress sets value for IP(V6)_RECVORIGDSTADDR option.
func (so *SocketOptions) SetReceiveOriginalDstAddress(v bool) {
	storeAtomicBool(&so.receiveOriginalDstAddress, v)
}

// GetIPv4RecvError gets value for IP_RECVERR option.
func (so *SocketOptions) GetIPv4RecvError() bool {
	return so.ipv4RecvErrEnabled.Load() != 0
}

// SetIPv4RecvError sets value for IP_RECVERR option.
func (so *SocketOptions) SetIPv4RecvError(v bool) {
	storeAtomicBool(&so.ipv4RecvErrEnabled, v)
	if !v {
		so.pruneErrQueue()
	}
}

// GetIPv6RecvError gets value for IPV6_RECVERR option.
func (so *SocketOptions) GetIPv6RecvError() bool {
	return so.ipv6RecvErrEnabled.Load() != 0
}

// SetIPv6RecvError sets value for IPV6_RECVERR option.
func (so *SocketOptions) SetIPv6RecvError(v bool) {
	storeAtomicBool(&so.ipv6RecvErrEnabled, v)
	if !v {
		so.pruneErrQueue()
	}
}

// GetLastError gets value for SO_ERROR option.
func (so *SocketOptions) GetLastError() Error {
	return so.handler.LastError()
}

// GetOutOfBandInline gets value for SO_OOBINLINE option.
func (*SocketOptions) GetOutOfBandInline() bool {
	return true
}

// SetOutOfBandInline sets value for SO_OOBINLINE option. We currently do not
// support disabling this option.
func (*SocketOptions) SetOutOfBandInline(bool) {}

// GetLinger gets value for SO_LINGER option.
func (so *SocketOptions) GetLinger() LingerOption {
	so.mu.Lock()
	linger := so.linger
	so.mu.Unlock()
	return linger
}

// SetLinger sets value for SO_LINGER option.
func (so *SocketOptions) SetLinger(linger LingerOption) {
	so.mu.Lock()
	so.linger = linger
	so.mu.Unlock()
}

// SockErrOrigin represents the constants for error origin.
type SockErrOrigin uint8

const (
	// SockExtErrorOriginNone represents an unknown error origin.
	SockExtErrorOriginNone SockErrOrigin = iota

	// SockExtErrorOriginLocal indicates a local error.
	SockExtErrorOriginLocal

	// SockExtErrorOriginICMP indicates an IPv4 ICMP error.
	SockExtErrorOriginICMP

	// SockExtErrorOriginICMP6 indicates an IPv6 ICMP error.
	SockExtErrorOriginICMP6
)

// IsICMPErr indicates if the error originated from an ICMP error.
func (origin SockErrOrigin) IsICMPErr() bool {
	return origin == SockExtErrorOriginICMP || origin == SockExtErrorOriginICMP6
}

// SockErrorCause is the cause of a socket error.
type SockErrorCause interface {
	// Origin is the source of the error.
	Origin() SockErrOrigin

	// Type is the origin specific type of error.
	Type() uint8

	// Code is the origin and type specific error code.
	Code() uint8

	// Info is any extra information about the error.
	Info() uint32
}

// LocalSockError is a socket error that originated from the local host.
//
// +stateify savable
type LocalSockError struct {
	info uint32
}

// Origin implements SockErrorCause.
func (*LocalSockError) Origin() SockErrOrigin {
	return SockExtErrorOriginLocal
}

// Type implements SockErrorCause.
func (*LocalSockError) Type() uint8 {
	return 0
}

// Code implements SockErrorCause.
func (*LocalSockError) Code() uint8 {
	return 0
}

// Info implements SockErrorCause.
func (l *LocalSockError) Info() uint32 {
	return l.info
}

// SockError represents a queue entry in the per-socket error queue.
//
// +stateify savable
type SockError struct {
	sockErrorEntry

	// Err is the error caused by the errant packet.
	Err Error
	// Cause is the detailed cause of the error.
	Cause SockErrorCause

	// Payload is the errant packet's payload.
	Payload []byte
	// Dst is the original destination address of the errant packet.
	Dst FullAddress
	// Offender is the original sender address of the errant packet.
	Offender FullAddress
	// NetProto is the network protocol being used to transmit the packet.
	NetProto NetworkProtocolNumber
}

// pruneErrQueue resets the queue.
func (so *SocketOptions) pruneErrQueue() {
	so.errQueueMu.Lock()
	so.errQueue.Reset()
	so.errQueueMu.Unlock()
}

// DequeueErr dequeues a socket extended error from the error queue and returns
// it. Returns nil if queue is empty.
func (so *SocketOptions) DequeueErr() *SockError {
	so.errQueueMu.Lock()
	defer so.errQueueMu.Unlock()

	err := so.errQueue.Front()
	if err != nil {
		so.errQueue.Remove(err)
	}
	return err
}

// PeekErr returns the error in the front of the error queue. Returns nil if
// the error queue is empty.
func (so *SocketOptions) PeekErr() *SockError {
	so.errQueueMu.Lock()
	defer so.errQueueMu.Unlock()
	return so.errQueue.Front()
}

// QueueErr inserts the error at the back of the error queue.
//
// Preconditions: so.GetIPv4RecvError() or so.GetIPv6RecvError() is true.
func (so *SocketOptions) QueueErr(err *SockError) {
	so.errQueueMu.Lock()
	defer so.errQueueMu.Unlock()
	so.errQueue.PushBack(err)
}

// QueueLocalErr queues a local error onto the local queue.
func (so *SocketOptions) QueueLocalErr(err Error, net NetworkProtocolNumber, info uint32, dst FullAddress, payload []byte) {
	so.QueueErr(&SockError{
		Err:      err,
		Cause:    &LocalSockError{info: info},
		Payload:  payload,
		Dst:      dst,
		NetProto: net,
	})
}

// GetBindToDevice gets value for SO_BINDTODEVICE option.
func (so *SocketOptions) GetBindToDevice() int32 {
	return so.bindToDevice.Load()
}

// SetBindToDevice sets value for SO_BINDTODEVICE option. If bindToDevice is
// zero, the socket device binding is removed.
func (so *SocketOptions) SetBindToDevice(bindToDevice int32) Error {
	if bindToDevice != 0 && !so.handler.HasNIC(bindToDevice) {
		return &ErrUnknownDevice{}
	}

	so.bindToDevice.Store(bindToDevice)
	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) {
	limits := so.getSendBufferLimits(so.stackHandler)
	return int64(limits.Min), int64(limits.Max)
}

// 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) {
	if notify {
		sendBufferSize = so.handler.OnSetSendBufferSize(sendBufferSize)
	}
	so.sendBufferSize.Store(sendBufferSize)
	if notify {
		so.handler.WakeupWriters()
	}
}

// GetReceiveBufferSize gets value for SO_RCVBUF option.
func (so *SocketOptions) GetReceiveBufferSize() int64 {
	return so.receiveBufferSize.Load()
}

// ReceiveBufferLimits returns the [min, max) range of allowable receive buffer
// sizes.
func (so *SocketOptions) ReceiveBufferLimits() (min, max int64) {
	limits := so.getReceiveBufferLimits(so.stackHandler)
	return int64(limits.Min), int64(limits.Max)
}

// SetReceiveBufferSize sets the value of the SO_RCVBUF option, optionally
// notifying the owning endpoint.
func (so *SocketOptions) SetReceiveBufferSize(receiveBufferSize int64, notify bool) {
	var postSet func()
	if notify {
		oldSz := so.receiveBufferSize.Load()
		receiveBufferSize, postSet = so.handler.OnSetReceiveBufferSize(receiveBufferSize, oldSz)
	}
	so.receiveBufferSize.Store(receiveBufferSize)
	if postSet != nil {
		postSet()
	}
}

// GetRcvlowat gets value for SO_RCVLOWAT option.
func (so *SocketOptions) GetRcvlowat() int32 {
	// TODO(b/226603727): Return so.rcvlowat after adding complete support
	// for SO_RCVLOWAT option. For now, return the default value of 1.
	defaultRcvlowat := int32(1)
	return defaultRcvlowat
}

// SetRcvlowat sets value for SO_RCVLOWAT option.
func (so *SocketOptions) SetRcvlowat(rcvlowat int32) Error {
	so.rcvlowat.Store(rcvlowat)
	return nil
}
