Internal QUICHE change
PiperOrigin-RevId: 317961822
Change-Id: I82e3c50088a3c6b8f158bc1eb096b32c3d4a92aa
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index cb1480e..1398965 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -6,6 +6,7 @@
#include <cstddef>
#include <cstdint>
+#include <limits>
#include <memory>
#include <string>
#include <utility>
@@ -20,6 +21,7 @@
#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
+#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
@@ -28,6 +30,7 @@
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
#include "net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h"
+#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
@@ -622,6 +625,17 @@
}
// static
+size_t QuicFramer::GetAckFrequencyFrameSize(
+ const QuicAckFrequencyFrame& frame) {
+ return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
+ QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+ QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
+ QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
+ // One byte for encoding boolean
+ 1;
+}
+
+// static
size_t QuicFramer::GetPathChallengeFrameSize(
const QuicPathChallengeFrame& frame) {
return kQuicFrameTypeSize + sizeof(frame.data_buffer);
@@ -675,7 +689,8 @@
case HANDSHAKE_DONE_FRAME:
// HANDSHAKE_DONE has no payload.
return kQuicFrameTypeSize;
-
+ case ACK_FREQUENCY_FRAME:
+ return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
case STREAM_FRAME:
case ACK_FRAME:
case STOP_WAITING_FRAME:
@@ -1185,6 +1200,12 @@
case HANDSHAKE_DONE_FRAME:
// HANDSHAKE_DONE has no payload.
break;
+ case ACK_FREQUENCY_FRAME:
+ if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
+ QUIC_BUG << "AppendAckFrequencyFrame failed: " << detailed_error();
+ return 0;
+ }
+ break;
default:
set_detailed_error("Tried to append unknown frame type.");
RaiseError(QUIC_INVALID_FRAME_DATA);
@@ -3349,7 +3370,20 @@
<< handshake_done_frame;
break;
}
-
+ case IETF_ACK_FREQUENCY: {
+ QuicAckFrequencyFrame frame;
+ if (!ProcessAckFrequencyFrame(reader, &frame)) {
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
+ }
+ QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
+ << frame;
+ if (!visitor_->OnAckFrequencyFrame(frame)) {
+ QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
+ }
+ break;
+ }
default:
set_detailed_error("Illegal frame type.");
QUIC_DLOG(WARNING)
@@ -3529,6 +3563,47 @@
return true;
}
+bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
+ QuicAckFrequencyFrame* frame) {
+ if (!reader->ReadVarInt62(&frame->sequence_number)) {
+ set_detailed_error("Unable to read sequence number.");
+ return false;
+ }
+
+ if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
+ set_detailed_error("Unable to read packet tolerance.");
+ return false;
+ }
+ if (frame->packet_tolerance == 0) {
+ set_detailed_error("Invalid packet tolerance.");
+ return false;
+ }
+ uint64_t max_ack_delay_us;
+ if (!reader->ReadVarInt62(&max_ack_delay_us)) {
+ set_detailed_error("Unable to read max_ack_delay_us.");
+ return false;
+ }
+ constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
+ if (max_ack_delay_us > kMaxAckDelayUsBound) {
+ set_detailed_error("Invalid max_ack_delay_us.");
+ return false;
+ }
+ frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
+
+ uint8_t ignore_order;
+ if (!reader->ReadUInt8(&ignore_order)) {
+ set_detailed_error("Unable to read ignore_order.");
+ return false;
+ }
+ if (ignore_order > 1) {
+ set_detailed_error("Invalid ignore_order.");
+ return false;
+ }
+ frame->ignore_order = ignore_order;
+
+ return true;
+}
+
bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
const bool has_ack_blocks =
ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
@@ -4914,6 +4989,9 @@
case HANDSHAKE_DONE_FRAME:
type_byte = IETF_HANDSHAKE_DONE;
break;
+ case ACK_FREQUENCY_FRAME:
+ type_byte = IETF_ACK_FREQUENCY;
+ break;
default:
QUIC_BUG << "Attempt to generate a frame type for an unsupported value: "
<< frame.type;
@@ -5131,6 +5209,29 @@
return true;
}
+bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteVarInt62(frame.sequence_number)) {
+ set_detailed_error("Writing sequence number failed.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.packet_tolerance)) {
+ set_detailed_error("Writing packet tolerance failed.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(
+ static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
+ set_detailed_error("Writing max_ack_delay_us failed.");
+ return false;
+ }
+ if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
+ set_detailed_error("Writing ignore_order failed.");
+ return false;
+ }
+
+ return true;
+}
+
void QuicFramer::set_version(const ParsedQuicVersion version) {
DCHECK(IsSupportedVersion(version)) << ParsedQuicVersionToString(version);
version_ = version;