Class PacketSpace

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

public final class PacketSpace extends Object
One packet number space (RFC 9000 section 12.3, RFC 9002 appendix A): its keys, the packets received and to acknowledge, the next packet number, the packets sent and not yet acknowledged or lost, the frames waiting to be sent, the CRYPTO stream, and the loss detection state that Recovery keeps per space.

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

  • Constructor Details

    • PacketSpace

      public PacketSpace(SpaceId id, long now)
      An empty space.
      Parameters:
      id - which space this is
      now - the current time
  • Method Details

    • id

      public SpaceId id()
      Which space this is.
      Returns:
      the space
    • keys

      public Keys keys()
      The space's keys.
      Returns:
      the keys, or null before they are installed and after they are discarded
    • setKeys

      public void setKeys(Keys keys)
      Installs keys.
      Parameters:
      keys - the keys
    • dedup

      public Dedup dedup()
      The duplicate detector of received packet numbers.
      Returns:
      the detector
    • pending

      public Retransmits pending()
      The frames waiting to be sent in this space.
      Returns:
      the pending frames
    • pendingAcks

      public PendingAcks pendingAcks()
      The packets waiting to be acknowledged.
      Returns:
      the pending ACK state
    • cryptoStream

      public Assembler cryptoStream()
      The incoming CRYPTO stream.
      Returns:
      its assembler
    • cryptoOffset

      public long cryptoOffset()
      The offset of the next outgoing CRYPTO byte.
      Returns:
      the offset
    • advanceCryptoOffset

      public void advanceCryptoOffset(long length)
      Advances the outgoing CRYPTO offset.
      Parameters:
      length - the bytes queued
    • sentPackets

      public SentPackets sentPackets()
      The packets sent and not yet acknowledged or lost.
      Returns:
      the packets
    • nextPacketNumber

      public long nextPacketNumber()
      The number of the next packet to send.
      Returns:
      the packet number
    • largestAckedPacket

      public long largestAckedPacket()
      The largest packet number the peer acknowledged.
      Returns:
      the packet number, or -1
    • rxPacket

      public long rxPacket()
      The highest packet number received.
      Returns:
      the packet number
    • onPacketReceived

      public boolean onPacketReceived(long now, long packetNumber, boolean ackEliciting)
      Records the receipt of an authenticated packet: duplicate detection, ACK bookkeeping and the highest packet number.
      Parameters:
      now - the current time
      packetNumber - the packet number
      ackEliciting - whether the packet is ack-eliciting
      Returns:
      true if the packet is a duplicate and must be dropped unprocessed
    • onEcnReceived

      public void onEcnReceived(int codepoint)
      Records an ECN codepoint on a received packet (RFC 9000 section 13.4.1). A CE mark asks for an immediate ACK.
      Parameters:
      codepoint - 1 for ECT(1), 2 for ECT(0), 3 for CE; 0 (not ECT) is ignored
    • ecnCounters

      public Frame.EcnCounts ecnCounters()
      The ECN counts to report in ACK frames.
      Returns:
      the counts of received ECT(0), ECT(1) and CE codepoints
    • lossTime

      public long lossTime()
      Whether time-threshold loss detection is pending.
      Returns:
      the loss time, or NanoClock.NONE
    • lossProbes

      public int lossProbes()
      The probes to send after a PTO.
      Returns:
      the count
    • probeSent

      public void probeSent()
      Records that one probe packet was sent.
    • pingPending

      public boolean pingPending()
      Whether a PING must be sent.
      Returns:
      true if pending
    • setPingPending

      public void setPingPending(boolean pending)
      Sets whether a PING must be sent.
      Parameters:
      pending - whether one is needed
    • immediateAckPending

      public boolean immediateAckPending()
      Whether an IMMEDIATE_ACK must be sent.
      Returns:
      true if pending
    • setImmediateAckPending

      public void setImmediateAckPending(boolean pending)
      Sets whether an IMMEDIATE_ACK must be sent.
      Parameters:
      pending - whether one is needed
    • timeOfLastAckElicitingPacket

      public long timeOfLastAckElicitingPacket()
      When the last ack-eliciting packet was sent.
      Returns:
      the time, or NanoClock.NONE
    • maybeQueueProbe

      public void maybeQueueProbe(boolean requestImmediateAck, boolean hasAckElicitingData, StreamsState streams)
      Fills a loss probe after a PTO (RFC 9002 section 6.2.4): if no new data is waiting, the oldest in-flight packet's control frames are queued again (and taken from that packet, so they are not resent twice), and failing that a PING.
      Parameters:
      requestImmediateAck - whether to ask for an immediate ACK (application data space, with a peer that supports the ACK frequency extension)
      hasAckElicitingData - whether other ack-eliciting data, such as a DATAGRAM, will be sent
      streams - the connection's streams
    • getTxNumber

      public long getTxNumber()
      Allocates the next packet number. In the application data space use PacketNumberFilter.allocate(java.util.random.RandomGenerator, io.github.mahmoudimus.quic.connection.PacketSpace) instead.
      Returns:
      the packet number
      Throws:
      IllegalStateException - if packet numbers are exhausted
    • canSend

      public PacketSpace.Sendable canSend(StreamsState streams)
      Whether anything can be sent in this space.
      Parameters:
      streams - the connection's streams
      Returns:
      whether an ACK must be sent, and whether other frames are waiting
    • detectEcn

      public boolean detectEcn(long newlyAcked, Frame.EcnCounts ecn)
      Validates an ACK's ECN counts (RFC 9000 section 13.4.2.1) and records them.
      Parameters:
      newlyAcked - the packets the ACK newly acknowledged
      ecn - the counts
      Returns:
      true if the CE count increased, a congestion signal
      Throws:
      IllegalArgumentException - if the counts went backwards, show bleaching or corruption; ECN should then be disabled on the path
    • take

      public SentPacket take(long number)
      Stops tracking a sent packet.
      Parameters:
      number - the packet number
      Returns:
      what was known about it, or null if it was not tracked
    • sent

      public SentPacket sent(long number, SentPacket packet)
      Tracks a sent packet. Of the packets after the last ack-eliciting one, at most 1000L are kept, since nothing guarantees an ACK for them.
      Parameters:
      number - the packet number
      packet - the packet
      Returns:
      a packet to forget (remove from the in-flight counts), or null
    • hasInFlight

      public boolean hasInFlight()
      Whether any congestion-controlled packet of this space is unacknowledged and not lost.
      Returns:
      true if one is in flight