diff options
author | Ian Gudger <igudger@google.com> | 2018-11-13 18:01:26 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-13 18:02:43 -0800 |
commit | 7f60294a7367ee62cc5e0bd21648a68184c4ca5e (patch) | |
tree | 4de6614555660418c24b7c1b88c35e6fe7dcc173 /pkg/sentry/socket/epsocket/epsocket.go | |
parent | 40f843fc7802271654314e1c339c372e72900845 (diff) |
Implement TCP_NODELAY and TCP_CORK
Previously, TCP_NODELAY was always enabled and we would lie about it being
configurable. TCP_NODELAY is now disabled by default (to match Linux) in the
socket layer so that non-gVisor users don't automatically start using this
questionable optimization.
PiperOrigin-RevId: 221368472
Change-Id: Ib0240f66d94455081f4e0ca94f09d9338b2c1356
Diffstat (limited to 'pkg/sentry/socket/epsocket/epsocket.go')
-rw-r--r-- | pkg/sentry/socket/epsocket/epsocket.go | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 39a0b9941..d14bbad01 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -157,7 +157,13 @@ type SocketOperations struct { } // New creates a new endpoint socket. -func New(t *kernel.Task, family int, skType transport.SockType, queue *waiter.Queue, endpoint tcpip.Endpoint) *fs.File { +func New(t *kernel.Task, family int, skType transport.SockType, queue *waiter.Queue, endpoint tcpip.Endpoint) (*fs.File, *syserr.Error) { + if skType == transport.SockStream { + if err := endpoint.SetSockOpt(tcpip.DelayOption(1)); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + } + dirent := socket.NewDirent(t, epsocketDevice) defer dirent.DecRef() return fs.NewFile(t, dirent, fs.FileFlags{Read: true, Write: true}, &SocketOperations{ @@ -165,7 +171,7 @@ func New(t *kernel.Task, family int, skType transport.SockType, queue *waiter.Qu family: family, Endpoint: endpoint, skType: skType, - }) + }), nil } var sockAddrInetSize = int(binary.Size(linux.SockAddrInet{})) @@ -426,10 +432,10 @@ func (s *SocketOperations) blockingAccept(t *kernel.Task) (tcpip.Endpoint, *wait // tcpip.Endpoint. func (s *SocketOperations) Accept(t *kernel.Task, peerRequested bool, flags int, blocking bool) (kdefs.FD, interface{}, uint32, *syserr.Error) { // Issue the accept request to get the new endpoint. - ep, wq, err := s.Endpoint.Accept() - if err != nil { - if err != tcpip.ErrWouldBlock || !blocking { - return 0, nil, 0, syserr.TranslateNetstackError(err) + ep, wq, terr := s.Endpoint.Accept() + if terr != nil { + if terr != tcpip.ErrWouldBlock || !blocking { + return 0, nil, 0, syserr.TranslateNetstackError(terr) } var err *syserr.Error @@ -439,7 +445,10 @@ func (s *SocketOperations) Accept(t *kernel.Task, peerRequested bool, flags int, } } - ns := New(t, s.family, s.skType, wq, ep) + ns, err := New(t, s.family, s.skType, wq, ep) + if err != nil { + return 0, nil, 0, err + } defer ns.DecRef() if flags&linux.SOCK_NONBLOCK != 0 { @@ -632,7 +641,22 @@ func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, return nil, syserr.ErrInvalidArgument } - var v tcpip.NoDelayOption + var v tcpip.DelayOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + if v == 0 { + return int32(1), nil + } + return int32(0), nil + + case syscall.TCP_CORK: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.CorkOption if err := ep.GetSockOpt(&v); err != nil { return nil, syserr.TranslateNetstackError(err) } @@ -748,7 +772,18 @@ func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, n } v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.NoDelayOption(v))) + var o tcpip.DelayOption + if v == 0 { + o = 1 + } + return syserr.TranslateNetstackError(ep.SetSockOpt(o)) + case syscall.TCP_CORK: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.CorkOption(v))) } case syscall.SOL_IPV6: switch name { |