Skip to main content

UdpFlow

Struct UdpFlow 

Source
pub struct UdpFlow {
    pub client: SocketAddr,
    pub backend_id: Option<String>,
    pub backend_addr: Option<SocketAddr>,
    pub phase: FlowPhase,
    pub config: ClusterConfig,
    pub requests_seen: u32,
    pub responses_seen: u32,
    pub idle_deadline: Instant,
    pub timer_gen: u64,
    pub first_upstream_pending: bool,
    pub pending_payload: Option<Vec<u8>>,
}
Expand description

Per-admitted-flow state. Slab slot payload owned by the manager.

Fields§

§client: SocketAddr

Real (pre-NAT) client source address — the symmetric NAT return target and the PPv2 source address.

§backend_id: Option<String>

Resolved backend id, set on BackendResolved.

§backend_addr: Option<SocketAddr>

Resolved backend address, set on BackendResolved.

§phase: FlowPhase

Lifecycle phase.

§config: ClusterConfig

Captured per-cluster knobs (responses/requests/timeouts/PPv2). Captured at admission so a mid-flow reconfig does not change a live flow’s teardown contract (stable affinity).

§requests_seen: u32

Client datagrams forwarded so far (counts toward requests).

§responses_seen: u32

Backend replies returned so far (counts toward responses).

§idle_deadline: Instant

Absolute idle deadline; reset on every datagram in either direction.

§timer_gen: u64

Generation token. Incremented every time the idle deadline is pushed back. A wheel expiry only closes the flow when its captured generation still matches — defeating the stale-close busy-loop bug.

§first_upstream_pending: bool

True until the first upstream datagram is sent; gates PPv2 prefixing when proxy_protocol_every_datagram is false (first-datagram-only).

§pending_payload: Option<Vec<u8>>

One-slot buffer for a client datagram that arrived while AwaitingBackend. Flushed on BackendResolved. A second datagram in the window replaces it (newest wins) rather than allocating an unbounded queue.

Implementations§

Source§

impl UdpFlow

Source

pub fn new(client: SocketAddr, config: ClusterConfig, now: Instant) -> Self

Create a flow for client, awaiting a backend, with its idle deadline armed front_timeout from now.

Source

pub fn touch(&mut self, timeout: Duration, now: Instant) -> u64

Push the idle deadline back to now + timeout and bump the generation token so any in-flight wheel expiry for the old deadline is invalidated. Returns the new generation so the manager can re-arm the wheel.

Source

pub fn on_client_datagram(&mut self, now: Instant) -> u64

Record that one client datagram was actually forwarded upstream: bump the requests counter and refresh the front idle deadline. Returns the new generation token. Call this only at a real forward site — a datagram merely buffered while AwaitingBackend and later overwritten (newest-wins) must NOT count, or a burst during await could trip the requests cap having delivered fewer than requests datagrams. Use touch for the buffer-only idle refresh.

Source

pub fn on_backend_datagram(&mut self, now: Instant) -> u64

Record that one backend reply was returned; refresh the back idle deadline. Returns the new generation token.

Source

pub fn set_phase(&mut self, next: FlowPhase)

Transition the flow to next, asserting the move is legal. The lifecycle is strictly forward: AwaitingBackend → Established → Closing, with a self-loop allowed only into Closing (idempotent close). A backward move (Established → AwaitingBackend) or skipping straight from AwaitingBackend → Closing is allowed only into Closing (a flow may be aborted before it establishes); every other transition is a bug.

Debug-only guard — the assignment itself is unconditional so release behavior is identical.

Source

pub fn requests_exhausted(&self) -> bool

Whether the requests knob has been exhausted (0 = unlimited).

Source

pub fn responses_exhausted(&self) -> bool

Whether the responses knob has been exhausted (0 = unlimited). A DNS flow with responses = 1 closes after its single reply.

Source

pub fn teardown_reason(&self) -> Option<CloseReason>

The teardown reason if any knob is exhausted, else None. Idle is handled separately by the manager via the timer wheel.

Source

pub fn take_proxy_protocol(&mut self) -> bool

Whether this upstream datagram should carry a PPv2 DGRAM prefix, given the cluster’s first-datagram-only vs every-datagram policy. Marks the first-datagram bookkeeping as consumed.

Trait Implementations§

Source§

impl Clone for UdpFlow

Source§

fn clone(&self) -> UdpFlow

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for UdpFlow

Source§

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

Formats the value using the given formatter. Read more

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more