-
Notifications
You must be signed in to change notification settings - Fork 142
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
100% CPU spin loop forever when writeAndFlush
gets run from channelActive
#467
Comments
Thanks @glbrntt , this could be a reentrancy bug
So we're calling out before calling Possible that reversing those two lines will fix it because we never do the implicit handshake in BoringSSL. |
Obviously those channel events are wrong. That's a bug in NIO too. |
Motivation: The NIOSSLHandler can enter a spin loop in `doUnbufferActions` if writing data into BoringSSL fails with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. One way these errors can happen is if a write into BoringSSL happens prior to the handshake completing. The NIOSSLHandler is explicit about starting the handshake: it's done in channel active and in handler added if the channel is already active. However, the handshaking step is currently done without any state checking, so if the state is 'closed' (as it would be after channel inactive) then the handshake will still start. This can happen if channel inactive happens before channel active. To reach the write loop there must be a buffered write and flush prior to the handshake step starting and the state isn't 'idle' or 'handshaking'. This can happen if a write and flush hapens while 'NIOSSLHandler' is in 'channelActive' (it forwards the 'channelActive' event _before_ starting the handshake) and 'channelInactive' came first. Modifications: - Early exit from 'doHandshakeStep' if the state isn't applicable for starting a handshake. - Don't buffer writes when the state is 'closed' as they'll never succeed and can be failed immediately. - If the write isn't succesful in 'doUnbufferActions' then either write to the network or try reading. - Only allow a limited number of spins through 'doUnbufferActions' Result: - Resolves apple#467
NIOSSL has the following loop
Precisely what happens is this:
NIOSSLHandler.channelActive
WebsocketClientHandshakeHander.channelActive
issues awriteAndFlush
NIOSSLHandler.flush
SSLConnection.writeDataToNetwork
SSL_write
(namespaced toCNIOBoringSSL_SSL_write
)ssl_can_write
which says false// If necessary, complete the handshake implicitly.
) handshake throughSSL_do_handshake
which returns-1
(andSSL_ERROR_WANT_READ
)writeDataToNetwork
return.incomplete
which makes_encodeSingleWrite
returnfalse
The text was updated successfully, but these errors were encountered: