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
Creating multiple https requests fail because of race condition #20228
Comments
Ouch, thanks for finding this nasty bug! |
I shall have a shot at fixing this bug. The fix shouldn't be too much work. I will go for copying the SSLParameters, since modifying them allows for a race condition when connecting to multiple domains. |
That would be great, @markvandertol |
Cleaning up things in TLSActor I came across this issue. I need a bit of clarification to prevent that I undo your fix in the process.
Do I understand correctly: |
That is correct. The TLSActor had to alter the SSLContext to apply the SNI settings for that specific connection, but since this SSLParameters instance was shared between multiple actors a race condition occurred. Two actors indeed altered the same SSLParameters instance at once. |
I tried to use akka-http to open multiple https connections at once, but most of the time this fails with an exception. Also, when I insert a delay between the requests it will always succeed.
I used akka-http-core, version 2.4.3 on Java Hotspot 1.8.0_77 (64-bits).
Sample code to reproduce the issue:
The Futures don't complete and the following errors are logged:
I did some debugging and I found it to be a race condition caused by modifying the same
SSLParameters
object from multiple threads at the same time. The mutable SSLParameters instance is created at theakka.http.scaladsl.DefaultSSLContextCreation#createDefaultClientHttpsContext
method. This instance is then modified atakka.stream.impl.io.TLSActor#applySNI
from two threads at once, leaving the serverNames property of the SSLParameters instance in an invalid state.Internal details: The Oracle implementation of
javax.net.ssl.SSLParameters#setServerNames
first replaces the internal field with a new HashMap and then copies the server names passed as argument to that Map. Between the creation of the Map and the copying of the newly passed server names the first part of the race condition occurs and causes both threads to write to the same Map. Then the second part of the race condition occurs: while both threads write to the same Map, they both insert the same key, causing the Map to contains a duplicate key. This leaves the Map of the SSLParameters in an invalid state. A later call tosslParameters1.setServerNames(sslParameters2.getServerNames())
causes the exception shown above to be thrown.A fix would be copy the SSLParameters before modifying them or use some sort of synchronization mechanism. Since SSLParameters just has some getter and setter methods, I would suggest copying it.
The text was updated successfully, but these errors were encountered: