rustls: keep WRITABLE and drain buffered ciphertext when the socket backs up, and bound the plaintext buffer at 256KiB — rustls accepts all plaintext and buffers ciphertext internally on WouldBlock (unlike openssl, which surfaces backpressure through write); expose wants_write()/flush() so the reactor drains it and the sendq caps govern a slow reader. no-op for the openssl and plaintext paths

This commit is contained in:
Jean Chevronnet 2026-08-19 17:19:15 +00:00
parent ebd6e29589
commit 598a019620
No known key found for this signature in database
GPG key ID: 439666D63A9477E4
3 changed files with 51 additions and 4 deletions

View file

@ -219,7 +219,11 @@ impl TlsBackend for RustlsBackend {
}
fn start(&self, sock: MioStream) -> io::Result<Box<dyn TlsSession>> {
let conn = ServerConnection::new(self.cfg()).map_err(err)?;
let mut conn = ServerConnection::new(self.cfg()).map_err(err)?;
// bound the buffered plaintext so a slow-reading client makes writer().write()
// return short (backpressure) instead of growing without limit; the reactor's
// sendq caps then govern it, matching the openssl backend.
conn.set_buffer_limit(Some(256 * 1024));
Ok(Box::new(RustlsSession { conn, sock }))
}
}
@ -307,6 +311,14 @@ impl TlsSession for RustlsSession {
self.pump_write()?;
Ok(n)
}
fn wants_write(&self) -> bool {
// rustls holds encrypted bytes when the socket filled mid-flush; the reactor
// must keep WRITABLE interest and drain them, or a burst strands here.
self.conn.wants_write()
}
fn flush(&mut self) -> io::Result<()> {
self.pump_write()
}
fn source(&mut self) -> &mut MioStream {
&mut self.sock
}