Initialize the send buffer handler in endpoint creation.

- This CL will initialize the function handler used for getting the send
buffer size limits during endpoint creation and does not require the caller of
SetSendBufferSize(..) to know the endpoint type(tcp/udp/..)

PiperOrigin-RevId: 353992634
This commit is contained in:
Nayana Bidari
2021-01-26 18:05:29 -08:00
committed by gVisor bot
parent 8bb7d61bdc
commit 8e66044741
16 changed files with 42 additions and 38 deletions
+2 -7
View File
@@ -1615,20 +1615,15 @@ func setSockOptSocket(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam
return syserr.ErrInvalidArgument
}
family, skType, skProto := s.Type()
family, _, _ := s.Type()
// TODO(gvisor.dev/issue/5132): We currently do not support
// setting this option for unix sockets.
if family == linux.AF_UNIX {
return nil
}
getBufferLimits := tcpip.GetStackSendBufferLimits
if isTCPSocket(skType, skProto) {
getBufferLimits = tcp.GetTCPSendBufferLimits
}
v := usermem.ByteOrder.Uint32(optVal)
ep.SocketOptions().SetSendBufferSize(int64(v), true, getBufferLimits)
ep.SocketOptions().SetSendBufferSize(int64(v), true)
return nil
case linux.SO_RCVBUF:
@@ -128,7 +128,7 @@ func newConnectioned(ctx context.Context, stype linux.SockType, uid UniqueIDProv
idGenerator: uid,
stype: stype,
}
ep.ops.InitHandler(ep, nil)
ep.ops.InitHandler(ep, nil, nil)
return ep
}
@@ -173,7 +173,7 @@ func NewExternal(ctx context.Context, stype linux.SockType, uid UniqueIDProvider
idGenerator: uid,
stype: stype,
}
ep.ops.InitHandler(ep, nil)
ep.ops.InitHandler(ep, nil, nil)
return ep
}
@@ -296,7 +296,7 @@ func (e *connectionedEndpoint) BidirectionalConnect(ctx context.Context, ce Conn
idGenerator: e.idGenerator,
stype: e.stype,
}
ne.ops.InitHandler(ne, nil)
ne.ops.InitHandler(ne, nil, nil)
readQueue := &queue{ReaderQueue: ce.WaiterQueue(), WriterQueue: ne.Queue, limit: initialLimit}
readQueue.InitRefs()
@@ -44,7 +44,7 @@ func NewConnectionless(ctx context.Context) Endpoint {
q := queue{ReaderQueue: ep.Queue, WriterQueue: &waiter.Queue{}, limit: initialLimit}
q.InitRefs()
ep.receiver = &queueReceiver{readQueue: &q}
ep.ops.InitHandler(ep, nil)
ep.ops.InitHandler(ep, nil, nil)
return ep
}
+13 -4
View File
@@ -205,6 +205,11 @@ type SocketOptions struct {
// bindToDevice determines the device to which the socket is bound.
bindToDevice int32
// getSendBufferLimits provides the handler to get the min, default and
// max size for send buffer. It is initialized at the creation time and
// will not change.
getSendBufferLimits GetSendBufferLimits `state:"manual"`
// sendBufferSize determines the send buffer size for this socket.
sendBufferSize int64
@@ -218,9 +223,10 @@ type SocketOptions struct {
// InitHandler initializes the handler. This must be called before using the
// socket options utility.
func (so *SocketOptions) InitHandler(handler SocketOptionsHandler, stack StackHandler) {
func (so *SocketOptions) InitHandler(handler SocketOptionsHandler, stack StackHandler, getSendBufferLimits GetSendBufferLimits) {
so.handler = handler
so.stackHandler = stack
so.getSendBufferLimits = getSendBufferLimits
}
func storeAtomicBool(addr *uint32, v bool) {
@@ -568,14 +574,17 @@ func (so *SocketOptions) GetSendBufferSize() (int64, *Error) {
// SetSendBufferSize sets value for SO_SNDBUF option. notify indicates if the
// stack handler should be invoked to set the send buffer size.
func (so *SocketOptions) SetSendBufferSize(sendBufferSize int64, notify bool, getBufferLimits GetSendBufferLimits) {
v := sendBufferSize
ss := getBufferLimits(so.stackHandler)
func (so *SocketOptions) SetSendBufferSize(sendBufferSize int64, notify bool) {
if so.handler.IsUnixSocket() {
return
}
v := sendBufferSize
if notify {
// TODO(b/176170271): Notify waiters after size has grown.
// Make sure the send buffer size is within the min and max
// allowed.
ss := so.getSendBufferLimits(so.stackHandler)
min := int64(ss.Min)
max := int64(ss.Max)
// Validate the send buffer size with min and max values.
+2 -2
View File
@@ -70,7 +70,7 @@ func (f *fakeTransportEndpoint) SocketOptions() *tcpip.SocketOptions {
func newFakeTransportEndpoint(proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber, s *stack.Stack) tcpip.Endpoint {
ep := &fakeTransportEndpoint{TransportEndpointInfo: stack.TransportEndpointInfo{NetProto: netProto}, proto: proto, uniqueID: s.UniqueID()}
ep.ops.InitHandler(ep, s)
ep.ops.InitHandler(ep, s, tcpip.GetStackSendBufferLimits)
return ep
}
@@ -233,7 +233,7 @@ func (f *fakeTransportEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *
peerAddr: route.RemoteAddress,
route: route,
}
ep.ops.InitHandler(ep, f.proto.stack)
ep.ops.InitHandler(ep, f.proto.stack, tcpip.GetStackSendBufferLimits)
f.acceptQueue = append(f.acceptQueue, ep)
}
+3 -3
View File
@@ -96,13 +96,13 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProt
state: stateInitial,
uniqueID: s.UniqueID(),
}
ep.ops.InitHandler(ep, ep.stack)
ep.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits)
ep.ops.InitHandler(ep, ep.stack, tcpip.GetStackSendBufferLimits)
ep.ops.SetSendBufferSize(32*1024, false /* notify */)
// Override with stack defaults.
var ss tcpip.SendBufferSizeOption
if err := s.Option(&ss); err == nil {
ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits)
ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */)
}
return ep, nil
}
+1 -1
View File
@@ -69,7 +69,7 @@ func (e *endpoint) afterLoad() {
// Resume implements tcpip.ResumableEndpoint.Resume.
func (e *endpoint) Resume(s *stack.Stack) {
e.stack = s
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits)
if e.state != stateBound && e.state != stateConnected {
return
+2 -2
View File
@@ -105,12 +105,12 @@ func NewEndpoint(s *stack.Stack, cooked bool, netProto tcpip.NetworkProtocolNumb
waiterQueue: waiterQueue,
rcvBufSizeMax: 32 * 1024,
}
ep.ops.InitHandler(ep, ep.stack)
ep.ops.InitHandler(ep, ep.stack, tcpip.GetStackSendBufferLimits)
// Override with stack defaults.
var ss tcpip.SendBufferSizeOption
if err := s.Option(&ss); err == nil {
ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits)
ep.ops.SetSendBufferSize(int64(ss.Default), false /* notify */)
}
var rs stack.ReceiveBufferSizeOption
+1 -1
View File
@@ -64,7 +64,7 @@ func (ep *endpoint) loadRcvBufSizeMax(max int) {
// afterLoad is invoked by stateify.
func (ep *endpoint) afterLoad() {
ep.stack = stack.StackFromEnv
ep.ops.InitHandler(ep, ep.stack)
ep.ops.InitHandler(ep, ep.stack, tcpip.GetStackSendBufferLimits)
// TODO(gvisor.dev/173): Once bind is supported, choose the right NIC.
if err := ep.stack.RegisterPacketEndpoint(0, ep.netProto, ep); err != nil {
+3 -3
View File
@@ -112,14 +112,14 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProt
rcvBufSizeMax: 32 * 1024,
associated: associated,
}
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits)
e.ops.SetHeaderIncluded(!associated)
e.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits)
e.ops.SetSendBufferSize(32*1024, false /* notify */)
// Override with stack defaults.
var ss tcpip.SendBufferSizeOption
if err := s.Option(&ss); err == nil {
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits)
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */)
}
var rs stack.ReceiveBufferSizeOption
+1 -1
View File
@@ -69,7 +69,7 @@ func (e *endpoint) afterLoad() {
// Resume implements tcpip.ResumableEndpoint.Resume.
func (e *endpoint) Resume(s *stack.Stack) {
e.stack = s
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits)
// If the endpoint is connected, re-connect.
if e.connected {
+3 -3
View File
@@ -880,14 +880,14 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue
windowClamp: DefaultReceiveBufferSize,
maxSynRetries: DefaultSynRetries,
}
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, GetTCPSendBufferLimits)
e.ops.SetMulticastLoop(true)
e.ops.SetQuickAck(true)
e.ops.SetSendBufferSize(DefaultSendBufferSize, false /* notify */, GetTCPSendBufferLimits)
e.ops.SetSendBufferSize(DefaultSendBufferSize, false /* notify */)
var ss tcpip.TCPSendBufferSizeRangeOption
if err := s.TransportProtocolOption(ProtocolNumber, &ss); err == nil {
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, GetTCPSendBufferLimits)
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */)
}
var rs tcpip.TCPReceiveBufferSizeRangeOption
+1 -1
View File
@@ -181,7 +181,7 @@ func (e *endpoint) afterLoad() {
// Resume implements tcpip.ResumableEndpoint.Resume.
func (e *endpoint) Resume(s *stack.Stack) {
e.stack = s
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, GetTCPSendBufferLimits)
e.segmentQueue.thaw()
epState := e.origEndpointState
switch epState {
+2 -2
View File
@@ -4473,7 +4473,7 @@ func TestMinMaxBufferSizes(t *testing.T) {
checkRecvBufferSize(t, ep, 200)
ep.SocketOptions().SetSendBufferSize(149, true, tcp.GetTCPSendBufferLimits)
ep.SocketOptions().SetSendBufferSize(149, true)
checkSendBufferSize(t, ep, 300)
@@ -4485,7 +4485,7 @@ func TestMinMaxBufferSizes(t *testing.T) {
// Values above max are capped at max and then doubled.
checkRecvBufferSize(t, ep, tcp.DefaultReceiveBufferSize*20*2)
ep.SocketOptions().SetSendBufferSize(1+tcp.DefaultSendBufferSize*30, true, tcp.GetTCPSendBufferLimits)
ep.SocketOptions().SetSendBufferSize(1+tcp.DefaultSendBufferSize*30, true)
// Values above max are capped at max and then doubled.
checkSendBufferSize(t, ep, tcp.DefaultSendBufferSize*30*2)
+3 -3
View File
@@ -178,14 +178,14 @@ func newEndpoint(s *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQue
state: StateInitial,
uniqueID: s.UniqueID(),
}
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits)
e.ops.SetMulticastLoop(true)
e.ops.SetSendBufferSize(32*1024, false /* notify */, tcpip.GetStackSendBufferLimits)
e.ops.SetSendBufferSize(32*1024, false /* notify */)
// Override with stack defaults.
var ss tcpip.SendBufferSizeOption
if err := s.Option(&ss); err == nil {
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */, tcpip.GetStackSendBufferLimits)
e.ops.SetSendBufferSize(int64(ss.Default), false /* notify */)
}
var rs stack.ReceiveBufferSizeOption
+1 -1
View File
@@ -91,7 +91,7 @@ func (e *endpoint) Resume(s *stack.Stack) {
defer e.mu.Unlock()
e.stack = s
e.ops.InitHandler(e, e.stack)
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits)
for m := range e.multicastMemberships {
if err := e.stack.JoinGroup(e.NetProto, m.nicID, m.multicastAddr); err != nil {