Skip to content

improve: HTTP2 & Kernel TLS #407

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

Merged
merged 8 commits into from
Jul 24, 2025
Merged

improve: HTTP2 & Kernel TLS #407

merged 8 commits into from
Jul 24, 2025

Conversation

rbqvq
Copy link
Contributor

@rbqvq rbqvq commented Jul 19, 2025

Hello, I'm owner of Kernel TLS package gitlab.com/go-extension/tls

Thanks for using my package.


See commit messages for details.

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 19, 2025

In released version, Kernel TLS never be used.

minio.New incorrect setting on Kernel TLS


Should we provide precompiled packages for Kernel TLS?


Kernel TLS package will auto try modprobe tls on Linux.

@harshavardhana
Copy link
Member

kernel TLS was added that whoever is testing this knows what they are doing, we are not building it on purpose for now to avoid confusion.

@harshavardhana
Copy link
Member

kernel TLS was added that whoever is testing this knows what they are doing, we are not building it on purpose for now to avoid confusion.

we will add k-tls support as a separate binary perhaps in time when we get to it, for now it was used internally for benchmarking.

@rbqvq

This comment was marked as off-topic.

@harshavardhana
Copy link
Member

PTAL the linter errors when you get time. Thank you for the PR.

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 19, 2025

PTAL the linter errors when you get time. Thank you for the PR.

Tomorrow, Thanks

@rbqvq rbqvq force-pushed the master branch 2 times, most recently from d8cd53b to 866b11c Compare July 20, 2025 17:00
@klauspost
Copy link
Collaborator

@rbqvq Thanks for your awesome work! This was mainly added for experimentation - and to evaluate for use in our server. I don't believe anyone has had a chance to test it yet. Adding it to warp seemed like a erasonable canary.

Is it completely unfeasible to make this feature work as a co-compiled option? In both servers and clients we would like this to be a software opt-in, with seamless fallback if possible. We try very, very hard to never build feature specific binaries, since it adds complexity for the user and support for us. As such, we would like to have the option to opt-in to the feature on existing binaries, if we identify that TLS is a bottleneck.

Just asking because I didn't understand the reason for having it a compile-time option.

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 21, 2025

@rbqvq Thanks for your awesome work! This was mainly added for experimentation - and to evaluate for use in our server. I don't believe anyone has had a chance to test it yet. Adding it to warp seemed like a erasonable canary.

Is it completely unfeasible to make this feature work as a co-compiled option? In both servers and clients we would like this to be a software opt-in, with seamless fallback if possible. We try very, very hard to never build feature specific binaries, since it adds complexity for the user and support for us. As such, we would like to have the option to opt-in to the feature on existing binaries, if we identify that TLS is a bottleneck.

Just asking because I didn't understand the reason for having it a compile-time option.

Before recently commit, convert tls.ConnectionState use reflect to full convert (include unexported fields).
In recently commit, I use safe convert, and move reflect convert to FullCompatible

I think its no problem, go.mod protected the version.

But I can't confirm if newer golang version will has some compatible issue.

Ofcourse, It will not affect the non-ktls part.

I will update this PR later.


v2 changes (TODO):

  • Remove build flag
  • If http2 not enable, directly use http.Client (No type convert to improve performance)
  • Changes 0-RTT to a flag (not enabled by default)

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 21, 2025

I have a question, Can I remove -ktls flag?

I perfer use -ktls-tx and -ktls-rx


And should we throw a new Error if ktls not setup successfully instead of fallback to software implement

rbqvq added 2 commits July 21, 2025 08:52
Update all dependencies

Signed-off-by: Coia Prant <coiaprant@gmail.com>
`Secure: false` will cause the endpoint to be http, Kernel TLS is never used

Signed-off-by: Coia Prant <coiaprant@gmail.com>
@klauspost
Copy link
Collaborator

Can I remove -ktls flag? I prefer use -ktls-tx and -ktls-rx

You are welcome to either hide (use Hidden: true) or remove it temporarily if it doesn't work.

I don't see any upsides from separating rx/tx, so that is not the UX we are looking for, as it just adds complexity.

As a side note, http/2 is not a huge priority - as we generally see more problems and less performance (same for http/3), but of course nice to have.

