Class AckFrequencyState

java.lang.Object
io.github.mahmoudimus.quic.connection.AckFrequencyState

public final class AckFrequencyState extends Object
State of the QUIC ACK frequency extension, as quinn implements it: the max_ack_delay the peer uses (its transport parameter, or what we last asked for in an ACK_FREQUENCY frame once it is acknowledged) and the one we use (ours, or what the peer asked for). Durations are nanoseconds.

Without the extension this simply holds both endpoints' max_ack_delay.

Threads. Not thread-safe; owned by one connection.

  • Constructor Summary

    Constructors
    Constructor
    Description
    AckFrequencyState(long defaultMaxAckDelay)
    The state before any ACK_FREQUENCY frame.
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    Applies a received ACK_FREQUENCY frame, unless an equal or newer one was applied already.
    void
    ackFrequencySent(long pn, long requestedMaxAckDelay)
    Records that a packet carried an ACK_FREQUENCY frame.
    long
    candidateMaxAckDelay(long rtt, long configuredMaxAckDelay, long peerMinAckDelayMicros)
    The max_ack_delay to ask the peer for: the configured one or the peer's own, at most the RTT (but not below 25 ms) and at least the peer's min_ack_delay.
    long
    Our max_ack_delay.
    long
    The max_ack_delay to compute the PTO with: the larger of the peer's and any requested but unacknowledged one, which the peer may already use.
    long
    Allocates the next ACK_FREQUENCY sequence number.
    void
    onAcked(long pn)
    Records an acknowledged application data packet; acknowledging the ACK_FREQUENCY frame makes its delay the peer's.
    long
    The peer's max_ack_delay.
    void
    setMaxAckDelay(long delay)
    Sets our max_ack_delay.
    void
    setPeerMaxAckDelay(long delay)
    Sets the peer's max_ack_delay, from its transport parameters.
    boolean
    shouldSendAckFrequency(long rtt, long configuredMaxAckDelay, long peerMinAckDelayMicros)
    Whether to send an ACK_FREQUENCY frame: always first, then when the desired delay differs from the current request by more than 20%.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • AckFrequencyState

      public AckFrequencyState(long defaultMaxAckDelay)
      The state before any ACK_FREQUENCY frame.
      Parameters:
      defaultMaxAckDelay - the default max_ack_delay, 25 ms, used for both endpoints until their transport parameters are known
  • Method Details

    • peerMaxAckDelay

      public long peerMaxAckDelay()
      The peer's max_ack_delay.
      Returns:
      nanoseconds
    • setPeerMaxAckDelay

      public void setPeerMaxAckDelay(long delay)
      Sets the peer's max_ack_delay, from its transport parameters.
      Parameters:
      delay - nanoseconds
    • maxAckDelay

      public long maxAckDelay()
      Our max_ack_delay.
      Returns:
      nanoseconds
    • setMaxAckDelay

      public void setMaxAckDelay(long delay)
      Sets our max_ack_delay.
      Parameters:
      delay - nanoseconds
    • candidateMaxAckDelay

      public long candidateMaxAckDelay(long rtt, long configuredMaxAckDelay, long peerMinAckDelayMicros)
      The max_ack_delay to ask the peer for: the configured one or the peer's own, at most the RTT (but not below 25 ms) and at least the peer's min_ack_delay.
      Parameters:
      rtt - the RTT estimate, in nanoseconds
      configuredMaxAckDelay - a configured delay in nanoseconds, or -1 to use the peer's
      peerMinAckDelayMicros - the peer's min_ack_delay in microseconds, or -1
      Returns:
      nanoseconds
    • maxAckDelayForPto

      public long maxAckDelayForPto()
      The max_ack_delay to compute the PTO with: the larger of the peer's and any requested but unacknowledged one, which the peer may already use.
      Returns:
      nanoseconds
    • nextSequenceNumber

      public long nextSequenceNumber()
      Allocates the next ACK_FREQUENCY sequence number.
      Returns:
      the sequence number
    • shouldSendAckFrequency

      public boolean shouldSendAckFrequency(long rtt, long configuredMaxAckDelay, long peerMinAckDelayMicros)
      Whether to send an ACK_FREQUENCY frame: always first, then when the desired delay differs from the current request by more than 20%.
      Parameters:
      rtt - the RTT estimate, in nanoseconds
      configuredMaxAckDelay - a configured delay in nanoseconds, or -1
      peerMinAckDelayMicros - the peer's min_ack_delay in microseconds, or -1
      Returns:
      true if a frame should be sent
    • ackFrequencySent

      public void ackFrequencySent(long pn, long requestedMaxAckDelay)
      Records that a packet carried an ACK_FREQUENCY frame.
      Parameters:
      pn - the packet number
      requestedMaxAckDelay - the delay it asked for, in nanoseconds
    • onAcked

      public void onAcked(long pn)
      Records an acknowledged application data packet; acknowledging the ACK_FREQUENCY frame makes its delay the peer's.
      Parameters:
      pn - the packet number
    • ackFrequencyReceived

      public boolean ackFrequencyReceived(Frame.AckFrequency frame, PendingAcks pendingAcks) throws QuicException
      Applies a received ACK_FREQUENCY frame, unless an equal or newer one was applied already.
      Parameters:
      frame - the frame
      pendingAcks - the application data space's ACK state, which takes the thresholds
      Returns:
      false if the frame was stale and ignored
      Throws:
      QuicException - PROTOCOL_VIOLATION if the requested delay is below the timer granularity, which is our min_ack_delay