socketops.go raw

   1  // Copyright 2020 The gVisor Authors.
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //     http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  package tcpip
  16  
  17  import (
  18  	"gvisor.dev/gvisor/pkg/atomicbitops"
  19  	"gvisor.dev/gvisor/pkg/buffer"
  20  	"gvisor.dev/gvisor/pkg/sync"
  21  )
  22  
  23  // SocketOptionsHandler holds methods that help define endpoint specific
  24  // behavior for socket level socket options. These must be implemented by
  25  // endpoints to get notified when socket level options are set.
  26  type SocketOptionsHandler interface {
  27  	// OnReuseAddressSet is invoked when SO_REUSEADDR is set for an endpoint.
  28  	OnReuseAddressSet(v bool)
  29  
  30  	// OnReusePortSet is invoked when SO_REUSEPORT is set for an endpoint.
  31  	OnReusePortSet(v bool)
  32  
  33  	// OnKeepAliveSet is invoked when SO_KEEPALIVE is set for an endpoint.
  34  	OnKeepAliveSet(v bool)
  35  
  36  	// OnDelayOptionSet is invoked when TCP_NODELAY is set for an endpoint.
  37  	// Note that v will be the inverse of TCP_NODELAY option.
  38  	OnDelayOptionSet(v bool)
  39  
  40  	// OnCorkOptionSet is invoked when TCP_CORK is set for an endpoint.
  41  	OnCorkOptionSet(v bool)
  42  
  43  	// LastError is invoked when SO_ERROR is read for an endpoint.
  44  	LastError() Error
  45  
  46  	// UpdateLastError updates the endpoint specific last error field.
  47  	UpdateLastError(err Error)
  48  
  49  	// HasNIC is invoked to check if the NIC is valid for SO_BINDTODEVICE.
  50  	HasNIC(v int32) bool
  51  
  52  	// OnSetSendBufferSize is invoked when the send buffer size for an endpoint is
  53  	// changed. The handler is invoked with the new value for the socket send
  54  	// buffer size. It also returns the newly set value.
  55  	OnSetSendBufferSize(v int64) (newSz int64)
  56  
  57  	// OnSetReceiveBufferSize is invoked by SO_RCVBUF and SO_RCVBUFFORCE. The
  58  	// handler can optionally return a callback which will be called after
  59  	// the buffer size is updated to newSz.
  60  	OnSetReceiveBufferSize(v, oldSz int64) (newSz int64, postSet func())
  61  
  62  	// WakeupWriters is invoked when the send buffer size for an endpoint is
  63  	// changed. The handler notifies the writers if the send buffer size is
  64  	// increased with setsockopt(2) for TCP endpoints.
  65  	WakeupWriters()
  66  
  67  	// GetAcceptConn returns true if the socket is a TCP socket and is in
  68  	// listening state.
  69  	GetAcceptConn() bool
  70  }
  71  
  72  // DefaultSocketOptionsHandler is an embeddable type that implements no-op
  73  // implementations for SocketOptionsHandler methods.
  74  type DefaultSocketOptionsHandler struct{}
  75  
  76  var _ SocketOptionsHandler = (*DefaultSocketOptionsHandler)(nil)
  77  
  78  // OnReuseAddressSet implements SocketOptionsHandler.OnReuseAddressSet.
  79  func (*DefaultSocketOptionsHandler) OnReuseAddressSet(bool) {}
  80  
  81  // OnReusePortSet implements SocketOptionsHandler.OnReusePortSet.
  82  func (*DefaultSocketOptionsHandler) OnReusePortSet(bool) {}
  83  
  84  // OnKeepAliveSet implements SocketOptionsHandler.OnKeepAliveSet.
  85  func (*DefaultSocketOptionsHandler) OnKeepAliveSet(bool) {}
  86  
  87  // OnDelayOptionSet implements SocketOptionsHandler.OnDelayOptionSet.
  88  func (*DefaultSocketOptionsHandler) OnDelayOptionSet(bool) {}
  89  
  90  // OnCorkOptionSet implements SocketOptionsHandler.OnCorkOptionSet.
  91  func (*DefaultSocketOptionsHandler) OnCorkOptionSet(bool) {}
  92  
  93  // LastError implements SocketOptionsHandler.LastError.
  94  func (*DefaultSocketOptionsHandler) LastError() Error {
  95  	return nil
  96  }
  97  
  98  // UpdateLastError implements SocketOptionsHandler.UpdateLastError.
  99  func (*DefaultSocketOptionsHandler) UpdateLastError(Error) {}
 100  
 101  // HasNIC implements SocketOptionsHandler.HasNIC.
 102  func (*DefaultSocketOptionsHandler) HasNIC(int32) bool {
 103  	return false
 104  }
 105  
 106  // OnSetSendBufferSize implements SocketOptionsHandler.OnSetSendBufferSize.
 107  func (*DefaultSocketOptionsHandler) OnSetSendBufferSize(v int64) (newSz int64) {
 108  	return v
 109  }
 110  
 111  // WakeupWriters implements SocketOptionsHandler.WakeupWriters.
 112  func (*DefaultSocketOptionsHandler) WakeupWriters() {}
 113  
 114  // OnSetReceiveBufferSize implements SocketOptionsHandler.OnSetReceiveBufferSize.
 115  func (*DefaultSocketOptionsHandler) OnSetReceiveBufferSize(v, oldSz int64) (newSz int64, postSet func()) {
 116  	return v, nil
 117  }
 118  
 119  // GetAcceptConn implements SocketOptionsHandler.GetAcceptConn.
 120  func (*DefaultSocketOptionsHandler) GetAcceptConn() bool {
 121  	return false
 122  }
 123  
 124  // StackHandler holds methods to access the stack options. These must be
 125  // implemented by the stack.
 126  type StackHandler interface {
 127  	// Option allows retrieving stack wide options.
 128  	Option(option any) Error
 129  
 130  	// TransportProtocolOption allows retrieving individual protocol level
 131  	// option values.
 132  	TransportProtocolOption(proto TransportProtocolNumber, option GettableTransportProtocolOption) Error
 133  }
 134  
 135  // SocketOptions contains all the variables which store values for SOL_SOCKET,
 136  // SOL_IP, SOL_IPV6 and SOL_TCP level options.
 137  //
 138  // +stateify savable
 139  type SocketOptions struct {
 140  	handler SocketOptionsHandler
 141  
 142  	// StackHandler is initialized at the creation time and will not change.
 143  	stackHandler StackHandler `state:"manual"`
 144  
 145  	// These fields are accessed and modified using atomic operations.
 146  
 147  	// broadcastEnabled determines whether datagram sockets are allowed to
 148  	// send packets to a broadcast address.
 149  	broadcastEnabled atomicbitops.Uint32
 150  
 151  	// passCredEnabled determines whether SCM_CREDENTIALS socket control
 152  	// messages are enabled.
 153  	passCredEnabled atomicbitops.Uint32
 154  
 155  	// noChecksumEnabled determines whether UDP checksum is disabled while
 156  	// transmitting for this socket.
 157  	noChecksumEnabled atomicbitops.Uint32
 158  
 159  	// reuseAddressEnabled determines whether Bind() should allow reuse of
 160  	// local address.
 161  	reuseAddressEnabled atomicbitops.Uint32
 162  
 163  	// reusePortEnabled determines whether to permit multiple sockets to be
 164  	// bound to an identical socket address.
 165  	reusePortEnabled atomicbitops.Uint32
 166  
 167  	// keepAliveEnabled determines whether TCP keepalive is enabled for this
 168  	// socket.
 169  	keepAliveEnabled atomicbitops.Uint32
 170  
 171  	// multicastLoopEnabled determines whether multicast packets sent over a
 172  	// non-loopback interface will be looped back.
 173  	multicastLoopEnabled atomicbitops.Uint32
 174  
 175  	// receiveTOSEnabled is used to specify if the TOS ancillary message is
 176  	// passed with incoming packets.
 177  	receiveTOSEnabled atomicbitops.Uint32
 178  
 179  	// receiveTTLEnabled is used to specify if the TTL ancillary message is passed
 180  	// with incoming packets.
 181  	receiveTTLEnabled atomicbitops.Uint32
 182  
 183  	// receiveHopLimitEnabled is used to specify if the HopLimit ancillary message
 184  	// is passed with incoming packets.
 185  	receiveHopLimitEnabled atomicbitops.Uint32
 186  
 187  	// receiveTClassEnabled is used to specify if the IPV6_TCLASS ancillary
 188  	// message is passed with incoming packets.
 189  	receiveTClassEnabled atomicbitops.Uint32
 190  
 191  	// receivePacketInfoEnabled is used to specify if more information is
 192  	// provided with incoming IPv4 packets.
 193  	receivePacketInfoEnabled atomicbitops.Uint32
 194  
 195  	// receivePacketInfoEnabled is used to specify if more information is
 196  	// provided with incoming IPv6 packets.
 197  	receiveIPv6PacketInfoEnabled atomicbitops.Uint32
 198  
 199  	// hdrIncludeEnabled is used to indicate for a raw endpoint that all packets
 200  	// being written have an IP header and the endpoint should not attach an IP
 201  	// header.
 202  	hdrIncludedEnabled atomicbitops.Uint32
 203  
 204  	// v6OnlyEnabled is used to determine whether an IPv6 socket is to be
 205  	// restricted to sending and receiving IPv6 packets only.
 206  	v6OnlyEnabled atomicbitops.Uint32
 207  
 208  	// quickAckEnabled is used to represent the value of TCP_QUICKACK option.
 209  	// It currently does not have any effect on the TCP endpoint.
 210  	quickAckEnabled atomicbitops.Uint32
 211  
 212  	// delayOptionEnabled is used to specify if data should be sent out immediately
 213  	// by the transport protocol. For TCP, it determines if the Nagle algorithm
 214  	// is on or off.
 215  	delayOptionEnabled atomicbitops.Uint32
 216  
 217  	// corkOptionEnabled is used to specify if data should be held until segments
 218  	// are full by the TCP transport protocol.
 219  	corkOptionEnabled atomicbitops.Uint32
 220  
 221  	// receiveOriginalDstAddress is used to specify if the original destination of
 222  	// the incoming packet should be returned as an ancillary message.
 223  	receiveOriginalDstAddress atomicbitops.Uint32
 224  
 225  	// ipv4RecvErrEnabled determines whether extended reliable error message
 226  	// passing is enabled for IPv4.
 227  	ipv4RecvErrEnabled atomicbitops.Uint32
 228  
 229  	// ipv6RecvErrEnabled determines whether extended reliable error message
 230  	// passing is enabled for IPv6.
 231  	ipv6RecvErrEnabled atomicbitops.Uint32
 232  
 233  	// errQueue is the per-socket error queue. It is protected by errQueueMu.
 234  	errQueueMu sync.Mutex `state:"nosave"`
 235  	errQueue   sockErrorList
 236  
 237  	// bindToDevice determines the device to which the socket is bound.
 238  	bindToDevice atomicbitops.Int32
 239  
 240  	// getSendBufferLimits provides the handler to get the min, default and max
 241  	// size for send buffer. It is initialized at the creation time and will not
 242  	// change.
 243  	getSendBufferLimits GetSendBufferLimits `state:"manual"`
 244  
 245  	// sendBufferSize determines the send buffer size for this socket.
 246  	sendBufferSize atomicbitops.Int64
 247  
 248  	// getReceiveBufferLimits provides the handler to get the min, default and
 249  	// max size for receive buffer. It is initialized at the creation time and
 250  	// will not change.
 251  	getReceiveBufferLimits GetReceiveBufferLimits `state:"manual"`
 252  
 253  	// receiveBufferSize determines the receive buffer size for this socket.
 254  	receiveBufferSize atomicbitops.Int64
 255  
 256  	// mu protects the access to the below fields.
 257  	mu sync.Mutex `state:"nosave"`
 258  
 259  	// linger determines the amount of time the socket should linger before
 260  	// close. We currently implement this option for TCP socket only.
 261  	linger LingerOption
 262  
 263  	// rcvlowat specifies the minimum number of bytes which should be
 264  	// received to indicate the socket as readable.
 265  	rcvlowat atomicbitops.Int32
 266  
 267  	// experimentOptionValue is the value set for the IP option experiment header
 268  	// if it is not zero.
 269  	experimentOptionValue atomicbitops.Uint32
 270  }
 271  
 272  // InitHandler initializes the handler. This must be called before using the
 273  // socket options utility.
 274  func (so *SocketOptions) InitHandler(handler SocketOptionsHandler, stack StackHandler, getSendBufferLimits GetSendBufferLimits, getReceiveBufferLimits GetReceiveBufferLimits) {
 275  	so.handler = handler
 276  	so.stackHandler = stack
 277  	so.getSendBufferLimits = getSendBufferLimits
 278  	so.getReceiveBufferLimits = getReceiveBufferLimits
 279  }
 280  
 281  func storeAtomicBool(addr *atomicbitops.Uint32, v bool) {
 282  	var val uint32
 283  	if v {
 284  		val = 1
 285  	}
 286  	addr.Store(val)
 287  }
 288  
 289  // SetLastError sets the last error for a socket.
 290  func (so *SocketOptions) SetLastError(err Error) {
 291  	so.handler.UpdateLastError(err)
 292  }
 293  
 294  // GetBroadcast gets value for SO_BROADCAST option.
 295  func (so *SocketOptions) GetBroadcast() bool {
 296  	return so.broadcastEnabled.Load() != 0
 297  }
 298  
 299  // SetBroadcast sets value for SO_BROADCAST option.
 300  func (so *SocketOptions) SetBroadcast(v bool) {
 301  	storeAtomicBool(&so.broadcastEnabled, v)
 302  }
 303  
 304  // GetPassCred gets value for SO_PASSCRED option.
 305  func (so *SocketOptions) GetPassCred() bool {
 306  	return so.passCredEnabled.Load() != 0
 307  }
 308  
 309  // SetPassCred sets value for SO_PASSCRED option.
 310  func (so *SocketOptions) SetPassCred(v bool) {
 311  	storeAtomicBool(&so.passCredEnabled, v)
 312  }
 313  
 314  // GetNoChecksum gets value for SO_NO_CHECK option.
 315  func (so *SocketOptions) GetNoChecksum() bool {
 316  	return so.noChecksumEnabled.Load() != 0
 317  }
 318  
 319  // SetNoChecksum sets value for SO_NO_CHECK option.
 320  func (so *SocketOptions) SetNoChecksum(v bool) {
 321  	storeAtomicBool(&so.noChecksumEnabled, v)
 322  }
 323  
 324  // GetReuseAddress gets value for SO_REUSEADDR option.
 325  func (so *SocketOptions) GetReuseAddress() bool {
 326  	return so.reuseAddressEnabled.Load() != 0
 327  }
 328  
 329  // SetReuseAddress sets value for SO_REUSEADDR option.
 330  func (so *SocketOptions) SetReuseAddress(v bool) {
 331  	storeAtomicBool(&so.reuseAddressEnabled, v)
 332  	so.handler.OnReuseAddressSet(v)
 333  }
 334  
 335  // GetReusePort gets value for SO_REUSEPORT option.
 336  func (so *SocketOptions) GetReusePort() bool {
 337  	return so.reusePortEnabled.Load() != 0
 338  }
 339  
 340  // SetReusePort sets value for SO_REUSEPORT option.
 341  func (so *SocketOptions) SetReusePort(v bool) {
 342  	storeAtomicBool(&so.reusePortEnabled, v)
 343  	so.handler.OnReusePortSet(v)
 344  }
 345  
 346  // GetKeepAlive gets value for SO_KEEPALIVE option.
 347  func (so *SocketOptions) GetKeepAlive() bool {
 348  	return so.keepAliveEnabled.Load() != 0
 349  }
 350  
 351  // SetKeepAlive sets value for SO_KEEPALIVE option.
 352  func (so *SocketOptions) SetKeepAlive(v bool) {
 353  	storeAtomicBool(&so.keepAliveEnabled, v)
 354  	so.handler.OnKeepAliveSet(v)
 355  }
 356  
 357  // GetMulticastLoop gets value for IP_MULTICAST_LOOP option.
 358  func (so *SocketOptions) GetMulticastLoop() bool {
 359  	return so.multicastLoopEnabled.Load() != 0
 360  }
 361  
 362  // SetMulticastLoop sets value for IP_MULTICAST_LOOP option.
 363  func (so *SocketOptions) SetMulticastLoop(v bool) {
 364  	storeAtomicBool(&so.multicastLoopEnabled, v)
 365  }
 366  
 367  // GetReceiveTOS gets value for IP_RECVTOS option.
 368  func (so *SocketOptions) GetReceiveTOS() bool {
 369  	return so.receiveTOSEnabled.Load() != 0
 370  }
 371  
 372  // SetReceiveTOS sets value for IP_RECVTOS option.
 373  func (so *SocketOptions) SetReceiveTOS(v bool) {
 374  	storeAtomicBool(&so.receiveTOSEnabled, v)
 375  }
 376  
 377  // GetReceiveTTL gets value for IP_RECVTTL option.
 378  func (so *SocketOptions) GetReceiveTTL() bool {
 379  	return so.receiveTTLEnabled.Load() != 0
 380  }
 381  
 382  // SetReceiveTTL sets value for IP_RECVTTL option.
 383  func (so *SocketOptions) SetReceiveTTL(v bool) {
 384  	storeAtomicBool(&so.receiveTTLEnabled, v)
 385  }
 386  
 387  // GetReceiveHopLimit gets value for IP_RECVHOPLIMIT option.
 388  func (so *SocketOptions) GetReceiveHopLimit() bool {
 389  	return so.receiveHopLimitEnabled.Load() != 0
 390  }
 391  
 392  // SetReceiveHopLimit sets value for IP_RECVHOPLIMIT option.
 393  func (so *SocketOptions) SetReceiveHopLimit(v bool) {
 394  	storeAtomicBool(&so.receiveHopLimitEnabled, v)
 395  }
 396  
 397  // GetReceiveTClass gets value for IPV6_RECVTCLASS option.
 398  func (so *SocketOptions) GetReceiveTClass() bool {
 399  	return so.receiveTClassEnabled.Load() != 0
 400  }
 401  
 402  // SetReceiveTClass sets value for IPV6_RECVTCLASS option.
 403  func (so *SocketOptions) SetReceiveTClass(v bool) {
 404  	storeAtomicBool(&so.receiveTClassEnabled, v)
 405  }
 406  
 407  // GetReceivePacketInfo gets value for IP_PKTINFO option.
 408  func (so *SocketOptions) GetReceivePacketInfo() bool {
 409  	return so.receivePacketInfoEnabled.Load() != 0
 410  }
 411  
 412  // SetReceivePacketInfo sets value for IP_PKTINFO option.
 413  func (so *SocketOptions) SetReceivePacketInfo(v bool) {
 414  	storeAtomicBool(&so.receivePacketInfoEnabled, v)
 415  }
 416  
 417  // GetIPv6ReceivePacketInfo gets value for IPV6_RECVPKTINFO option.
 418  func (so *SocketOptions) GetIPv6ReceivePacketInfo() bool {
 419  	return so.receiveIPv6PacketInfoEnabled.Load() != 0
 420  }
 421  
 422  // SetIPv6ReceivePacketInfo sets value for IPV6_RECVPKTINFO option.
 423  func (so *SocketOptions) SetIPv6ReceivePacketInfo(v bool) {
 424  	storeAtomicBool(&so.receiveIPv6PacketInfoEnabled, v)
 425  }
 426  
 427  // GetHeaderIncluded gets value for IP_HDRINCL option.
 428  func (so *SocketOptions) GetHeaderIncluded() bool {
 429  	return so.hdrIncludedEnabled.Load() != 0
 430  }
 431  
 432  // SetHeaderIncluded sets value for IP_HDRINCL option.
 433  func (so *SocketOptions) SetHeaderIncluded(v bool) {
 434  	storeAtomicBool(&so.hdrIncludedEnabled, v)
 435  }
 436  
 437  // GetV6Only gets value for IPV6_V6ONLY option.
 438  func (so *SocketOptions) GetV6Only() bool {
 439  	return so.v6OnlyEnabled.Load() != 0
 440  }
 441  
 442  // SetV6Only sets value for IPV6_V6ONLY option.
 443  //
 444  // Preconditions: the backing TCP or UDP endpoint must be in initial state.
 445  func (so *SocketOptions) SetV6Only(v bool) {
 446  	storeAtomicBool(&so.v6OnlyEnabled, v)
 447  }
 448  
 449  // GetQuickAck gets value for TCP_QUICKACK option.
 450  func (so *SocketOptions) GetQuickAck() bool {
 451  	return so.quickAckEnabled.Load() != 0
 452  }
 453  
 454  // SetQuickAck sets value for TCP_QUICKACK option.
 455  func (so *SocketOptions) SetQuickAck(v bool) {
 456  	storeAtomicBool(&so.quickAckEnabled, v)
 457  }
 458  
 459  // GetDelayOption gets inverted value for TCP_NODELAY option.
 460  func (so *SocketOptions) GetDelayOption() bool {
 461  	return so.delayOptionEnabled.Load() != 0
 462  }
 463  
 464  // SetDelayOption sets inverted value for TCP_NODELAY option.
 465  func (so *SocketOptions) SetDelayOption(v bool) {
 466  	storeAtomicBool(&so.delayOptionEnabled, v)
 467  	so.handler.OnDelayOptionSet(v)
 468  }
 469  
 470  // GetCorkOption gets value for TCP_CORK option.
 471  func (so *SocketOptions) GetCorkOption() bool {
 472  	return so.corkOptionEnabled.Load() != 0
 473  }
 474  
 475  // SetCorkOption sets value for TCP_CORK option.
 476  func (so *SocketOptions) SetCorkOption(v bool) {
 477  	storeAtomicBool(&so.corkOptionEnabled, v)
 478  	so.handler.OnCorkOptionSet(v)
 479  }
 480  
 481  // GetReceiveOriginalDstAddress gets value for IP(V6)_RECVORIGDSTADDR option.
 482  func (so *SocketOptions) GetReceiveOriginalDstAddress() bool {
 483  	return so.receiveOriginalDstAddress.Load() != 0
 484  }
 485  
 486  // SetReceiveOriginalDstAddress sets value for IP(V6)_RECVORIGDSTADDR option.
 487  func (so *SocketOptions) SetReceiveOriginalDstAddress(v bool) {
 488  	storeAtomicBool(&so.receiveOriginalDstAddress, v)
 489  }
 490  
 491  // GetIPv4RecvError gets value for IP_RECVERR option.
 492  func (so *SocketOptions) GetIPv4RecvError() bool {
 493  	return so.ipv4RecvErrEnabled.Load() != 0
 494  }
 495  
 496  // SetIPv4RecvError sets value for IP_RECVERR option.
 497  func (so *SocketOptions) SetIPv4RecvError(v bool) {
 498  	storeAtomicBool(&so.ipv4RecvErrEnabled, v)
 499  	if !v {
 500  		so.pruneErrQueue()
 501  	}
 502  }
 503  
 504  // GetIPv6RecvError gets value for IPV6_RECVERR option.
 505  func (so *SocketOptions) GetIPv6RecvError() bool {
 506  	return so.ipv6RecvErrEnabled.Load() != 0
 507  }
 508  
 509  // SetIPv6RecvError sets value for IPV6_RECVERR option.
 510  func (so *SocketOptions) SetIPv6RecvError(v bool) {
 511  	storeAtomicBool(&so.ipv6RecvErrEnabled, v)
 512  	if !v {
 513  		so.pruneErrQueue()
 514  	}
 515  }
 516  
 517  // GetLastError gets value for SO_ERROR option.
 518  func (so *SocketOptions) GetLastError() Error {
 519  	return so.handler.LastError()
 520  }
 521  
 522  // GetOutOfBandInline gets value for SO_OOBINLINE option.
 523  func (*SocketOptions) GetOutOfBandInline() bool {
 524  	return true
 525  }
 526  
 527  // SetOutOfBandInline sets value for SO_OOBINLINE option. We currently do not
 528  // support disabling this option.
 529  func (*SocketOptions) SetOutOfBandInline(bool) {}
 530  
 531  // GetLinger gets value for SO_LINGER option.
 532  func (so *SocketOptions) GetLinger() LingerOption {
 533  	so.mu.Lock()
 534  	linger := so.linger
 535  	so.mu.Unlock()
 536  	return linger
 537  }
 538  
 539  // SetLinger sets value for SO_LINGER option.
 540  func (so *SocketOptions) SetLinger(linger LingerOption) {
 541  	so.mu.Lock()
 542  	so.linger = linger
 543  	so.mu.Unlock()
 544  }
 545  
 546  // GetExperimentOptionValue gets value for the experiment IP option header.
 547  func (so *SocketOptions) GetExperimentOptionValue() uint16 {
 548  	v := so.experimentOptionValue.Load()
 549  	return uint16(v)
 550  }
 551  
 552  // SetExperimentOptionValue sets the value for the experiment IP option header.
 553  func (so *SocketOptions) SetExperimentOptionValue(v uint16) {
 554  	so.experimentOptionValue.Store(uint32(v))
 555  }
 556  
 557  // SockErrOrigin represents the constants for error origin.
 558  type SockErrOrigin uint8
 559  
 560  const (
 561  	// SockExtErrorOriginNone represents an unknown error origin.
 562  	SockExtErrorOriginNone SockErrOrigin = iota
 563  
 564  	// SockExtErrorOriginLocal indicates a local error.
 565  	SockExtErrorOriginLocal
 566  
 567  	// SockExtErrorOriginICMP indicates an IPv4 ICMP error.
 568  	SockExtErrorOriginICMP
 569  
 570  	// SockExtErrorOriginICMP6 indicates an IPv6 ICMP error.
 571  	SockExtErrorOriginICMP6
 572  )
 573  
 574  // IsICMPErr indicates if the error originated from an ICMP error.
 575  func (origin SockErrOrigin) IsICMPErr() bool {
 576  	return origin == SockExtErrorOriginICMP || origin == SockExtErrorOriginICMP6
 577  }
 578  
 579  // SockErrorCause is the cause of a socket error.
 580  type SockErrorCause interface {
 581  	// Origin is the source of the error.
 582  	Origin() SockErrOrigin
 583  
 584  	// Type is the origin specific type of error.
 585  	Type() uint8
 586  
 587  	// Code is the origin and type specific error code.
 588  	Code() uint8
 589  
 590  	// Info is any extra information about the error.
 591  	Info() uint32
 592  }
 593  
 594  // LocalSockError is a socket error that originated from the local host.
 595  //
 596  // +stateify savable
 597  type LocalSockError struct {
 598  	info uint32
 599  }
 600  
 601  // Origin implements SockErrorCause.
 602  func (*LocalSockError) Origin() SockErrOrigin {
 603  	return SockExtErrorOriginLocal
 604  }
 605  
 606  // Type implements SockErrorCause.
 607  func (*LocalSockError) Type() uint8 {
 608  	return 0
 609  }
 610  
 611  // Code implements SockErrorCause.
 612  func (*LocalSockError) Code() uint8 {
 613  	return 0
 614  }
 615  
 616  // Info implements SockErrorCause.
 617  func (l *LocalSockError) Info() uint32 {
 618  	return l.info
 619  }
 620  
 621  // SockError represents a queue entry in the per-socket error queue.
 622  //
 623  // +stateify savable
 624  type SockError struct {
 625  	sockErrorEntry
 626  
 627  	// Err is the error caused by the errant packet.
 628  	Err Error
 629  	// Cause is the detailed cause of the error.
 630  	Cause SockErrorCause
 631  
 632  	// Payload is the errant packet's payload.
 633  	Payload *buffer.View
 634  	// Dst is the original destination address of the errant packet.
 635  	Dst FullAddress
 636  	// Offender is the original sender address of the errant packet.
 637  	Offender FullAddress
 638  	// NetProto is the network protocol being used to transmit the packet.
 639  	NetProto NetworkProtocolNumber
 640  }
 641  
 642  // pruneErrQueue resets the queue.
 643  func (so *SocketOptions) pruneErrQueue() {
 644  	so.errQueueMu.Lock()
 645  	so.errQueue.Reset()
 646  	so.errQueueMu.Unlock()
 647  }
 648  
 649  // DequeueErr dequeues a socket extended error from the error queue and returns
 650  // it. Returns nil if queue is empty.
 651  func (so *SocketOptions) DequeueErr() *SockError {
 652  	so.errQueueMu.Lock()
 653  	defer so.errQueueMu.Unlock()
 654  
 655  	err := so.errQueue.Front()
 656  	if err != nil {
 657  		so.errQueue.Remove(err)
 658  	}
 659  	return err
 660  }
 661  
 662  // PeekErr returns the error in the front of the error queue. Returns nil if
 663  // the error queue is empty.
 664  func (so *SocketOptions) PeekErr() *SockError {
 665  	so.errQueueMu.Lock()
 666  	defer so.errQueueMu.Unlock()
 667  	return so.errQueue.Front()
 668  }
 669  
 670  // QueueErr inserts the error at the back of the error queue.
 671  //
 672  // Preconditions: so.GetIPv4RecvError() or so.GetIPv6RecvError() is true.
 673  func (so *SocketOptions) QueueErr(err *SockError) {
 674  	so.errQueueMu.Lock()
 675  	defer so.errQueueMu.Unlock()
 676  	so.errQueue.PushBack(err)
 677  }
 678  
 679  // QueueLocalErr queues a local error onto the local queue.
 680  func (so *SocketOptions) QueueLocalErr(err Error, net NetworkProtocolNumber, info uint32, dst FullAddress, payload *buffer.View) {
 681  	so.QueueErr(&SockError{
 682  		Err:      err,
 683  		Cause:    &LocalSockError{info: info},
 684  		Payload:  payload,
 685  		Dst:      dst,
 686  		NetProto: net,
 687  	})
 688  }
 689  
 690  // GetBindToDevice gets value for SO_BINDTODEVICE option.
 691  func (so *SocketOptions) GetBindToDevice() int32 {
 692  	return so.bindToDevice.Load()
 693  }
 694  
 695  // SetBindToDevice sets value for SO_BINDTODEVICE option. If bindToDevice is
 696  // zero, the socket device binding is removed.
 697  func (so *SocketOptions) SetBindToDevice(bindToDevice int32) Error {
 698  	if bindToDevice != 0 && !so.handler.HasNIC(bindToDevice) {
 699  		return &ErrUnknownDevice{}
 700  	}
 701  
 702  	so.bindToDevice.Store(bindToDevice)
 703  	return nil
 704  }
 705  
 706  // GetSendBufferSize gets value for SO_SNDBUF option.
 707  func (so *SocketOptions) GetSendBufferSize() int64 {
 708  	return so.sendBufferSize.Load()
 709  }
 710  
 711  // SendBufferLimits returns the [min, max) range of allowable send buffer
 712  // sizes.
 713  func (so *SocketOptions) SendBufferLimits() (min, max int64) {
 714  	limits := so.getSendBufferLimits(so.stackHandler)
 715  	return int64(limits.Min), int64(limits.Max)
 716  }
 717  
 718  // SetSendBufferSize sets value for SO_SNDBUF option. notify indicates if the
 719  // stack handler should be invoked to set the send buffer size.
 720  func (so *SocketOptions) SetSendBufferSize(sendBufferSize int64, notify bool) {
 721  	if notify {
 722  		sendBufferSize = so.handler.OnSetSendBufferSize(sendBufferSize)
 723  	}
 724  	so.sendBufferSize.Store(sendBufferSize)
 725  	if notify {
 726  		so.handler.WakeupWriters()
 727  	}
 728  }
 729  
 730  // GetReceiveBufferSize gets value for SO_RCVBUF option.
 731  func (so *SocketOptions) GetReceiveBufferSize() int64 {
 732  	return so.receiveBufferSize.Load()
 733  }
 734  
 735  // ReceiveBufferLimits returns the [min, max) range of allowable receive buffer
 736  // sizes.
 737  func (so *SocketOptions) ReceiveBufferLimits() (min, max int64) {
 738  	limits := so.getReceiveBufferLimits(so.stackHandler)
 739  	return int64(limits.Min), int64(limits.Max)
 740  }
 741  
 742  // SetReceiveBufferSize sets the value of the SO_RCVBUF option, optionally
 743  // notifying the owning endpoint.
 744  func (so *SocketOptions) SetReceiveBufferSize(receiveBufferSize int64, notify bool) {
 745  	var postSet func()
 746  	if notify {
 747  		oldSz := so.receiveBufferSize.Load()
 748  		receiveBufferSize, postSet = so.handler.OnSetReceiveBufferSize(receiveBufferSize, oldSz)
 749  	}
 750  	so.receiveBufferSize.Store(receiveBufferSize)
 751  	if postSet != nil {
 752  		postSet()
 753  	}
 754  }
 755  
 756  // GetRcvlowat gets value for SO_RCVLOWAT option.
 757  func (so *SocketOptions) GetRcvlowat() int32 {
 758  	// TODO(b/226603727): Return so.rcvlowat after adding complete support
 759  	// for SO_RCVLOWAT option. For now, return the default value of 1.
 760  	defaultRcvlowat := int32(1)
 761  	return defaultRcvlowat
 762  }
 763  
 764  // SetRcvlowat sets value for SO_RCVLOWAT option.
 765  func (so *SocketOptions) SetRcvlowat(rcvlowat int32) Error {
 766  	so.rcvlowat.Store(rcvlowat)
 767  	return nil
 768  }
 769  
 770  // GetAcceptConn gets value for SO_ACCEPTCONN option.
 771  func (so *SocketOptions) GetAcceptConn() bool {
 772  	return so.handler.GetAcceptConn()
 773  }
 774