Skip to main content

FrontRustls

Struct FrontRustls 

Source
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: bool

Peer 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: bool

The 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: bool

process_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: Ulid

Connection/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: RecvMemory

What 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

Source

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

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl SocketHandler for FrontRustls

Source§

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)

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)

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>

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.

Source§

fn socket_read(&mut self, buf: &mut [u8]) -> (usize, SocketResult)

Source§

fn socket_close(&mut self)

Source§

fn socket_wants_write(&self) -> bool

Source§

fn socket_ref(&self) -> &TcpStream ⓘ

Source§

fn socket_mut(&mut self) -> &mut TcpStream ⓘ

Source§

fn protocol(&self) -> TransportProtocol

Source§

fn read_error(&self)

Source§

fn write_error(&self)

Source§

fn session_ulid(&self) -> Option<Ulid>

Returns the owning connection’s session ULID when known. Used by 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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.