summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/tcp
diff options
context:
space:
mode:
authorMithun Iyer <iyerm@google.com>2020-11-09 14:52:50 -0800
committergVisor bot <gvisor-bot@google.com>2020-11-09 14:54:57 -0800
commit199fcd0fe512f2fa4af63b0ec74e36aea7c4a8e1 (patch)
treedf4a8866f0d479451039ce06adf78cbce9d04f06 /pkg/tcpip/transport/tcp
parent2fcca60a7bf084a28e878941d9dcb47e11268cbd (diff)
Skip `EventHUp` notify in `FIN_WAIT2` on a socket close.
This Notify was added as part of cl/279106406; but notifying `EventHUp` in `FIN_WAIT2` is incorrect, as we want to only notify later on `TIME_WAIT` or a reset. However, we do need to notify any blocked waiters of an activity on the endpoint with `EventIn`|`EventOut`. PiperOrigin-RevId: 341490913
Diffstat (limited to 'pkg/tcpip/transport/tcp')
-rw-r--r--pkg/tcpip/transport/tcp/connect.go1
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go11
-rw-r--r--pkg/tcpip/transport/tcp/tcp_test.go4
3 files changed, 9 insertions, 7 deletions
diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go
index 2facbebec..6e9015be1 100644
--- a/pkg/tcpip/transport/tcp/connect.go
+++ b/pkg/tcpip/transport/tcp/connect.go
@@ -1451,7 +1451,6 @@ func (e *endpoint) protocolMainLoop(handshake bool, wakerInitDone chan<- struct{
// The socket has been closed and we are in FIN_WAIT2
// so start the FIN_WAIT2 timer.
closeTimer = time.AfterFunc(e.tcpLingerTimeout, closeWaker.Assert)
- e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut)
}
}
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index 258f9f1bb..23b9de8c5 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -1069,9 +1069,7 @@ func (e *endpoint) Close() {
e.closeNoShutdownLocked()
}
-// closeNoShutdown closes the endpoint without doing a full shutdown. This is
-// used when a connection needs to be aborted with a RST and we want to skip
-// a full 4 way TCP shutdown.
+// closeNoShutdown closes the endpoint without doing a full shutdown.
func (e *endpoint) closeNoShutdownLocked() {
// For listening sockets, we always release ports inline so that they
// are immediately available for reuse after Close() is called. If also
@@ -1098,6 +1096,7 @@ func (e *endpoint) closeNoShutdownLocked() {
return
}
+ eventMask := waiter.EventIn | waiter.EventOut
// Either perform the local cleanup or kick the worker to make sure it
// knows it needs to cleanup.
if e.workerRunning {
@@ -1109,8 +1108,12 @@ func (e *endpoint) closeNoShutdownLocked() {
} else {
e.transitionToStateCloseLocked()
// Notify that the endpoint is closed.
- e.waiterQueue.Notify(waiter.EventHUp)
+ eventMask |= waiter.EventHUp
}
+
+ // The TCP closing state-machine would eventually notify EventHUp, but we
+ // notify EventIn|EventOut immediately to unblock any blocked waiters.
+ e.waiterQueue.Notify(eventMask)
}
// closePendingAcceptableConnections closes all connections that have completed
diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go
index 5f05608e2..fcc3c5000 100644
--- a/pkg/tcpip/transport/tcp/tcp_test.go
+++ b/pkg/tcpip/transport/tcp/tcp_test.go
@@ -63,7 +63,7 @@ func TestGiveUpConnect(t *testing.T) {
// Register for notification, then start connection attempt.
waitEntry, notifyCh := waiter.NewChannelEntry(nil)
- wq.EventRegister(&waitEntry, waiter.EventOut)
+ wq.EventRegister(&waitEntry, waiter.EventHUp)
defer wq.EventUnregister(&waitEntry)
if err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted {
@@ -1448,7 +1448,7 @@ func TestSynSent(t *testing.T) {
// Start connection attempt.
waitEntry, ch := waiter.NewChannelEntry(nil)
- c.WQ.EventRegister(&waitEntry, waiter.EventOut)
+ c.WQ.EventRegister(&waitEntry, waiter.EventHUp)
defer c.WQ.EventUnregister(&waitEntry)
addr := tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}