Skip to content

Expose ECN information in Controller::on_ack #2487

@B1gG

Description

@B1gG

Summary

Add ECN (Explicit Congestion Notification) visibility to the Controller::on_ack callback to enable custom congestion control algorithms to react to per-packet ECN CE marks.

Motivation

Currently, Quinn's Controller trait receives ECN CE information only through on_congestion_event, which is triggered after ECN-based congestion detection. However, custom congestion control algorithms may need finer-grained access to ECN information on a per-ACK basis to:

  1. Implement ECN-aware algorithms: Custom controllers could implement sophisticated ECN-based congestion control (e.g., DCTCP-like algorithms, L4S, or experimental protocols)
  2. Early congestion detection: React to ECN CE marks before they accumulate into a congestion event
  3. Telemetry and monitoring: Track ECN mark rates for debugging and performance analysis
  4. Research and experimentation: Enable development of novel congestion control mechanisms that leverage ECN

Proposed API Change

Modify the Controller::on_ack method signature to include ECN information:

fn on_ack(
    &mut self,
    now: Instant,
    sent: Instant,
    bytes: u64,
    app_limited: bool,
    rtt: &RttEstimator,
    ecn: Option<EcnCodepoint>,
) {
    // Default implementation remains unchanged for backward compatibility
}

Parameters

  • ecn: An Option<EcnCodepoint> indicating the ECN marking on the acknowledged packet
    • Some(EcnCodepoint::Ce): Packet was marked with Congestion Experienced
    • Some(EcnCodepoint::Ect0) or Some(EcnCodepoint::Ect1): ECN-capable but not congested
    • None: No ECN information available (e.g., peer doesn't support ECN, or network stripped ECN bits)

Example Use Case

impl Controller for CustomController {
    fn on_ack(
        &mut self,
        now: Instant,
        sent: Instant,
        bytes: u64,
        app_limited: bool,
        rtt: &RttEstimator,
        ecn: Option<EcnCodepoint>,
    ) {
        // Track ECN CE marks for telemetry
        if let Some(EcnCodepoint::Ce) = ecn {
            self.ce_marks_received += 1;
            // React immediately to congestion signal
            self.reduce_cwnd_early();
        }
        
        // Continue with normal ACK processing
        self.handle_ack(bytes, rtt);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions