code/quic-toy-server/net/quic/core/quic_framer.cc
// IETF Ack Frame consists of
//   Largest Ack'ed
//   Ack Delay
//   Ack Block Count
//   First Ack Block
//    additional gap/ack-blocks
IETF Ack Frame consists of
Largest Ack'ed
Ack Delay
Ack Block Count
First Ack Block
additional gap/ack-blocks
IETF Ack Frame consists of Largest Ack ' ed Ack Delay Ack Block Count First Ack Block additional gap / ack - blocks
bool QuicFramer::ProcessIetfAckFrame(QuicDataReader* reader,
                                     uint8_t frame_type,
                                     QuicAckFrame* ack_frame) {
  QuicPacketNumber largest_acked;
  if (!reader->ReadVarInt62(&largest_acked)) {
    set_detailed_error("Unable to read largest acked.");
    return false;
  }
  ack_frame->largest_acked = static_cast<QuicPacketNumber>(largest_acked);
  uint64_t ack_delay_time_in_us;
  if (!reader->ReadVarInt62(&ack_delay_time_in_us)) {
    set_detailed_error("Unable to read ack-delay-time.");
    return false;
  }
  ack_delay_time_in_us = (ack_delay_time_in_us << kIetfAckTimestampShift);
  if (ack_delay_time_in_us == 0x3ffffffffff8) {  
    ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
  } else {
    ack_frame->ack_delay_time =
        QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us);
  }
  uint64_t ack_block_count;
  if (!reader->ReadVarInt62(&ack_block_count)) {
    set_detailed_error("Unable to ack block count.");
    return false;
  }
  uint64_t ack_block_value;
  if (!reader->ReadVarInt62(&ack_block_value)) {
    set_detailed_error("Unable to read first ack block value.");
    return false;
  }
  QuicPacketNumber block_high = largest_acked + 1;
  QuicPacketNumber block_low = largest_acked - ack_block_value;
  ack_frame->packets.AddRange(block_low, block_high);
  while (ack_block_count != 0) {
    uint64_t gap_block_value;
    if (!reader->ReadVarInt62(&gap_block_value)) {
      set_detailed_error("Unable to read gap block value.");
      return false;
    }
    if (!reader->ReadVarInt62(&ack_block_value)) {
      set_detailed_error("Unable to read gap block value.");
      return false;
    }
    block_high = block_high - (ack_block_value + gap_block_value + 2);
    block_low = block_low - (ack_block_value + gap_block_value + 2);
    ack_frame->packets.AddRange(block_low, block_high);
    ack_block_count--;
  }
  return true;
}
bool QuicFramer :: ProcessIetfAckFrame ( QuicDataReader * reader , uint8_t frame_type , QuicAckFrame * ack_frame ) { QuicPacketNumber largest_acked ; if ( ! reader -> ReadVarInt62 ( & largest_acked ) ) { set_detailed_error ( " " ) ; return false ; } ack_frame -> largest_acked = static_cast < QuicPacketNumber > ( largest_acked ) ; uint64_t ack_delay_time_in_us ; if ( ! reader -> ReadVarInt62 ( & ack_delay_time_in_us ) ) { set_detailed_error ( " " ) ; return false ; } ack_delay_time_in_us = ( ack_delay_time_in_us << kIetfAckTimestampShift ) ; if ( ack_delay_time_in_us == 0x3ffffffffff8 ) { ack_frame -> ack_delay_time = QuicTime :: Delta :: Infinite ( ) ; } else { ack_frame -> ack_delay_time = QuicTime :: Delta :: FromMicroseconds ( ack_delay_time_in_us ) ; } uint64_t ack_block_count ; if ( ! reader -> ReadVarInt62 ( & ack_block_count ) ) { set_detailed_error ( " " ) ; return false ; } uint64_t ack_block_value ; if ( ! reader -> ReadVarInt62 ( & ack_block_value ) ) { set_detailed_error ( " " ) ; return false ; } QuicPacketNumber block_high = largest_acked + 1 ; QuicPacketNumber block_low = largest_acked - ack_block_value ; ack_frame -> packets . AddRange ( block_low , block_high ) ; while ( ack_block_count != 0 ) { uint64_t gap_block_value ; if ( ! reader -> ReadVarInt62 ( & gap_block_value ) ) { set_detailed_error ( " " ) ; return false ; } if ( ! reader -> ReadVarInt62 ( & ack_block_value ) ) { set_detailed_error ( " " ) ; return false ; } block_high = block_high - ( ack_block_value + gap_block_value + 2 ) ; block_low = block_low - ( ack_block_value + gap_block_value + 2 ) ; ack_frame -> packets . AddRange ( block_low , block_high ) ; ack_block_count -- ; } return true ; }
IETF Ack Frame consists of
Largest Ack'ed
Ack Delay
Ack Block Count
First Ack Block
additional gap/ack-blocks
IETF Ack Frame consists of Largest Ack ' ed Ack Delay Ack Block Count First Ack Block additional gap / ack - blocks
// TODO(fkastenholz) when we get real IETF QUIC, need to get // the currect shift from the transport parameters. // May want a more // realistic max? // Get number of ack blocks from the packet // there always is a first ack block // Calculate the packets being acked in the first block. //  +1 because AddRange is [low,high) // Get the sizes of the gap and ack blocks, // Slide the high/low values of the ack block down to the next // block in the frame. +2 is because the value encoded in the // frame is (length_of_block- 1). Then add the range. // Another one done.