Use HTTP/3 error code when unidirectional stream limit is too low.

gfe-relnote: protected by gfe2_reloadable_flag_quic_enable_version_draft_25_v3
PiperOrigin-RevId: 308318955
Change-Id: I5c86ceadd48a62301158703c026a04d94abb4aff
diff --git a/quic/core/quic_error_codes.cc b/quic/core/quic_error_codes.cc
index 9916463..e8324b5 100644
--- a/quic/core/quic_error_codes.cc
+++ b/quic/core/quic_error_codes.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include <cstdint>
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
@@ -199,6 +200,7 @@
     RETURN_STRING_LITERAL(QUIC_HTTP_MISSING_SETTINGS_FRAME);
     RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
     RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
+    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
     RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR);
     RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR);
     RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR);
@@ -560,6 +562,9 @@
       return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
     case QUIC_HTTP_INVALID_MAX_PUSH_ID:
       return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
     case QUIC_HPACK_INDEX_VARINT_ERROR:
       return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
     case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
diff --git a/quic/core/quic_error_codes.h b/quic/core/quic_error_codes.h
index efdb5f3..f057fea 100644
--- a/quic/core/quic_error_codes.h
+++ b/quic/core/quic_error_codes.h
@@ -429,6 +429,8 @@
   // MAX_PUSH_ID frame received with push ID value smaller than a previously
   // received value.
   QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
+  // Received unidirectional stream limit is lower than required by HTTP/3.
+  QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
 
   // HPACK header block decoding errors.
   // Index varint beyond implementation limit.
@@ -465,7 +467,7 @@
   QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
 
   // No error. Used as bound while iterating.
-  QUIC_LAST_ERROR = 160,
+  QUIC_LAST_ERROR = 161,
 };
 // QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
 // or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index e85644d..4862d50 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -1129,13 +1129,14 @@
       max_streams = config_.ReceivedMaxUnidirectionalStreams();
     }
     if (max_streams < num_expected_unidirectional_static_streams_) {
-      // TODO(ianswett): Change this to an application error for HTTP/3.
       QUIC_DLOG(ERROR) << "Received unidirectional stream limit of "
                        << max_streams << " < "
                        << num_expected_unidirectional_static_streams_;
       connection_->CloseConnection(
-          QUIC_MAX_STREAMS_ERROR, "New unidirectional stream limit is too low.",
+          QUIC_HTTP_STREAM_LIMIT_TOO_LOW,
+          "New unidirectional stream limit is too low.",
           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
     }
     QUIC_DVLOG(1) << ENDPOINT
                   << "Setting Unidirectional outgoing_max_streams_ to "