summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp/endpoint.go
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-06-29 12:39:22 -0700
committerShentubot <shentubot@google.com>2018-06-29 12:40:26 -0700
commit23f49097c77213175e9b11755c28c3ff5ccc1118 (patch)
treeee5bf5cba6b056d51e6cb8aa6ae8fa400b8b1fc8 /pkg/tcpip/transport/tcp/endpoint.go
parent1b5e09f968bf923f5583e8bc7627691b7c62770a (diff)
Panic in netstack during cleanup where a FIN becomes a RST.
There is a subtle bug where during cleanup with unread data a FIN can be converted to a RST, at that point the entire connection should be aborted as we're not expecting any ACKs to the RST. PiperOrigin-RevId: 202691271 Change-Id: Idae70800208ca26e07a379bc6b2b8090805d0a22
Diffstat (limited to 'pkg/tcpip/transport/tcp/endpoint.go')
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go16
1 files changed, 15 insertions, 1 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index b21c2b4ab..191dc1acc 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -40,6 +40,7 @@ const (
notifyClose
notifyMTUChanged
notifyDrain
+ notifyReset
)
// SACKInfo holds TCP SACK related information for a given endpoint.
@@ -919,7 +920,20 @@ func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error {
switch e.state {
case stateConnected:
// Close for write.
- if (flags & tcpip.ShutdownWrite) != 0 {
+ if (e.shutdownFlags & tcpip.ShutdownWrite) != 0 {
+ if (e.shutdownFlags & tcpip.ShutdownRead) != 0 {
+ // We're fully closed, if we have unread data we need to abort
+ // the connection with a RST.
+ e.rcvListMu.Lock()
+ rcvBufUsed := e.rcvBufUsed
+ e.rcvListMu.Unlock()
+
+ if rcvBufUsed > 0 {
+ e.notifyProtocolGoroutine(notifyReset)
+ return nil
+ }
+ }
+
e.sndBufMu.Lock()
if e.sndClosed {