UDXStream constructor

UDXStream(
  1. UDX udx,
  2. int id, {
  3. bool framed = false,
  4. int initialSeq = 0,
  5. bool firewall(
    1. UDPSocket socket,
    2. int port,
    3. String host
    )?,
  6. int? initialCwnd,
  7. CongestionController? congestionControllerForTest,
  8. PacketManager? packetManagerForTest,
  9. bool isInitiator = false,
})

Creates a new UDX stream

Implementation

UDXStream(
  this.udx,
  this.id, {
  this.framed = false,
  this.initialSeq = 0,
  this.firewall,
  int? initialCwnd,
  CongestionController? congestionControllerForTest,
  PacketManager? packetManagerForTest,
  this.isInitiator = false,
}) : _nextExpectedSeq = initialSeq {
  // With the circular dependency broken, we can initialize cleanly.
  // The order matters: PacketManager needs a CongestionController,
  // and CongestionController needs a PacketManager.
  // The new design is:
  // 1. CC constructor takes a PM.
  // 2. PM constructor takes an optional CC.
  // 3. PM has a `late` CC property.

  // This allows us to create the PM, then the CC, then link the CC back to the PM.
  packetManager = packetManagerForTest ?? PacketManager();
  _congestionController = congestionControllerForTest ??
      CongestionController(
          packetManager: packetManager, initialCwnd: initialCwnd);

  if (packetManagerForTest == null) {
    packetManager.congestionController = _congestionController;
  }

  _congestionController.onProbe = () {
    if (remoteId != null && _socket != null) {
      packetManager.sendProbe(_socket!.cids.remoteCid, _socket!.cids.localCid, remoteId!, id);
    }
  };
  _congestionController.onFastRetransmit = (sequence) {
    packetManager.retransmitPacket(sequence);
  };
  // Note: Removed onPacketPermanentlyLost callback that was causing stream crashes.
  // The QUIC-compliant PTO system in CongestionController now handles loss detection
  // without arbitrary retry limits that would crash streams.
}