github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/tcpip/socketops.go (about) 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 "github.com/metacubex/gvisor/pkg/atomicbitops" 19 "github.com/metacubex/gvisor/pkg/buffer" 20 "github.com/metacubex/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 268 // InitHandler initializes the handler. This must be called before using the 269 // socket options utility. 270 func (so *SocketOptions) InitHandler(handler SocketOptionsHandler, stack StackHandler, getSendBufferLimits GetSendBufferLimits, getReceiveBufferLimits GetReceiveBufferLimits) { 271 so.handler = handler 272 so.stackHandler = stack 273 so.getSendBufferLimits = getSendBufferLimits 274 so.getReceiveBufferLimits = getReceiveBufferLimits 275 } 276 277 func storeAtomicBool(addr *atomicbitops.Uint32, v bool) { 278 var val uint32 279 if v { 280 val = 1 281 } 282 addr.Store(val) 283 } 284 285 // SetLastError sets the last error for a socket. 286 func (so *SocketOptions) SetLastError(err Error) { 287 so.handler.UpdateLastError(err) 288 } 289 290 // GetBroadcast gets value for SO_BROADCAST option. 291 func (so *SocketOptions) GetBroadcast() bool { 292 return so.broadcastEnabled.Load() != 0 293 } 294 295 // SetBroadcast sets value for SO_BROADCAST option. 296 func (so *SocketOptions) SetBroadcast(v bool) { 297 storeAtomicBool(&so.broadcastEnabled, v) 298 } 299 300 // GetPassCred gets value for SO_PASSCRED option. 301 func (so *SocketOptions) GetPassCred() bool { 302 return so.passCredEnabled.Load() != 0 303 } 304 305 // SetPassCred sets value for SO_PASSCRED option. 306 func (so *SocketOptions) SetPassCred(v bool) { 307 storeAtomicBool(&so.passCredEnabled, v) 308 } 309 310 // GetNoChecksum gets value for SO_NO_CHECK option. 311 func (so *SocketOptions) GetNoChecksum() bool { 312 return so.noChecksumEnabled.Load() != 0 313 } 314 315 // SetNoChecksum sets value for SO_NO_CHECK option. 316 func (so *SocketOptions) SetNoChecksum(v bool) { 317 storeAtomicBool(&so.noChecksumEnabled, v) 318 } 319 320 // GetReuseAddress gets value for SO_REUSEADDR option. 321 func (so *SocketOptions) GetReuseAddress() bool { 322 return so.reuseAddressEnabled.Load() != 0 323 } 324 325 // SetReuseAddress sets value for SO_REUSEADDR option. 326 func (so *SocketOptions) SetReuseAddress(v bool) { 327 storeAtomicBool(&so.reuseAddressEnabled, v) 328 so.handler.OnReuseAddressSet(v) 329 } 330 331 // GetReusePort gets value for SO_REUSEPORT option. 332 func (so *SocketOptions) GetReusePort() bool { 333 return so.reusePortEnabled.Load() != 0 334 } 335 336 // SetReusePort sets value for SO_REUSEPORT option. 337 func (so *SocketOptions) SetReusePort(v bool) { 338 storeAtomicBool(&so.reusePortEnabled, v) 339 so.handler.OnReusePortSet(v) 340 } 341 342 // GetKeepAlive gets value for SO_KEEPALIVE option. 343 func (so *SocketOptions) GetKeepAlive() bool { 344 return so.keepAliveEnabled.Load() != 0 345 } 346 347 // SetKeepAlive sets value for SO_KEEPALIVE option. 348 func (so *SocketOptions) SetKeepAlive(v bool) { 349 storeAtomicBool(&so.keepAliveEnabled, v) 350 so.handler.OnKeepAliveSet(v) 351 } 352 353 // GetMulticastLoop gets value for IP_MULTICAST_LOOP option. 354 func (so *SocketOptions) GetMulticastLoop() bool { 355 return so.multicastLoopEnabled.Load() != 0 356 } 357 358 // SetMulticastLoop sets value for IP_MULTICAST_LOOP option. 359 func (so *SocketOptions) SetMulticastLoop(v bool) { 360 storeAtomicBool(&so.multicastLoopEnabled, v) 361 } 362 363 // GetReceiveTOS gets value for IP_RECVTOS option. 364 func (so *SocketOptions) GetReceiveTOS() bool { 365 return so.receiveTOSEnabled.Load() != 0 366 } 367 368 // SetReceiveTOS sets value for IP_RECVTOS option. 369 func (so *SocketOptions) SetReceiveTOS(v bool) { 370 storeAtomicBool(&so.receiveTOSEnabled, v) 371 } 372 373 // GetReceiveTTL gets value for IP_RECVTTL option. 374 func (so *SocketOptions) GetReceiveTTL() bool { 375 return so.receiveTTLEnabled.Load() != 0 376 } 377 378 // SetReceiveTTL sets value for IP_RECVTTL option. 379 func (so *SocketOptions) SetReceiveTTL(v bool) { 380 storeAtomicBool(&so.receiveTTLEnabled, v) 381 } 382 383 // GetReceiveHopLimit gets value for IP_RECVHOPLIMIT option. 384 func (so *SocketOptions) GetReceiveHopLimit() bool { 385 return so.receiveHopLimitEnabled.Load() != 0 386 } 387 388 // SetReceiveHopLimit sets value for IP_RECVHOPLIMIT option. 389 func (so *SocketOptions) SetReceiveHopLimit(v bool) { 390 storeAtomicBool(&so.receiveHopLimitEnabled, v) 391 } 392 393 // GetReceiveTClass gets value for IPV6_RECVTCLASS option. 394 func (so *SocketOptions) GetReceiveTClass() bool { 395 return so.receiveTClassEnabled.Load() != 0 396 } 397 398 // SetReceiveTClass sets value for IPV6_RECVTCLASS option. 399 func (so *SocketOptions) SetReceiveTClass(v bool) { 400 storeAtomicBool(&so.receiveTClassEnabled, v) 401 } 402 403 // GetReceivePacketInfo gets value for IP_PKTINFO option. 404 func (so *SocketOptions) GetReceivePacketInfo() bool { 405 return so.receivePacketInfoEnabled.Load() != 0 406 } 407 408 // SetReceivePacketInfo sets value for IP_PKTINFO option. 409 func (so *SocketOptions) SetReceivePacketInfo(v bool) { 410 storeAtomicBool(&so.receivePacketInfoEnabled, v) 411 } 412 413 // GetIPv6ReceivePacketInfo gets value for IPV6_RECVPKTINFO option. 414 func (so *SocketOptions) GetIPv6ReceivePacketInfo() bool { 415 return so.receiveIPv6PacketInfoEnabled.Load() != 0 416 } 417 418 // SetIPv6ReceivePacketInfo sets value for IPV6_RECVPKTINFO option. 419 func (so *SocketOptions) SetIPv6ReceivePacketInfo(v bool) { 420 storeAtomicBool(&so.receiveIPv6PacketInfoEnabled, v) 421 } 422 423 // GetHeaderIncluded gets value for IP_HDRINCL option. 424 func (so *SocketOptions) GetHeaderIncluded() bool { 425 return so.hdrIncludedEnabled.Load() != 0 426 } 427 428 // SetHeaderIncluded sets value for IP_HDRINCL option. 429 func (so *SocketOptions) SetHeaderIncluded(v bool) { 430 storeAtomicBool(&so.hdrIncludedEnabled, v) 431 } 432 433 // GetV6Only gets value for IPV6_V6ONLY option. 434 func (so *SocketOptions) GetV6Only() bool { 435 return so.v6OnlyEnabled.Load() != 0 436 } 437 438 // SetV6Only sets value for IPV6_V6ONLY option. 439 // 440 // Preconditions: the backing TCP or UDP endpoint must be in initial state. 441 func (so *SocketOptions) SetV6Only(v bool) { 442 storeAtomicBool(&so.v6OnlyEnabled, v) 443 } 444 445 // GetQuickAck gets value for TCP_QUICKACK option. 446 func (so *SocketOptions) GetQuickAck() bool { 447 return so.quickAckEnabled.Load() != 0 448 } 449 450 // SetQuickAck sets value for TCP_QUICKACK option. 451 func (so *SocketOptions) SetQuickAck(v bool) { 452 storeAtomicBool(&so.quickAckEnabled, v) 453 } 454 455 // GetDelayOption gets inverted value for TCP_NODELAY option. 456 func (so *SocketOptions) GetDelayOption() bool { 457 return so.delayOptionEnabled.Load() != 0 458 } 459 460 // SetDelayOption sets inverted value for TCP_NODELAY option. 461 func (so *SocketOptions) SetDelayOption(v bool) { 462 storeAtomicBool(&so.delayOptionEnabled, v) 463 so.handler.OnDelayOptionSet(v) 464 } 465 466 // GetCorkOption gets value for TCP_CORK option. 467 func (so *SocketOptions) GetCorkOption() bool { 468 return so.corkOptionEnabled.Load() != 0 469 } 470 471 // SetCorkOption sets value for TCP_CORK option. 472 func (so *SocketOptions) SetCorkOption(v bool) { 473 storeAtomicBool(&so.corkOptionEnabled, v) 474 so.handler.OnCorkOptionSet(v) 475 } 476 477 // GetReceiveOriginalDstAddress gets value for IP(V6)_RECVORIGDSTADDR option. 478 func (so *SocketOptions) GetReceiveOriginalDstAddress() bool { 479 return so.receiveOriginalDstAddress.Load() != 0 480 } 481 482 // SetReceiveOriginalDstAddress sets value for IP(V6)_RECVORIGDSTADDR option. 483 func (so *SocketOptions) SetReceiveOriginalDstAddress(v bool) { 484 storeAtomicBool(&so.receiveOriginalDstAddress, v) 485 } 486 487 // GetIPv4RecvError gets value for IP_RECVERR option. 488 func (so *SocketOptions) GetIPv4RecvError() bool { 489 return so.ipv4RecvErrEnabled.Load() != 0 490 } 491 492 // SetIPv4RecvError sets value for IP_RECVERR option. 493 func (so *SocketOptions) SetIPv4RecvError(v bool) { 494 storeAtomicBool(&so.ipv4RecvErrEnabled, v) 495 if !v { 496 so.pruneErrQueue() 497 } 498 } 499 500 // GetIPv6RecvError gets value for IPV6_RECVERR option. 501 func (so *SocketOptions) GetIPv6RecvError() bool { 502 return so.ipv6RecvErrEnabled.Load() != 0 503 } 504 505 // SetIPv6RecvError sets value for IPV6_RECVERR option. 506 func (so *SocketOptions) SetIPv6RecvError(v bool) { 507 storeAtomicBool(&so.ipv6RecvErrEnabled, v) 508 if !v { 509 so.pruneErrQueue() 510 } 511 } 512 513 // GetLastError gets value for SO_ERROR option. 514 func (so *SocketOptions) GetLastError() Error { 515 return so.handler.LastError() 516 } 517 518 // GetOutOfBandInline gets value for SO_OOBINLINE option. 519 func (*SocketOptions) GetOutOfBandInline() bool { 520 return true 521 } 522 523 // SetOutOfBandInline sets value for SO_OOBINLINE option. We currently do not 524 // support disabling this option. 525 func (*SocketOptions) SetOutOfBandInline(bool) {} 526 527 // GetLinger gets value for SO_LINGER option. 528 func (so *SocketOptions) GetLinger() LingerOption { 529 so.mu.Lock() 530 linger := so.linger 531 so.mu.Unlock() 532 return linger 533 } 534 535 // SetLinger sets value for SO_LINGER option. 536 func (so *SocketOptions) SetLinger(linger LingerOption) { 537 so.mu.Lock() 538 so.linger = linger 539 so.mu.Unlock() 540 } 541 542 // SockErrOrigin represents the constants for error origin. 543 type SockErrOrigin uint8 544 545 const ( 546 // SockExtErrorOriginNone represents an unknown error origin. 547 SockExtErrorOriginNone SockErrOrigin = iota 548 549 // SockExtErrorOriginLocal indicates a local error. 550 SockExtErrorOriginLocal 551 552 // SockExtErrorOriginICMP indicates an IPv4 ICMP error. 553 SockExtErrorOriginICMP 554 555 // SockExtErrorOriginICMP6 indicates an IPv6 ICMP error. 556 SockExtErrorOriginICMP6 557 ) 558 559 // IsICMPErr indicates if the error originated from an ICMP error. 560 func (origin SockErrOrigin) IsICMPErr() bool { 561 return origin == SockExtErrorOriginICMP || origin == SockExtErrorOriginICMP6 562 } 563 564 // SockErrorCause is the cause of a socket error. 565 type SockErrorCause interface { 566 // Origin is the source of the error. 567 Origin() SockErrOrigin 568 569 // Type is the origin specific type of error. 570 Type() uint8 571 572 // Code is the origin and type specific error code. 573 Code() uint8 574 575 // Info is any extra information about the error. 576 Info() uint32 577 } 578 579 // LocalSockError is a socket error that originated from the local host. 580 // 581 // +stateify savable 582 type LocalSockError struct { 583 info uint32 584 } 585 586 // Origin implements SockErrorCause. 587 func (*LocalSockError) Origin() SockErrOrigin { 588 return SockExtErrorOriginLocal 589 } 590 591 // Type implements SockErrorCause. 592 func (*LocalSockError) Type() uint8 { 593 return 0 594 } 595 596 // Code implements SockErrorCause. 597 func (*LocalSockError) Code() uint8 { 598 return 0 599 } 600 601 // Info implements SockErrorCause. 602 func (l *LocalSockError) Info() uint32 { 603 return l.info 604 } 605 606 // SockError represents a queue entry in the per-socket error queue. 607 // 608 // +stateify savable 609 type SockError struct { 610 sockErrorEntry 611 612 // Err is the error caused by the errant packet. 613 Err Error 614 // Cause is the detailed cause of the error. 615 Cause SockErrorCause 616 617 // Payload is the errant packet's payload. 618 Payload *buffer.View 619 // Dst is the original destination address of the errant packet. 620 Dst FullAddress 621 // Offender is the original sender address of the errant packet. 622 Offender FullAddress 623 // NetProto is the network protocol being used to transmit the packet. 624 NetProto NetworkProtocolNumber 625 } 626 627 // pruneErrQueue resets the queue. 628 func (so *SocketOptions) pruneErrQueue() { 629 so.errQueueMu.Lock() 630 so.errQueue.Reset() 631 so.errQueueMu.Unlock() 632 } 633 634 // DequeueErr dequeues a socket extended error from the error queue and returns 635 // it. Returns nil if queue is empty. 636 func (so *SocketOptions) DequeueErr() *SockError { 637 so.errQueueMu.Lock() 638 defer so.errQueueMu.Unlock() 639 640 err := so.errQueue.Front() 641 if err != nil { 642 so.errQueue.Remove(err) 643 } 644 return err 645 } 646 647 // PeekErr returns the error in the front of the error queue. Returns nil if 648 // the error queue is empty. 649 func (so *SocketOptions) PeekErr() *SockError { 650 so.errQueueMu.Lock() 651 defer so.errQueueMu.Unlock() 652 return so.errQueue.Front() 653 } 654 655 // QueueErr inserts the error at the back of the error queue. 656 // 657 // Preconditions: so.GetIPv4RecvError() or so.GetIPv6RecvError() is true. 658 func (so *SocketOptions) QueueErr(err *SockError) { 659 so.errQueueMu.Lock() 660 defer so.errQueueMu.Unlock() 661 so.errQueue.PushBack(err) 662 } 663 664 // QueueLocalErr queues a local error onto the local queue. 665 func (so *SocketOptions) QueueLocalErr(err Error, net NetworkProtocolNumber, info uint32, dst FullAddress, payload *buffer.View) { 666 so.QueueErr(&SockError{ 667 Err: err, 668 Cause: &LocalSockError{info: info}, 669 Payload: payload, 670 Dst: dst, 671 NetProto: net, 672 }) 673 } 674 675 // GetBindToDevice gets value for SO_BINDTODEVICE option. 676 func (so *SocketOptions) GetBindToDevice() int32 { 677 return so.bindToDevice.Load() 678 } 679 680 // SetBindToDevice sets value for SO_BINDTODEVICE option. If bindToDevice is 681 // zero, the socket device binding is removed. 682 func (so *SocketOptions) SetBindToDevice(bindToDevice int32) Error { 683 if bindToDevice != 0 && !so.handler.HasNIC(bindToDevice) { 684 return &ErrUnknownDevice{} 685 } 686 687 so.bindToDevice.Store(bindToDevice) 688 return nil 689 } 690 691 // GetSendBufferSize gets value for SO_SNDBUF option. 692 func (so *SocketOptions) GetSendBufferSize() int64 { 693 return so.sendBufferSize.Load() 694 } 695 696 // SendBufferLimits returns the [min, max) range of allowable send buffer 697 // sizes. 698 func (so *SocketOptions) SendBufferLimits() (min, max int64) { 699 limits := so.getSendBufferLimits(so.stackHandler) 700 return int64(limits.Min), int64(limits.Max) 701 } 702 703 // SetSendBufferSize sets value for SO_SNDBUF option. notify indicates if the 704 // stack handler should be invoked to set the send buffer size. 705 func (so *SocketOptions) SetSendBufferSize(sendBufferSize int64, notify bool) { 706 if notify { 707 sendBufferSize = so.handler.OnSetSendBufferSize(sendBufferSize) 708 } 709 so.sendBufferSize.Store(sendBufferSize) 710 if notify { 711 so.handler.WakeupWriters() 712 } 713 } 714 715 // GetReceiveBufferSize gets value for SO_RCVBUF option. 716 func (so *SocketOptions) GetReceiveBufferSize() int64 { 717 return so.receiveBufferSize.Load() 718 } 719 720 // ReceiveBufferLimits returns the [min, max) range of allowable receive buffer 721 // sizes. 722 func (so *SocketOptions) ReceiveBufferLimits() (min, max int64) { 723 limits := so.getReceiveBufferLimits(so.stackHandler) 724 return int64(limits.Min), int64(limits.Max) 725 } 726 727 // SetReceiveBufferSize sets the value of the SO_RCVBUF option, optionally 728 // notifying the owning endpoint. 729 func (so *SocketOptions) SetReceiveBufferSize(receiveBufferSize int64, notify bool) { 730 var postSet func() 731 if notify { 732 oldSz := so.receiveBufferSize.Load() 733 receiveBufferSize, postSet = so.handler.OnSetReceiveBufferSize(receiveBufferSize, oldSz) 734 } 735 so.receiveBufferSize.Store(receiveBufferSize) 736 if postSet != nil { 737 postSet() 738 } 739 } 740 741 // GetRcvlowat gets value for SO_RCVLOWAT option. 742 func (so *SocketOptions) GetRcvlowat() int32 { 743 // TODO(b/226603727): Return so.rcvlowat after adding complete support 744 // for SO_RCVLOWAT option. For now, return the default value of 1. 745 defaultRcvlowat := int32(1) 746 return defaultRcvlowat 747 } 748 749 // SetRcvlowat sets value for SO_RCVLOWAT option. 750 func (so *SocketOptions) SetRcvlowat(rcvlowat int32) Error { 751 so.rcvlowat.Store(rcvlowat) 752 return nil 753 } 754 755 // GetAcceptConn gets value for SO_ACCEPTCONN option. 756 func (so *SocketOptions) GetAcceptConn() bool { 757 return so.handler.GetAcceptConn() 758 }