Use VarInt encoding for IETF QUIC Reset Stream error code

Update IETF QUIC Rese Stream frame to use VarInt encoding, per Version 22
the IETF spec.

gfe-relnote: N/A for IETF Quic/V99 only.
PiperOrigin-RevId: 258411235
Change-Id: Ia51a2033ae45a5ee638bc4aaf24c2b4a072d25a4
diff --git a/quic/core/frames/quic_rst_stream_frame.h b/quic/core/frames/quic_rst_stream_frame.h
index 0957614..9a9ed56 100644
--- a/quic/core/frames/quic_rst_stream_frame.h
+++ b/quic/core/frames/quic_rst_stream_frame.h
@@ -39,6 +39,7 @@
     QuicRstStreamErrorCode error_code;
     // In IETF QUIC the code is up to the app on top of quic, so is
     // more general than QuicRstStreamErrorCode allows.
+    // TODO(fkastenholz): Upgrade to uint64_t
     uint16_t ietf_error_code;
   };
 
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index ffed8cc..1280f2e 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -556,7 +556,8 @@
   if (VersionHasIetfQuicFrames(version)) {
     return QuicDataWriter::GetVarInt62Len(frame.stream_id) +
            QuicDataWriter::GetVarInt62Len(frame.byte_offset) +
-           kQuicFrameTypeSize + kQuicIetfQuicErrorCodeSize;
+           kQuicFrameTypeSize +
+           QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
   }
   return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
          kQuicErrorCodeSize;
@@ -5812,7 +5813,7 @@
     set_detailed_error("Writing reset-stream stream id failed.");
     return false;
   }
-  if (!writer->WriteUInt16(frame.ietf_error_code)) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.ietf_error_code))) {
     set_detailed_error("Writing reset-stream error code failed.");
     return false;
   }
@@ -5833,10 +5834,18 @@
     return false;
   }
 
-  if (!reader->ReadUInt16(&frame->ietf_error_code)) {
+  uint64_t error_code;
+  if (!reader->ReadVarInt62(&error_code)) {
     set_detailed_error("Unable to read rst stream error code.");
     return false;
   }
+  if (error_code > 0xffff) {
+    frame->ietf_error_code = 0xffff;
+    QUIC_DLOG(ERROR) << "Reset stream error code (" << error_code
+                     << ") > 0xffff";
+  } else {
+    frame->ietf_error_code = static_cast<uint16_t>(error_code);
+  }
 
   if (!reader->ReadVarInt62(&frame->byte_offset)) {
     set_detailed_error("Unable to read rst stream sent byte offset.");
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 95b9187..690e911 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -4544,7 +4544,7 @@
        {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
       // application error code
       {"Unable to read rst stream error code.",
-       {0x00, 0x01}},   // Not varint62 encoded
+       {kVarInt62OneByte + 0x01}},
       // Final Offset
       {"Unable to read rst stream sent byte offset.",
        {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}}
@@ -7801,8 +7801,8 @@
     0x04,
     // stream id
     kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // error code (not VarInt32 encoded)
-    0x00, 0x01,
+    // error code
+    kVarInt62OneByte + 0x01,
     // sent byte offset
     kVarInt62EightBytes + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
   };
diff --git a/quic/core/quic_ietf_framer_test.cc b/quic/core/quic_ietf_framer_test.cc
index 9d07e49..dbbacdd 100644
--- a/quic/core/quic_ietf_framer_test.cc
+++ b/quic/core/quic_ietf_framer_test.cc
@@ -457,9 +457,10 @@
     // Write the frame to the packet buffer.
     EXPECT_TRUE(QuicFramerPeer::AppendIetfResetStreamFrame(
         &framer_, transmit_frame, &writer));
-    // Check that the size of the serialzed frame is in the allowed range.
-    EXPECT_LT(3u, writer.length());
-    EXPECT_GT(19u, writer.length());
+    // Check that the size of the serialzed frame is in the allowed range (3 to
+    // 24 bytes, inclusive).
+    EXPECT_LT(2u, writer.length());
+    EXPECT_GT(25u, writer.length());
     // Now set up a reader to read in the thing in.
     QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);