pub struct FrontRustls {
pub stream: TcpStream,
pub session: ServerConnection,
pub peer_disconnected: bool,
pub peer_reset: bool,
pub tls_fatal: bool,
pub session_ulid: Ulid,
pub configured_peer: Option<SocketAddr>,
pub recv_memory: RecvMemory,
}Fields§
§stream: TcpStream§session: ServerConnection§peer_disconnected: boolPeer sent a graceful FIN on the read side (read() returned Ok(0)).
We can no longer receive plaintext, but may still have rustls-buffered
records to flush on the write side — do NOT abort pending writes.
peer_reset: boolThe TCP channel is dead: the peer reset the connection
(RST/ConnectionAborted/BrokenPipe), or a write answered
SocketResult::Error — a socket error other than WouldBlock
(an Interrupted write is retried in flush_tls and never gets
here), a rustls writer failure, or the write loop’s budget. Further
writes are pointless and short-circuit, and
SocketHandler::socket_wants_write stops reporting the records
rustls still holds: no write can deliver them, so they must neither
keep the session open nor wait for a WRITABLE edge that will not come.
tls_fatal: boolprocess_new_packets failed on this connection: a corrupt record, a
fatal alert, a protocol violation. rustls keeps that error for good,
so from then on SocketHandler::socket_read answers (0, Error)
at once, without serving plaintext rustls decrypted before the
failure. See rustls_socket_read.
session_ulid: UlidConnection/session ULID propagated from the enclosing mux session.
Rendered into SOCKET-layer error logs via Self::session_ulid.
configured_peer: Option<SocketAddr>Peer address snapshot, same role as SessionTcpStream::configured_peer
and same name so the two handlers read alike. Seeded from
HttpsSession::peer_address, which is the PROXY-advertised source on an
expect-proxy frontend and the accepted socket’s peer otherwise — NOT
from stream.peer_addr(), which would be the load balancer in the first
case and would die with ENOTCONN in both. Read through
SocketHandler::peer_addr.
recv_memory: RecvMemoryWhat the read path may assume about stream’s receive queue from one
SocketHandler::socket_read call to the next. See RecvMemory.
Implementations§
Source§impl FrontRustls
impl FrontRustls
Sourcepub fn readiness_delivered(&mut self, events: Ready)
pub fn readiness_delivered(&mut self, events: Ready)
Record that the event loop delivered events for stream: whatever a
recv proved before, bytes may have arrived since. The HTTPS session
calls it for every event on its frontend token, whatever its state
(HttpsSession::update_readiness, lib/src/https.rs), which is the
only way events reach a session (Server::ready, lib/src/server.rs).
Trait Implementations§
Source§impl Debug for FrontRustls
impl Debug for FrontRustls
Source§impl SocketHandler for FrontRustls
impl SocketHandler for FrontRustls
Source§fn socket_write(&mut self, buf: &[u8]) -> (usize, SocketResult)
fn socket_write(&mut self, buf: &[u8]) -> (usize, SocketResult)
Keep these two functions structurally symmetric — a divergence
caused the 4.5 MB H2 truncation bug. Tests
e2e::tests::h2_correctness_tests::* and
e2e::tests::h2_tests::test_h2_large_* are the regression guard.
Source§fn socket_write_vectored(
&mut self,
bufs: &[IoSlice<'_>],
) -> (usize, SocketResult)
fn socket_write_vectored( &mut self, bufs: &[IoSlice<'_>], ) -> (usize, SocketResult)
Write a list of plaintext slices through the rustls session.
Empty-buffer invariant: callers may legitimately pass bufs.is_empty()
or an all-empty slice to request a pure flush pass. In that case
total_len == 0, the top-of-loop buffered_size == total_len guard
fires immediately after write_tls drains any pending TLS records the
session still has buffered (e.g. the remainder of a record split by
the previous call, or close_notify output). This mirrors
Self::socket_write: both entry points must stay structurally
symmetric so that a zero-byte flush never early-returns without giving
rustls a chance to emit bytes.
Keep these two functions structurally symmetric — a divergence
caused the 4.5 MB H2 truncation bug. Tests
e2e::tests::h2_correctness_tests::* and
e2e::tests::h2_tests::test_h2_large_* are the regression guard.
Source§fn socket_write_then_close(&mut self, buf: &[u8]) -> (usize, SocketResult)
fn socket_write_then_close(&mut self, buf: &[u8]) -> (usize, SocketResult)
Queue buf and the close_notify behind it, then flush both with one
write_tls, which hands every pending record to one write_vectored
(rustls-0.23.45/src/vecbuf.rs, ChunkVecBuffer::write_to).
The plaintext must be queued first: rustls encrypts it into the send buffer at once (the handshake is over on every connection the mux drives), and the alert queued after it is the next record on the wire, so the peer reads the bytes and then the close. The other order would end the peer’s reading before the bytes.
When rustls does not take all of buf (its send buffer is full) the
alert is not queued, as the trait requires, and the caller’s next call
carries the rest. A write error falls back to Self::socket_write,
which reports it with the socket context.
Source§fn peer_addr(&self) -> Option<SocketAddr>
fn peer_addr(&self) -> Option<SocketAddr>
No production route reaches the fallback any more. The expect-proxy
route gets there only through upgrade_expect, which returns None
unless both PROXY addresses parse, so peer_address is Some by the
time a handshake exists; the direct route seeds it in
HttpsSession::new (https.rs) with the address accept(2) returned
with the socket, which cannot fail the way getpeername(2) can. The
arm stays as defence in depth: a handler built without a peer would
otherwise blank the peer= slot of a healthy connection. Do not
delete it — https::tests::front_rustls_peer_addr_falls_back_to_the_live_lookup
builds such a handler by hand and fails without it.
fn socket_read(&mut self, buf: &mut [u8]) -> (usize, SocketResult)
fn socket_close(&mut self)
fn socket_wants_write(&self) -> bool
fn socket_ref(&self) -> &TcpStream ⓘ
fn socket_mut(&mut self) -> &mut TcpStream ⓘ
fn protocol(&self) -> TransportProtocol
fn read_error(&self)
fn write_error(&self)
Source§fn session_ulid(&self) -> Option<Ulid>
fn session_ulid(&self) -> Option<Ulid>
log_socket_context! to render the [<session_ulid> - - -] segment
of the socket-layer log prefix, matching the format used by the
rest of the mux stack. Returns None for contextless implementations
(e.g. raw mio::TcpStream); the macro renders - in the ULID slot.