github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/tcpip/stack/stack_options.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 stack 16 17 import ( 18 "time" 19 20 "github.com/MerlinKodo/gvisor/pkg/tcpip" 21 ) 22 23 const ( 24 // MinBufferSize is the smallest size of a receive or send buffer. 25 MinBufferSize = 4 << 10 // 4 KiB 26 27 // DefaultBufferSize is the default size of the send/recv buffer for a 28 // transport endpoint. 29 DefaultBufferSize = 212 << 10 // 212 KiB 30 31 // DefaultMaxBufferSize is the default maximum permitted size of a 32 // send/receive buffer. 33 DefaultMaxBufferSize = 4 << 20 // 4 MiB 34 35 // defaultTCPInvalidRateLimit is the default value for 36 // stack.TCPInvalidRateLimit. 37 defaultTCPInvalidRateLimit = 500 * time.Millisecond 38 ) 39 40 // ReceiveBufferSizeOption is used by stack.(Stack*).Option/SetOption to 41 // get/set the default, min and max receive buffer sizes. 42 type ReceiveBufferSizeOption struct { 43 Min int 44 Default int 45 Max int 46 } 47 48 // TCPInvalidRateLimitOption is used by stack.(Stack*).Option/SetOption to get/set 49 // stack.tcpInvalidRateLimit. 50 type TCPInvalidRateLimitOption time.Duration 51 52 // SetOption allows setting stack wide options. 53 func (s *Stack) SetOption(option any) tcpip.Error { 54 switch v := option.(type) { 55 case tcpip.SendBufferSizeOption: 56 // Make sure we don't allow lowering the buffer below minimum 57 // required for stack to work. 58 if v.Min < MinBufferSize { 59 return &tcpip.ErrInvalidOptionValue{} 60 } 61 62 if v.Default < v.Min || v.Default > v.Max { 63 return &tcpip.ErrInvalidOptionValue{} 64 } 65 66 s.mu.Lock() 67 s.sendBufferSize = v 68 s.mu.Unlock() 69 return nil 70 71 case tcpip.ReceiveBufferSizeOption: 72 // Make sure we don't allow lowering the buffer below minimum 73 // required for stack to work. 74 if v.Min < MinBufferSize { 75 return &tcpip.ErrInvalidOptionValue{} 76 } 77 78 if v.Default < v.Min || v.Default > v.Max { 79 return &tcpip.ErrInvalidOptionValue{} 80 } 81 82 s.mu.Lock() 83 s.receiveBufferSize = v 84 s.mu.Unlock() 85 return nil 86 87 case TCPInvalidRateLimitOption: 88 if v < 0 { 89 return &tcpip.ErrInvalidOptionValue{} 90 } 91 s.mu.Lock() 92 s.tcpInvalidRateLimit = time.Duration(v) 93 s.mu.Unlock() 94 return nil 95 96 default: 97 return &tcpip.ErrUnknownProtocolOption{} 98 } 99 } 100 101 // Option allows retrieving stack wide options. 102 func (s *Stack) Option(option any) tcpip.Error { 103 switch v := option.(type) { 104 case *tcpip.SendBufferSizeOption: 105 s.mu.RLock() 106 *v = s.sendBufferSize 107 s.mu.RUnlock() 108 return nil 109 110 case *tcpip.ReceiveBufferSizeOption: 111 s.mu.RLock() 112 *v = s.receiveBufferSize 113 s.mu.RUnlock() 114 return nil 115 116 case *TCPInvalidRateLimitOption: 117 s.mu.RLock() 118 *v = TCPInvalidRateLimitOption(s.tcpInvalidRateLimit) 119 s.mu.RUnlock() 120 return nil 121 122 default: 123 return &tcpip.ErrUnknownProtocolOption{} 124 } 125 }