diff options
author | Mithun Iyer <iyerm@google.com> | 2020-09-18 10:47:52 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-09-18 10:49:21 -0700 |
commit | fcf8d7c6ddac1146cf0d48f833c982cbfb0991e5 (patch) | |
tree | 36e9b4cd639ef8bbfbc05af457230d1fc3229e26 /pkg/tcpip/transport/tcp/endpoint.go | |
parent | 93fd164fa24e1f70e4c69fc2edfb0d4961a6683b (diff) |
Enqueue TCP sends arriving in SYN_SENT state.
TCP needs to enqueue any send requests arriving when the connection is in
SYN_SENT state. The data should be sent out soon after completion of the
connection handshake.
Fixes #3995
PiperOrigin-RevId: 332482041
Diffstat (limited to 'pkg/tcpip/transport/tcp/endpoint.go')
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index faea7f2bb..120483838 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1317,14 +1317,17 @@ func (e *endpoint) readLocked() (buffer.View, *tcpip.Error) { // indicating the reason why it's not writable. // Caller must hold e.mu and e.sndBufMu func (e *endpoint) isEndpointWritableLocked() (int, *tcpip.Error) { - // The endpoint cannot be written to if it's not connected. - if !e.EndpointState().connected() { - switch e.EndpointState() { - case StateError: - return 0, e.HardError - default: - return 0, tcpip.ErrClosedForSend - } + switch s := e.EndpointState(); { + case s == StateError: + return 0, e.HardError + case !s.connecting() && !s.connected(): + return 0, tcpip.ErrClosedForSend + case s.connecting(): + // As per RFC793, page 56, a send request arriving when in connecting + // state, can be queued to be completed after the state becomes + // connected. Return an error code for the caller of endpoint Write to + // try again, until the connection handshake is complete. + return 0, tcpip.ErrWouldBlock } // Check if the connection has already been closed for sends. |