Add GetLargestGuaranteedMessagePayload to QuicSession/Connection/Generator/Creator to expose the largest message payload that's guaranteed to fit in any packet containing application data.
gfe-relnote: n/a (Only used in Quartc)
PiperOrigin-RevId: 242135946
Change-Id: I52cc763af88d22fc240210e00cf4d4062d0b9c59
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index 224aadf..4d5bd14 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -10,9 +10,11 @@
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.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_writer.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"
#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
@@ -984,7 +986,7 @@
}
}
-QuicPacketLength QuicPacketCreator::GetLargestMessagePayload() const {
+QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
if (framer_->transport_version() <= QUIC_VERSION_44) {
return 0;
}
@@ -992,13 +994,44 @@
framer_->transport_version(), GetDestinationConnectionIdLength(),
GetSourceConnectionIdLength(), IncludeVersionInHeader(),
IncludeNonceInPublicHeader(), GetPacketNumberLength(),
- GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
+ // No Retry token on packets containing application data.
+ VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
// This is the largest possible message payload when the length field is
// omitted.
return max_plaintext_size_ -
std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
}
+QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
+ if (framer_->transport_version() <= QUIC_VERSION_44) {
+ return 0;
+ }
+ // QUIC Crypto server packets may include a diversification nonce.
+ const bool may_include_nonce =
+ framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+ framer_->perspective() == Perspective::IS_SERVER;
+ // IETF QUIC long headers include a length on client 0RTT packets.
+ QuicVariableLengthIntegerLength length_length =
+ framer_->perspective() == Perspective::IS_CLIENT
+ ? VARIABLE_LENGTH_INTEGER_LENGTH_2
+ : VARIABLE_LENGTH_INTEGER_LENGTH_0;
+ const size_t packet_header_size = GetPacketHeaderSize(
+ framer_->transport_version(), GetDestinationConnectionIdLength(),
+ // Assume CID lengths don't change, but version may be present.
+ GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
+ PACKET_4BYTE_PACKET_NUMBER,
+ // No Retry token on packets containing application data.
+ VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
+ // This is the largest possible message payload when the length field is
+ // omitted.
+ const QuicPacketLength largest_payload =
+ max_plaintext_size_ -
+ std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
+ // This must always be less than or equal to GetCurrentLargestMessagePayload.
+ DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
+ return largest_payload;
+}
+
bool QuicPacketCreator::HasIetfLongHeader() const {
return framer_->transport_version() > QUIC_VERSION_43 &&
packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;