Apply GREASE to QUIC Version Negotiation packets
This prevents client implementations from breaking when they observe unknown versions.
This also ensures that the produced packet will always be long enough to allow QUIC proxy munging.
gfe-relnote: minor change to packet format of Version Negotiation packets, protected by --gfe2_reloadable_flag_quic_disable_version_negotiation_grease_randomness
PiperOrigin-RevId: 255015606
Change-Id: I8070d543a765e914a2cdc07fd941fa5e1b359c14
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 7e828a7..afaae66 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quic/core/quic_tag.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
@@ -25,6 +26,22 @@
return MakeQuicTag(d, c, b, a);
}
+QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
+ if (!GetQuicReloadableFlag(quic_version_negotiation_grease)) {
+ return MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a);
+ }
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_version_negotiation_grease, 2, 2);
+ QuicVersionLabel result;
+ if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
+ QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+ } else {
+ result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
+ }
+ result &= 0xf0f0f0f0;
+ result |= 0x0a0a0a0a;
+ return result;
+}
+
} // namespace
ParsedQuicVersion::ParsedQuicVersion(HandshakeProtocol handshake_protocol,
@@ -112,7 +129,7 @@
}
return MakeVersionLabel(proto, '0', '9', '9');
case QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
- return MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a);
+ return CreateRandomVersionLabelForNegotiation();
default:
// This is a bug because we should never attempt to convert an invalid
// QuicTransportVersion to be written to the wire.