Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@t-bast
Copy link
Contributor

@t-bast t-bast commented Jul 11, 2023

Subsystem
Client, TLS over TCP

Motivation
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.

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 the catch. You'll also see the ClosedSendChannelException in the test output if you comment the catch block, 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?

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
@t-bast
Copy link
Contributor Author

t-bast commented Jul 24, 2023

The test seems to be flaky on some platforms, mostly because it's not actually really testing what we'd like.
Any idea on how I could improve that? Is that test actually necessary?

@t-bast
Copy link
Contributor Author

t-bast commented Jul 25, 2023

@e5l I have simplified the test, and I believe it shouldn't be flaky now, but I was only able to test on linux.

t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Jul 25, 2023
We actually still need it until ktorio/ktor#3690
is integrated into a ktor release.
t-bast added a commit to ACINQ/lightning-kmp that referenced this pull request Jul 28, 2023
We actually still need it until ktorio/ktor#3690
is integrated into a ktor release.
@t-bast
Copy link
Contributor Author

t-bast commented Aug 8, 2023

@e5l any chance this could be included or reviewed?

@e5l
Copy link
Member

e5l commented Aug 8, 2023

Thanks! Will take a look

@t-bast
Copy link
Contributor Author

t-bast commented Sep 1, 2023

@e5l is there anything I can do to help integrate this fix?

@e5l e5l merged commit 1905329 into ktorio:main Sep 4, 2023
@e5l
Copy link
Member

e5l commented Sep 4, 2023

lgtm, merged

@t-bast t-bast deleted the fix-tls-closed-send-exception branch September 4, 2023 12:57
e5l pushed a commit that referenced this pull request Oct 2, 2023
* 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)
e5l added a commit that referenced this pull request Oct 4, 2023
* 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]>
marychatte added a commit to jacekgajek/ktor that referenced this pull request Sep 5, 2024
* 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants