fitToPath method

List<UDXPacket> fitToPath(
  1. UDXPacket packet,
  2. int limit
)

Re-chunks a packet larger than the path now carries (the size fell back after a black hole, MtuDiscovery) into packets that fit, in its place: the original is dropped from tracking and the pieces take fresh sequences when they are re-sent (resend). A packet that fits is returned as it is. Only a packet carrying one STREAM frame is split, which is every data packet a stream sends.

Implementation

List<UDXPacket> fitToPath(UDXPacket packet, int limit) {
  final size = packet.wireSize ?? packet.toBytes().length;
  if (size <= limit || packet.frames.length != 1) return [packet];
  final frame = packet.frames.single;
  if (frame is! StreamFrame) return [packet];
  UDXPacket build(StreamFrame f) => UDXPacket(
        destinationCid: packet.destinationCid,
        sourceCid: packet.sourceCid,
        destinationStreamId: packet.destinationStreamId,
        sourceStreamId: packet.sourceStreamId,
        sequence: 0,
        frames: [f],
      );
  final overhead = build(StreamFrame(data: Uint8List(0), offset: frame.offset, isSyn: frame.isSyn)).toBytes().length;
  final piece = limit - overhead;
  if (piece <= 0 || piece >= frame.data.length) return [packet];
  drop(packet);
  final pieces = <UDXPacket>[];
  var data = frame.data;
  var offset = frame.offset;
  var isSyn = frame.isSyn;
  while (data.isNotEmpty) {
    final k = piece < data.length ? piece : data.length;
    final p = build(StreamFrame(
      data: Uint8List.sublistView(data, 0, k),
      offset: offset,
      isSyn: isSyn,
      isFin: frame.isFin && k == data.length,
    ))
      ..sentTime = packet.sentTime
      ..retransmitCount = packet.retransmitCount;
    p.wireSize = p.toBytes().length;
    pieces.add(p);
    isSyn = false;
    offset += k;
    data = Uint8List.sublistView(data, k);
  }
  return pieces;
}