Comments (9)
I believe this is because the poll_read
call is passing in a large uninitialized ReadBuf
, causing the stream to zeroing the ReadBuf
unnecessarily.
https://github.com/rustls/tokio-rustls/blob/main/src/common/mod.rs#L218
We can do some optimizations on read_buf
cfg. https://github.com/rustls/rustls/blob/main/rustls/src/conn.rs#L230
from tokio-rustls.
This problem can also be fixed if you change Vec::with_capacity(4 * 1024 * 1024)
to vec![0; 4 * 1024 * 1024]
and do not clear
.
from tokio-rustls.
I believe this is because the
poll_read
call is passing in a large uninitializedReadBuf
, causing the stream to zeroing theReadBuf
unnecessarily.https://github.com/rustls/tokio-rustls/blob/main/src/common/mod.rs#L218
We can do some optimizations on
read_buf
cfg. https://github.com/rustls/rustls/blob/main/rustls/src/conn.rs#L230
We could limit zero-initialization to the maximum TLS record size. On modern CPUs, a 16KB memset should not have a noticeable impact.
from tokio-rustls.
A possible solution could be the following. I think this is sound, since Reader
is a concrete type whose behavior we know, and not a trait where adversarial implementations would be possible. But it seems a bit hacky.
I'm profiling this on an aws m6in.8xlarge instance, downloading from s3. In the flamegraph the memset
with default buffer sizes was taking about 5% of time. The throughput is varying too much quantify the benefit.
The call stack is coming from hyper h1 poll_read_from_io
, which seems to create a new ReadBuf
on every call, so maybe there is also potential improvement on that side.
diff --git a/src/common/mod.rs b/src/common/mod.rs
index fde34c0..a9e3115 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -248,6 +248,10 @@ where
}
}
+ // Safety: We trust `read` to only write initialized bytes to the slice and never read from it.
+ unsafe {
+ buf.assume_init(buf.remaining());
+ }
match self.session.reader().read(buf.initialize_unfilled()) {
// If Rustls returns `Ok(0)` (while `buf` is non-empty), the peer closed the
// connection with a `CloseNotify` message and no more data will be forthcoming.
from tokio-rustls.
@seanmonstar do you think it's feasible to avoid recreating the ReadBuf
on every call?
from tokio-rustls.
I suppose theoretically, but realistically at the moment, that ReadBuf
is backed by the unfilled part of a BytesMut
, which doesn't expose a way to know how much of it is initialized.
from tokio-rustls.
I think best way for now, apart from stabilize read_buf
feature in std, is for rustls
to provide a ReadBuf
of own (or a trait to avoid unsafe in rustls).
like
pub trait ReadBuf {
fn append(&mut self, buf: &[u8]);
}
pub fn read_buf(&mut self, buf: &mut dyn ReadBuf) {
//
}
from tokio-rustls.
rustls can be asked how much data it would write into an infinite size buffer provided to reader().read()
-- self.session.process_new_packets().unwrap().plaintext_bytes_to_read
1 -- and I think it would be reasonable to expose that quantity as a new method on reader()
. I think that would resolve the immediate issue (clearing an 4MB buffer to use the first 4 bytes).
Footnotes
-
unwrap()
is for brevity only! ↩
from tokio-rustls.
I am considering using unbuffered api refactor, which would also solve the problem.
from tokio-rustls.
Related Issues (20)
- README and examples use unavailable API HOT 7
- Version tags HOT 6
- tokio-rustls write only first IoSlice when use write_vectored HOT 1
- Override `poll_write_vectored`? HOT 5
- Allow non-static lifetime for ServerName? HOT 3
- I can't find OwnedTrustAnchor??????
- Error: tls handshake eof HOT 1
- How to get peer certificates as server? HOT 2
- Error `NotConnected` when serving a `TlsStream<TcpStream>` when using `hyper` HOT 4
- Error: badRecordMac HOT 2
- Sending plaintext response for non-TLS connection attempts HOT 8
- Proposal: Share code between tokio-rustls and futures-rustls HOT 1
- Use Unbuffered API
- 0.5-RTT support
- Remove TCP shutdown
- Secure WebSocket Implementation with tokio-tungstenite | tokio-rustls | rustls-platform-verifier HOT 2
- Detailed Error Messages HOT 1
- Test failure in common::test_stream::stream_handshake_regression_issues_77 HOT 2
- does TLSAcceptor read early data? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tokio-rustls.