Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Socket: don't perform RST close on Dispose when user called Shutdown #41250

Merged
merged 5 commits into from
Oct 16, 2019

Conversation

tmds
Copy link
Member

@tmds tmds commented Sep 23, 2019

@davidsh davidsh added this to the 5.0 milestone Sep 23, 2019
// In case we cancel operations, switch to an abortive close.
// Unless the user requested a normal close using Socket.Shutdown.
bool canceledOperations = false;
bool canAbort = abortive || !_sentShutdown;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble following what abortive vs canAbort means. Can you clarify?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR, TryUnblockSocket always performed an abortive (that is :Connection reset by peer) close.
We're changing to take into account if the user has called Socket.Shutdown.
canAbort tells TryUnblockSocket if it can do an abortive close.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR, TryUnblockSocket always performed an abortive close.

But TryUnblockSocket was already taking a bool abortive argument. If it always performed an abortive close, what was the purpose of that argument?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a special case for Sockets that don't have the CLOEXEC flag set:

// Unless we're doing an abortive close, don't touch sockets which don't have the CLOEXEC flag set.
// These may be shared with other processes and we want to avoid disconnecting them.
if (!abortive)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still struggling here, @tmds. Are you saying that both canAbort and abortive mean "do an abortive close", but they communicate that information to different parts of the stack? The names are too close to be meaningful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this comment.

canAbort contains whether a CloseAsIs that was called with abortive: false, can become a an innerSocket.Close with abortive: true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove canAbort and replace it with !hasShutdownSend.

@davidsh
Copy link
Contributor

davidsh commented Oct 3, 2019

@stephentoub Do you have any additional feedback on this? Or are you ready to sign-off?

@davidsh
Copy link
Contributor

davidsh commented Oct 3, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

Copy link
Member

@halter73 halter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth asserting in TryUnblockSocket that canAbort is always true if abortive is true. The names are a little confusing. Maybe a tri-state enum would be better, but that's definitely a nit.

@tmds
Copy link
Member Author

tmds commented Oct 14, 2019

There are a number of System.Security.Cryptography.Cng test failures, like:


Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException : The parameter is incorrect.

Stack trace
   at System.Security.Cryptography.CngKey.SetProperty(CngProperty property) in /_/src/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Properties.cs:line 72
   at Internal.Cryptography.BasicSymmetricCipherNCrypt..ctor(Func`1 cngKeyFactory, CipherMode cipherMode, Int32 blockSizeInBytes, Byte[] iv, Boolean encrypting) in /_/src/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs:line 36
   at Internal.Cryptography.CngSymmetricAlgorithmCore.CreatePersistedCryptoTransformCore(Func`1 cngKeyFactory, Byte[] iv, Boolean encrypting) in /_/src/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs:line 181
   at Internal.Cryptography.CngSymmetricAlgorithmCore.CreateCryptoTransform(Boolean encrypting) in /_/src/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs:line 130
   at Internal.Cryptography.CngSymmetricAlgorithmCore.CreateEncryptor() in /_/src/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs:line 105
   at System.Security.Cryptography.TripleDESCng.CreateEncryptor() in /_/src/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs:line 79
   at System.Security.Cryptography.Cng.Tests.SymmetricCngTestHelpers.VerifyPersistedKey(String keyName, Int32 plainBytesCount, Func`2 persistedFunc, Func`1 ephemeralFunc, CipherMode cipherMode, PaddingMode paddingMode) in /_/src/System.Security.Cryptography.Cng/tests/SymmetricCngTestHelpers.cs:line 74
   at System.Security.Cryptography.Cng.Tests.SymmetricCngTestHelpers.VerifyPersistedKey(CngAlgorithm algorithm, Int32 keySize, Int32 plainBytesCount, Func`2 persistedFunc, Func`1 ephemeralFunc, CipherMode cipherMode, PaddingMode paddingMode) in /_/src/System.Security.Cryptography.Cng/tests/SymmetricCngTestHelpers.cs:line 39
   at System.Security.Cryptography.Cng.Tests.TripleDESCngTests.VerifyPersistedKey(Int32 plainBytesCount, CipherMode cipherMode, PaddingMode paddingMode) in /_/src/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs:line 30

There is also a failure of PostAsyncDuplex_CancelledBeforeResponseHeadersReceived_ResetsStream.


Error message
Assert.Throws() Failure\r\nExpected: typeof(System.OperationCanceledException)\r\nActual: (No exception was thrown)

Stack trace
   at System.Net.Http.Functional.Tests.HttpClientHandlerTest_Http2.PostAsyncDuplex_CancelledBeforeResponseHeadersReceived_ResetsStream() in /_/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs:line 2304
--- End of stack trace from previous location where exception was thrown ---

Is this good to merge?

@stephentoub
Copy link
Member

Is this good to merge?

I was hoping to continue to discuss #41250 (comment)

@tmds
Copy link
Member Author

tmds commented Oct 15, 2019

@stephentoub I removed the canAbort local.

CI passed except for Azure DevOps unavailable:

TF10216: Azure DevOps services are currently unavailable.

@stephentoub
Copy link
Member

Thanks, @tmds.

@stephentoub
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@stephentoub stephentoub merged commit 4826532 into dotnet:master Oct 16, 2019
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…otnet/corefx#41250)

* Socket: don't perform RST close on Dispose when user called Shutdown

* Add test

* PR feedback

* Remove confusing 'canAbort' local

* Improve comments


Commit migrated from dotnet/corefx@4826532
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
7 participants