rbqvq added 2 commits July 21, 2025 09:02
Use `ForceAttemptHTTP2` to use `http/2` without importing the `http2` package

Signed-off-by: Coia Prant <coiaprant@gmail.com>
Use hardware preference instead of always AES first

Signed-off-by: Coia Prant <coiaprant@gmail.com>
@rbqvq rbqvq force-pushed the master branch 4 times, most recently from 2b6364e to 469b2bf Compare July 21, 2025 10:38
@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 21, 2025

This is a performance testing tool

Expose all options to the user so they can control variables for testing


My comment on the proposal for crypto/tls to support Kernel TLS

One more thing.

Here is test result with iperf3 using this package.

TLS 1.3 CHACHA20
Linux 6.13 (splice)
SW (4.69 Gbps) > kTLS TX (4.65 Gbps) > kTLS RX (3.98 Gbps) > kTLS Both (3.88 Gbps)
FreeBSD 14 (no splice)
SW (3.05 Gbps) > kTLS RX (1.89 Gbps) > kTLS TX (1.71 Gbps) > kTLS Both (935 Mbps)
It seems that throughput is not as good as software implementation, even with zerocopy.

It is recommended that the option be given to the user rather than being turned on by default.

Kernel TLS will cause performance regression, especially RX offload
I only enable TX offload for my own projects
It would be a better choice to expose it to user control

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 21, 2025

I have reworked the PR and now the commit message contains the full description

Please review, Thanks


Please do not squash the commit, as it contains other fixes

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 21, 2025

kernel TLS was added that whoever is testing this knows what they are doing, we are not building it on purpose for now to avoid confusion.

we will add k-tls support as a separate binary perhaps in time when we get to it, for now it was used internally for benchmarking.

When I first made this package, I also tested it.

In the initial test, the situation was like this

KTLS TX > SW > KTLS RX > KTLS Both
When only TX is enabled, the throughput is doubled compared to SW.

In general, there are too many RX problems (performance regression, splice stuck after receiving BADMSG), See this comment

Therefore, I do not recommend turning on RX at this time.

The best thing about Kernel TLS is that you can use splice and sendfile to start zerocopy

Please continue testing, Thank you

@rbqvq rbqvq force-pushed the master branch 2 times, most recently from b635dd7 to 58250de Compare July 21, 2025 11:51
rbqvq added 4 commits July 22, 2025 06:55
Disable RX offload by default due to severe performance regressions and issues
- golang/go#44506 (comment)
- golang/go#44506 (comment)

Disable experimental EarlyData, only enable KTLS features.
Make behavior the same as standard library to control variables

Signed-off-by: Coia Prant <coiaprant@gmail.com>
`net/http` will upgrade the connection to http/2 only if it is able to assert type `*crypto/tls.Conn` and successfully negotiate `h2`.

If other tls stack is used, http/2 will never be used.

Use modified packages and use compatibility layers

Signed-off-by: Coia Prant <coiaprant@gmail.com>
Use Option to dynamically configure clientTransport

Signed-off-by: Coia Prant <coiaprant@gmail.com>
Without using HTTP/2, we don't need to use the http compatibility layer designed for ktls

This can reduce the additional overhead caused by the compatibility layer conversion to improve performance

Signed-off-by: Coia Prant <coiaprant@gmail.com>
@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 22, 2025

Changes (v3)

  • Command line changes reverted
  • KTLS RX disabled by default
  • EarlyData disabled by default

@klauspost
Copy link
Collaborator

OK. Thanks for the information 👍🏼 Much appreciated.

@rbqvq
Copy link
Contributor Author

rbqvq commented Jul 22, 2025

The main function of ktls is to speed up the TX direction (through splice and sendfile)

If you use http2, turning on ktls may be a negative optimization

So our recommendation is to use HTTP/1.1 with compression turned off


The recommended kernel is Linux 6.x+

6.14 added KeyUpdate method (But probably not many servers or clients will send it)

I just pushed a new commit to support ktls KeyUpdate, please update the dependencies yourself after the merge if you need to.
(I'm not sure if the previous version works, but in theory it's fine to call setup again to rekey)

Copy link
Collaborator

@klauspost klauspost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@klauspost klauspost merged commit 4358eca into minio:master Jul 24, 2025
6 checks passed
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.

3 participants