-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce some allocations in SslStream handshake. #103814
Conversation
byte[]? hash = null; | ||
|
||
if (sslAuthenticationOptions.CertificateContext?.TargetCertificate is X509Certificate2 cert) | ||
{ | ||
// This is equivalent to cert.GetCertHash(HashAlgorithmName.Sha256), but this | ||
// way the code does not allocate a new byte[] with raw cert contents.every time | ||
hash = SHA256.HashData(cert.RawDataMemory.Span); | ||
} | ||
|
||
var key = new SslContextCacheKey(protocols, hash); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bartonjs is the X509Certificate.GetCertHash(...)
behavior by design? looks like something that could potentially help in multiple places if we can change the implementation to use the internaly cached RawData.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Not Jeremy, but...) I don't think so. We can probably make some improvements here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's using certPal.RawData instead of this.RawData, I think it's trying to avoid the allocation; but clearly some PALs are caching that and others are not, because we started off with a weak PAL contract and haven't ever cleaned it up.
In this case, it looks like just switching from certPal.RawData to this.RawDataMemory.Span will mean we know exactly what caching is involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With #103828 merged I am not sure this is needed anymore.
@@ -149,7 +149,7 @@ internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticati | |||
|
|||
private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols protocols) | |||
{ | |||
if (protocols.HasFlag(SslProtocols.Tls12) || protocols.HasFlag(SslProtocols.Tls13)) | |||
if ((protocols & (SslProtocols.Tls12 | SslProtocols.Tls13)) != SslProtocols.None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change is fine, but did you see this allocating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I collected a trace via dotnet trace
and saw an entry for this. The signature is apparently
public bool HasFlag (Enum flag);
so I assume it is boxing the argument. The trace was in Debug configuration, I am not sure if it happens in Release as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if it happens in Release as well.
The JIT special-cases HasFlag. It shouldn't be allocating in optimized code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trace was in Debug configuration
You generally don't want to do any perf analysis based on debug. Optimizations are disabled, both at the JIT level and also the C# level (e.g. async methods get emitted as classes rather than structs), so it provides a skewed view of the world.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got unsure and rechecked the trace, it indeed comes from a different place. But I don't see it in the most recent traces for some reason.
dfeca77
to
50a9450
Compare
This removes some unnecessary allocations on TLS handshakes, mostly on Linux.