-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Avoid crashing when TLS TCP socket is closed #3690
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
Conversation
When using a plain TCP socket with TLS, two worker jobs are spawned: - cio-tls-input-loop - cio-tls-output-loop These worker jobs live in their own scope, and exceptions they throw can't easily be caught by the caller: the only option is to install a `CoroutineExceptionHandler` for the whole TLS socket, which is quite hacky and may hide bugs. When the TCP socket is closed, this is only caught when trying to write on the output channel, which throws a `ClosedSendChannelException`. We now catch that exception and cleanly stop the background job. Fixes https://youtrack.jetbrains.com/issue/KTOR-5178/TLSSocket-cannot-catch-the-exception-thrown-by-appDataOutputLoop Fixes https://youtrack.jetbrains.com/issue/KTOR-4360/Android-Impossible-to-catch-the-ClosedSendChannelException-when-TLS-connection-socket-is-closed
|
The test seems to be flaky on some platforms, mostly because it's not actually really testing what we'd like. |
|
@e5l I have simplified the test, and I believe it shouldn't be flaky now, but I was only able to test on linux. |
We actually still need it until ktorio/ktor#3690 is integrated into a ktor release.
We actually still need it until ktorio/ktor#3690 is integrated into a ktor release.
|
@e5l any chance this could be included or reviewed? |
|
Thanks! Will take a look |
|
@e5l is there anything I can do to help integrate this fix? |
|
lgtm, merged |
* Avoid crashing when TLS TCP socket is closed When using a plain TCP socket with TLS, two worker jobs are spawned: - cio-tls-input-loop - cio-tls-output-loop These worker jobs live in their own scope, and exceptions they throw can't easily be caught by the caller: the only option is to install a `CoroutineExceptionHandler` for the whole TLS socket, which is quite hacky and may hide bugs. When the TCP socket is closed, this is only caught when trying to write on the output channel, which throws a `ClosedSendChannelException`. We now catch that exception and cleanly stop the background job. Fixes https://youtrack.jetbrains.com/issue/KTOR-5178/TLSSocket-cannot-catch-the-exception-thrown-by-appDataOutputLoop Fixes https://youtrack.jetbrains.com/issue/KTOR-4360/Android-Impossible-to-catch-the-ClosedSendChannelException-when-TLS-connection-socket-is-closed * fixup! Avoid crashing when TLS TCP socket is closed (cherry picked from commit 1905329)
* KTOR-6221: Fix reduced concurrent reqs in Apache5 (#3738) When using the Apache5 engine, total concurrent requests to a single route were limited to 5 requests. This is due to the code which tried to increase the concurrency to the ktor-standard 1000 concurrent having a typo and setting the total max connections twice and missing the max connections completely. (cherry picked from commit fa5cba1) * Avoid crashing when TLS TCP socket is closed (#3690) * Avoid crashing when TLS TCP socket is closed When using a plain TCP socket with TLS, two worker jobs are spawned: - cio-tls-input-loop - cio-tls-output-loop These worker jobs live in their own scope, and exceptions they throw can't easily be caught by the caller: the only option is to install a `CoroutineExceptionHandler` for the whole TLS socket, which is quite hacky and may hide bugs. When the TCP socket is closed, this is only caught when trying to write on the output channel, which throws a `ClosedSendChannelException`. We now catch that exception and cleanly stop the background job. Fixes https://youtrack.jetbrains.com/issue/KTOR-5178/TLSSocket-cannot-catch-the-exception-thrown-by-appDataOutputLoop Fixes https://youtrack.jetbrains.com/issue/KTOR-4360/Android-Impossible-to-catch-the-ClosedSendChannelException-when-TLS-connection-socket-is-closed * fixup! Avoid crashing when TLS TCP socket is closed (cherry picked from commit 1905329) * KTOR-6229 Fix hostname verification in CIO (#3746) (cherry picked from commit 53fa31a) * KTOR-5540 Fix darwin ws pong message (#3747) * KTOR-5540 Fix darwin ws pong message * Update ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt Co-authored-by: Vitor Hugo Schwaab <[email protected]> --------- Co-authored-by: Rustam <[email protected]> Co-authored-by: Vitor Hugo Schwaab <[email protected]> (cherry picked from commit 375b0d3) * Update netty monorepo to v4.1.97.Final (#3627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit a0ae1eb) * KTOR-6292 Make client use Dispatchers.IO by default (#3748) * KTOR-6292 Make client use Dispatchers.IO by default (cherry picked from commit a22852c) * Update kotlin to 1.9.10 (#3761) * Fix mingwX64 compilation * Update kotlin to 1.9.10 * Fix CallLogging tests * Fix js compilation (cherry picked from commit 8a9f4a5) * fixup! Update kotlin to 1.9.10 (#3761) * KTOR-6286 Update xmlutil to 0.86.2 (#3770) (cherry picked from commit 87181e4) --------- Co-authored-by: Sebastian Mayr <[email protected]> Co-authored-by: Bastien Teinturier <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Mariia Skripchenko <[email protected]>
* KTOR-6221: Fix reduced concurrent reqs in Apache5 (ktorio#3738) When using the Apache5 engine, total concurrent requests to a single route were limited to 5 requests. This is due to the code which tried to increase the concurrency to the ktor-standard 1000 concurrent having a typo and setting the total max connections twice and missing the max connections completely. (cherry picked from commit fa5cba1) * Avoid crashing when TLS TCP socket is closed (ktorio#3690) * Avoid crashing when TLS TCP socket is closed When using a plain TCP socket with TLS, two worker jobs are spawned: - cio-tls-input-loop - cio-tls-output-loop These worker jobs live in their own scope, and exceptions they throw can't easily be caught by the caller: the only option is to install a `CoroutineExceptionHandler` for the whole TLS socket, which is quite hacky and may hide bugs. When the TCP socket is closed, this is only caught when trying to write on the output channel, which throws a `ClosedSendChannelException`. We now catch that exception and cleanly stop the background job. Fixes https://youtrack.jetbrains.com/issue/KTOR-5178/TLSSocket-cannot-catch-the-exception-thrown-by-appDataOutputLoop Fixes https://youtrack.jetbrains.com/issue/KTOR-4360/Android-Impossible-to-catch-the-ClosedSendChannelException-when-TLS-connection-socket-is-closed * fixup! Avoid crashing when TLS TCP socket is closed (cherry picked from commit 1905329) * KTOR-6229 Fix hostname verification in CIO (ktorio#3746) (cherry picked from commit 53fa31a) * KTOR-5540 Fix darwin ws pong message (ktorio#3747) * KTOR-5540 Fix darwin ws pong message * Update ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt Co-authored-by: Vitor Hugo Schwaab <[email protected]> --------- Co-authored-by: Rustam <[email protected]> Co-authored-by: Vitor Hugo Schwaab <[email protected]> (cherry picked from commit 375b0d3) * Update netty monorepo to v4.1.97.Final (ktorio#3627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit a0ae1eb) * KTOR-6292 Make client use Dispatchers.IO by default (ktorio#3748) * KTOR-6292 Make client use Dispatchers.IO by default (cherry picked from commit a22852c) * Update kotlin to 1.9.10 (ktorio#3761) * Fix mingwX64 compilation * Update kotlin to 1.9.10 * Fix CallLogging tests * Fix js compilation (cherry picked from commit 8a9f4a5) * fixup! Update kotlin to 1.9.10 (ktorio#3761) * KTOR-6286 Update xmlutil to 0.86.2 (ktorio#3770) (cherry picked from commit 87181e4) --------- Co-authored-by: Sebastian Mayr <[email protected]> Co-authored-by: Bastien Teinturier <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Mariia Skripchenko <[email protected]>
Subsystem
Client, TLS over TCP
Motivation
When using a plain TCP socket with TLS, two worker jobs are spawned:
These worker jobs live in their own scope, and exceptions they throw can't easily be caught by the caller: the only option is to install a
CoroutineExceptionHandlerfor the whole TLS socket, which is quite hacky and may hide bugs.When the TCP socket is closed, this is only caught when trying to write on the output channel, which throws a
ClosedSendChannelException.See the following tickets for that issue:
Solution
We now catch that exception which cleanly stops the background job.
The unit test added fails when we remove the
catch. It is unfortunately a slightly roundabout way of testing our behavior, because it's the last check (channel.isClosedForWrite) that will fail if you comment thecatch. You'll also see theClosedSendChannelExceptionin the test output if you comment thecatchblock, but it's not sufficient to make the test fail, because the test runner allows exceptions in background threads (but it will crash an android app for example). I'm not sure if there are better ways to test this?