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