IETF CONNECTION CLOSE code is varint encoded

In the recent (-22) version of the IETF QUIC Internet Draft, the
encoding of the close code in the Connection Close frames was changed
from uint16_t to varint62.

NOTE WELL, this just changes the serialization of the code. The error
code is stored as a uint16_t. A separate CL will change the base type
for the Transport Error Code and Application Error Code.

gfe-relnote: N/A is IETF QUIC/v99 code only.
PiperOrigin-RevId: 258377932
Change-Id: I0be6068b1a2194d4c45d464b393698389a73cb75
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 6c089c1..5324206 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -578,10 +578,16 @@
   // extend the error string to include " QuicErrorCode: #"
   const size_t truncated_error_string_size =
       TruncatedErrorStringSize(frame.error_details);
+  uint64_t close_code = 0;
+  if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    close_code = static_cast<uint64_t>(frame.transport_error_code);
+  } else if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    close_code = static_cast<uint64_t>(frame.application_error_code);
+  }
   const size_t frame_size =
       truncated_error_string_size +
       QuicDataWriter::GetVarInt62Len(truncated_error_string_size) +
-      kQuicFrameTypeSize + kQuicIetfQuicErrorCodeSize;
+      kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(close_code);
   if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
     return frame_size;
   }
@@ -5667,7 +5673,14 @@
     return false;
   }
 
-  if (!writer->WriteUInt16(frame.application_error_code)) {
+  uint64_t close_code = 0;
+  if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    close_code = static_cast<uint64_t>(frame.transport_error_code);
+  } else if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    close_code = static_cast<uint64_t>(frame.application_error_code);
+  }
+
+  if (!writer->WriteVarInt62(close_code)) {
     set_detailed_error("Can not write connection close frame error code");
     return false;
   }
@@ -5698,13 +5711,30 @@
     QuicConnectionCloseType type,
     QuicConnectionCloseFrame* frame) {
   frame->close_type = type;
-  uint16_t code;
-  if (!reader->ReadUInt16(&code)) {
+  uint64_t error_code;
+  if (!reader->ReadVarInt62(&error_code)) {
     set_detailed_error("Unable to read connection close error code.");
     return false;
   }
-  frame->transport_error_code = static_cast<QuicIetfTransportErrorCodes>(code);
 
+  if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    if (error_code > 0xffff) {
+      frame->transport_error_code =
+          static_cast<QuicIetfTransportErrorCodes>(0xffff);
+      QUIC_DLOG(ERROR) << "Transport error code " << error_code << " > 0xffff";
+    } else {
+      frame->transport_error_code =
+          static_cast<QuicIetfTransportErrorCodes>(error_code);
+    }
+  } else if (frame->close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    if (error_code > 0xffff) {
+      frame->application_error_code = 0xffff;
+      QUIC_DLOG(ERROR) << "Application error code " << error_code
+                       << " > 0xffff";
+    } else {
+      frame->application_error_code = static_cast<uint16_t>(error_code);
+    }
+  }
   if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
     // The frame-type of the frame causing the error is present only
     // if it's a CONNECTION_CLOSE/Transport.