diff options
author | Brian Geffon <bgeffon@google.com> | 2018-05-24 15:17:42 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-05-24 15:18:21 -0700 |
commit | 7f62e9c32ea6af19ccd92107252fd869e6ef1005 (patch) | |
tree | 00fab3faeb7dbb2b689247157f8be0767e128758 | |
parent | e48f7078761b00552ac74068c184ee4fb90fe9aa (diff) |
rpcinet connect doesn't handle all errnos correctly.
These were causing non-blocking related errnos to be returned to
the sentry when they were created as blocking FDs internally.
PiperOrigin-RevId: 197962932
Change-Id: I3f843535ff87ebf4cb5827e9f3d26abfb79461b0
-rw-r--r-- | pkg/sentry/socket/rpcinet/socket.go | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 11925f8d8..bca91ab5f 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -213,21 +213,19 @@ func (s *socketOperations) Connect(t *kernel.Task, sockaddr []byte, blocking boo // Register for notification when the endpoint becomes writable, then // initiate the connection. e, ch := waiter.NewChannelEntry(nil) - s.EventRegister(&e, waiter.EventOut) + s.EventRegister(&e, waiter.EventOut|waiter.EventIn|waiter.EventHUp) defer s.EventUnregister(&e) + for { + if err := rpcConnect(t, s.fd, sockaddr); err == nil || err != syserr.ErrInProgress && err != syserr.ErrAlreadyInProgress { + return err + } - if err := rpcConnect(t, s.fd, sockaddr); err != syserr.ErrConnectStarted && err != syserr.ErrAlreadyConnecting { - return err - } - - // It's pending, so we have to wait for a notification, and fetch the - // result once the wait completes. - if err := t.Block(ch); err != nil { - return syserr.FromError(err) + // It's pending, so we have to wait for a notification, and fetch the + // result once the wait completes. + if err := t.Block(ch); err != nil { + return syserr.FromError(err) + } } - - // Call Connect() again after blocking to find connect's result. - return rpcConnect(t, s.fd, sockaddr) } func rpcAccept(t *kernel.Task, fd uint32, peer bool) (*pb.AcceptResponse_ResultPayload, *syserr.Error) { |