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