summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-12 15:59:20 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-25 06:57:22 +0000
commitf7eaed5286974984ba5f9e3189d8f49d03e99f81 (patch)
treecaed19b2af2024f35449fb0b781d0a25e09d4f8f /chromium/net/third_party/quiche/src/quic
parent9729c4479fe23554eae6e6dd1f30ff488f470c84 (diff)
downloadqtwebengine-chromium-f7eaed5286974984ba5f9e3189d8f49d03e99f81.tar.gz
BASELINE: Update Chromium to 100.0.4896.167
Change-Id: I98cbeb5d7543d966ffe04d8cefded0c493a11333 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic')
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc280
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h46
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc116
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc92
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h40
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc110
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc100
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h9
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc160
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc81
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.cc74
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.h11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc447
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.cc575
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.h59
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc800
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc225
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_types.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc22
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.cc104
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.h59
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc176
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc26
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc64
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h30
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc14
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h9
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h6
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc47
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h6
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h8
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc13
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc158
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc39
135 files changed, 3124 insertions, 2083 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc
index fbf1343f58b..c634db5d4a3 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -29,15 +29,14 @@
#include "quic/test_tools/simulator/simulator.h"
#include "quic/test_tools/simulator/switch.h"
#include "quic/test_tools/simulator/traffic_policer.h"
+#include "common/platform/api/quiche_command_line_flags.h"
using testing::AllOf;
using testing::Ge;
using testing::Le;
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_bbr2_test_regression_mode,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_bbr2_test_regression_mode, "",
"One of a) 'record' to record test result (one file per test), or "
"b) 'regress' to regress against recorded results, or "
"c) <anything else> for non-regression mode.");
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc
index 8973f94728a..caba9b1c7f4 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc
@@ -28,15 +28,14 @@
#include "quic/test_tools/simulator/quic_endpoint.h"
#include "quic/test_tools/simulator/simulator.h"
#include "quic/test_tools/simulator/switch.h"
+#include "common/platform/api/quiche_command_line_flags.h"
using testing::AllOf;
using testing::Ge;
using testing::Le;
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_bbr_test_regression_mode,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_bbr_test_regression_mode, "",
"One of a) 'record' to record test result (one file per test), or "
"b) 'regress' to regress against recorded results, or "
"c) <anything else> for non-regression mode.");
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h
index d473a38cd91..b2401a2b6c7 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h
@@ -79,6 +79,8 @@ class QUIC_EXPORT_PRIVATE PacingSender {
return {ideal_next_packet_send_time_, allow_burst};
}
+ uint32_t initial_burst_size() const { return initial_burst_size_; }
+
protected:
uint32_t lumpy_tokens() const { return lumpy_tokens_; }
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h
index 2fa1217a9ea..42716033c6d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h
@@ -33,27 +33,28 @@ class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
public:
// Network Params for AdjustNetworkParameters.
struct QUIC_NO_EXPORT NetworkParams {
- NetworkParams()
- : NetworkParams(QuicBandwidth::Zero(), QuicTime::Delta::Zero(), false) {
- }
+ NetworkParams() = default;
NetworkParams(const QuicBandwidth& bandwidth,
const QuicTime::Delta& rtt,
bool allow_cwnd_to_decrease)
: bandwidth(bandwidth),
rtt(rtt),
allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
+ explicit NetworkParams(int burst_token) : burst_token(burst_token) {}
bool operator==(const NetworkParams& other) const {
return bandwidth == other.bandwidth && rtt == other.rtt &&
max_initial_congestion_window ==
other.max_initial_congestion_window &&
+ burst_token == other.burst_token &&
allow_cwnd_to_decrease == other.allow_cwnd_to_decrease;
}
- QuicBandwidth bandwidth;
- QuicTime::Delta rtt;
+ QuicBandwidth bandwidth = QuicBandwidth::Zero();
+ QuicTime::Delta rtt = QuicTime::Delta::Zero();
int max_initial_congestion_window = 0;
- bool allow_cwnd_to_decrease;
+ int burst_token = 0;
+ bool allow_cwnd_to_decrease = false;
};
static SendAlgorithmInterface* Create(
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index cf2a532e463..be4d2b2ad8d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -96,8 +96,7 @@ class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
QuicTime::Delta rtt);
void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
void ExitSlowstart();
- void OnPacketLost(QuicPacketNumber largest_loss,
- QuicByteCount lost_bytes,
+ void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes,
QuicByteCount prior_in_flight);
void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
QuicByteCount acked_bytes,
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h
index 2927b891f98..d623fa25af5 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h
@@ -23,6 +23,12 @@ inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) {
return result;
}
+inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb,
+ absl::string_view piece) {
+ return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()),
+ piece.size());
+}
+
} // namespace quic
#endif // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc
new file mode 100644
index 00000000000..550adffa582
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc
@@ -0,0 +1,280 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quic/core/crypto/certificate_util.h"
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/boringssl/src/include/openssl/pkcs7.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/stack.h"
+#include "quic/core/crypto/boring_utils.h"
+#include "quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+bool AddEcdsa256SignatureAlgorithm(CBB* cbb) {
+ // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2.
+ static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
+ 0x3d, 0x04, 0x03, 0x02};
+
+ // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
+ CBB sequence, oid;
+ if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
+ return false;
+ }
+
+ if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) {
+ return false;
+ }
+
+ // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field.
+ return CBB_flush(cbb);
+}
+
+// Adds an X.509 Name with the specified distinguished name to |cbb|.
+bool AddName(CBB* cbb, absl::string_view name) {
+ // See RFC 4519.
+ static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
+ static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
+ static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
+ static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
+
+ std::vector<std::string> attributes =
+ absl::StrSplit(name, ',', absl::SkipEmpty());
+
+ if (attributes.empty()) {
+ QUIC_LOG(ERROR) << "Missing DN or wrong format";
+ return false;
+ }
+
+ // See RFC 5280, section 4.1.2.4.
+ CBB rdns;
+ if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
+ return false;
+ }
+
+ for (const std::string& attribute : attributes) {
+ std::vector<std::string> parts =
+ absl::StrSplit(absl::StripAsciiWhitespace(attribute), '=');
+ if (parts.size() != 2) {
+ QUIC_LOG(ERROR) << "Wrong DN format at " + attribute;
+ return false;
+ }
+
+ const std::string& type_string = parts[0];
+ const std::string& value_string = parts[1];
+ absl::Span<const uint8_t> type_bytes;
+ if (type_string == "CN") {
+ type_bytes = kCommonName;
+ } else if (type_string == "C") {
+ type_bytes = kCountryName;
+ } else if (type_string == "O") {
+ type_bytes = kOrganizationName;
+ } else if (type_string == "OU") {
+ type_bytes = kOrganizationalUnitName;
+ } else {
+ QUIC_LOG(ERROR) << "Unrecognized type " + type_string;
+ return false;
+ }
+
+ CBB rdn, attr, type, value;
+ if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
+ !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
+ !CBB_add_asn1(&attr, &value,
+ type_string == "C" ? CBS_ASN1_PRINTABLESTRING
+ : CBS_ASN1_UTF8STRING) ||
+ !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) {
+ return false;
+ }
+ }
+ if (!CBB_flush(cbb)) {
+ return false;
+ }
+ return true;
+}
+
+bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) {
+ CBB child;
+ std::string formatted_time;
+
+ // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
+ // UTCTime rather than GeneralizedTime.
+ const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050);
+ if (is_utc_time) {
+ uint16_t year = timestamp.year - 1900;
+ if (year >= 100) {
+ year -= 100;
+ }
+ formatted_time = absl::StrFormat("%02d", year);
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) {
+ return false;
+ }
+ } else {
+ formatted_time = absl::StrFormat("%04d", timestamp.year);
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) {
+ return false;
+ }
+ }
+
+ absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ",
+ timestamp.month, timestamp.day, timestamp.hour,
+ timestamp.minute, timestamp.second);
+
+ static const size_t kGeneralizedTimeLength = 15;
+ static const size_t kUTCTimeLength = 13;
+ QUICHE_DCHECK_EQ(formatted_time.size(),
+ is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength);
+
+ return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb);
+}
+
+bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid,
+ bool critical, absl::Span<const uint8_t> contents) {
+ CBB extension, cbb_oid, cbb_contents;
+ if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) ||
+ (critical && !CBB_add_asn1_bool(&extension, 1)) ||
+ !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) ||
+ !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) ||
+ !CBB_flush(extensions)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool IsEcdsa256Key(const EVP_PKEY& evp_key) {
+ if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) {
+ return false;
+ }
+ const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key);
+ if (key == nullptr) {
+ return false;
+ }
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ if (group == nullptr) {
+ return false;
+ }
+ return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1;
+}
+
+} // namespace
+
+bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() {
+ bssl::UniquePtr<EVP_PKEY_CTX> context(
+ EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
+ if (!context) {
+ return nullptr;
+ }
+ if (EVP_PKEY_keygen_init(context.get()) != 1) {
+ return nullptr;
+ }
+ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(),
+ NID_X9_62_prime256v1) != 1) {
+ return nullptr;
+ }
+ EVP_PKEY* raw_key = nullptr;
+ if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) {
+ return nullptr;
+ }
+ return bssl::UniquePtr<EVP_PKEY>(raw_key);
+}
+
+std::string CreateSelfSignedCertificate(EVP_PKEY& key,
+ const CertificateOptions& options) {
+ std::string error;
+ if (!IsEcdsa256Key(key)) {
+ QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys";
+ return error;
+ }
+
+ // See RFC 5280, section 4.1. First, construct the TBSCertificate.
+ bssl::ScopedCBB cbb;
+ CBB tbs_cert, version, validity;
+ uint8_t* tbs_cert_bytes;
+ size_t tbs_cert_len;
+
+ if (!CBB_init(cbb.get(), 64) ||
+ !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&tbs_cert, &version,
+ CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+ !CBB_add_asn1_uint64(&version, 2) || // X.509 version 3
+ !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) ||
+ !AddEcdsa256SignatureAlgorithm(&tbs_cert) || // signature algorithm
+ !AddName(&tbs_cert, options.subject) || // issuer
+ !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
+ !CBBAddTime(&validity, options.validity_start) ||
+ !CBBAddTime(&validity, options.validity_end) ||
+ !AddName(&tbs_cert, options.subject) || // subject
+ !EVP_marshal_public_key(&tbs_cert, &key)) { // subjectPublicKeyInfo
+ return error;
+ }
+
+ CBB outer_extensions, extensions;
+ if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
+ 3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
+ !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
+ return error;
+ }
+
+ // Key Usage
+ constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
+ constexpr uint8_t kKeyUsageContent[] = {
+ 0x3, // BIT STRING
+ 0x2, // Length
+ 0x0, // Unused bits
+ 0x80, // bit(0): digitalSignature
+ };
+ CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent);
+
+ // TODO(wub): Add more extensions here if needed.
+
+ if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
+ return error;
+ }
+
+ bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
+
+ // Sign the TBSCertificate and write the entire certificate.
+ CBB cert, signature;
+ bssl::ScopedEVP_MD_CTX ctx;
+ uint8_t* sig_out;
+ size_t sig_len;
+ uint8_t* cert_bytes;
+ size_t cert_len;
+ if (!CBB_init(cbb.get(), tbs_cert_len) ||
+ !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
+ !AddEcdsa256SignatureAlgorithm(&cert) ||
+ !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
+ !CBB_add_u8(&signature, 0 /* no unused bits */) ||
+ !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) ||
+ // Compute the maximum signature length.
+ !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
+ tbs_cert_len) ||
+ !CBB_reserve(&signature, &sig_out, sig_len) ||
+ // Actually sign the TBSCertificate.
+ !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
+ tbs_cert_len) ||
+ !CBB_did_write(&signature, sig_len) ||
+ !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
+ return error;
+ }
+ bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
+ return std::string(reinterpret_cast<char*>(cert_bytes), cert_len);
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h
new file mode 100644
index 00000000000..ebc1cf48d6e
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h
@@ -0,0 +1,46 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quic/core/quic_time.h"
+#include "quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_NO_EXPORT CertificateTimestamp {
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+};
+
+struct QUIC_NO_EXPORT CertificateOptions {
+ absl::string_view subject;
+ uint64_t serial_number;
+ CertificateTimestamp validity_start; // a.k.a not_valid_before
+ CertificateTimestamp validity_end; // a.k.a not_valid_after
+};
+
+// Creates a ECDSA P-256 key pair.
+QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY>
+MakeKeyPairForSelfSignedCertificate();
+
+// Creates a self-signed, DER-encoded X.509 certificate.
+// |key| must be a ECDSA P-256 key.
+// This is mostly stolen from Chromium's net/cert/x509_util.h, with
+// modifications to make it work in QUICHE.
+QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate(
+ EVP_PKEY& key, const CertificateOptions& options);
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc
new file mode 100644
index 00000000000..1ffe6f551ee
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc
@@ -0,0 +1,49 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quic/core/crypto/certificate_util.h"
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quic/core/crypto/certificate_view.h"
+#include "quic/platform/api/quic_test.h"
+#include "quic/platform/api/quic_test_output.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(CertificateUtilTest, CreateSelfSignedCertificate) {
+ bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate();
+ ASSERT_NE(key, nullptr);
+
+ CertificatePrivateKey cert_key(std::move(key));
+
+ CertificateOptions options;
+ options.subject = "CN=subject";
+ options.serial_number = 0x12345678;
+ options.validity_start = {2020, 1, 1, 0, 0, 0};
+ options.validity_end = {2049, 12, 31, 0, 0, 0};
+ std::string der_cert =
+ CreateSelfSignedCertificate(*cert_key.private_key(), options);
+ ASSERT_FALSE(der_cert.empty());
+
+ QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert);
+
+ std::unique_ptr<CertificateView> cert_view =
+ CertificateView::ParseSingleCertificate(der_cert);
+ ASSERT_NE(cert_view, nullptr);
+ EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256);
+
+ absl::optional<std::string> subject = cert_view->GetHumanReadableSubject();
+ ASSERT_TRUE(subject.has_value());
+ EXPECT_EQ(*subject, options.subject);
+
+ EXPECT_TRUE(
+ cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
+ EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view));
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
index f0b1c18a195..12866670783 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
@@ -49,14 +49,6 @@ constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02};
// 2.5.29.17
constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11};
-enum class PublicKeyType {
- kRsa,
- kP256,
- kP384,
- kEd25519,
- kUnknown,
-};
-
PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
switch (EVP_PKEY_id(public_key)) {
case EVP_PKEY_RSA:
@@ -176,6 +168,22 @@ absl::optional<std::string> DistinguishedNameToString(CBS input) {
} // namespace
+std::string PublicKeyTypeToString(PublicKeyType type) {
+ switch (type) {
+ case PublicKeyType::kRsa:
+ return "RSA";
+ case PublicKeyType::kP256:
+ return "ECDSA P-256";
+ case PublicKeyType::kP384:
+ return "ECDSA P-384";
+ case PublicKeyType::kEd25519:
+ return "Ed25519";
+ case PublicKeyType::kUnknown:
+ return "unknown";
+ }
+ return "";
+}
+
absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag,
absl::string_view payload) {
if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
@@ -469,11 +477,13 @@ std::vector<std::string> CertificateView::LoadPemFromStream(
}
}
+PublicKeyType CertificateView::public_key_type() const {
+ return PublicKeyTypeFromKey(public_key_.get());
+}
+
bool CertificateView::ValidatePublicKeyParameters() {
- // The profile here affects what certificates can be used:
- // (1) when QUIC is used as a server library without any custom certificate
- // provider logic,
- // (2) when QuicTransport is handling self-signed certificates.
+ // The profile here affects what certificates can be used when QUIC is used as
+ // a server library without any custom certificate provider logic.
// The goal is to allow at minimum any certificate that would be allowed on a
// regular Web session over TLS 1.3 while ensuring we do not expose any
// algorithms we don't want to support long-term.
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h
index f2826cdd668..5b3c8c762c6 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h
@@ -34,6 +34,16 @@ struct QUIC_EXPORT_PRIVATE PemReadResult {
// Reads |input| line-by-line and returns the next available PEM message.
QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
+// Cryptograhpic algorithms recognized in X.509.
+enum class PublicKeyType {
+ kRsa,
+ kP256,
+ kP384,
+ kEd25519,
+ kUnknown,
+};
+QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
+
// CertificateView represents a parsed version of a single X.509 certificate. As
// the word "view" implies, it does not take ownership of the underlying strings
// and consists primarily of pointers into the certificate that is passed into
@@ -69,6 +79,9 @@ class QUIC_EXPORT_PRIVATE CertificateView {
absl::string_view signature,
uint16_t signature_algorithm) const;
+ // Returns the type of the key used in the certificate's SPKI.
+ PublicKeyType public_key_type() const;
+
private:
CertificateView() = default;
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc
index 5d743b2114c..fbca9159c82 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc
@@ -58,6 +58,8 @@ TEST(CertificateViewTest, Parse) {
const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
*quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
EXPECT_EQ(view->validity_end(), validity_end);
+ EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa);
+ EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA");
EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1",
view->GetHumanReadableSubject());
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc
index 68e3d9cbe19..0159e3004e5 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc
@@ -13,6 +13,7 @@
#include "absl/strings/escaping.h"
#include "quic/core/crypto/crypto_framer.h"
#include "quic/core/quic_utils.h"
+#include "common/platform/api/quiche_command_line_flags.h"
using std::cerr;
using std::cout;
@@ -37,9 +38,9 @@ class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface {
int main(int argc, char* argv[]) {
const char* usage = "Usage: crypto_message_printer <hex>";
std::vector<std::string> messages =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (messages.size() != 1) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
exit(0);
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h
index 5a3003861e1..0ebe0e430b8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h
@@ -121,9 +121,9 @@ const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7'); // Reduce bw_lo by
const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8'); // Reduce bw_lo by
// bw_lo * bytes_lost/inflight
const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9'); // Reduce bw_lo by
+ // bw_lo * bytes_lost/cwnd
const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0'); // Increase bytes_acked in
// PROBE_UP when app limited.
- // bw_lo * bytes_lost/cwnd
const QuicTag kRENO = TAG('R', 'E', 'N', 'O'); // Reno Congestion Control
const QuicTag kTPCC = TAG('P', 'C', 'C', '\0'); // Performance-Oriented
// Congestion Control
@@ -434,6 +434,7 @@ const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on
// Client Hints triggers.
const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H');
+const QuicTag kACH0 = TAG('A', 'C', 'H', '0');
// Rejection tags
const QuicTag kRREJ = TAG('R', 'R', 'E', 'J'); // Reasons for server sending
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc
index 1826212d83c..a4a7a2a615d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc
@@ -44,8 +44,11 @@ size_t CryptoSecretBoxer::GetKeySize() {
// kAEAD is the AEAD used for boxing: AES-256-GCM-SIV.
static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv;
-void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
- QUICHE_DCHECK(!keys.empty());
+bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
+ if (keys.empty()) {
+ QUIC_LOG(DFATAL) << "No keys supplied!";
+ return false;
+ }
const EVP_AEAD* const aead = kAEAD();
std::unique_ptr<State> new_state(new State);
@@ -57,7 +60,7 @@ void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
if (!ctx) {
ERR_clear_error();
QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed";
- return;
+ return false;
}
new_state->ctxs.push_back(std::move(ctx));
@@ -65,6 +68,7 @@ void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
QuicWriterMutexLock l(&lock_);
state_ = std::move(new_state);
+ return true;
}
std::string CryptoSecretBoxer::Box(QuicRandom* rand,
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h
index 5dd5cb24985..e2cd0377786 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h
@@ -34,13 +34,15 @@ class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
// SetKeys sets a list of encryption keys. The first key in the list will be
// used by |Box|, but all supplied keys will be tried by |Unbox|, to handle
// key skew across the fleet. This must be called before |Box| or |Unbox|.
- // Keys must be |GetKeySize()| bytes long.
- void SetKeys(const std::vector<std::string>& keys);
+ // Keys must be |GetKeySize()| bytes long. No change is made if any key is
+ // invalid, or if there are no keys supplied.
+ bool SetKeys(const std::vector<std::string>& keys);
// Box encrypts |plaintext| using a random nonce generated from |rand| and
// returns the resulting ciphertext. Since an authenticator and nonce are
// included, the result will be slightly larger than |plaintext|. The first
- // key in the vector supplied to |SetKeys| will be used.
+ // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be
+ // called before calling this method.
std::string Box(QuicRandom* rand, absl::string_view plaintext) const;
// Unbox takes the result of a previous call to |Box| in |ciphertext| and
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc
index 225bfc8b14e..7b07d96d11d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc
@@ -56,9 +56,9 @@ TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
CryptoSecretBoxer boxer_11, boxer_12, boxer;
- boxer_11.SetKeys({key_11});
- boxer_12.SetKeys({key_12});
- boxer.SetKeys({key_12, key_11});
+ EXPECT_TRUE(boxer_11.SetKeys({key_11}));
+ EXPECT_TRUE(boxer_12.SetKeys({key_12}));
+ EXPECT_TRUE(boxer.SetKeys({key_12, key_11}));
// Neither single-key boxer can decode the other's tokens.
EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
@@ -74,7 +74,7 @@ TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
// After we flush key_11 from |boxer|, it can no longer decode tokens from
// |boxer_11|.
- boxer.SetKeys({key_12});
+ EXPECT_TRUE(boxer.SetKeys({key_12}));
EXPECT_FALSE(CanDecode(boxer, boxer_11));
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc
index 50bbfefa4dc..05bbdfe6321 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc
@@ -57,8 +57,7 @@ namespace {
// |out_len|, respectively. The resulting expanded secret is returned.
std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
const std::vector<uint8_t>& secret,
- const std::string& label,
- size_t out_len) {
+ const std::string& label, size_t out_len) {
bssl::ScopedCBB quic_hkdf_label;
CBB inner_label;
const char label_prefix[] = "tls13 ";
@@ -91,13 +90,23 @@ std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
} // namespace
+const std::string getLabelForVersion(const ParsedQuicVersion& version,
+ const absl::string_view& predicate) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync with HKDF labels");
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ return absl::StrCat("quicv2 ", predicate);
+ } else {
+ return absl::StrCat("quic ", predicate);
+ }
+}
+
void CryptoUtils::InitializeCrypterSecrets(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- QuicCrypter* crypter) {
- SetKeyAndIV(prf, pp_secret, crypter);
- std::vector<uint8_t> header_protection_key =
- GenerateHeaderProtectionKey(prf, pp_secret, crypter->GetKeySize());
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, QuicCrypter* crypter) {
+ SetKeyAndIV(prf, pp_secret, version, crypter);
+ std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
+ prf, pp_secret, version, crypter->GetKeySize());
crypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -105,11 +114,13 @@ void CryptoUtils::InitializeCrypterSecrets(
void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter) {
std::vector<uint8_t> key =
- HkdfExpandLabel(prf, pp_secret, "quic key", crypter->GetKeySize());
- std::vector<uint8_t> iv =
- HkdfExpandLabel(prf, pp_secret, "quic iv", crypter->GetIVSize());
+ HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
+ crypter->GetKeySize());
+ std::vector<uint8_t> iv = HkdfExpandLabel(
+ prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
crypter->SetKey(
absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
crypter->SetIV(
@@ -117,16 +128,17 @@ void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
}
std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- size_t out_len) {
- return HkdfExpandLabel(prf, pp_secret, "quic hp", out_len);
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, size_t out_len) {
+ return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
+ out_len);
}
std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
- const EVP_MD* prf,
+ const EVP_MD* prf, const ParsedQuicVersion& version,
const std::vector<uint8_t>& current_secret) {
- return HkdfExpandLabel(prf, current_secret, "quic ku", current_secret.size());
+ return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
+ current_secret.size());
}
namespace {
@@ -138,6 +150,9 @@ const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
+const uint8_t kV2Draft01InitialSalt[] = {
+ 0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
+ 0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
// Salts used by deployed versions of QUIC. When introducing a new version,
// generate a new salt by running `openssl rand -hex 20`.
@@ -154,9 +169,12 @@ const uint8_t kReservedForNegotiationSalt[] = {
const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
size_t* out_len) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync with initial encryption salts");
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
+ return kV2Draft01InitialSalt;
+ } else if (version == ParsedQuicVersion::RFCv1()) {
*out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
return kRFCv1InitialSalt;
} else if (version == ParsedQuicVersion::Draft29()) {
@@ -191,6 +209,11 @@ const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66,
0xe3, 0x68, 0xc8, 0x4e};
const uint8_t kRFCv1RetryIntegrityNonce[] = {
0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
+const uint8_t kV2Draft01RetryIntegrityKey[] = {
+ 0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
+ 0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
+const uint8_t kV2Draft01RetryIntegrityNonce[] = {
+ 0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
@@ -204,13 +227,21 @@ const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = {
bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
absl::string_view* key,
absl::string_view* nonce) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync with retry integrity keys");
if (!version.UsesTls()) {
QUIC_BUG(quic_bug_10699_2)
<< "Attempted to get retry integrity keys for invalid version "
<< version;
return false;
+ } else if (version == ParsedQuicVersion::V2Draft01()) {
+ *key = absl::string_view(
+ reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
+ ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
+ *nonce = absl::string_view(
+ reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
+ ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
+ return true;
} else if (version == ParsedQuicVersion::RFCv1()) {
*key = absl::string_view(
reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
@@ -291,20 +322,20 @@ void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
hash, handshake_secret, encryption_label, EVP_MD_size(hash));
crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
- InitializeCrypterSecrets(hash, encryption_secret, crypters->encrypter.get());
+ InitializeCrypterSecrets(hash, encryption_secret, version,
+ crypters->encrypter.get());
std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
hash, handshake_secret, decryption_label, EVP_MD_size(hash));
crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
- InitializeCrypterSecrets(hash, decryption_secret, crypters->decrypter.get());
+ InitializeCrypterSecrets(hash, decryption_secret, version,
+ crypters->decrypter.get());
}
// static
bool CryptoUtils::ValidateRetryIntegrityTag(
- ParsedQuicVersion version,
- QuicConnectionId original_connection_id,
- absl::string_view retry_without_tag,
- absl::string_view integrity_tag) {
+ ParsedQuicVersion version, QuicConnectionId original_connection_id,
+ absl::string_view retry_without_tag, absl::string_view integrity_tag) {
unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
QUIC_BUG(quic_bug_10699_4)
@@ -348,10 +379,8 @@ bool CryptoUtils::ValidateRetryIntegrityTag(
}
// static
-void CryptoUtils::GenerateNonce(QuicWallTime now,
- QuicRandom* random_generator,
- absl::string_view orbit,
- std::string* nonce) {
+void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+ absl::string_view orbit, std::string* nonce) {
// a 4-byte timestamp + 28 random bytes.
nonce->reserve(kNonceSize);
nonce->resize(kNonceSize);
@@ -375,17 +404,13 @@ void CryptoUtils::GenerateNonce(QuicWallTime now,
}
// static
-bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version,
- absl::string_view premaster_secret,
- QuicTag aead,
- absl::string_view client_nonce,
- absl::string_view server_nonce,
- absl::string_view pre_shared_key,
- const std::string& hkdf_input,
- Perspective perspective,
- Diversification diversification,
- CrypterPair* crypters,
- std::string* subkey_secret) {
+bool CryptoUtils::DeriveKeys(
+ const ParsedQuicVersion& version, absl::string_view premaster_secret,
+ QuicTag aead, absl::string_view client_nonce,
+ absl::string_view server_nonce, absl::string_view pre_shared_key,
+ const std::string& hkdf_input, Perspective perspective,
+ Diversification diversification, CrypterPair* crypters,
+ std::string* subkey_secret) {
// If the connection is using PSK, concatenate it with the pre-master secret.
std::unique_ptr<char[]> psk_premaster_secret;
if (!pre_shared_key.empty()) {
@@ -573,8 +598,7 @@ QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
}
QuicErrorCode CryptoUtils::ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- ParsedQuicVersion version,
+ const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) {
if (client_hello.tag() != kCHLO) {
@@ -597,8 +621,7 @@ QuicErrorCode CryptoUtils::ValidateClientHello(
}
QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
- QuicVersionLabel client_version,
- ParsedQuicVersion connection_version,
+ QuicVersionLabel client_version, ParsedQuicVersion connection_version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) {
if (client_version != CreateQuicVersionLabel(connection_version)) {
@@ -736,8 +759,7 @@ std::string CryptoUtils::EarlyDataReasonToString(
// static
std::string CryptoUtils::HashHandshakeMessage(
- const CryptoHandshakeMessage& message,
- Perspective /*perspective*/) {
+ const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
std::string output;
const QuicData& serialized = message.GetSerialized();
uint8_t digest[SHA256_DIGEST_LENGTH];
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h
index 8884f6fa096..fce62018823 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h
@@ -79,9 +79,11 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// on the given QuicCrypter |*crypter|.
// This follows the derivation described in section 7.3 of RFC 8446, except
// with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
- // as described in draft-ietf-quic-tls-14, section 5.1.
+ // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
+ // described in draft-ietf-quic-v2-01.
static void InitializeCrypterSecrets(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter);
// Derives the key and IV from the packet protection secret and sets those
@@ -90,17 +92,17 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// called before using |crypter|.
static void SetKeyAndIV(const EVP_MD* prf,
const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version,
QuicCrypter* crypter);
// Derives the header protection key from the packet protection secret.
static std::vector<uint8_t> GenerateHeaderProtectionKey(
- const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- size_t out_len);
+ const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const ParsedQuicVersion& version, size_t out_len);
// Given a secret for key phase n, return the secret for phase n+1.
static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
- const EVP_MD* prf,
+ const EVP_MD* prf, const ParsedQuicVersion& version,
const std::vector<uint8_t>& current_secret);
// IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
@@ -130,10 +132,8 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// <4 bytes> current time
// <8 bytes> |orbit| (or random if |orbit| is empty)
// <20 bytes> random
- static void GenerateNonce(QuicWallTime now,
- QuicRandom* random_generator,
- absl::string_view orbit,
- std::string* nonce);
+ static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+ absl::string_view orbit, std::string* nonce);
// DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
// |subkey_secret| (optional -- may be null) given the contents of
@@ -155,15 +155,12 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// |SetDiversificationNonce| with a diversification nonce will be needed to
// complete keying.
static bool DeriveKeys(const ParsedQuicVersion& version,
- absl::string_view premaster_secret,
- QuicTag aead,
+ absl::string_view premaster_secret, QuicTag aead,
absl::string_view client_nonce,
absl::string_view server_nonce,
absl::string_view pre_shared_key,
- const std::string& hkdf_input,
- Perspective perspective,
- Diversification diversification,
- CrypterPair* crypters,
+ const std::string& hkdf_input, Perspective perspective,
+ Diversification diversification, CrypterPair* crypters,
std::string* subkey_secret);
// Computes the FNV-1a hash of the provided DER-encoded cert for use in the
@@ -199,8 +196,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
// code and sets |error_details|.
static QuicErrorCode ValidateClientHello(
- const CryptoHandshakeMessage& client_hello,
- ParsedQuicVersion version,
+ const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details);
@@ -212,8 +208,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
// code and sets |error_details|.
static QuicErrorCode ValidateClientHelloVersion(
- QuicVersionLabel client_version,
- ParsedQuicVersion connection_version,
+ QuicVersionLabel client_version, ParsedQuicVersion connection_version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details);
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc
index 251f136ec5d..f0d944b4fea 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc
@@ -8,6 +8,7 @@
#include "absl/base/macros.h"
#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/quic_test_utils.h"
@@ -165,6 +166,97 @@ TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
EXPECT_FALSE(error_details.empty());
}
+// Test that the library is using the correct labels for each version, and
+// therefore generating correct obfuscators, using the test vectors in appendix
+// A of each RFC or internet-draft.
+TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
+ // if the number of HTTP/3 QUIC versions has changed, we need to change the
+ // expected_keys hardcoded into this test. Regrettably, this is not a
+ // compile-time constant.
+ EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
+ const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
+ 0x14,
+ static_cast<char>(0x9d),
+ 0x0b,
+ 0x16,
+ 0x62,
+ static_cast<char>(0xab),
+ static_cast<char>(0x87),
+ 0x1f,
+ static_cast<char>(0xbe),
+ 0x63,
+ static_cast<char>(0xc4),
+ static_cast<char>(0x9b),
+ 0x5e,
+ 0x65,
+ 0x5a,
+ 0x5d};
+ const char v1_key[] = {// test vector from RFC 9001, A.1
+ static_cast<char>(0xcf),
+ 0x3a,
+ 0x53,
+ 0x31,
+ 0x65,
+ 0x3c,
+ 0x36,
+ 0x4c,
+ static_cast<char>(0x88),
+ static_cast<char>(0xf0),
+ static_cast<char>(0xf3),
+ 0x79,
+ static_cast<char>(0xb6),
+ 0x06,
+ 0x7e,
+ 0x37};
+ const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
+ 0x15,
+ static_cast<char>(0xd5),
+ static_cast<char>(0xb4),
+ static_cast<char>(0xd9),
+ static_cast<char>(0xa2),
+ static_cast<char>(0xb8),
+ static_cast<char>(0x91),
+ 0x6a,
+ static_cast<char>(0xa3),
+ static_cast<char>(0x9b),
+ 0x1b,
+ static_cast<char>(0xfe),
+ 0x57,
+ 0x4d,
+ 0x2a,
+ static_cast<char>(0xad)};
+ const char connection_id[] = // test vector from both docs
+ {static_cast<char>(0x83),
+ static_cast<char>(0x94),
+ static_cast<char>(0xc8),
+ static_cast<char>(0xf0),
+ 0x3e,
+ 0x51,
+ 0x57,
+ 0x08};
+ const QuicConnectionId cid(connection_id, sizeof(connection_id));
+ const char* key_str;
+ size_t key_size;
+ for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+ if (version == ParsedQuicVersion::Draft29()) {
+ key_str = draft_29_key;
+ key_size = sizeof(draft_29_key);
+ } else if (version == ParsedQuicVersion::RFCv1()) {
+ key_str = v1_key;
+ key_size = sizeof(v1_key);
+ } else { // draft-ietf-quic-v2-01
+ key_str = v2_01_key;
+ key_size = sizeof(v2_01_key);
+ }
+ const absl::string_view expected_key{key_str, key_size};
+
+ CrypterPair crypters;
+ CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
+ &crypters);
+ EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
+ }
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc
index e4989bc302a..1b1790adc75 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc
@@ -834,9 +834,8 @@ void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) {
}
bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
- const QuicServerId& server_id,
- CachedState* server_state) {
- QUICHE_DCHECK(server_state->IsEmpty());
+ const QuicServerId& server_id, CachedState* cached) {
+ QUICHE_DCHECK(cached->IsEmpty());
size_t i = 0;
for (; i < canonical_suffixes_.size(); ++i) {
if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) {
@@ -867,7 +866,7 @@ bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
// Update canonical version to point at the "most recent" entry.
it->second = server_id;
- server_state->InitializeFrom(*canonical_state);
+ cached->InitializeFrom(*canonical_state);
return true;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h
index 13517299087..9c71acafa08 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h
@@ -332,16 +332,14 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
std::string* error_details);
- // Processes the message in |server_update|, updating the cached source
+ // Processes the message in |server_config_update|, updating the cached source
// address token, and server config.
- // If |server_update| is invalid then |error_details| will contain an error
- // message, and an error code will be returned. If all has gone well
+ // If |server_config_update| is invalid then |error_details| will contain an
+ // error message, and an error code will be returned. If all has gone well
// QUIC_NO_ERROR is returned.
QuicErrorCode ProcessServerConfigUpdate(
- const CryptoHandshakeMessage& server_update,
- QuicWallTime now,
- const QuicTransportVersion version,
- absl::string_view chlo_hash,
+ const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
+ const QuicTransportVersion version, absl::string_view chlo_hash,
CachedState* cached,
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params,
std::string* error_details);
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc
index 16a53fa920c..71c177552a0 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc
@@ -512,15 +512,17 @@ bool QuicCryptoServerConfig::SetConfigs(
void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
const std::vector<std::string>& keys) {
+ // TODO(b/208866709)
source_address_token_boxer_.SetKeys(keys);
}
-void QuicCryptoServerConfig::GetConfigIds(
- std::vector<std::string>* scids) const {
+std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const {
QuicReaderMutexLock locked(&configs_lock_);
+ std::vector<std::string> scids;
for (auto it = configs_.begin(); it != configs_.end(); ++it) {
- scids->push_back(it->first);
+ scids.push_back(it->first);
}
+ return scids;
}
void QuicCryptoServerConfig::ValidateClientHello(
@@ -538,6 +540,10 @@ void QuicCryptoServerConfig::ValidateClientHello(
client_hello, client_address.host(), now));
absl::string_view requested_scid;
+ // We ignore here the return value from GetStringPiece. If there is no SCID
+ // tag, EvaluateClientHello will discover that because GetCurrentConfigs will
+ // not have found the requested config (i.e. because none of the configs will
+ // have an empty string as its id).
client_hello.GetStringPiece(kSCID, &requested_scid);
Configs configs;
if (!GetCurrentConfigs(now, requested_scid,
@@ -1575,9 +1581,14 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
std::unique_ptr<CryptoHandshakeMessage> msg =
CryptoFramer::ParseMessage(protobuf.config());
+ if (!msg) {
+ QUIC_LOG(WARNING) << "Failed to parse server config message";
+ return nullptr;
+ }
+
if (msg->tag() != kSCFG) {
QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag()
- << " expected " << kSCFG;
+ << ", but expected " << kSCFG;
return nullptr;
}
@@ -1597,6 +1608,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
QUIC_LOG(WARNING) << "Server config message is missing SCID";
return nullptr;
}
+ QUICHE_DCHECK(!scid.empty());
config->id = std::string(scid);
if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h
index ca6dbe5e32f..799058d70ff 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h
@@ -200,7 +200,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
// p256 determines whether a P-256 public key will be included in the
// server config. Note that this breaks deterministic server-config
// generation since P-256 key generation doesn't use the QuicRandom given
- // to DefaultConfig().
+ // to GenerateConfig().
bool p256;
};
@@ -238,8 +238,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
const QuicServerConfigProtobuf& protobuf,
QuicWallTime now);
- // AddDefaultConfig calls DefaultConfig to create a config and then calls
- // AddConfig to add it. See the comment for |DefaultConfig| for details of
+ // AddDefaultConfig calls GenerateConfig to create a config and then calls
+ // AddConfig to add it. See the comment for |GenerateConfig| for details of
// the arguments.
std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig(
QuicRandom* rand,
@@ -264,7 +264,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
void SetSourceAddressTokenKeys(const std::vector<std::string>& keys);
// Get the server config ids for all known configs.
- void GetConfigIds(std::vector<std::string>* scids) const;
+ std::vector<std::string> GetConfigIds() const;
// Checks |client_hello| for gross errors and determines whether it can be
// shown to be fresh (i.e. not a replay). The result of the validation step
@@ -282,9 +282,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
// port may be used for certificate selection.
// version: protocol version used for this connection.
// clock: used to validate client nonces and ephemeral keys.
- // crypto_proof: in/out parameter to which will be written the crypto proof
- // used in reply to a proof demand. The pointed-to-object must
- // live until the callback is invoked.
+ // signed_config: in/out parameter to which will be written the crypto proof
+ // used in reply to a proof demand. The pointed-to-object must live until
+ // the callback is invoked.
// done_cb: single-use callback that accepts an opaque
// ValidatedClientHelloMsg token that holds information about
// the client hello. The callback will always be called exactly
@@ -293,10 +293,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
void ValidateClientHello(
const CryptoHandshakeMessage& client_hello,
const QuicSocketAddress& client_address,
- const QuicSocketAddress& server_address,
- QuicTransportVersion version,
+ const QuicSocketAddress& server_address, QuicTransportVersion version,
const QuicClock* clock,
- QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof,
+ QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
// ProcessClientHello processes |client_hello| and decides whether to accept
@@ -323,27 +322,22 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
// certs. Owned by QuicDispatcher.
// params: the state of the handshake. This may be updated with a server
// nonce when we send a rejection.
- // crypto_proof: output structure containing the crypto proof used in reply to
- // a proof demand.
+ // signed_config: output structure containing the crypto proof used in reply
+ // to a proof demand.
// total_framing_overhead: the total per-packet overhead for a stream frame
// chlo_packet_size: the size, in bytes, of the CHLO packet
// done_cb: the callback invoked on completion
void ProcessClientHello(
QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
validate_chlo_result,
- bool reject_only,
- QuicConnectionId connection_id,
+ bool reject_only, QuicConnectionId connection_id,
const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- ParsedQuicVersion version,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- QuicRandom* rand,
- QuicCompressedCertsCache* compressed_certs_cache,
+ const QuicSocketAddress& client_address, ParsedQuicVersion version,
+ const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
+ QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params,
- QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof,
- QuicByteCount total_framing_overhead,
- QuicByteCount chlo_packet_size,
+ QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+ QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const;
// BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc
index fa9be976f69..901ae66e3c1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc
@@ -106,8 +106,8 @@ TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
ssl(), ssl_config_.signing_algorithm_prefs->data(),
ssl_config_.signing_algorithm_prefs->size());
}
- if (ssl_config.disable_ticket_support.has_value()) {
- if (*ssl_config.disable_ticket_support) {
+ if (ssl_config_.disable_ticket_support.has_value()) {
+ if (*ssl_config_.disable_ticket_support) {
SSL_set_options(ssl(), SSL_OP_NO_TICKET);
}
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc
index 61e8f7c8720..0d828db2d2b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc
@@ -54,9 +54,9 @@ enum TransportParameters::TransportParameterId : uint64_t {
kInitialRoundTripTime = 0x3127,
kGoogleConnectionOptions = 0x3128,
- kGoogleUserAgentId = 0x3129,
+ // 0x3129 was used to convey the user agent string.
// 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
- kGoogleKeyUpdateNotYetSupported = 0x312B,
+ // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
// 0x4751 was used for non-standard Google-specific parameters encoded as a
// Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
kGoogleQuicVersion =
@@ -122,10 +122,6 @@ std::string TransportParameterIdToString(
return "initial_round_trip_time";
case TransportParameters::kGoogleConnectionOptions:
return "google_connection_options";
- case TransportParameters::kGoogleUserAgentId:
- return "user_agent_id";
- case TransportParameters::kGoogleKeyUpdateNotYetSupported:
- return "key_update_not_yet_supported";
case TransportParameters::kGoogleQuicVersion:
return "google-version";
case TransportParameters::kMinAckDelay:
@@ -164,10 +160,6 @@ bool TransportParameterIdIsKnown(
return true;
case TransportParameters::kVersionInformation:
return GetQuicReloadableFlag(quic_version_information);
- case TransportParameters::kGoogleUserAgentId:
- return !GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter);
- case TransportParameters::kGoogleKeyUpdateNotYetSupported:
- return !GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported);
}
return false;
}
@@ -447,13 +439,6 @@ std::string TransportParameters::ToString() const {
rv += QuicTagToString(connection_option);
}
}
- if (user_agent_id.has_value()) {
- rv += " " + TransportParameterIdToString(kGoogleUserAgentId) + " \"" +
- user_agent_id.value() + "\"";
- }
- if (key_update_not_yet_supported) {
- rv += " " + TransportParameterIdToString(kGoogleKeyUpdateNotYetSupported);
- }
for (const auto& kv : custom_parameters) {
absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
"=");
@@ -493,8 +478,7 @@ TransportParameters::TransportParameters()
kMinActiveConnectionIdLimitTransportParam,
kVarInt62MaxValue),
max_datagram_frame_size(kMaxDatagramFrameSize),
- initial_round_trip_time_us(kInitialRoundTripTime),
- key_update_not_yet_supported(false)
+ initial_round_trip_time_us(kInitialRoundTripTime)
// Important note: any new transport parameters must be added
// to TransportParameters::AreValid, SerializeTransportParameters and
// ParseTransportParameters, TransportParameters's custom copy constructor, the
@@ -528,8 +512,6 @@ TransportParameters::TransportParameters(const TransportParameters& other)
max_datagram_frame_size(other.max_datagram_frame_size),
initial_round_trip_time_us(other.initial_round_trip_time_us),
google_connection_options(other.google_connection_options),
- user_agent_id(other.user_agent_id),
- key_update_not_yet_supported(other.key_update_not_yet_supported),
custom_parameters(other.custom_parameters) {
if (other.preferred_address) {
preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
@@ -570,8 +552,6 @@ bool TransportParameters::operator==(const TransportParameters& rhs) const {
initial_round_trip_time_us.value() ==
rhs.initial_round_trip_time_us.value() &&
google_connection_options == rhs.google_connection_options &&
- user_agent_id == rhs.user_agent_id &&
- key_update_not_yet_supported == rhs.key_update_not_yet_supported &&
custom_parameters == rhs.custom_parameters)) {
return false;
}
@@ -646,10 +626,6 @@ bool TransportParameters::AreValid(std::string* error_details) const {
*error_details = "Server cannot send initial round trip time";
return false;
}
- if (perspective == Perspective::IS_SERVER && user_agent_id.has_value()) {
- *error_details = "Server cannot send user agent ID";
- return false;
- }
if (version_information.has_value()) {
const QuicVersionLabel& chosen_version =
version_information.value().chosen_version;
@@ -758,8 +734,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
kIntegerParameterLength + // max_datagram_frame_size
kIntegerParameterLength + // initial_round_trip_time_us
kTypeAndValueLength + // google_connection_options
- kTypeAndValueLength + // user_agent_id
- kTypeAndValueLength + // key_update_not_yet_supported
kTypeAndValueLength; // google-version
std::vector<TransportParameters::TransportParameterId> parameter_ids = {
@@ -784,8 +758,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
TransportParameters::kInitialSourceConnectionId,
TransportParameters::kRetrySourceConnectionId,
TransportParameters::kGoogleConnectionOptions,
- TransportParameters::kGoogleUserAgentId,
- TransportParameters::kGoogleKeyUpdateNotYetSupported,
TransportParameters::kGoogleQuicVersion,
TransportParameters::kVersionInformation,
};
@@ -796,10 +768,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
max_transport_param_length +=
in.google_connection_options.value().size() * sizeof(QuicTag);
}
- // user_agent_id.
- if (in.user_agent_id.has_value()) {
- max_transport_param_length += in.user_agent_id.value().length();
- }
// Google-specific version extension.
if (in.legacy_version_information.has_value()) {
max_transport_param_length +=
@@ -1124,30 +1092,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
}
}
} break;
- // Google-specific user agent identifier.
- case TransportParameters::kGoogleUserAgentId: {
- if (in.user_agent_id.has_value()) {
- if (!writer.WriteVarInt62(TransportParameters::kGoogleUserAgentId) ||
- !writer.WriteStringPieceVarInt62(in.user_agent_id.value())) {
- QUIC_BUG(Failed to write Google user agent ID)
- << "Failed to write Google user agent ID \""
- << in.user_agent_id.value() << "\" for " << in;
- return false;
- }
- }
- } break;
- // Google-specific indicator for key update not yet supported.
- case TransportParameters::kGoogleKeyUpdateNotYetSupported: {
- if (in.key_update_not_yet_supported) {
- if (!writer.WriteVarInt62(
- TransportParameters::kGoogleKeyUpdateNotYetSupported) ||
- !writer.WriteVarInt62(/* transport parameter length */ 0)) {
- QUIC_BUG(Failed to write key_update_not_yet_supported)
- << "Failed to write key_update_not_yet_supported for " << in;
- return false;
- }
- }
- } break;
// Google-specific version extension.
case TransportParameters::kGoogleQuicVersion: {
if (!in.legacy_version_information.has_value()) {
@@ -1470,54 +1414,6 @@ bool ParseTransportParameters(ParsedQuicVersion version,
out->google_connection_options.value().push_back(connection_option);
}
} break;
- case TransportParameters::kGoogleUserAgentId:
- if (GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_ignore_user_agent_transport_parameter);
- // This is a copy of the default switch statement below.
- // TODO(dschinazi) remove this case entirely when deprecating the
- // quic_ignore_user_agent_transport_parameter flag.
- if (out->custom_parameters.find(param_id) !=
- out->custom_parameters.end()) {
- *error_details = "Received a second unknown parameter" +
- TransportParameterIdToString(param_id);
- return false;
- }
- out->custom_parameters[param_id] =
- std::string(value_reader.ReadRemainingPayload());
- break;
- }
- if (out->user_agent_id.has_value()) {
- *error_details = "Received a second user_agent_id";
- return false;
- }
- out->user_agent_id = std::string(value_reader.ReadRemainingPayload());
- break;
- case TransportParameters::kGoogleKeyUpdateNotYetSupported:
- if (GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_key_update_not_yet_supported,
- 1, 2);
- QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_ignored);
- // This is a copy of the default switch statement below.
- // TODO(dschinazi) remove this case entirely when deprecating the
- // quic_ignore_key_update_not_yet_supported flag.
- if (out->custom_parameters.find(param_id) !=
- out->custom_parameters.end()) {
- *error_details = "Received a second unknown parameter" +
- TransportParameterIdToString(param_id);
- return false;
- }
- out->custom_parameters[param_id] =
- std::string(value_reader.ReadRemainingPayload());
- break;
- }
- QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_received);
- if (out->key_update_not_yet_supported) {
- *error_details = "Received a second key_update_not_yet_supported";
- return false;
- }
- out->key_update_not_yet_supported = true;
- break;
case TransportParameters::kGoogleQuicVersion: {
if (!out->legacy_version_information.has_value()) {
out->legacy_version_information =
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
index fa349359571..1b6f51684fa 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
@@ -260,13 +260,6 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
// Google-specific connection options.
absl::optional<QuicTagVector> google_connection_options;
- // Google-specific user agent identifier.
- absl::optional<std::string> user_agent_id;
-
- // Google-specific mechanism to indicate that IETF QUIC Key Update has not
- // yet been implemented. This will be removed once we implement it.
- bool key_update_not_yet_supported;
-
// Validates whether transport parameters are valid according to
// the specification. If the transport parameters are not valid, this method
// will write a human-readable error message to |error_details|.
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc
index d9b55730454..c9df18a3d8a 100644
--- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc
@@ -37,7 +37,6 @@ const uint64_t kFakeInitialRoundTripTime = 53;
const uint8_t kFakePreferredStatelessResetTokenData[16] = {
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
-const bool kFakeKeyUpdateNotYetSupported = true;
const auto kCustomParameter1 =
static_cast<TransportParameters::TransportParameterId>(0xffcd);
@@ -128,10 +127,6 @@ QuicTagVector CreateFakeGoogleConnectionOptions() {
MakeQuicTag('H', 'I', 'J', 0xff)};
}
-std::string CreateFakeUserAgentId() {
- return "FakeUAID";
-}
-
void RemoveGreaseParameters(TransportParameters* params) {
std::vector<TransportParameters::TransportParameterId> grease_params;
for (const auto& kv : params->custom_parameters) {
@@ -291,8 +286,6 @@ TEST_P(TransportParametersTest, CopyConstructor) {
orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- orig_params.user_agent_id = CreateFakeUserAgentId();
- orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
@@ -329,12 +322,6 @@ TEST_P(TransportParametersTest, RoundTripClient) {
CreateFakeInitialSourceConnectionId();
orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) {
- orig_params.user_agent_id = CreateFakeUserAgentId();
- }
- if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
- orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
- }
orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
@@ -578,13 +565,6 @@ TEST_P(TransportParametersTest, ParseClientParams) {
'A', 'L', 'P', 'N', // value
'E', 'F', 'G', 0x00,
'H', 'I', 'J', 0xff,
- // user_agent_id
- 0x71, 0x29, // parameter id
- 0x08, // length
- 'F', 'a', 'k', 'e', 'U', 'A', 'I', 'D', // value
- // key_update_not_yet_supported
- 0x71, 0x2B, // parameter id
- 0x00, // length
// Google version extension
0x80, 0x00, 0x47, 0x52, // parameter id
0x04, // length
@@ -649,15 +629,6 @@ TEST_P(TransportParametersTest, ParseClientParams) {
ASSERT_TRUE(new_params.google_connection_options.has_value());
EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
new_params.google_connection_options.value());
- if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) {
- ASSERT_TRUE(new_params.user_agent_id.has_value());
- EXPECT_EQ(CreateFakeUserAgentId(), new_params.user_agent_id.value());
- } else {
- EXPECT_FALSE(new_params.user_agent_id.has_value());
- }
- if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
- EXPECT_TRUE(new_params.key_update_not_yet_supported);
- }
}
TEST_P(TransportParametersTest,
@@ -844,9 +815,6 @@ TEST_P(TransportParametersTest, ParseServerParams) {
'A', 'L', 'P', 'N', // value
'E', 'F', 'G', 0x00,
'H', 'I', 'J', 0xff,
- // key_update_not_yet_supported
- 0x71, 0x2B, // parameter id
- 0x00, // length
// Google version extension
0x80, 0x00, 0x47, 0x52, // parameter id
0x0d, // length
@@ -933,10 +901,6 @@ TEST_P(TransportParametersTest, ParseServerParams) {
ASSERT_TRUE(new_params.google_connection_options.has_value());
EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
new_params.google_connection_options.value());
- EXPECT_FALSE(new_params.user_agent_id.has_value());
- if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
- EXPECT_TRUE(new_params.key_update_not_yet_supported);
- }
}
TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
@@ -1054,8 +1018,6 @@ TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
CreateFakeInitialSourceConnectionId();
orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
- orig_params.user_agent_id = CreateFakeUserAgentId();
- orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported;
orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h
index 8a5c7e6e12e..c9c46d41d3c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h
+++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h
@@ -111,6 +111,8 @@ struct QUIC_EXPORT_PRIVATE QuicAckFrame {
QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
// Vector of <packet_number, time> for when packets arrived.
+ // For IETF versions, packet numbers and timestamps in this vector are both in
+ // ascending orders. Packets received out of order are not saved here.
PacketTimeVector received_packet_times;
// Set of packets.
diff --git a/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h b/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h
index 1e47d16a5f1..7fbc5ae33db 100644
--- a/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h
+++ b/chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h
@@ -7,6 +7,7 @@
#include "quic/core/crypto/transport_parameters.h"
#include "quic/core/quic_types.h"
+#include "quic/core/quic_versions.h"
namespace quic {
@@ -21,15 +22,12 @@ class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
// Called when new decryption key of |level| is available. Returns true if
// decrypter is set successfully, otherwise, returns false.
virtual bool OnNewDecryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
- bool set_alternative_decrypter,
- bool latch_once_used) = 0;
+ EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+ bool set_alternative_decrypter, bool latch_once_used) = 0;
// Called when new encryption key of |level| is available.
virtual void OnNewEncryptionKeyAvailable(
- EncryptionLevel level,
- std::unique_ptr<QuicEncrypter> encrypter) = 0;
+ EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
// Called to set default encryption level to |level|. Only used in QUIC
// crypto.
@@ -68,8 +66,7 @@ class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
// On failure, returns a QuicErrorCode and saves a detailed error in
// |error_details|.
virtual QuicErrorCode ProcessTransportParameters(
- const TransportParameters& params,
- bool is_resumption,
+ const TransportParameters& params, bool is_resumption,
std::string* error_details) = 0;
// Called at the end of an handshake operation callback.
@@ -77,6 +74,10 @@ class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
// Whether a packet flusher is currently attached.
virtual bool PacketFlusherAttached() const = 0;
+
+ // Get the QUIC version currently in use. tls_handshaker needs this to pass
+ // to crypto_utils to apply version-dependent HKDF labels.
+ virtual ParsedQuicVersion parsed_version() const = 0;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
index 29e6377280b..cad9cacb022 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc
@@ -485,8 +485,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
}
- void AddToCache(absl::string_view path,
- int response_code,
+ void AddToCache(absl::string_view path, int response_code,
absl::string_view body) {
memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
response_code, body);
@@ -553,12 +552,6 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
EXPECT_EQ(0u, server_stats.packets_lost);
}
EXPECT_EQ(0u, server_stats.packets_discarded);
- if (!GetQuicReloadableFlag(
- quic_ignore_user_agent_transport_parameter)) {
- EXPECT_EQ(
- server_session->user_agent_id().value_or("MissingUserAgent"),
- kTestUserAgentId);
- }
} else {
ADD_FAILURE() << "Missing server connection";
}
@@ -657,16 +650,14 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
bool SendSynchronousRequestAndCheckResponse(
- QuicTestClient* client,
- const std::string& request,
+ QuicTestClient* client, const std::string& request,
const std::string& expected_response) {
std::string received_response = client->SendSynchronousRequest(request);
return CheckResponse(client, received_response, expected_response);
}
bool SendSynchronousRequestAndCheckResponse(
- const std::string& request,
- const std::string& expected_response) {
+ const std::string& request, const std::string& expected_response) {
return SendSynchronousRequestAndCheckResponse(client_.get(), request,
expected_response);
}
@@ -844,8 +835,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
};
// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(EndToEndTests,
- EndToEndTest,
+INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
::testing::ValuesIn(GetTestParams()),
::testing::PrintToStringParamName());
@@ -3210,8 +3200,7 @@ TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
class DuplicatePacketWithSpoofedSelfAddressWriter
: public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -3246,7 +3235,8 @@ TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
GetClientConnection()));
- QuicIpAddress real_host = TestLoopback(1);
+ QuicIpAddress real_host =
+ client_->client()->session()->connection()->self_address().host();
ASSERT_TRUE(client_->MigrateSocket(real_host));
SendSynchronousFooRequestAndCheckResponse();
EXPECT_EQ(
@@ -4384,13 +4374,10 @@ TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
public:
ServerStreamWithErrorResponseBody(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend,
std::string response_body)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
response_body_(std::move(response_body)) {}
@@ -4419,8 +4406,7 @@ class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
~StreamWithErrorFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamWithErrorResponseBody(
id, session, quic_simple_server_backend, response_body_);
@@ -4433,12 +4419,9 @@ class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
// A test server stream that drops all received body.
class ServerStreamThatDropsBody : public QuicSimpleServerStream {
public:
- ServerStreamThatDropsBody(QuicStreamId id,
- QuicSpdySession* session,
+ ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend) {}
~ServerStreamThatDropsBody() override = default;
@@ -4480,8 +4463,7 @@ class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
~ServerStreamThatDropsBodyFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatDropsBody(id, session,
quic_simple_server_backend);
@@ -4492,13 +4474,9 @@ class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
public:
ServerStreamThatSendsHugeResponse(
- QuicStreamId id,
- QuicSpdySession* session,
- QuicSimpleServerBackend* quic_simple_server_backend,
- int64_t body_bytes)
- : QuicSimpleServerStream(id,
- session,
- BIDIRECTIONAL,
+ QuicStreamId id, QuicSpdySession* session,
+ QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
+ : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
quic_simple_server_backend),
body_bytes_(body_bytes) {}
@@ -4528,8 +4506,7 @@ class ServerStreamThatSendsHugeResponseFactory
~ServerStreamThatSendsHugeResponseFactory() override = default;
QuicSimpleServerStream* CreateStream(
- QuicStreamId id,
- QuicSpdySession* session,
+ QuicStreamId id, QuicSpdySession* session,
QuicSimpleServerBackend* quic_simple_server_backend) override {
return new ServerStreamThatSendsHugeResponse(
id, session, quic_simple_server_backend, body_bytes_);
@@ -5254,8 +5231,7 @@ TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
// called.
class PacketHoldingWriter : public QuicPacketWriterWrapper {
public:
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
@@ -5533,11 +5509,13 @@ TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
}
TEST_P(EndToEndPacketReorderingTest,
- MigrateAgainAfterPathValidationFailureWithNonZeroClientConnectionId) {
+ MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
if (!version_.SupportsClientConnectionIds()) {
ASSERT_TRUE(Initialize());
return;
}
+ SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
+ true);
override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
ASSERT_TRUE(Initialize());
if (!GetClientConnection()->connection_migration_use_new_cid()) {
@@ -5707,8 +5685,7 @@ class BadShloPacketWriter : public QuicPacketWriterWrapper {
: error_returned_(false), version_(version) {}
~BadShloPacketWriter() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
@@ -5725,6 +5702,9 @@ class BadShloPacketWriter : public QuicPacketWriterWrapper {
}
bool TypeByteIsServerHello(uint8_t type_byte) {
+ if (version_.UsesV2PacketTypes()) {
+ return ((type_byte & 0x30) >> 4) == 3;
+ }
if (version_.UsesQuicCrypto()) {
// ENCRYPTION_ZERO_RTT packet.
return ((type_byte & 0x30) >> 4) == 1;
@@ -5781,21 +5761,23 @@ TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
public:
- BadShloPacketWriter2() : error_returned_(false) {}
+ BadShloPacketWriter2(ParsedQuicVersion version)
+ : error_returned_(false), version_(version) {}
~BadShloPacketWriter2() override {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override {
const uint8_t type_byte = buffer[0];
- if ((type_byte & FLAGS_LONG_HEADER) &&
- (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
- QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
- return WriteResult(WRITE_STATUS_OK, buf_len);
- }
- if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
+
+ if (type_byte & FLAGS_LONG_HEADER) {
+ if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
+ ((type_byte & 0x7F) == 0x7C)) {
+ QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+ return WriteResult(WRITE_STATUS_OK, buf_len);
+ }
+ } else if (!error_returned_) {
QUIC_DVLOG(1) << "Return write error for short header packet";
error_returned_ = true;
return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
@@ -5806,6 +5788,7 @@ class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
private:
bool error_returned_;
+ ParsedQuicVersion version_;
};
TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
@@ -5836,7 +5819,7 @@ TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
dispatcher,
// This causes the all server sent ZERO_RTT_PROTECTED packets to be
// dropped, and first short header packet causes write error.
- new BadShloPacketWriter2());
+ new BadShloPacketWriter2(version_));
server_thread_->Resume();
client_.reset(CreateQuicClient(client_writer_));
EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
@@ -5913,10 +5896,6 @@ TEST_P(EndToEndTest, CustomTransportParameters) {
QuicConfig* server_config = nullptr;
if (server_session != nullptr) {
server_config = server_session->config();
- if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) {
- EXPECT_EQ(server_session->user_agent_id().value_or("MissingUserAgent"),
- kTestUserAgentId);
- }
} else {
ADD_FAILURE() << "Missing server session";
}
@@ -6025,8 +6004,7 @@ class CopyingPacketWriter : public PacketDroppingTestWriter {
public:
explicit CopyingPacketWriter(int num_packets_to_copy)
: num_packets_to_copy_(num_packets_to_copy) {}
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
+ WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
PerPacketOptions* options) override {
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
index 42fef63c978..3a44f79a1d1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream_test.cc
@@ -50,7 +50,6 @@ using spdy::SpdyGoAwayIR;
using spdy::SpdyHeaderBlock;
using spdy::SpdyHeadersHandlerInterface;
using spdy::SpdyHeadersIR;
-using spdy::SpdyKnownSettingsId;
using spdy::SpdyPingId;
using spdy::SpdyPingIR;
using spdy::SpdyPriority;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
index 30c4178feca..2d144d2465c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc
@@ -45,7 +45,6 @@ using testing::_;
using testing::StrictMock;
using testing::AtLeast;
-using testing::Return;
namespace quic {
namespace test {
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
index 5a859271e6e..cfc47296417 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc
@@ -43,7 +43,6 @@ using spdy::SpdyFrameType;
using spdy::SpdyHeaderBlock;
using spdy::SpdyHeadersHandlerInterface;
using spdy::SpdyHeadersIR;
-using spdy::SpdyKnownSettingsId;
using spdy::SpdyPingId;
using spdy::SpdyPriority;
using spdy::SpdyPriorityIR;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
index 5db1aab4e91..45506211f9d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc
@@ -153,7 +153,6 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
}
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return false; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
index 8147ce00dcc..5317137d7e0 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc
@@ -185,6 +185,8 @@ QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
headers_payload_length_(0),
trailers_decompressed_(false),
trailers_consumed_(false),
+ qpack_decoded_headers_accumulator_reset_reason_(
+ QpackDecodedHeadersAccumulatorResetReason::kUnSet),
http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
decoder_(http_decoder_visitor_.get(),
HttpDecoderOptionsForBidiStream(spdy_session)),
@@ -225,6 +227,8 @@ QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
headers_payload_length_(0),
trailers_decompressed_(false),
trailers_consumed_(false),
+ qpack_decoded_headers_accumulator_reset_reason_(
+ QpackDecodedHeadersAccumulatorResetReason::kUnSet),
http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
decoder_(http_decoder_visitor_.get()),
sequencer_offset_(sequencer()->NumBytesConsumed()),
@@ -563,6 +567,8 @@ void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
bool header_list_size_limit_exceeded) {
header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
QuicSpdySession::LogHeaderCompressionRatioHistogram(
/* using_qpack = */ true,
@@ -592,6 +598,8 @@ void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
absl::string_view error_message) {
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
std::string connection_close_error_message = absl::StrCat(
"Error decoding ", headers_decompressed_ ? "trailers" : "headers",
@@ -756,6 +764,8 @@ void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
}
}
@@ -769,6 +779,8 @@ void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
if (!fin_received() && spdy_session_->qpack_decoder()) {
spdy_session_->qpack_decoder()->OnStreamReset(id());
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
}
QuicStream::OnStreamReset(frame);
@@ -791,6 +803,8 @@ void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
}
}
@@ -893,6 +907,8 @@ void QuicSpdyStream::OnClose() {
QuicStream::OnClose();
qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
if (visitor_) {
Visitor* visitor = visitor_;
@@ -1088,7 +1104,14 @@ bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(qpack_decoded_headers_accumulator_);
+
+ if (!qpack_decoded_headers_accumulator_) {
+ QUIC_BUG(b215142466_OnHeadersFramePayload)
+ << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+ OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+ "qpack_decoded_headers_accumulator_ is nullptr");
+ return false;
+ }
qpack_decoded_headers_accumulator_->Decode(payload);
@@ -1103,7 +1126,14 @@ bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
bool QuicSpdyStream::OnHeadersFrameEnd() {
QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK(qpack_decoded_headers_accumulator_);
+
+ if (!qpack_decoded_headers_accumulator_) {
+ QUIC_BUG(b215142466_OnHeadersFrameEnd)
+ << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+ OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+ "qpack_decoded_headers_accumulator_ is nullptr");
+ return false;
+ }
qpack_decoded_headers_accumulator_->EndHeaderBlock();
@@ -1244,9 +1274,7 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
std::string protocol;
absl::optional<QuicDatagramStreamId> flow_id;
bool version_indicated = false;
- for (const auto& header : header_list_) {
- const std::string& header_name = header.first;
- const std::string& header_value = header.second;
+ for (const auto& [header_name, header_value] : header_list_) {
if (header_name == ":method") {
if (!method.empty() || header_value.empty()) {
return;
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
index 8ec56d58f06..14ac2f2f585 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h
@@ -391,6 +391,20 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
WebTransportStreamAdapter adapter;
};
+ // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
+ enum class QpackDecodedHeadersAccumulatorResetReason {
+ // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
+ kUnSet = 0,
+ // `qpack_decoded_headers_accumulator_` was reset in the corresponding
+ // method.
+ kResetInOnHeadersDecoded = 1,
+ kResetInOnHeaderDecodingError = 2,
+ kResetInOnStreamReset1 = 3,
+ kResetInOnStreamReset2 = 4,
+ kResetInResetWithError = 5,
+ kResetInOnClose = 6,
+ };
+
// Called by HttpDecoderVisitor.
bool OnDataFrameStart(QuicByteCount header_length,
QuicByteCount payload_length);
@@ -462,6 +476,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
// Headers accumulator for decoding HEADERS frame payload.
std::unique_ptr<QpackDecodedHeadersAccumulator>
qpack_decoded_headers_accumulator_;
+ // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
+ QpackDecodedHeadersAccumulatorResetReason
+ qpack_decoded_headers_accumulator_reset_reason_;
// Visitor of the HttpDecoder.
std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
// HttpDecoder for processing raw incoming stream frames.
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
index 3bad6efe6ee..c8146e1c5a1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc
@@ -136,7 +136,6 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
}
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return true; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
@@ -3424,6 +3423,32 @@ TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
EXPECT_EQ(size - 1, size_with_context);
}
+TEST_P(QuicSpdyStreamTest,
+ QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
+ if (!UsesHttp3()) {
+ return;
+ }
+
+ Initialize(kShouldProcessData);
+
+ // Creates QpackDecodedHeadersAccumulator in
+ // `qpack_decoded_headers_accumulator_`.
+ std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+ stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+ // Resets `qpack_decoded_headers_accumulator_`.
+ stream_->OnHeadersDecoded({}, false);
+
+ // This private method should never be called when
+ // `qpack_decoded_headers_accumulator_` is nullptr. The number 1 identifies
+ // the site where `qpack_decoded_headers_accumulator_` was last reset.
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _));
+ bool result = true;
+ EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
+ "b215142466_OnHeadersFrameEnd.: 1$");
+ EXPECT_FALSE(result);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
index 74c9c53a72d..5b744077402 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.cc
@@ -13,6 +13,7 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"
@@ -194,4 +195,23 @@ void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
(*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
}
+// static
+ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions) {
+ for (const ParsedQuicVersion& version : supported_versions) {
+ if (version.AlpnDeferToRFCv1()) {
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ continue;
+ }
+ if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
+ return version;
+ }
+ }
+
+ return ParsedQuicVersion::Unsupported();
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
index 01fae4f17a7..85099ab15e7 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils.h
@@ -14,6 +14,7 @@
#include "quic/core/http/quic_header_list.h"
#include "quic/core/quic_packets.h"
#include "quic/platform/api/quic_export.h"
+#include "spdy/core/spdy_alt_svc_wire_format.h"
#include "spdy/core/spdy_header_block.h"
namespace quic {
@@ -61,6 +62,14 @@ class QUIC_EXPORT_PRIVATE SpdyUtils {
// Adds the "datagram-flow-id" header.
static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
QuicDatagramStreamId flow_id);
+
+ // Returns the advertised QUIC version from the specified alternative service
+ // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
+ // is advertised.
+ static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
index 918739d6f90..85c5ceccd57 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_utils_test.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "quic/core/http/spdy_utils.h"
+
#include <memory>
#include <string>
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_test.h"
using spdy::SpdyHeaderBlock;
@@ -408,5 +410,33 @@ TEST_F(DatagramFlowIdTest, DatagramFlowId) {
ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
}
+using ExtractQuicVersionFromAltSvcEntry = QuicTest;
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ for (const ParsedQuicVersion& version : supported_versions) {
+ entry.protocol_id = AlpnForVersion(version);
+ ParsedQuicVersion expected_version = version;
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
+ version != ParsedQuicVersion::RFCv1()) {
+ expected_version = ParsedQuicVersion::RFCv1();
+ }
+ EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, supported_versions))
+ << "version: " << version;
+ }
+}
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ entry.protocol_id = "quic";
+ EXPECT_EQ(ParsedQuicVersion::Unsupported(),
+ SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, AllSupportedVersions()));
+}
+
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc
index 4e50e728ee4..934cc5f0d4d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.cc
@@ -7,6 +7,7 @@
#include "absl/strings/string_view.h"
#include "quic/core/qpack/qpack_decoder.h"
#include "quic/core/qpack/qpack_header_table.h"
+#include "quic/platform/api/quic_bug_tracker.h"
namespace quic {
@@ -88,6 +89,11 @@ void QpackDecodedHeadersAccumulator::EndHeaderBlock() {
QUICHE_DCHECK(!error_detected_);
QUICHE_DCHECK(!headers_decoded_);
+ if (!decoder_) {
+ QUIC_BUG(b215142466_EndHeaderBlock);
+ return;
+ }
+
// Might destroy |this|.
decoder_->EndHeaderBlock();
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc
index 3ae944152c0..974f7b2274f 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc
@@ -87,6 +87,12 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
const QuicByteCount initial_encoder_stream_buffered_byte_count =
encoder_stream_sender_.BufferedByteCount();
+ bool can_write_to_encoder_stream = true;
+ if (GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_stream_buffering);
+ can_write_to_encoder_stream = encoder_stream_sender_.CanWrite();
+ }
+
Representations representations;
representations.reserve(header_list.size());
@@ -152,17 +158,20 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
std::min(smallest_blocking_index, index))) {
dynamic_table_insertion_blocked = true;
} else {
- // If allowed, duplicate entry and refer to it.
- encoder_stream_sender_.SendDuplicate(
- QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- index, header_table_.inserted_entry_count()));
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- is_static, new_index, referred_indices));
- smallest_blocking_index = std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
-
- break;
+ if (can_write_to_encoder_stream) {
+ // If allowed, duplicate entry and refer to it.
+ encoder_stream_sender_.SendDuplicate(
+ QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+ index, header_table_.inserted_entry_count()));
+ uint64_t new_index = header_table_.InsertEntry(name, value);
+ representations.push_back(EncodeIndexedHeaderField(
+ is_static, new_index, referred_indices));
+ smallest_blocking_index =
+ std::min(smallest_blocking_index, index);
+ header_table_.set_dynamic_table_entry_referenced();
+
+ break;
+ }
}
}
@@ -182,15 +191,17 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
smallest_blocking_index)) {
// If allowed, insert entry into dynamic table and refer to it.
- encoder_stream_sender_.SendInsertWithNameReference(is_static, index,
- value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- /* is_static = */ false, new_index, referred_indices));
- smallest_blocking_index =
- std::min<uint64_t>(smallest_blocking_index, new_index);
-
- break;
+ if (can_write_to_encoder_stream) {
+ encoder_stream_sender_.SendInsertWithNameReference(is_static,
+ index, value);
+ uint64_t new_index = header_table_.InsertEntry(name, value);
+ representations.push_back(EncodeIndexedHeaderField(
+ /* is_static = */ false, new_index, referred_indices));
+ smallest_blocking_index =
+ std::min<uint64_t>(smallest_blocking_index, new_index);
+
+ break;
+ }
}
// Emit literal field with name reference.
@@ -208,18 +219,20 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
dynamic_table_insertion_blocked = true;
} else {
// If allowed, insert entry with name reference and refer to it.
- encoder_stream_sender_.SendInsertWithNameReference(
- is_static,
- QpackAbsoluteIndexToEncoderStreamRelativeIndex(
- index, header_table_.inserted_entry_count()),
- value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(
- EncodeIndexedHeaderField(is_static, new_index, referred_indices));
- smallest_blocking_index = std::min(smallest_blocking_index, index);
- header_table_.set_dynamic_table_entry_referenced();
+ if (can_write_to_encoder_stream) {
+ encoder_stream_sender_.SendInsertWithNameReference(
+ is_static,
+ QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+ index, header_table_.inserted_entry_count()),
+ value);
+ uint64_t new_index = header_table_.InsertEntry(name, value);
+ representations.push_back(EncodeIndexedHeaderField(
+ is_static, new_index, referred_indices));
+ smallest_blocking_index = std::min(smallest_blocking_index, index);
+ header_table_.set_dynamic_table_entry_referenced();
- break;
+ break;
+ }
}
if ((blocking_allowed || index < known_received_count) &&
@@ -251,14 +264,16 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
smallest_blocking_index)) {
dynamic_table_insertion_blocked = true;
} else {
- encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
- uint64_t new_index = header_table_.InsertEntry(name, value);
- representations.push_back(EncodeIndexedHeaderField(
- /* is_static = */ false, new_index, referred_indices));
- smallest_blocking_index =
- std::min<uint64_t>(smallest_blocking_index, new_index);
+ if (can_write_to_encoder_stream) {
+ encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
+ uint64_t new_index = header_table_.InsertEntry(name, value);
+ representations.push_back(EncodeIndexedHeaderField(
+ /* is_static = */ false, new_index, referred_indices));
+ smallest_blocking_index =
+ std::min<uint64_t>(smallest_blocking_index, new_index);
- break;
+ break;
+ }
}
// Encode entry as string literals.
@@ -275,12 +290,18 @@ QpackEncoder::Representations QpackEncoder::FirstPassEncode(
encoder_stream_sender_.BufferedByteCount();
QUICHE_DCHECK_GE(encoder_stream_buffered_byte_count,
initial_encoder_stream_buffered_byte_count);
+
if (encoder_stream_sent_byte_count) {
*encoder_stream_sent_byte_count =
encoder_stream_buffered_byte_count -
initial_encoder_stream_buffered_byte_count;
}
- encoder_stream_sender_.Flush();
+ if (can_write_to_encoder_stream) {
+ encoder_stream_sender_.Flush();
+ } else {
+ QUICHE_DCHECK_EQ(encoder_stream_buffered_byte_count,
+ initial_encoder_stream_buffered_byte_count);
+ }
++header_list_count_;
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc
index 4079ba45a85..8b6f887cf3c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.cc
@@ -14,6 +14,14 @@
namespace quic {
+namespace {
+
+// If QUIC stream bufferes more that this number of bytes,
+// CanWrite() will return false.
+constexpr uint64_t kMaxBytesBufferedByStream = 64 * 1024;
+
+} // anonymous namespace
+
QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
void QpackEncoderStreamSender::SendInsertWithNameReference(
@@ -44,6 +52,11 @@ void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
QpackInstructionWithValues::SetDynamicTableCapacity(capacity), &buffer_);
}
+bool QpackEncoderStreamSender::CanWrite() const {
+ return delegate_ && delegate_->NumBytesBuffered() + buffer_.size() <=
+ kMaxBytesBufferedByStream;
+}
+
void QpackEncoderStreamSender::Flush() {
if (buffer_.empty()) {
return;
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h
index 44d777d8d90..d8c64306a78 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h
@@ -38,9 +38,18 @@ class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender {
// 5.2.4. Set Dynamic Table Capacity
void SendSetDynamicTableCapacity(uint64_t capacity);
- // Returns number of buffered bytes.
+ // Returns number of bytes buffered by this object.
+ // There is no limit on how much data this object is willing to buffer.
QuicByteCount BufferedByteCount() const { return buffer_.size(); }
+ // Returns whether writing to the encoder stream is allowed. Writing is
+ // disallowed if the amount of data buffered by the underlying stream exceeds
+ // a hardcoded limit, in order to limit memory consumption in case the encoder
+ // stream is blocked. CanWrite() returning true does not mean that the
+ // encoder stream is not blocked, it just means the blocked data does not
+ // exceed the threshold.
+ bool CanWrite() const;
+
// Writes all buffered instructions on the encoder stream.
void Flush();
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
index 21397ed8571..30f578e9378 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
@@ -18,12 +18,19 @@
using ::testing::_;
using ::testing::Eq;
+using ::testing::Return;
using ::testing::StrictMock;
namespace quic {
namespace test {
namespace {
+// A number larger than kMaxBytesBufferedByStream in
+// qpack_encoder_stream_sender.cc. Returning this value from NumBytesBuffered()
+// will instruct QpackEncoder not to generate any instructions for the encoder
+// stream.
+constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
+
class QpackEncoderTest : public QuicTest {
protected:
QpackEncoderTest()
@@ -47,6 +54,8 @@ class QpackEncoderTest : public QuicTest {
};
TEST_F(QpackEncoderTest, Empty) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
std::string output = Encode(header_list);
@@ -54,6 +63,8 @@ TEST_F(QpackEncoderTest, Empty) {
}
TEST_F(QpackEncoderTest, EmptyName) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list[""] = "foo";
std::string output = Encode(header_list);
@@ -62,6 +73,8 @@ TEST_F(QpackEncoderTest, EmptyName) {
}
TEST_F(QpackEncoderTest, EmptyValue) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "";
std::string output = Encode(header_list);
@@ -70,6 +83,8 @@ TEST_F(QpackEncoderTest, EmptyValue) {
}
TEST_F(QpackEncoderTest, EmptyNameAndValue) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list[""] = "";
std::string output = Encode(header_list);
@@ -78,6 +93,8 @@ TEST_F(QpackEncoderTest, EmptyNameAndValue) {
}
TEST_F(QpackEncoderTest, Simple) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "bar";
std::string output = Encode(header_list);
@@ -86,6 +103,8 @@ TEST_F(QpackEncoderTest, Simple) {
}
TEST_F(QpackEncoderTest, Multiple) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "bar";
// 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
@@ -108,6 +127,8 @@ TEST_F(QpackEncoderTest, Multiple) {
}
TEST_F(QpackEncoderTest, StaticTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
{
spdy::Http2HeaderBlock header_list;
header_list[":method"] = "GET";
@@ -149,6 +170,8 @@ TEST_F(QpackEncoderTest, DecoderStreamError) {
}
TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
std::string output = Encode(header_list);
@@ -217,6 +240,8 @@ TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
}
TEST_F(QpackEncoderTest, DynamicTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(4096);
encoder_.SetDynamicTableCapacity(4096);
@@ -252,6 +277,8 @@ TEST_F(QpackEncoderTest, DynamicTable) {
// There is no room in the dynamic table after inserting the first entry.
TEST_F(QpackEncoderTest, SmallDynamicTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
@@ -288,6 +315,8 @@ TEST_F(QpackEncoderTest, SmallDynamicTable) {
}
TEST_F(QpackEncoderTest, BlockedStream) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(4096);
encoder_.SetDynamicTableCapacity(4096);
@@ -395,6 +424,8 @@ TEST_F(QpackEncoderTest, BlockedStream) {
}
TEST_F(QpackEncoderTest, Draining) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list1;
header_list1["one"] = "foo";
header_list1["two"] = "foo";
@@ -467,6 +498,135 @@ TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
EXPECT_EQ(30u, header_table->dynamic_table_capacity());
}
+TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
+ if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
+ return;
+ }
+
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(kTooManyBytesBuffered));
+ encoder_.SetMaximumBlockedStreams(1);
+ encoder_.SetMaximumDynamicTableCapacity(4096);
+ encoder_.SetDynamicTableCapacity(4096);
+
+ spdy::Http2HeaderBlock header_list1;
+ header_list1["foo"] = "bar";
+ header_list1.AppendValueOrAddHeader("foo", "baz");
+ header_list1["cookie"] = "baz"; // name matches static entry
+
+ // Encoder is not allowed to write on the encoder stream.
+ // No Set Dynamic Table Capacity or Insert instructions are sent.
+ // Headers are encoded as string literals.
+ EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
+ "2a94e7" // literal name "foo"
+ "03626172" // with literal value "bar"
+ "2a94e7" // literal name "foo"
+ "0362617a" // with literal value "baz"
+ "55" // name of static entry 5
+ "0362617a"), // with literal value "baz"
+ Encode(header_list1));
+
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+ // If number of bytes buffered by encoder stream goes under the threshold,
+ // then QpackEncoder will resume emitting encoder stream instructions.
+ ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
+
+ spdy::Http2HeaderBlock header_list2;
+ header_list2["foo"] = "bar";
+ header_list2.AppendValueOrAddHeader("foo",
+ "baz"); // name matches dynamic entry
+ header_list2["cookie"] = "baz"; // name matches static entry
+
+ // Set Dynamic Table Capacity instruction.
+ std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+ // Insert three entries into the dynamic table.
+ std::string insert_entries = absl::HexStringToBytes(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172" // value "bar"
+ "80" // insert with name reference, dynamic index 0
+ "0362617a" // value "baz"
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
+ EXPECT_CALL(encoder_stream_sender_delegate_,
+ WriteStreamData(Eq(
+ absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+ EXPECT_EQ(absl::HexStringToBytes(
+ "0400" // prefix
+ "828180"), // dynamic entries with relative index 0, 1, and 2
+ Encode(header_list2));
+
+ EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
+ if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
+ return;
+ }
+
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
+ encoder_.SetMaximumBlockedStreams(1);
+ encoder_.SetMaximumDynamicTableCapacity(4096);
+ encoder_.SetDynamicTableCapacity(4096);
+
+ spdy::Http2HeaderBlock header_list1;
+ header_list1["foo"] = "bar";
+ header_list1.AppendValueOrAddHeader("foo",
+ "baz"); // name matches dynamic entry
+ header_list1["cookie"] = "baz"; // name matches static entry
+
+ // Set Dynamic Table Capacity instruction.
+ std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+ // Insert three entries into the dynamic table.
+ std::string insert_entries = absl::HexStringToBytes(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172" // value "bar"
+ "80" // insert with name reference, dynamic index 0
+ "0362617a" // value "baz"
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
+ EXPECT_CALL(encoder_stream_sender_delegate_,
+ WriteStreamData(Eq(
+ absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+ EXPECT_EQ(absl::HexStringToBytes(
+ "0400" // prefix
+ "828180"), // dynamic entries with relative index 0, 1, and 2
+ Encode(header_list1));
+
+ EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+ // If number of bytes buffered by encoder stream goes over the threshold,
+ // then QpackEncoder will stop emitting encoder stream instructions.
+ ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(kTooManyBytesBuffered));
+
+ spdy::Http2HeaderBlock header_list2;
+ header_list2["foo"] = "bar"; // matches previously inserted dynamic entry
+ header_list2["bar"] = "baz";
+ header_list2["cookie"] = "baz"; // name matches static entry
+
+ // Encoder is not allowed to write on the encoder stream.
+ // No Set Dynamic Table Capacity or Insert instructions are sent.
+ // Headers are encoded as string literals.
+ EXPECT_EQ(
+ absl::HexStringToBytes("0400" // prefix
+ "82" // dynamic entry with relative index 0
+ "23626172" // literal name "bar"
+ "0362617a" // with literal value "baz"
+ "80"), // dynamic entry with relative index 2
+ Encode(header_list2));
+
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc
index 8cd1108a458..20f7a62731b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_offline_decoder_bin.cc
@@ -9,16 +9,17 @@
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/test_tools/qpack/qpack_offline_decoder.h"
+#include "common/platform/api/quiche_command_line_flags.h"
int main(int argc, char* argv[]) {
const char* usage =
"Usage: qpack_offline_decoder input_filename expected_headers_filename "
"....";
std::vector<std::string> args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (args.size() < 2 || args.size() % 2 != 0) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc
index 626d0639bf5..3e921d860f6 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.cc
@@ -34,6 +34,10 @@ void QpackSendStream::WriteStreamData(absl::string_view data) {
WriteOrBufferData(data, false, nullptr);
}
+uint64_t QpackSendStream::NumBytesBuffered() const {
+ return QuicStream::BufferedDataBytes();
+}
+
void QpackSendStream::MaybeSendStreamType() {
if (!stream_type_sent_) {
char type[sizeof(http3_stream_type_)];
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h
index 086ad638d46..72dc677ecc7 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h
@@ -43,6 +43,9 @@ class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
// before the first instruction so that the peer can open an qpack stream.
void WriteStreamData(absl::string_view data) override;
+ // Return the number of bytes buffered due to underlying stream being blocked.
+ uint64_t NumBytesBuffered() const override;
+
// TODO(b/112770235): Remove this method once QuicStreamIdManager supports
// creating HTTP/3 unidirectional streams dynamically.
void MaybeSendStreamType();
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h
index 4bd1a3ae72d..04f533d3084 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h
@@ -17,6 +17,9 @@ class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate {
// Write data on the unidirectional stream.
virtual void WriteStreamData(absl::string_view data) = 0;
+
+ // Return the number of bytes buffered due to underlying stream being blocked.
+ virtual uint64_t NumBytesBuffered() const = 0;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h
index 3206b373dd7..9607054bd38 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h
@@ -90,8 +90,7 @@ class QUIC_NO_EXPORT QuicBufferedPacketStore {
BufferedPacketList early_arrived_packets) = 0;
};
- QuicBufferedPacketStore(VisitorInterface* vistor,
- const QuicClock* clock,
+ QuicBufferedPacketStore(VisitorInterface* visitor, const QuicClock* clock,
QuicAlarmFactory* alarm_factory);
QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config.cc b/chromium/net/third_party/quiche/src/quic/core/quic_config.cc
index 796c641051b..8313ef76fbd 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_config.cc
@@ -456,8 +456,6 @@ QuicConfig::QuicConfig()
initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
- key_update_supported_remotely_(false),
- key_update_supported_locally_(false),
alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
@@ -863,22 +861,6 @@ bool QuicConfig::DisableConnectionMigration() const {
return connection_migration_disabled_.HasReceivedValue();
}
-void QuicConfig::SetKeyUpdateSupportedLocally() {
- key_update_supported_locally_ = true;
-}
-
-bool QuicConfig::KeyUpdateSupportedForConnection() const {
- return KeyUpdateSupportedRemotely() && KeyUpdateSupportedLocally();
-}
-
-bool QuicConfig::KeyUpdateSupportedLocally() const {
- return key_update_supported_locally_;
-}
-
-bool QuicConfig::KeyUpdateSupportedRemotely() const {
- return key_update_supported_remotely_;
-}
-
void QuicConfig::SetIPv6AlternateServerAddressToSend(
const QuicSocketAddress& alternate_server_address_ipv6) {
if (!alternate_server_address_ipv6.host().IsIPv6()) {
@@ -1297,10 +1279,6 @@ bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
params->google_connection_options = connection_options_.GetSendValues();
}
- if (!KeyUpdateSupportedLocally()) {
- params->key_update_not_yet_supported = true;
- }
-
params->custom_parameters = custom_transport_parameters_to_send_;
return true;
@@ -1410,9 +1388,6 @@ QuicErrorCode QuicConfig::ProcessTransportParameters(
if (params.disable_active_migration) {
connection_migration_disabled_.SetReceivedValue(1u);
}
- if (!is_resumption && !params.key_update_not_yet_supported) {
- key_update_supported_remotely_ = true;
- }
active_connection_id_limit_.SetReceivedValue(
params.active_connection_id_limit.value());
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config.h b/chromium/net/third_party/quiche/src/quic/core/quic_config.h
index d122be7ff29..cb8b4ecdf1e 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_config.h
@@ -67,7 +67,7 @@ class QUIC_EXPORT_PRIVATE QuicConfigValue {
// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
public:
- QuicFixedUint32(QuicTag name, QuicConfigPresence presence);
+ QuicFixedUint32(QuicTag tag, QuicConfigPresence presence);
~QuicFixedUint32() override;
bool HasSendValue() const;
@@ -384,12 +384,6 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
void SetDisableConnectionMigration();
bool DisableConnectionMigration() const;
- // Key update support.
- void SetKeyUpdateSupportedLocally();
- bool KeyUpdateSupportedForConnection() const;
- bool KeyUpdateSupportedLocally() const;
- bool KeyUpdateSupportedRemotely() const;
-
// IPv6 alternate server address.
void SetIPv6AlternateServerAddressToSend(
const QuicSocketAddress& alternate_server_address_ipv6);
@@ -593,13 +587,6 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
// Uses the disable_active_migration transport parameter in IETF QUIC.
QuicFixedUint32 connection_migration_disabled_;
- // Whether key update is supported by the peer. Uses key_update_not_yet
- // supported transport parameter in IETF QUIC.
- bool key_update_supported_remotely_;
-
- // Whether key update is supported locally.
- bool key_update_supported_locally_;
-
// Alternate server addresses the client could connect to.
// Uses the preferred_address transport parameter in IETF QUIC.
// Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc
index 5124a975bf8..e53d429030e 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc
@@ -56,9 +56,6 @@ TEST_P(QuicConfigTest, SetDefaults) {
EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
- EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
}
TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
@@ -519,7 +516,6 @@ TEST_P(QuicConfigTest, FillTransportParams) {
EXPECT_EQ(
static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
params.min_ack_delay_us.value());
- EXPECT_TRUE(params.key_update_not_yet_supported);
EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
@@ -685,83 +681,6 @@ TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
EXPECT_TRUE(config_.DisableConnectionMigration());
}
-TEST_P(QuicConfigTest, KeyUpdateNotYetSupportedTransportParameterNorLocally) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
- EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
- TransportParameters params;
- params.key_update_not_yet_supported = true;
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
- EXPECT_FALSE(config_.KeyUpdateSupportedRemotely());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateNotYetSupportedTransportParameter) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- config_.SetKeyUpdateSupportedLocally();
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-
- TransportParameters params;
- params.key_update_not_yet_supported = true;
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateSupportedRemotelyButNotLocally) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-
- TransportParameters params;
- params.key_update_not_yet_supported = false;
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
- EXPECT_FALSE(config_.KeyUpdateSupportedLocally());
- EXPECT_TRUE(config_.KeyUpdateSupportedRemotely());
-}
-
-TEST_P(QuicConfigTest, KeyUpdateSupported) {
- if (!version_.UsesTls()) {
- // TransportParameters are only used for QUIC+TLS.
- return;
- }
- config_.SetKeyUpdateSupportedLocally();
- EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
- EXPECT_FALSE(config_.KeyUpdateSupportedForConnection());
-
- TransportParameters params;
- params.key_update_not_yet_supported = false;
- std::string error_details;
- EXPECT_THAT(config_.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- EXPECT_TRUE(config_.KeyUpdateSupportedForConnection());
- EXPECT_TRUE(config_.KeyUpdateSupportedLocally());
- EXPECT_TRUE(config_.KeyUpdateSupportedRemotely());
-}
-
TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
if (!version_.UsesTls()) {
// TransportParameters are only used for QUIC+TLS.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc
index e31408a3116..2fe7af38717 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection.cc
@@ -505,8 +505,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (!ValidateConfigConnectionIds(config)) {
return;
}
- support_key_update_for_connection_ =
- config.KeyUpdateSupportedForConnection();
+ support_key_update_for_connection_ = version().UsesTls();
framer_.SetKeyUpdateSupportForConnection(
support_key_update_for_connection_);
} else {
@@ -641,7 +640,6 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
// 2) Client side's rollout can be protected by the same connection option.
connection_migration_use_new_cid_ =
validate_client_addresses_ &&
- GetQuicReloadableFlag(quic_drop_unsent_path_response) &&
GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
if (config.HasReceivedMaxPacketSize()) {
peer_max_packet_size_ = config.ReceivedMaxPacketSize();
@@ -1742,19 +1740,10 @@ bool QuicConnection::OnPathChallengeFrameInternal(
// Queue or send PATH_RESPONSE. Send PATH_RESPONSE to the source address of
// the current incoming packet, even if it's not the default path or the
// alternative path.
- const bool success = SendPathResponse(
- frame.data_buffer, last_received_packet_info_.source_address,
- current_effective_peer_address);
- if (GetQuicReloadableFlag(quic_drop_unsent_path_response)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_drop_unsent_path_response);
- }
- if (!success) {
+ if (!SendPathResponse(frame.data_buffer,
+ last_received_packet_info_.source_address,
+ current_effective_peer_address)) {
QUIC_CODE_COUNT(quic_failed_to_send_path_response);
- if (!GetQuicReloadableFlag(quic_drop_unsent_path_response)) {
- // Queue the payloads to re-try later.
- pending_path_challenge_payloads_.push_back(
- {frame.data_buffer, last_received_packet_info_.source_address});
- }
}
// TODO(b/150095588): change the stats to
// num_valid_path_challenge_received.
@@ -2870,23 +2859,6 @@ void QuicConnection::OnCanWrite() {
}
}
- // TODO(danzh) PATH_RESPONSE is of more interest to the peer than ACK,
- // evaluate if it's worth to send them before sending ACKs.
- while (!pending_path_challenge_payloads_.empty()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response2, 4, 5);
- const PendingPathChallenge& pending_path_challenge =
- pending_path_challenge_payloads_.front();
- // Note connection_migration_use_cid_ will depends on
- // quic_drop_unsent_path_response flag eventually, and hence the empty
- // effective_peer_address here will not be used.
- if (!SendPathResponse(pending_path_challenge.received_path_challenge,
- pending_path_challenge.peer_address,
- /*effective_peer_address=*/QuicSocketAddress())) {
- break;
- }
- pending_path_challenge_payloads_.pop_front();
- }
-
// Sending queued packets may have caused the socket to become write blocked,
// or the congestion manager to prohibit sending.
if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
@@ -3273,11 +3245,9 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
return false;
}
- if (GetQuicReloadableFlag(quic_suppress_write_mid_packet_processing) &&
- version().CanSendCoalescedPackets() &&
+ if (version().CanSendCoalescedPackets() &&
framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) &&
framer_.is_processing_packet()) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_suppress_write_mid_packet_processing);
// While we still have initial keys, suppress sending in mid of packet
// processing.
// TODO(fayang): always suppress sending while in the mid of packet
@@ -3726,15 +3696,8 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
return true;
}
}
- if (GetQuicReloadableFlag(
- quic_donot_rearm_pto_on_application_data_during_handshake)) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_donot_rearm_pto_on_application_data_during_handshake);
- if (ShouldSetRetransmissionAlarmOnPacketSent(in_flight,
- packet->encryption_level)) {
- SetRetransmissionAlarm();
- }
- } else if (in_flight || !retransmission_alarm_->IsSet()) {
+ if (ShouldSetRetransmissionAlarmOnPacketSent(in_flight,
+ packet->encryption_level)) {
SetRetransmissionAlarm();
}
SetPingAlarm();
@@ -6765,6 +6728,21 @@ void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
}
}
+void QuicConnection::RetirePeerIssuedConnectionIdsOnPathValidationFailure() {
+ // The alarm to retire connection IDs no longer on paths is scheduled at the
+ // end of writing and reading packet. On path validation failure, there could
+ // be no packet to write or read. Hence the retirement alarm for the
+ // connection ID associated with the failed path needs to be proactively
+ // scheduled here.
+ if (GetQuicReloadableFlag(
+ quic_retire_cid_on_reverse_path_validation_failure) ||
+ perspective_ == Perspective::IS_CLIENT) {
+ QUIC_RELOADABLE_FLAG_COUNT(
+ quic_retire_cid_on_reverse_path_validation_failure);
+ RetirePeerIssuedConnectionIdsNoLongerOnPath();
+ }
+}
+
bool QuicConnection::MigratePath(const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
QuicPacketWriter* writer,
@@ -6816,12 +6794,7 @@ void QuicConnection::OnPathValidationFailureAtClient() {
QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
alternative_path_.Clear();
}
- // The alarm to retire connection IDs no longer on paths is scheduled at the
- // end of writing and reading packet. On path validation failure, there could
- // be no packet to write or read. Hence the retirement alarm for the
- // connection ID associated with the failed path needs to be proactively
- // scheduled here.
- RetirePeerIssuedConnectionIdsNoLongerOnPath();
+ RetirePeerIssuedConnectionIdsOnPathValidationFailure();
}
QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
@@ -7075,6 +7048,7 @@ void QuicConnection::ReversePathValidationResultDelegate::
QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 6, 6);
connection_->alternative_path_.Clear();
}
+ connection_->RetirePeerIssuedConnectionIdsOnPathValidationFailure();
}
QuicConnection::ScopedRetransmissionTimeoutIndicator::
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection.h
index 3b310c8f838..954eb6a6d0f 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection.h
@@ -1564,6 +1564,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// any path.
void RetirePeerIssuedConnectionIdsNoLongerOnPath();
+ // When path validation fails, proactively retire peer issued connection IDs
+ // no longer used on any path.
+ void RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+
// Writes the given packet to socket, encrypted with packet's
// encryption_level. Returns true on successful write, and false if the writer
// was blocked and the write needs to be tried again. Notifies the
@@ -2165,13 +2169,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
quiche::QuicheCircularDeque<QuicPathFrameBuffer>
received_path_challenge_payloads_;
- // Buffer outstanding PATH_CHALLENGEs if socket write is blocked, future
- // OnCanWrite will attempt to respond with PATH_RESPONSEs using the retained
- // payload and peer addresses.
- // TODO(fayang): remove this when deprecating quic_drop_unsent_path_response.
- quiche::QuicheCircularDeque<PendingPathChallenge>
- pending_path_challenge_payloads_;
-
// When we receive a RETRY packet or some INITIAL packets, we replace
// |server_connection_id_| with the value from that packet and save off the
// original value of |server_connection_id_| into
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc
index 89fb70bacb1..fba066caf68 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc
@@ -184,19 +184,12 @@ class TestConnection : public QuicConnection {
TestConnection(QuicConnectionId connection_id,
QuicSocketAddress initial_self_address,
QuicSocketAddress initial_peer_address,
- TestConnectionHelper* helper,
- TestAlarmFactory* alarm_factory,
- TestPacketWriter* writer,
- Perspective perspective,
+ TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
+ TestPacketWriter* writer, Perspective perspective,
ParsedQuicVersion version)
- : QuicConnection(connection_id,
- initial_self_address,
- initial_peer_address,
- helper,
- alarm_factory,
- writer,
- /* owns_writer= */ false,
- perspective,
+ : QuicConnection(connection_id, initial_self_address,
+ initial_peer_address, helper, alarm_factory, writer,
+ /* owns_writer= */ false, perspective,
SupportedVersions(version)),
notifier_(nullptr) {
writer->set_perspective(perspective);
@@ -215,11 +208,9 @@ class TestConnection : public QuicConnection {
QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
}
- void SendPacket(EncryptionLevel /*level*/,
- uint64_t packet_number,
+ void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
std::unique_ptr<QuicPacket> packet,
- HasRetransmittableData retransmittable,
- bool has_ack,
+ HasRetransmittableData retransmittable, bool has_ack,
bool has_pending_frames) {
ScopedPacketFlusher flusher(this);
char buffer[kMaxOutgoingPacketSize];
@@ -239,8 +230,7 @@ class TestConnection : public QuicConnection {
}
QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
- const struct iovec* iov,
- int iov_count,
+ const struct iovec* iov, int iov_count,
size_t total_length,
QuicStreamOffset offset,
StreamSendingState state) {
@@ -555,8 +545,7 @@ enum class AckResponse { kDefer, kImmediate };
// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
struct TestParams {
- TestParams(ParsedQuicVersion version,
- AckResponse ack_response,
+ TestParams(ParsedQuicVersion version, AckResponse ack_response,
bool no_stop_waiting)
: version(version),
ack_response(ack_response),
@@ -609,30 +598,20 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
protected:
QuicConnectionTest()
: connection_id_(TestConnectionId()),
- framer_(SupportedVersions(version()),
- QuicTime::Zero(),
- Perspective::IS_CLIENT,
- connection_id_.length()),
+ framer_(SupportedVersions(version()), QuicTime::Zero(),
+ Perspective::IS_CLIENT, connection_id_.length()),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
alarm_factory_(new TestAlarmFactory()),
- peer_framer_(SupportedVersions(version()),
- QuicTime::Zero(),
- Perspective::IS_SERVER,
- connection_id_.length()),
- peer_creator_(connection_id_,
- &peer_framer_,
+ peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
+ Perspective::IS_SERVER, connection_id_.length()),
+ peer_creator_(connection_id_, &peer_framer_,
/*delegate=*/nullptr),
writer_(
new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
- connection_(connection_id_,
- kSelfAddress,
- kPeerAddress,
- helper_.get(),
- alarm_factory_.get(),
- writer_.get(),
- Perspective::IS_CLIENT,
+ connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
+ alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
version()),
creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
@@ -872,16 +851,14 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
}
- size_t ProcessFramePacketAtLevel(uint64_t number,
- QuicFrame frame,
+ size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
EncryptionLevel level) {
QuicFrames frames;
frames.push_back(frame);
return ProcessFramesPacketAtLevel(number, frames, level);
}
- size_t ProcessFramesPacketAtLevel(uint64_t number,
- const QuicFrames& frames,
+ size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
EncryptionLevel level) {
QuicPacketHeader header = ConstructPacketHeader(number, level);
// Set the correct encryption level and encrypter on peer_creator and
@@ -1025,8 +1002,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
return encrypted_length;
}
- size_t ProcessDataPacketAtLevel(uint64_t number,
- bool has_stop_waiting,
+ size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
EncryptionLevel level) {
std::unique_ptr<QuicPacket> packet(
ConstructDataPacket(number, has_stop_waiting, level));
@@ -1055,8 +1031,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
}
- QuicByteCount SendStreamDataToPeer(QuicStreamId id,
- absl::string_view data,
+ QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
QuicStreamOffset offset,
StreamSendingState state,
QuicPacketNumber* last_packet) {
@@ -1084,8 +1059,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
.Times(AnyNumber());
}
- void SendRstStream(QuicStreamId id,
- QuicRstStreamErrorCode error,
+ void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written) {
notifier_.WriteOrBufferRstStream(id, error, bytes_written);
connection_.OnStreamReset(id, error);
@@ -4543,179 +4517,6 @@ TEST_P(QuicConnectionTest, TLP) {
EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
}
-TEST_P(QuicConnectionTest, TailLossProbeDelayForStreamDataInTLPR) {
- if (connection_.PtoEnabled() || GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
-
- // Set TLPR from QuicConfig.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kTLPR);
- config.SetConnectionOptionsToSend(options);
- connection_.SetFromConfig(config);
- connection_.SetMaxTailLossProbes(1);
-
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
- QuicTime::Delta expected_tlp_delay =
- 0.5 * manager_->GetRttStats()->SmoothedOrInitialRtt();
- EXPECT_EQ(expected_tlp_delay, retransmission_time - clock_.Now());
-
- EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
- // Simulate firing of the retransmission alarm and retransmit the packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
-
- // We do not raise the high water mark yet.
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-}
-
-TEST_P(QuicConnectionTest, TailLossProbeDelayForNonStreamDataInTLPR) {
- if (connection_.PtoEnabled() || GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
-
- // Set TLPR from QuicConfig.
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kTLPR);
- config.SetConnectionOptionsToSend(options);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- connection_.SetFromConfig(config);
- connection_.SetMaxTailLossProbes(1);
-
- // Sets retransmittable on wire.
- const QuicTime::Delta retransmittable_on_wire_timeout =
- QuicTime::Delta::FromMilliseconds(50);
- connection_.set_initial_retransmittable_on_wire_timeout(
- retransmittable_on_wire_timeout);
-
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
- .WillRepeatedly(Return(true));
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Send a data packet.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
-
- // Path degrading alarm should be set when there is a retransmittable packet
- // on the wire.
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-
- // Verify the path degrading delay.
- // First TLP with stream data.
- QuicTime::Delta srtt = manager_->GetRttStats()->SmoothedOrInitialRtt();
- QuicTime::Delta expected_delay = 0.5 * srtt;
- // Add 1st RTO.
- QuicTime::Delta retransmission_delay =
- QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
- expected_delay = expected_delay + retransmission_delay;
- // Add 2nd RTO.
- expected_delay = expected_delay + retransmission_delay * 2;
- EXPECT_EQ(expected_delay,
- QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay());
- ASSERT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Receive an ACK for the data packet.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
-
- // Path degrading alarm should be cancelled as there is no more
- // reretransmittable packets on the wire.
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- // The ping alarm should be set to the retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(retransmittable_on_wire_timeout,
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Simulate firing of the retransmittable on wire and send a PING.
- clock_.AdvanceTime(retransmittable_on_wire_timeout);
- connection_.GetPingAlarm()->Fire();
-
- // The retransmission alarm and the path degrading alarm should be set as
- // there is a retransmittable packet (PING) on the wire,
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-
- // Verify the retransmission delay.
- QuicTime::Delta min_rto_timeout =
- QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs);
- srtt = manager_->GetRttStats()->SmoothedOrInitialRtt();
-
- // Arm RTO mode since there is only PING in flight.
- expected_delay = manager_->GetPtoDelay();
- EXPECT_EQ(expected_delay,
- connection_.GetRetransmissionAlarm()->deadline() - clock_.Now());
-
- // Verify the path degrading delay = TLP delay + 1st RTO + 2nd RTO.
- // Add 1st RTO.
- expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout);
- retransmission_delay =
- std::max(manager_->GetRttStats()->smoothed_rtt() +
- 4 * manager_->GetRttStats()->mean_deviation(),
- min_rto_timeout);
- expected_delay = expected_delay + retransmission_delay;
- // Add 2nd RTO.
- expected_delay = expected_delay + retransmission_delay * 2;
- EXPECT_EQ(expected_delay,
- QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay());
-
- // The ping alarm is set for the ping timeout, not the shorter
- // retransmittable_on_wire_timeout.
- EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
- connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
- // Advance a small period of time: 5ms. And receive a retransmitted ACK.
- // This will update the retransmission alarm, verify the retransmission delay
- // is correct.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- QuicAckFrame ack = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&ack);
-
- // Verify the retransmission delay.
- // First TLP without unacked stream data will no longer use TLPR.
- // Arm RTO mode since there is only PING in flight.
- expected_delay = manager_->GetPtoDelay();
- expected_delay = expected_delay - QuicTime::Delta::FromMilliseconds(5);
- EXPECT_EQ(expected_delay,
- connection_.GetRetransmissionAlarm()->deadline() - clock_.Now());
-}
-
TEST_P(QuicConnectionTest, RTO) {
if (connection_.PtoEnabled()) {
return;
@@ -10672,7 +10473,12 @@ void QuicConnectionTest::TestClientRetryHandling(
return;
}
- // These values come from draft-ietf-quic-tls Appendix A.4.
+ // These values come from draft-ietf-quic-v2 Appendix A.4.
+ uint8_t retry_packet_rfcv2[] = {
+ 0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+ 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
+ 0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
+ // These values come from RFC9001 Appendix A.4.
uint8_t retry_packet_rfcv1[] = {
0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
@@ -10684,7 +10490,10 @@ void QuicConnectionTest::TestClientRetryHandling(
uint8_t* retry_packet;
size_t retry_packet_length;
- if (version() == ParsedQuicVersion::RFCv1()) {
+ if (version() == ParsedQuicVersion::V2Draft01()) {
+ retry_packet = retry_packet_rfcv2;
+ retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
+ } else if (version() == ParsedQuicVersion::RFCv1()) {
retry_packet = retry_packet_rfcv1;
retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
} else if (version() == ParsedQuicVersion::Draft29()) {
@@ -12719,30 +12528,6 @@ TEST_P(QuicConnectionTest, FailToWritePathResponse) {
writer_->SetWriteBlocked();
ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
ENCRYPTION_FORWARD_SECURE);
-
- if (GetQuicReloadableFlag(quic_drop_unsent_path_response)) {
- EXPECT_EQ(0u, QuicConnectionPeer::NumPendingPathChallengesToResponse(
- &connection_));
- return;
- }
- ASSERT_EQ(
- 1u, QuicConnectionPeer::NumPendingPathChallengesToResponse(&connection_));
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- writer_->SetWritable();
- connection_.OnCanWrite();
- EXPECT_EQ(1u, writer_->path_response_frames().size());
- // The final check is to ensure that the random data in the response
- // matches the random data from the challenge.
- EXPECT_EQ(0, memcmp(path_frame_buffer.data(),
- &(writer_->path_response_frames().front().data_buffer),
- sizeof(path_frame_buffer)));
- EXPECT_EQ(1u, writer_->padding_frames().size());
- // PATH_RESPONSE should be sent in another packet to a different peer
- // address.
- EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
- EXPECT_EQ(
- 0u, QuicConnectionPeer::NumPendingPathChallengesToResponse(&connection_));
}
// Regression test for b/168101557.
@@ -12949,13 +12734,11 @@ TEST_P(QuicConnectionTest, InitiateKeyUpdate) {
}
TransportParameters params;
- params.key_update_not_yet_supported = false;
QuicConfig config;
std::string error_details;
EXPECT_THAT(config.ProcessTransportParameters(
params, /* is_resumption = */ false, &error_details),
IsQuicNoError());
- config.SetKeyUpdateSupportedLocally();
QuicConfigPeer::SetNegotiated(&config, true);
if (connection_.version().UsesTls()) {
QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13111,12 +12894,10 @@ TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {
std::string error_details;
TransportParameters params;
// Key update is enabled.
- params.key_update_not_yet_supported = false;
QuicConfig config;
EXPECT_THAT(config.ProcessTransportParameters(
params, /* is_resumption = */ false, &error_details),
IsQuicNoError());
- config.SetKeyUpdateSupportedLocally();
QuicConfigPeer::SetNegotiated(&config, true);
if (connection_.version().UsesTls()) {
QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13209,12 +12990,10 @@ TEST_P(QuicConnectionTest,
std::string error_details;
TransportParameters params;
// Key update is enabled.
- params.key_update_not_yet_supported = false;
QuicConfig config;
EXPECT_THAT(config.ProcessTransportParameters(
params, /* is_resumption = */ false, &error_details),
IsQuicNoError());
- config.SetKeyUpdateSupportedLocally();
QuicConfigPeer::SetNegotiated(&config, true);
if (connection_.version().UsesTls()) {
QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13250,137 +13029,6 @@ TEST_P(QuicConnectionTest,
TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
}
-TEST_P(QuicConnectionTest,
- CloseConnectionOnConfidentialityLimitKeyUpdateNotSupportedByPeer) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- // Set key update confidentiality limit to 1 packet.
- SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
- // Use confidentiality limit for connection close of 3 packets.
- constexpr size_t kConfidentialityLimit = 3U;
-
- std::string error_details;
- TransportParameters params;
- // Key update not enabled for this connection as peer doesn't support it.
- params.key_update_not_yet_supported = true;
- QuicConfig config;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- // Key update is supported locally.
- config.SetKeyUpdateSupportedLocally();
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypterWithConfidentialityLimit>(
- Perspective::IS_CLIENT, kConfidentialityLimit));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
-
- QuicPacketNumber last_packet;
- // Send 3 packets and receive acks for them. Since key update is not enabled
- // the confidentiality limit should be reached, forcing the connection to be
- // closed.
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- // Receive ack for packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = InitAckFrame(1);
- ProcessAckPacket(&frame1);
-
- SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- // Receive ack for packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame2 = InitAckFrame(2);
- ProcessAckPacket(&frame2);
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
- EXPECT_FALSE(connection_.connected());
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_EQ(0U, stats.key_update_count);
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest,
- CloseConnectionOnConfidentialityLimitKeyUpdateNotEnabledLocally) {
- if (!connection_.version().UsesTls()) {
- return;
- }
-
- // Set key update confidentiality limit to 1 packet.
- SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
- // Use confidentiality limit for connection close of 3 packets.
- constexpr size_t kConfidentialityLimit = 3U;
-
- std::string error_details;
- TransportParameters params;
- // Key update is supported by peer but not locally
- // (config.SetKeyUpdateSupportedLocally is not called.)
- params.key_update_not_yet_supported = false;
- QuicConfig config;
- EXPECT_THAT(config.ProcessTransportParameters(
- params, /* is_resumption = */ false, &error_details),
- IsQuicNoError());
- QuicConfigPeer::SetNegotiated(&config, true);
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- connection_.SetFromConfig(config);
-
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- connection_.SetEncrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypterWithConfidentialityLimit>(
- Perspective::IS_CLIENT, kConfidentialityLimit));
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
-
- QuicPacketNumber last_packet;
- // Send 3 packets and receive acks for them. Since key update is not enabled
- // the confidentiality limit should be reached, forcing the connection to be
- // closed.
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- // Receive ack for packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame1 = InitAckFrame(1);
- ProcessAckPacket(&frame1);
-
- SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
- EXPECT_TRUE(connection_.connected());
- // Receive ack for packet.
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame frame2 = InitAckFrame(2);
- ProcessAckPacket(&frame2);
-
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
- EXPECT_FALSE(connection_.connected());
- const QuicConnectionStats& stats = connection_.GetStats();
- EXPECT_EQ(0U, stats.key_update_count);
- TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
if (!connection_.version().UsesTls()) {
return;
@@ -13536,13 +13184,11 @@ TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) {
constexpr QuicPacketCount kIntegrityLimit = 4;
TransportParameters params;
- params.key_update_not_yet_supported = false;
QuicConfig config;
std::string error_details;
EXPECT_THAT(config.ProcessTransportParameters(
params, /* is_resumption = */ false, &error_details),
IsQuicNoError());
- config.SetKeyUpdateSupportedLocally();
QuicConfigPeer::SetNegotiated(&config, true);
if (connection_.version().UsesTls()) {
QuicConfigPeer::SetReceivedOriginalConnectionId(
@@ -13987,12 +13633,10 @@ TEST_P(QuicConnectionTest,
// kept for key update, so enable key update for the test.
std::string error_details;
TransportParameters params;
- params.key_update_not_yet_supported = false;
QuicConfig config;
EXPECT_THAT(config.ProcessTransportParameters(
params, /* is_resumption = */ false, &error_details),
IsQuicNoError());
- config.SetKeyUpdateSupportedLocally();
QuicConfigPeer::SetNegotiated(&config, true);
QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
connection_.connection_id());
@@ -15265,14 +14909,8 @@ TEST_P(QuicConnectionTest, SendingZeroRttPacketsDoesNotPostponePTO) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- if (GetQuicReloadableFlag(
- quic_donot_rearm_pto_on_application_data_during_handshake)) {
- // PTO deadline should be unchanged.
- EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
- } else {
- // PTO gets re-armed.
- EXPECT_NE(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
- }
+ // PTO deadline should be unchanged.
+ EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
}
TEST_P(QuicConnectionTest, QueueingUndecryptablePacketsDoesntPostponePTO) {
@@ -15547,6 +15185,25 @@ TEST_P(QuicConnectionTest, AckElicitingFrames) {
}
}
+TEST_P(QuicConnectionTest, ReceivedChloAndAck) {
+ if (!version().HasIetfQuicFrames()) {
+ return;
+ }
+ set_perspective(Perspective::IS_SERVER);
+ QuicFrames frames;
+ QuicAckFrame ack_frame = InitAckFrame(1);
+ frames.push_back(MakeCryptoFrame());
+ frames.push_back(QuicFrame(&ack_frame));
+
+ EXPECT_CALL(visitor_, OnCryptoFrame(_))
+ .WillOnce(IgnoreResult(InvokeWithoutArgs(
+ &connection_, &TestConnection::SendCryptoStreamData)));
+ EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+ ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+ ENCRYPTION_INITIAL);
+}
+
// Regression test for b/201643321.
TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
if (!version().HasIetfQuicFrames()) {
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc
index e9a99167f46..872b050bf9c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc
@@ -180,10 +180,6 @@ size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
}
-bool QuicCryptoClientHandshaker::KeyUpdateSupportedLocally() const {
- return false;
-}
-
std::unique_ptr<QuicDecrypter>
QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
// Key update is only defined in QUIC+TLS.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h
index d9f10350553..c0c94b94cd8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h
@@ -51,7 +51,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
CryptoMessageParser* crypto_message_parser() override;
HandshakeState GetHandshakeState() const override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- bool KeyUpdateSupportedLocally() const override;
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc
index 31d96a37794..27a2a469ace 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc
@@ -114,10 +114,6 @@ size_t QuicCryptoClientStream::BufferSizeLimitForLevel(
return handshaker_->BufferSizeLimitForLevel(level);
}
-bool QuicCryptoClientStream::KeyUpdateSupportedLocally() const {
- return handshaker_->KeyUpdateSupportedLocally();
-}
-
std::unique_ptr<QuicDecrypter>
QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h
index e37a5707ba5..34928b61f81 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h
@@ -183,9 +183,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
// buffered at each encryption level.
virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
- // Returns whether the implementation supports key update.
- virtual bool KeyUpdateSupportedLocally() const = 0;
-
// Called to generate a decrypter for the next key phase. Each call should
// generate the key for phase n+1.
virtual std::unique_ptr<QuicDecrypter>
@@ -283,7 +280,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- bool KeyUpdateSupportedLocally() const override;
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc
index 28bfe4add34..55b7bf1a703 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc
@@ -435,10 +435,6 @@ size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
}
-bool QuicCryptoServerStream::KeyUpdateSupportedLocally() const {
- return false;
-}
-
std::unique_ptr<QuicDecrypter>
QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
// Key update is only defined in QUIC+TLS.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h
index cf4f6e00489..aca9e9a1170 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h
@@ -66,7 +66,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> state) override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- bool KeyUpdateSupportedLocally() const override;
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h
index 86b691309bc..8197a5f4d75 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h
@@ -149,9 +149,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
// encryption level |level|.
virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
- // Returns whether the implementation supports key update.
- virtual bool KeyUpdateSupportedLocally() const = 0;
-
// Called to generate a decrypter for the next key phase. Each call should
// generate the key for phase n+1.
virtual std::unique_ptr<QuicDecrypter>
@@ -245,6 +242,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
EncryptionLevel level);
+ QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
+ return &substreams_[level].sequencer;
+ }
+
private:
// Data sent and received in CRYPTO frames is sent at multiple encryption
// levels. Some of the state for the single logical crypto stream is split
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc
index 1c18c7b7886..2c9ec0db082 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc
@@ -80,7 +80,6 @@ class MockQuicCryptoStream : public QuicCryptoStream,
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return false; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc
index 4221d4fd9d0..0da608c6900 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc
@@ -367,7 +367,7 @@ QuicDispatcher::~QuicDispatcher() {
clear_stateless_reset_addresses_alarm_->PermanentCancel();
}
reference_counted_session_map_.clear();
- closed_ref_counted_session_list_.clear();
+ closed_session_list_.clear();
num_sessions_in_session_map_ = 0;
}
@@ -968,7 +968,7 @@ std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
void QuicDispatcher::DeleteSessions() {
if (!write_blocked_list_.empty()) {
- for (const auto& session : closed_ref_counted_session_list_) {
+ for (const auto& session : closed_session_list_) {
if (write_blocked_list_.erase(session->connection()) != 0) {
QUIC_BUG(quic_bug_12724_2)
<< "QuicConnection was in WriteBlockedList before destruction "
@@ -976,7 +976,7 @@ void QuicDispatcher::DeleteSessions() {
}
}
}
- closed_ref_counted_session_list_.clear();
+ closed_session_list_.clear();
}
void QuicDispatcher::ClearStatelessResetAddresses() {
@@ -1051,11 +1051,11 @@ void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
if (ShouldDestroySessionAsynchronously()) {
// Set up alarm to fire immediately to bring destruction of this session
// out of current call stack.
- if (closed_ref_counted_session_list_.empty()) {
+ if (closed_session_list_.empty()) {
delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
QuicTime::Delta::Zero());
}
- closed_ref_counted_session_list_.push_back(std::move(it->second));
+ closed_session_list_.push_back(std::move(it->second));
}
CleanUpSession(it->first, connection, error, error_details, source);
for (const QuicConnectionId& cid :
@@ -1377,11 +1377,6 @@ const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
return version_manager_->GetSupportedVersions();
}
-const ParsedQuicVersionVector&
-QuicDispatcher::GetSupportedVersionsWithQuicCrypto() {
- return version_manager_->GetSupportedVersionsWithQuicCrypto();
-}
-
void QuicDispatcher::DeliverPacketsToSession(
const std::list<BufferedPacket>& packets,
QuicSession* session) {
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h
index eab326a9679..f22d58aa4c9 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h
@@ -256,8 +256,6 @@ class QUIC_NO_EXPORT QuicDispatcher
const ParsedQuicVersionVector& GetSupportedVersions();
- const ParsedQuicVersionVector& GetSupportedVersionsWithQuicCrypto();
-
const QuicConfig& config() const { return *config_; }
const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
@@ -414,8 +412,7 @@ class QUIC_NO_EXPORT QuicDispatcher
std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
// The list of closed but not-yet-deleted sessions.
- std::vector<std::unique_ptr<QuicSession>> closed_session_list_;
- std::vector<std::shared_ptr<QuicSession>> closed_ref_counted_session_list_;
+ std::vector<std::shared_ptr<QuicSession>> closed_session_list_;
// The helper used for all connections.
std::unique_ptr<QuicConnectionHelperInterface> helper_;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc
index ca4ae483af8..add5164d674 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc
@@ -1521,7 +1521,7 @@ TEST_P(QuicDispatcherTestOneVersion,
dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
}
-static_assert(quic::SupportedVersions().size() == 5u,
+static_assert(quic::SupportedVersions().size() == 6u,
"Please add new RejectDeprecatedVersion tests above this assert "
"when deprecating versions");
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h
index 6fb1e02ed4e..986b842ae8d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h
@@ -15,7 +15,7 @@ namespace quic {
// Creates alarms that use the supplied EpollServer for timing and firing.
class QUIC_EXPORT_PRIVATE QuicEpollAlarmFactory : public QuicAlarmFactory {
public:
- explicit QuicEpollAlarmFactory(QuicEpollServer* eps);
+ explicit QuicEpollAlarmFactory(QuicEpollServer* epoll_server);
QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete;
QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete;
~QuicEpollAlarmFactory() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc
index 8f532562aee..42d2e0230cc 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.cc
@@ -12,11 +12,10 @@
namespace quic {
QuicEpollConnectionHelper::QuicEpollConnectionHelper(
- QuicEpollServer* epoll_server,
- QuicAllocator type)
+ QuicEpollServer* epoll_server, QuicAllocator allocator_type)
: clock_(epoll_server),
random_generator_(QuicRandom::GetInstance()),
- allocator_type_(type) {}
+ allocator_type_(allocator_type) {}
QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h
index 0db6ed2cd0a..d363d6bc97f 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h
@@ -30,7 +30,8 @@ enum class QuicAllocator { SIMPLE, BUFFER_POOL };
class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
: public QuicConnectionHelperInterface {
public:
- QuicEpollConnectionHelper(QuicEpollServer* eps, QuicAllocator allocator);
+ QuicEpollConnectionHelper(QuicEpollServer* epoll_server,
+ QuicAllocator allocator_type);
QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete;
QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) =
delete;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc
index 74922c37721..c7da0ae17ba 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc
@@ -279,6 +279,7 @@ const char* QuicErrorCodeToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL);
RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH);
RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE);
+ RETURN_STRING_LITERAL(QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
@@ -784,6 +785,8 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
case QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE:
return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+ case QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED:
+ return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
case QUIC_LAST_ERROR:
return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
index 218b12ff1ea..0ecef013ff9 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
@@ -608,9 +608,10 @@ enum QuicErrorCode {
QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL = 208,
QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH = 209,
QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE = 210,
+ QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED = 211,
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 211,
+ QUIC_LAST_ERROR = 212,
};
// 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/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h
index b7b7f155cb4..069ba10b822 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,8 @@
#ifdef QUIC_FLAG
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_set_burst_token, false)
+
QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false)
// A testonly reloadable flag that will always default to false.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
@@ -16,15 +18,15 @@ QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false)
// A testonly restart flag that will always default to true.
QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
// Donot check amplification limit if there is available pending_timer_transmission_count.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_check_amplification_limit_with_pending_timer_credit, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_check_amplification_limit_with_pending_timer_credit, true)
// If bytes in flight has dipped below 1.25*MaxBW in the last round, do not exit PROBE_UP due to excess queue buildup.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_probe_up_exit_if_no_queue, true)
// If true, 1) NEW_TOKENs sent from a IETF QUIC session will include the cached network parameters proto, 2) A min_rtt received from a validated token will be used to set the initial rtt, 3) Enable bandwidth resumption for IETF QUIC when connection options BWRE or BWMX exists.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_cached_network_parameters_to_address_token2, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_cached_network_parameters_to_address_token2, true)
// If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
-// If true, QUIC won\'t honor the connection option TLPR
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_deprecate_tlpr, true)
+// If true, QpackEncoder will stop emitting instructions on the encoder stream if amount of buffered data exceeds a hardcoded limit.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_limit_encoder_stream_buffering, true)
// If true, QuicGsoBatchWriter will support release time if it is available and the process has the permission to do so.
QUIC_FLAG(FLAGS_quic_restart_flag_quic_support_release_time_for_gso, false)
// If true, TlsServerHandshaker will be able to 1) request client cert, and 2) verify the client cert in the virtual method TlsServerHandshaker::VerifyCertChain.
@@ -32,7 +34,7 @@ QUIC_FLAG(FLAGS_quic_restart_flag_quic_tls_server_support_client_cert, true)
// If true, abort async QPACK header decompression in QuicSpdyStream::Reset() and in QuicSpdyStream::OnStreamReset().
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_reset, true)
// If true, accept empty crypto frame.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_accept_empty_crypto_frame, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_accept_empty_crypto_frame, true)
// If true, ack frequency frame can be sent from server to client.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true)
// If true, allow client to enable BBRv2 on server via connection option \'B2ON\'.
@@ -69,12 +71,8 @@ QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_single_ack_in_packet2, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_no_select_cert_if_disconnected, true)
// If true, do not count bytes sent/received on the alternative path into the bytes sent/received on the default path.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_count_bytes_on_alternative_path_seperately, true)
-// If true, do not re-arm PTO while sending application data during handshake.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_rearm_pto_on_application_data_during_handshake, true)
// If true, do not use the gQUIC common certificate set for certificate compression.
QUIC_FLAG(FLAGS_quic_restart_flag_quic_no_common_cert_set, true)
-// If true, drop unsent PATH_RESPONSEs and rely on peer\'s retry.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_drop_unsent_path_response, true)
// If true, enable server retransmittable on wire PING.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_server_on_wire_ping, true)
// If true, flush pending frames as well as pending padding bytes on connection migration.
@@ -99,12 +97,12 @@ QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reset_per_packet_state_for_undecryptable_packets, true)
// If true, send PATH_RESPONSE upon receiving PATH_CHALLENGE regardless of perspective. --gfe2_reloadable_flag_quic_start_peer_migration_earlier has to be true before turn on this flag.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response2, true)
+// If true, server proactively retires client issued connection ID on reverse path validation failure.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_retire_cid_on_reverse_path_validation_failure, false)
// If true, set burst token to 2 in cwnd bootstrapping experiment.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false)
// If true, stop resetting ideal_next_packet_send_time_ in pacing sender.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
-// If true, suppress crypto data write in mid of packet processing.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_suppress_write_mid_packet_processing, true)
// If true, use BBRv2 as the default congestion controller. Takes precedence over --quic_default_to_bbr.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false)
// If true, use max(max_bw, send_rate) as the estimated bandwidth in QUIC\'s MaxAckHeightTracker.
@@ -117,22 +115,18 @@ QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, fa
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path3, true)
// If true, when client attempts TLS resumption, use token in session_cache_ instead of cached_states_ in QuicCryptoClientConfig.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_use_token_in_session_cache, true)
-// When receiving STOP_SENDING, send a RESET_STREAM with a matching error code.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_match_ietf_reset_code, true)
// When the flag is true, exit STARTUP after the same number of loss events as PROBE_UP.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_probe_up_loss_events, true)
-// When true, QUIC server will ignore received key_update_not_yet_supported transport parameter.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_key_update_not_yet_supported, true)
-// When true, QUIC server will ignore received user agent transport parameter and rely on getting that information from HTTP headers.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_user_agent_transport_parameter, true)
// When true, QUIC will both send and validate the version_information transport parameter.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_version_information, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_version_information, true)
// When true, defaults to BBR congestion control instead of Cubic.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
// When true, prevents QUIC\'s PacingSender from generating bursts when the congestion controller is CWND limited and not pacing limited.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pacing_sender_bursts, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pacing_sender_bursts, true)
// When true, set the initial congestion control window from connection options in QuicSentPacketManager rather than TcpCubicSenderBytes.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, true)
+// When true, support draft-ietf-quic-v2-01
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_version_2_draft_01, false)
// When true, the B203 connection option causes the Bbr2Sender to ignore inflight_hi during PROBE_UP and increase it when the bytes delivered without loss are higher.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_ignore_inflight_hi_in_probe_up, true)
// When true, the B205 connection option enables extra acked in STARTUP, and B204 adds new logic to decrease it whenever max bandwidth increases.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc
index 79ace5a642d..da28e4c5b5c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_framer.cc
@@ -170,8 +170,7 @@ QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
}
}
-QuicPacketNumberLength ReadAckPacketNumberLength(
- uint8_t flags) {
+QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
case PACKET_FLAGS_8BYTE_PACKET:
return PACKET_6BYTE_PACKET_NUMBER;
@@ -197,16 +196,17 @@ QuicPacketNumberLength GetShortHeaderPacketNumberLength(uint8_t type) {
return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
}
-uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type) {
+uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
+ const ParsedQuicVersion& version) {
switch (type) {
case INITIAL:
- return 0;
+ return version.UsesV2PacketTypes() ? (1 << 4) : 0;
case ZERO_RTT_PROTECTED:
- return 1 << 4;
+ return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
case HANDSHAKE:
- return 2 << 4;
+ return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
case RETRY:
- return 3 << 4;
+ return version.UsesV2PacketTypes() ? 0 : (3 << 4);
case VERSION_NEGOTIATION:
return 0xF0; // Value does not matter
default:
@@ -215,27 +215,22 @@ uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type) {
}
}
-bool GetLongHeaderType(uint8_t type, QuicLongHeaderType* long_header_type) {
+QuicLongHeaderType GetLongHeaderType(uint8_t type,
+ const ParsedQuicVersion& version) {
QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
switch ((type & 0x30) >> 4) {
case 0:
- *long_header_type = INITIAL;
- break;
+ return version.UsesV2PacketTypes() ? RETRY : INITIAL;
case 1:
- *long_header_type = ZERO_RTT_PROTECTED;
- break;
+ return version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
case 2:
- *long_header_type = HANDSHAKE;
- break;
+ return version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
case 3:
- *long_header_type = RETRY;
- break;
+ return version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
default:
QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
- *long_header_type = INVALID_PACKET_TYPE;
- return false;
+ return INVALID_PACKET_TYPE;
}
- return true;
}
QuicPacketNumberLength GetLongHeaderPacketNumberLength(uint8_t type) {
@@ -331,8 +326,7 @@ bool IsValidFullPacketNumber(uint64_t full_packet_number,
return full_packet_number > 0 || version.HasIetfQuicFrames();
}
-bool AppendIetfConnectionIds(bool version_flag,
- bool use_length_prefix,
+bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
QuicConnectionId destination_connection_id,
QuicConnectionId source_connection_id,
QuicDataWriter* writer) {
@@ -412,6 +406,7 @@ QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
perspective_(perspective),
validate_flags_(true),
process_timestamps_(false),
+ max_receive_timestamps_per_ack_(std::numeric_limits<uint32_t>::max()),
receive_timestamps_exponent_(0),
creation_time_(creation_time),
last_timestamp_(QuicTime::Delta::Zero()),
@@ -476,13 +471,14 @@ size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
}
// static
-size_t QuicFramer::GetMinAckFrameSize(QuicTransportVersion version,
- const QuicAckFrame& ack_frame,
- uint32_t local_ack_delay_exponent) {
+size_t QuicFramer::GetMinAckFrameSize(
+ QuicTransportVersion version, const QuicAckFrame& ack_frame,
+ uint32_t local_ack_delay_exponent,
+ bool use_ietf_ack_with_receive_timestamp) {
if (VersionHasIetfQuicFrames(version)) {
// The minimal ack frame consists of the following fields: Largest
- // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and ECN
- // counts.
+ // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and either 0
+ // Timestamp Range Count or ECN counts.
// Type byte + largest acked.
size_t min_size =
kQuicFrameTypeSize +
@@ -496,10 +492,14 @@ size_t QuicFramer::GetMinAckFrameSize(QuicTransportVersion version,
min_size += QuicDataWriter::GetVarInt62Len(
ack_frame.packets.Empty() ? 0
: ack_frame.packets.rbegin()->Length() - 1);
- // ECN counts.
- if (ack_frame.ecn_counters_populated &&
- (ack_frame.ect_0_count || ack_frame.ect_1_count ||
- ack_frame.ecn_ce_count)) {
+
+ if (use_ietf_ack_with_receive_timestamp) {
+ // 0 Timestamp Range Count.
+ min_size += QuicDataWriter::GetVarInt62Len(0);
+ } else if (ack_frame.ecn_counters_populated &&
+ (ack_frame.ect_0_count || ack_frame.ect_1_count ||
+ ack_frame.ecn_ce_count)) {
+ // ECN counts.
min_size += (QuicDataWriter::GetVarInt62Len(ack_frame.ect_0_count) +
QuicDataWriter::GetVarInt62Len(ack_frame.ect_1_count) +
QuicDataWriter::GetVarInt62Len(ack_frame.ecn_ce_count));
@@ -533,8 +533,7 @@ size_t QuicFramer::GetRstStreamFrameSize(QuicTransportVersion version,
// static
size_t QuicFramer::GetConnectionCloseFrameSize(
- QuicTransportVersion version,
- const QuicConnectionCloseFrame& frame) {
+ QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
// Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
return kQuicFrameTypeSize + kQuicErrorCodeSize +
@@ -569,8 +568,7 @@ size_t QuicFramer::GetMinGoAwayFrameSize() {
// static
size_t QuicFramer::GetWindowUpdateFrameSize(
- QuicTransportVersion version,
- const QuicWindowUpdateFrame& frame) {
+ QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
}
@@ -599,8 +597,7 @@ size_t QuicFramer::GetMaxStreamsFrameSize(QuicTransportVersion version,
// static
size_t QuicFramer::GetStreamsBlockedFrameSize(
- QuicTransportVersion version,
- const QuicStreamsBlockedFrame& frame) {
+ QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
if (!VersionHasIetfQuicFrames(version)) {
QUIC_BUG(quic_bug_10850_10)
<< "In version " << version
@@ -658,8 +655,7 @@ size_t QuicFramer::GetPathResponseFrameSize(
// static
size_t QuicFramer::GetRetransmittableControlFrameSize(
- QuicTransportVersion version,
- const QuicFrame& frame) {
+ QuicTransportVersion version, const QuicFrame& frame) {
switch (frame.type) {
case PING_FRAME:
// Ping has no payload.
@@ -793,11 +789,8 @@ bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
}
size_t QuicFramer::GetSerializedFrameLength(
- const QuicFrame& frame,
- size_t free_bytes,
- bool first_frame,
- bool last_frame,
- QuicPacketNumberLength packet_number_length) {
+ const QuicFrame& frame, size_t free_bytes, bool first_frame,
+ bool last_frame, QuicPacketNumberLength packet_number_length) {
// Prevent a rare crash reported in b/19458523.
if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
QUIC_BUG(quic_bug_10850_13)
@@ -835,9 +828,10 @@ size_t QuicFramer::GetSerializedFrameLength(
}
bool can_truncate =
frame.type == ACK_FRAME &&
- free_bytes >= GetMinAckFrameSize(version_.transport_version,
- *frame.ack_frame,
- local_ack_delay_exponent_);
+ free_bytes >=
+ GetMinAckFrameSize(version_.transport_version, *frame.ack_frame,
+ local_ack_delay_exponent_,
+ UseIetfAckWithReceiveTimestamp(*frame.ack_frame));
if (can_truncate) {
// Truncate the frame so the packet will not exceed kMaxOutgoingPacketSize.
// Note that we may not use every byte of the writer in this case.
@@ -887,8 +881,7 @@ bool QuicFramer::WriteIetfLongHeaderLength(const QuicPacketHeader& header,
}
size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
- const QuicFrames& frames,
- char* buffer,
+ const QuicFrames& frames, char* buffer,
size_t packet_length,
EncryptionLevel level) {
QUIC_BUG_IF(quic_bug_12975_2,
@@ -1345,10 +1338,8 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildIetfStatelessResetPacket(
// static
std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
QuicConnectionId server_connection_id,
- QuicConnectionId client_connection_id,
- bool ietf_quic,
- bool use_length_prefix,
- const ParsedQuicVersionVector& versions) {
+ QuicConnectionId client_connection_id, bool ietf_quic,
+ bool use_length_prefix, const ParsedQuicVersionVector& versions) {
QUIC_CODE_COUNT(quic_build_version_negotiation);
if (use_length_prefix) {
QUICHE_DCHECK(ietf_quic);
@@ -1420,8 +1411,7 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
// static
std::unique_ptr<QuicEncryptedPacket>
QuicFramer::BuildIetfVersionNegotiationPacket(
- bool use_length_prefix,
- QuicConnectionId server_connection_id,
+ bool use_length_prefix, QuicConnectionId server_connection_id,
QuicConnectionId client_connection_id,
const ParsedQuicVersionVector& versions) {
QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
@@ -1566,8 +1556,7 @@ bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
}
bool QuicFramer::ProcessVersionNegotiationPacket(
- QuicDataReader* reader,
- const QuicPacketHeader& header) {
+ QuicDataReader* reader, const QuicPacketHeader& header) {
QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
QuicVersionNegotiationPacket packet(
@@ -1667,8 +1656,7 @@ bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader,
// If the IETF length field only spans part of the outer packet,
// then there is a coalesced packet after this one.
void QuicFramer::MaybeProcessCoalescedPacket(
- const QuicDataReader& encrypted_reader,
- uint64_t remaining_bytes_length,
+ const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
const QuicPacketHeader& header) {
if (header.remaining_packet_length >= remaining_bytes_length) {
// There is no coalesced packet.
@@ -2221,7 +2209,7 @@ bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
if (header.version_flag) {
type = static_cast<uint8_t>(
FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
- LongHeaderTypeToOnWireValue(header.long_packet_type) |
+ LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
PacketNumberLengthToOnWireValue(header.packet_number_length));
} else {
type = static_cast<uint8_t>(
@@ -2357,8 +2345,7 @@ const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
uint64_t QuicFramer::CalculatePacketNumberFromWire(
QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t packet_number) const {
+ QuicPacketNumber base_packet_number, uint64_t packet_number) const {
// The new packet number might have wrapped to the next epoch, or
// it might have reverse wrapped to the previous epoch, or it might
// remain in the same epoch. Select the packet number closest to the
@@ -2632,21 +2619,27 @@ bool QuicFramer::ProcessIetfHeaderTypeByte(QuicDataReader* reader,
set_detailed_error("Fixed bit is 0 in long header.");
return false;
}
- if (!GetLongHeaderType(type, &header->long_packet_type)) {
- set_detailed_error("Illegal long header type value.");
- return false;
- }
- if (header->long_packet_type == RETRY) {
- if (!version().SupportsRetry()) {
- set_detailed_error("RETRY not supported in this version.");
+ header->long_packet_type = GetLongHeaderType(type, header->version);
+ switch (header->long_packet_type) {
+ case INVALID_PACKET_TYPE:
+ set_detailed_error("Illegal long header type value.");
return false;
- }
- if (perspective_ == Perspective::IS_SERVER) {
- set_detailed_error("Client-initiated RETRY is invalid.");
- return false;
- }
- } else if (!header->version.HasHeaderProtection()) {
- header->packet_number_length = GetLongHeaderPacketNumberLength(type);
+ case RETRY:
+ if (!version().SupportsRetry()) {
+ set_detailed_error("RETRY not supported in this version.");
+ return false;
+ }
+ if (perspective_ == Perspective::IS_SERVER) {
+ set_detailed_error("Client-initiated RETRY is invalid.");
+ return false;
+ }
+ break;
+ default:
+ if (!header->version.HasHeaderProtection()) {
+ header->packet_number_length =
+ GetLongHeaderPacketNumberLength(type);
+ }
+ break;
}
}
}
@@ -2690,14 +2683,11 @@ bool QuicFramer::ProcessVersionLabel(QuicDataReader* reader,
// static
bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
- QuicDataReader* reader,
- ParsedQuicVersion version,
- Perspective perspective,
+ QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
bool should_update_expected_server_connection_id_length,
uint8_t* expected_server_connection_id_length,
uint8_t* destination_connection_id_length,
- uint8_t* source_connection_id_length,
- std::string* detailed_error) {
+ uint8_t* source_connection_id_length, std::string* detailed_error) {
uint8_t connection_id_lengths_byte;
if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
*detailed_error = "Unable to read ConnectionId length.";
@@ -2880,10 +2870,8 @@ bool QuicFramer::ProcessIetfPacketHeader(QuicDataReader* reader,
}
bool QuicFramer::ProcessAndCalculatePacketNumber(
- QuicDataReader* reader,
- QuicPacketNumberLength packet_number_length,
- QuicPacketNumber base_packet_number,
- uint64_t* packet_number) {
+ QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
+ QuicPacketNumber base_packet_number, uint64_t* packet_number) {
uint64_t wire_packet_number;
if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
return false;
@@ -3131,8 +3119,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
// static
bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
- uint64_t frame_type,
- EncryptionLevel level) {
+ uint64_t frame_type, EncryptionLevel level) {
switch (level) {
case ENCRYPTION_INITIAL:
case ENCRYPTION_HANDSHAKE:
@@ -3560,8 +3547,7 @@ void SetBit(uint8_t* flags, bool val, uint8_t offset) {
}
} // namespace
-bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader,
- uint8_t frame_type,
+bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
QuicStreamFrame* frame) {
uint8_t stream_flags = frame_type;
@@ -3748,12 +3734,12 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
// Determine the two lengths from the frame type: largest acked length,
// ack block length.
- const QuicPacketNumberLength ack_block_length = ReadAckPacketNumberLength(
- ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
- kActBlockLengthOffset));
- const QuicPacketNumberLength largest_acked_length = ReadAckPacketNumberLength(
- ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
- kLargestAckedOffset));
+ const QuicPacketNumberLength ack_block_length =
+ ReadAckPacketNumberLength(ExtractBits(
+ frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
+ const QuicPacketNumberLength largest_acked_length =
+ ReadAckPacketNumberLength(ExtractBits(
+ frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
uint64_t largest_acked;
if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
@@ -4179,7 +4165,7 @@ bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
// packet order.
timestamp_delta = timestamp_delta << receive_timestamps_exponent_;
if (i == 0 && j == 0) {
- last_timestamp_ = CalculateTimestampFromWire(timestamp_delta);
+ last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
} else {
last_timestamp_ = last_timestamp_ -
QuicTime::Delta::FromMicroseconds(timestamp_delta);
@@ -4188,10 +4174,10 @@ bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
return false;
}
}
- visitor_->OnAckTimestamp(packet_number - j,
- creation_time_ + last_timestamp_);
+ visitor_->OnAckTimestamp(packet_number, creation_time_ + last_timestamp_);
+ packet_number--;
}
- packet_number = packet_number - (timestamp_count - 1);
+ packet_number--;
}
return true;
}
@@ -4364,11 +4350,9 @@ bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader,
// static
absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
- QuicTransportVersion version,
- const QuicEncryptedPacket& encrypted,
+ QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
QuicConnectionIdLength destination_connection_id_length,
- QuicConnectionIdLength source_connection_id_length,
- bool includes_version,
+ QuicConnectionIdLength source_connection_id_length, bool includes_version,
bool includes_diversification_nonce,
QuicPacketNumberLength packet_number_length,
QuicVariableLengthIntegerLength retry_token_length_length,
@@ -4397,8 +4381,7 @@ void QuicFramer::SetDecrypter(EncryptionLevel level,
}
void QuicFramer::SetAlternativeDecrypter(
- EncryptionLevel level,
- std::unique_ptr<QuicDecrypter> decrypter,
+ EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used) {
QUICHE_DCHECK_NE(level, decrypter_level_);
QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
@@ -4523,10 +4506,8 @@ void QuicFramer::SetInitialObfuscators(QuicConnectionId connection_id) {
}
size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
- QuicPacketNumber packet_number,
- size_t ad_len,
- size_t total_len,
- size_t buffer_len,
+ QuicPacketNumber packet_number, size_t ad_len,
+ size_t total_len, size_t buffer_len,
char* buffer) {
QUICHE_DCHECK(packet_number.IsInitialized());
if (encrypter_[level] == nullptr) {
@@ -4568,10 +4549,8 @@ constexpr bool IsLongHeader(uint8_t type_byte) {
} // namespace
-bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level,
- char* buffer,
- size_t buffer_len,
- size_t ad_len) {
+bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
+ size_t buffer_len, size_t ad_len) {
QuicDataReader buffer_reader(buffer, buffer_len);
QuicDataWriter buffer_writer(buffer_len, buffer);
// The sample starts 4 bytes after the start of the packet number.
@@ -4615,7 +4594,8 @@ bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level,
QuicLongHeaderType header_type;
if (IsLongHeader(type_byte)) {
bitmask = 0x0f;
- if (!GetLongHeaderType(type_byte, &header_type)) {
+ header_type = GetLongHeaderType(type_byte, version_);
+ if (header_type == INVALID_PACKET_TYPE) {
return false;
}
}
@@ -4781,8 +4761,7 @@ bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
size_t QuicFramer::EncryptPayload(EncryptionLevel level,
QuicPacketNumber packet_number,
- const QuicPacket& packet,
- char* buffer,
+ const QuicPacket& packet, char* buffer,
size_t buffer_len) {
QUICHE_DCHECK(packet_number.IsInitialized());
if (encrypter_[level] == nullptr) {
@@ -4867,8 +4846,7 @@ bool QuicFramer::DecryptPayload(size_t udp_packet_length,
absl::string_view encrypted,
absl::string_view associated_data,
const QuicPacketHeader& header,
- char* decrypted_buffer,
- size_t buffer_length,
+ char* decrypted_buffer, size_t buffer_length,
size_t* decrypted_length,
EncryptionLevel* decrypted_level) {
if (!EncryptionLevelIsValid(decrypter_level_)) {
@@ -5088,9 +5066,11 @@ size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
previous_smallest = iter->min();
}
- // ECN counts.
- if (frame.ecn_counters_populated &&
- (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+ if (UseIetfAckWithReceiveTimestamp(frame)) {
+ ack_frame_size += GetIetfAckFrameTimestampSize(frame);
+ } else if (frame.ecn_counters_populated &&
+ (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+ // ECN counts.
ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_0_count);
ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_1_count);
ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count);
@@ -5099,9 +5079,22 @@ size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
return ack_frame_size;
}
+size_t QuicFramer::GetIetfAckFrameTimestampSize(const QuicAckFrame& ack) {
+ QUICHE_DCHECK(!ack.received_packet_times.empty());
+ std::string detailed_error;
+ absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+ GetAckTimestampRanges(ack, detailed_error);
+ if (!detailed_error.empty()) {
+ return 0;
+ }
+
+ int64_t size =
+ FrameAckTimestampRanges(ack, timestamp_ranges, /*writer=*/nullptr);
+ return std::max<int64_t>(0, size);
+}
+
size_t QuicFramer::GetAckFrameSize(
- const QuicAckFrame& ack,
- QuicPacketNumberLength /*packet_number_length*/) {
+ const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
QUICHE_DCHECK(!ack.packets.Empty());
size_t ack_size = 0;
@@ -5113,7 +5106,8 @@ size_t QuicFramer::GetAckFrameSize(
GetMinPacketNumberLength(QuicPacketNumber(ack_info.max_block_length));
ack_size = GetMinAckFrameSize(version_.transport_version, ack,
- local_ack_delay_exponent_);
+ local_ack_delay_exponent_,
+ UseIetfAckWithReceiveTimestamp(ack));
// First ack block length.
ack_size += ack_block_length;
if (ack_info.num_ack_blocks != 0) {
@@ -5141,8 +5135,7 @@ size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) {
}
size_t QuicFramer::ComputeFrameLength(
- const QuicFrame& frame,
- bool last_frame_in_packet,
+ const QuicFrame& frame, bool last_frame_in_packet,
QuicPacketNumberLength packet_number_length) {
switch (frame.type) {
case STREAM_FRAME:
@@ -5370,8 +5363,7 @@ bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
}
// static
-bool QuicFramer::AppendStreamId(size_t stream_id_length,
- QuicStreamId stream_id,
+bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
QuicDataWriter* writer) {
if (stream_id_length == 0 || stream_id_length > 4) {
QUIC_BUG(quic_bug_10850_77)
@@ -5397,8 +5389,7 @@ bool QuicFramer::AppendStreamOffset(size_t offset_length,
// static
bool QuicFramer::AppendAckBlock(uint8_t gap,
QuicPacketNumberLength length_length,
- uint64_t length,
- QuicDataWriter* writer) {
+ uint64_t length, QuicDataWriter* writer) {
if (length == 0) {
if (!IsValidPacketNumberLength(length_length)) {
QUIC_BUG(quic_bug_10850_79)
@@ -5613,7 +5604,8 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
int32_t available_timestamp_and_ack_block_bytes =
writer->capacity() - writer->length() - ack_block_length -
GetMinAckFrameSize(version_.transport_version, frame,
- local_ack_delay_exponent_) -
+ local_ack_delay_exponent_,
+ UseIetfAckWithReceiveTimestamp(frame)) -
(new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
QUICHE_DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
@@ -5808,6 +5800,172 @@ bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
return true;
}
+absl::InlinedVector<QuicFramer::AckTimestampRange, 2>
+QuicFramer::GetAckTimestampRanges(const QuicAckFrame& frame,
+ std::string& detailed_error) const {
+ detailed_error = "";
+ if (frame.received_packet_times.empty()) {
+ return {};
+ }
+
+ absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges;
+
+ for (size_t r = 0; r < std::min<size_t>(max_receive_timestamps_per_ack_,
+ frame.received_packet_times.size());
+ ++r) {
+ const size_t i = frame.received_packet_times.size() - 1 - r;
+ const QuicPacketNumber packet_number = frame.received_packet_times[i].first;
+ const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+
+ if (timestamp_ranges.empty()) {
+ if (receive_timestamp < creation_time_ ||
+ LargestAcked(frame) < packet_number) {
+ detailed_error =
+ "The first packet is either received earlier than framer creation "
+ "time, or larger than largest acked packet.";
+ QUIC_BUG(quic_framer_ack_ts_first_packet_bad)
+ << detailed_error << " receive_timestamp:" << receive_timestamp
+ << ", framer_creation_time:" << creation_time_
+ << ", packet_number:" << packet_number
+ << ", largest_acked:" << LargestAcked(frame);
+ return {};
+ }
+ timestamp_ranges.push_back(AckTimestampRange());
+ timestamp_ranges.back().gap = LargestAcked(frame) - packet_number;
+ timestamp_ranges.back().range_begin = i;
+ timestamp_ranges.back().range_end = i;
+ continue;
+ }
+
+ const size_t prev_i = timestamp_ranges.back().range_end;
+ const QuicPacketNumber prev_packet_number =
+ frame.received_packet_times[prev_i].first;
+ const QuicTime prev_receive_timestamp =
+ frame.received_packet_times[prev_i].second;
+
+ QUIC_DVLOG(3) << "prev_packet_number:" << prev_packet_number
+ << ", packet_number:" << packet_number;
+ if (prev_receive_timestamp < receive_timestamp ||
+ prev_packet_number <= packet_number) {
+ detailed_error = "Packet number and/or receive time not in order.";
+ QUIC_BUG(quic_framer_ack_ts_packet_out_of_order)
+ << detailed_error << " packet_number:" << packet_number
+ << ", receive_timestamp:" << receive_timestamp
+ << ", prev_packet_number:" << prev_packet_number
+ << ", prev_receive_timestamp:" << prev_receive_timestamp;
+ return {};
+ }
+
+ if (prev_packet_number == packet_number + 1) {
+ timestamp_ranges.back().range_end = i;
+ } else {
+ timestamp_ranges.push_back(AckTimestampRange());
+ timestamp_ranges.back().gap = prev_packet_number - 2 - packet_number;
+ timestamp_ranges.back().range_begin = i;
+ timestamp_ranges.back().range_end = i;
+ }
+ }
+
+ return timestamp_ranges;
+}
+
+int64_t QuicFramer::FrameAckTimestampRanges(
+ const QuicAckFrame& frame,
+ const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+ QuicDataWriter* writer) const {
+ int64_t size = 0;
+ auto maybe_write_var_int62 = [&](uint64_t value) {
+ size += QuicDataWriter::GetVarInt62Len(value);
+ if (writer != nullptr && !writer->WriteVarInt62(value)) {
+ return false;
+ }
+ return true;
+ };
+
+ if (!maybe_write_var_int62(timestamp_ranges.size())) {
+ return -1;
+ }
+
+ // |effective_prev_time| is the exponent-encoded timestamp of the previous
+ // packet.
+ absl::optional<QuicTime> effective_prev_time;
+ for (const AckTimestampRange& range : timestamp_ranges) {
+ QUIC_DVLOG(3) << "Range: gap:" << range.gap << ", beg:" << range.range_begin
+ << ", end:" << range.range_end;
+ if (!maybe_write_var_int62(range.gap)) {
+ return -1;
+ }
+
+ if (!maybe_write_var_int62(range.range_begin - range.range_end + 1)) {
+ return -1;
+ }
+
+ for (int64_t i = range.range_begin; i >= range.range_end; --i) {
+ const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+ uint64_t time_delta;
+ if (effective_prev_time.has_value()) {
+ time_delta =
+ (*effective_prev_time - receive_timestamp).ToMicroseconds();
+ QUIC_DVLOG(3) << "time_delta:" << time_delta
+ << ", exponent:" << receive_timestamps_exponent_
+ << ", effective_prev_time:" << *effective_prev_time
+ << ", recv_time:" << receive_timestamp;
+ time_delta = time_delta >> receive_timestamps_exponent_;
+ effective_prev_time = effective_prev_time.value() -
+ QuicTime::Delta::FromMicroseconds(
+ time_delta << receive_timestamps_exponent_);
+ } else {
+ // The first delta is from framer creation to the current receive
+ // timestamp (forward in time), whereas in the common case subsequent
+ // deltas move backwards in time.
+ time_delta = (receive_timestamp - creation_time_).ToMicroseconds();
+ QUIC_DVLOG(3) << "First time_delta:" << time_delta
+ << ", exponent:" << receive_timestamps_exponent_
+ << ", recv_time:" << receive_timestamp
+ << ", creation_time:" << creation_time_;
+ // Round up the first exponent-encoded time delta so that the next
+ // receive timestamp is guaranteed to be decreasing.
+ time_delta = ((time_delta - 1) >> receive_timestamps_exponent_) + 1;
+ effective_prev_time =
+ creation_time_ + QuicTime::Delta::FromMicroseconds(
+ time_delta << receive_timestamps_exponent_);
+ }
+
+ if (!maybe_write_var_int62(time_delta)) {
+ return -1;
+ }
+ }
+ }
+
+ return size;
+}
+
+bool QuicFramer::AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+ QuicDataWriter* writer) {
+ QUICHE_DCHECK(!frame.received_packet_times.empty());
+ std::string detailed_error;
+ const absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+ GetAckTimestampRanges(frame, detailed_error);
+ if (!detailed_error.empty()) {
+ set_detailed_error(std::move(detailed_error));
+ return false;
+ }
+
+ // Compute the size first using a null writer.
+ int64_t size =
+ FrameAckTimestampRanges(frame, timestamp_ranges, /*writer=*/nullptr);
+ if (size > static_cast<int64_t>(writer->capacity() - writer->length())) {
+ QUIC_DVLOG(1) << "Insufficient room to write IETF ack receive timestamps. "
+ "size_remain:"
+ << (writer->capacity() - writer->length())
+ << ", size_needed:" << size;
+ // Write a Timestamp Range Count of 0.
+ return writer->WriteVarInt62(0);
+ }
+
+ return FrameAckTimestampRanges(frame, timestamp_ranges, writer) > 0;
+}
+
bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
const QuicStopWaitingFrame& frame,
QuicDataWriter* writer) {
@@ -5845,8 +6003,10 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
QuicDataWriter* writer) {
uint8_t type = IETF_ACK;
uint64_t ecn_size = 0;
- if (frame.ecn_counters_populated &&
- (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+ if (UseIetfAckWithReceiveTimestamp(frame)) {
+ type = IETF_ACK_RECEIVE_TIMESTAMPS;
+ } else if (frame.ecn_counters_populated &&
+ (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
// Change frame type to ACK_ECN if any ECN count is available.
type = IETF_ACK_ECN;
ecn_size = (QuicDataWriter::GetVarInt62Len(frame.ect_0_count) +
@@ -5904,10 +6064,19 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
const uint64_t gap = previous_smallest - iter->max() - 1;
const uint64_t ack_range = iter->Length() - 1;
- if (writer->remaining() < ecn_size ||
- writer->remaining() - ecn_size <
+ if (type == IETF_ACK_RECEIVE_TIMESTAMPS &&
+ writer->remaining() <
static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) +
- QuicDataWriter::GetVarInt62Len(ack_range))) {
+ QuicDataWriter::GetVarInt62Len(ack_range) +
+ QuicDataWriter::GetVarInt62Len(0))) {
+ // If we write this ACK range we won't have space for a timestamp range
+ // count of 0.
+ break;
+ } else if (writer->remaining() < ecn_size ||
+ writer->remaining() - ecn_size <
+ static_cast<size_t>(
+ QuicDataWriter::GetVarInt62Len(gap) +
+ QuicDataWriter::GetVarInt62Len(ack_range))) {
// ACK range does not fit, truncate it.
break;
}
@@ -5951,6 +6120,12 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
}
}
+ if (type == IETF_ACK_RECEIVE_TIMESTAMPS) {
+ if (!AppendIetfTimestampsToAckFrame(frame, writer)) {
+ return false;
+ }
+ }
+
return true;
}
@@ -5976,8 +6151,7 @@ bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
}
bool QuicFramer::AppendConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer) {
+ const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
if (VersionHasIetfQuicFrames(version_.transport_version)) {
return AppendIetfConnectionCloseFrame(frame, writer);
}
@@ -6084,8 +6258,7 @@ bool QuicFramer::RaiseError(QuicErrorCode error) {
}
bool QuicFramer::IsVersionNegotiation(
- const QuicPacketHeader& header,
- bool packet_has_ietf_packet_header) const {
+ const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
if (!packet_has_ietf_packet_header &&
perspective_ == Perspective::IS_CLIENT) {
return header.version_flag;
@@ -6097,8 +6270,7 @@ bool QuicFramer::IsVersionNegotiation(
}
bool QuicFramer::AppendIetfConnectionCloseFrame(
- const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer) {
+ const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
QUIC_BUG(quic_bug_10850_90)
@@ -6135,8 +6307,7 @@ bool QuicFramer::AppendIetfConnectionCloseFrame(
}
bool QuicFramer::ProcessIetfConnectionCloseFrame(
- QuicDataReader* reader,
- QuicConnectionCloseType type,
+ QuicDataReader* reader, QuicConnectionCloseType type,
QuicConnectionCloseFrame* frame) {
frame->close_type = type;
@@ -6263,8 +6434,7 @@ bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
}
bool QuicFramer::ProcessStopSendingFrame(
- QuicDataReader* reader,
- QuicStopSendingFrame* stop_sending_frame) {
+ QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
&stop_sending_frame->stream_id)) {
return false;
@@ -6281,8 +6451,7 @@ bool QuicFramer::ProcessStopSendingFrame(
}
bool QuicFramer::AppendStopSendingFrame(
- const QuicStopSendingFrame& stop_sending_frame,
- QuicDataWriter* writer) {
+ const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
set_detailed_error("Can not write stop sending stream id");
return false;
@@ -6438,8 +6607,7 @@ bool QuicFramer::ProcessStreamsBlockedFrame(QuicDataReader* reader,
}
bool QuicFramer::AppendNewConnectionIdFrame(
- const QuicNewConnectionIdFrame& frame,
- QuicDataWriter* writer) {
+ const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(frame.sequence_number)) {
set_detailed_error("Can not write New Connection ID sequence number");
return false;
@@ -6500,8 +6668,7 @@ bool QuicFramer::ProcessNewConnectionIdFrame(QuicDataReader* reader,
}
bool QuicFramer::AppendRetireConnectionIdFrame(
- const QuicRetireConnectionIdFrame& frame,
- QuicDataWriter* writer) {
+ const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
if (!writer->WriteVarInt62(frame.sequence_number)) {
set_detailed_error("Can not write Retire Connection ID sequence number");
return false;
@@ -6510,8 +6677,7 @@ bool QuicFramer::AppendRetireConnectionIdFrame(
}
bool QuicFramer::ProcessRetireConnectionIdFrame(
- QuicDataReader* reader,
- QuicRetireConnectionIdFrame* frame) {
+ QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
if (!reader->ReadVarInt62(&frame->sequence_number)) {
set_detailed_error(
"Unable to read retire connection ID frame sequence number.");
@@ -6567,8 +6733,7 @@ uint8_t QuicFramer::GetStreamFrameTypeByte(const QuicStreamFrame& frame,
}
uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
- const QuicStreamFrame& frame,
- bool last_frame_in_packet) const {
+ const QuicStreamFrame& frame, bool last_frame_in_packet) const {
QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
uint8_t type_byte = IETF_STREAM;
if (!last_frame_in_packet) {
@@ -6662,14 +6827,10 @@ QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
// static
QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
- QuicDataReader* reader,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- QuicVersionLabel* version_label,
+ QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
+ bool* version_present, QuicVersionLabel* version_label,
ParsedQuicVersion* parsed_version,
- QuicConnectionId* destination_connection_id,
- std::string* detailed_error) {
+ QuicConnectionId* destination_connection_id, std::string* detailed_error) {
*format = GOOGLE_QUIC_PACKET;
*version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
uint8_t destination_connection_id_length = 0;
@@ -6696,10 +6857,8 @@ namespace {
const QuicVersionLabel kProxVersionLabel = 0x50524F58; // "PROX"
inline bool PacketHasLengthPrefixedConnectionIds(
- const QuicDataReader& reader,
- ParsedQuicVersion parsed_version,
- QuicVersionLabel version_label,
- uint8_t first_byte) {
+ const QuicDataReader& reader, ParsedQuicVersion parsed_version,
+ QuicVersionLabel version_label, uint8_t first_byte) {
if (parsed_version.IsKnown()) {
return parsed_version.HasLengthPrefixedConnectionIds();
}
@@ -6733,18 +6892,15 @@ inline bool PacketHasLengthPrefixedConnectionIds(
}
inline bool ParseLongHeaderConnectionIds(
- QuicDataReader* reader,
- bool has_length_prefix,
- QuicVersionLabel version_label,
- QuicConnectionId* destination_connection_id,
- QuicConnectionId* source_connection_id,
- std::string* detailed_error) {
+ QuicDataReader& reader, bool has_length_prefix,
+ QuicVersionLabel version_label, QuicConnectionId& destination_connection_id,
+ QuicConnectionId& source_connection_id, std::string& detailed_error) {
if (has_length_prefix) {
- if (!reader->ReadLengthPrefixedConnectionId(destination_connection_id)) {
- *detailed_error = "Unable to read destination connection ID.";
+ if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
+ detailed_error = "Unable to read destination connection ID.";
return false;
}
- if (!reader->ReadLengthPrefixedConnectionId(source_connection_id)) {
+ if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
if (version_label == kProxVersionLabel) {
// The "PROX" version does not follow the length-prefixed invariants,
// and can therefore attempt to read a payload byte and interpret it
@@ -6753,14 +6909,14 @@ inline bool ParseLongHeaderConnectionIds(
// parsing as successful.
return true;
}
- *detailed_error = "Unable to read source connection ID.";
+ detailed_error = "Unable to read source connection ID.";
return false;
}
} else {
// Parse connection ID lengths.
uint8_t connection_id_lengths_byte;
- if (!reader->ReadUInt8(&connection_id_lengths_byte)) {
- *detailed_error = "Unable to read connection ID lengths.";
+ if (!reader.ReadUInt8(&connection_id_lengths_byte)) {
+ detailed_error = "Unable to read connection ID lengths.";
return false;
}
uint8_t destination_connection_id_length =
@@ -6775,16 +6931,16 @@ inline bool ParseLongHeaderConnectionIds(
}
// Read destination connection ID.
- if (!reader->ReadConnectionId(destination_connection_id,
- destination_connection_id_length)) {
- *detailed_error = "Unable to read destination connection ID.";
+ if (!reader.ReadConnectionId(&destination_connection_id,
+ destination_connection_id_length)) {
+ detailed_error = "Unable to read destination connection ID.";
return false;
}
// Read source connection ID.
- if (!reader->ReadConnectionId(source_connection_id,
- source_connection_id_length)) {
- *detailed_error = "Unable to read source connection ID.";
+ if (!reader.ReadConnectionId(&source_connection_id,
+ source_connection_id_length)) {
+ detailed_error = "Unable to read source connection ID.";
return false;
}
}
@@ -6795,21 +6951,15 @@ inline bool ParseLongHeaderConnectionIds(
// static
QuicErrorCode QuicFramer::ParsePublicHeader(
- QuicDataReader* reader,
- uint8_t expected_destination_connection_id_length,
- bool ietf_format,
- uint8_t* first_byte,
- PacketHeaderFormat* format,
- bool* version_present,
- bool* has_length_prefix,
- QuicVersionLabel* version_label,
- ParsedQuicVersion* parsed_version,
+ QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
+ bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
+ bool* version_present, bool* has_length_prefix,
+ QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
QuicConnectionId* destination_connection_id,
QuicConnectionId* source_connection_id,
QuicLongHeaderType* long_packet_type,
QuicVariableLengthIntegerLength* retry_token_length_length,
- absl::string_view* retry_token,
- std::string* detailed_error) {
+ absl::string_view* retry_token, std::string* detailed_error) {
*version_present = false;
*has_length_prefix = false;
*version_label = 0;
@@ -6863,9 +7013,9 @@ QuicErrorCode QuicFramer::ParsePublicHeader(
*reader, *parsed_version, *version_label, *first_byte);
// Parse connection IDs.
- if (!ParseLongHeaderConnectionIds(reader, *has_length_prefix, *version_label,
- destination_connection_id,
- source_connection_id, detailed_error)) {
+ if (!ParseLongHeaderConnectionIds(*reader, *has_length_prefix, *version_label,
+ *destination_connection_id,
+ *source_connection_id, *detailed_error)) {
return QUIC_INVALID_PACKET_HEADER;
}
@@ -6875,14 +7025,20 @@ QuicErrorCode QuicFramer::ParsePublicHeader(
}
// Parse long packet type.
- if (!GetLongHeaderType(*first_byte, long_packet_type)) {
- *detailed_error = "Unable to parse long packet type.";
- return QUIC_INVALID_PACKET_HEADER;
- }
+ *long_packet_type = GetLongHeaderType(*first_byte, *parsed_version);
- if (!parsed_version->SupportsRetry() || *long_packet_type != INITIAL) {
- // Retry token is only present on initial packets for some versions.
- return QUIC_NO_ERROR;
+ switch (*long_packet_type) {
+ case INVALID_PACKET_TYPE:
+ *detailed_error = "Unable to parse long packet type.";
+ return QUIC_INVALID_PACKET_HEADER;
+ case INITIAL:
+ if (!parsed_version->SupportsRetry()) {
+ // Retry token is only present on initial packets for some versions.
+ return QUIC_NO_ERROR;
+ }
+ break;
+ default:
+ return QUIC_NO_ERROR;
}
*retry_token_length_length = reader->PeekVarInt62Length();
@@ -6903,8 +7059,7 @@ QuicErrorCode QuicFramer::ParsePublicHeader(
// static
bool QuicFramer::WriteClientVersionNegotiationProbePacket(
- char* packet_bytes,
- QuicByteCount packet_length,
+ char* packet_bytes, QuicByteCount packet_length,
const char* destination_connection_id_bytes,
uint8_t destination_connection_id_length) {
if (packet_bytes == nullptr) {
@@ -6981,10 +7136,8 @@ bool QuicFramer::WriteClientVersionNegotiationProbePacket(
// static
bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
- const char* packet_bytes,
- QuicByteCount packet_length,
- char* source_connection_id_bytes,
- uint8_t* source_connection_id_length_out,
+ const char* packet_bytes, QuicByteCount packet_length,
+ char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
std::string* detailed_error) {
if (detailed_error == nullptr) {
QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer.h b/chromium/net/third_party/quiche/src/quic/core/quic_framer.h
index 287888850b4..306f0491d58 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_framer.h
@@ -315,8 +315,15 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
process_timestamps_ = process_timestamps;
}
+ // Sets the max number of receive timestamps to send per ACK frame.
+ // TODO(wub): Remove the const once timestamps are negotiated via
+ // transport params.
+ void set_max_receive_timestamps_per_ack(uint32_t max_timestamps) const {
+ max_receive_timestamps_per_ack_ = max_timestamps;
+ }
+
// Sets the exponent to use when writing/reading ACK receive timestamps.
- void set_receive_timestamps_exponent(uint32_t exponent) {
+ void set_receive_timestamps_exponent(uint32_t exponent) const {
receive_timestamps_exponent_ = exponent;
}
@@ -347,7 +354,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// blocks.
static size_t GetMinAckFrameSize(QuicTransportVersion version,
const QuicAckFrame& ack_frame,
- uint32_t local_ack_delay_exponent);
+ uint32_t local_ack_delay_exponent,
+ bool use_ietf_ack_with_receive_timestamp);
// Size in bytes of a stop waiting frame.
static size_t GetStopWaitingFrameSize(
QuicPacketNumberLength packet_number_length);
@@ -521,8 +529,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
QuicDataWriter* writer);
size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
bool AppendStreamFrame(const QuicStreamFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
+ bool no_stream_frame_length, QuicDataWriter* writer);
bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
QuicDataWriter* writer);
@@ -728,6 +735,23 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
using NackRangeMap = std::map<QuicPacketNumber, uint8_t>;
+ // AckTimestampRange is a data structure derived from a QuicAckFrame. It is
+ // used to serialize timestamps in a IETF_ACK_RECEIVE_TIMESTAMPS frame.
+ struct QUIC_EXPORT_PRIVATE AckTimestampRange {
+ QuicPacketCount gap;
+ // |range_begin| and |range_end| are index(es) in
+ // QuicAckFrame.received_packet_times, representing a continuous range of
+ // packet numbers in descending order. |range_begin| >= |range_end|.
+ int64_t range_begin; // Inclusive
+ int64_t range_end; // Inclusive
+ };
+ absl::InlinedVector<AckTimestampRange, 2> GetAckTimestampRanges(
+ const QuicAckFrame& frame, std::string& detailed_error) const;
+ int64_t FrameAckTimestampRanges(
+ const QuicAckFrame& frame,
+ const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+ QuicDataWriter* writer) const;
+
struct QUIC_EXPORT_PRIVATE AckFrameInfo {
AckFrameInfo();
AckFrameInfo(const AckFrameInfo& other);
@@ -896,6 +920,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// Computes the wire size in bytes of time stamps in |ack|.
size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack);
+ size_t GetIetfAckFrameTimestampSize(const QuicAckFrame& ack);
// Computes the wire size in bytes of the |ack| frame.
size_t GetAckFrameSize(const QuicAckFrame& ack,
@@ -949,7 +974,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// |writer|, and return true if successful.
bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* builder);
+ QuicDataWriter* writer);
bool AppendTimestampsToAckFrame(const QuicAckFrame& frame,
QuicDataWriter* writer);
@@ -959,14 +984,16 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// of the frame.
bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
QuicDataWriter* writer);
+ bool AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+ QuicDataWriter* writer);
bool AppendStopWaitingFrame(const QuicPacketHeader& header,
const QuicStopWaitingFrame& frame,
- QuicDataWriter* builder);
+ QuicDataWriter* writer);
bool AppendRstStreamFrame(const QuicRstStreamFrame& frame,
- QuicDataWriter* builder);
+ QuicDataWriter* writer);
bool AppendConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
- QuicDataWriter* builder);
+ QuicDataWriter* writer);
bool AppendGoAwayFrame(const QuicGoAwayFrame& frame, QuicDataWriter* writer);
bool AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
QuicDataWriter* writer);
@@ -1081,6 +1108,15 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
+ // Determine whether the given QuicAckFrame should be serialized with a
+ // IETF_ACK_RECEIVE_TIMESTAMPS frame type.
+ bool UseIetfAckWithReceiveTimestamp(const QuicAckFrame& frame) const {
+ return VersionHasIetfQuicFrames(version_.transport_version) &&
+ process_timestamps_ &&
+ std::min<uint64_t>(max_receive_timestamps_per_ack_,
+ frame.received_packet_times.size()) > 0;
+ }
+
std::string detailed_error_;
QuicFramerVisitorInterface* visitor_;
QuicErrorCode error_;
@@ -1122,10 +1158,13 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// The diversification nonce from the last received packet.
DiversificationNonce last_nonce_;
// If true, send and process timestamps in the ACK frame.
- // TODO(ianswett): Remove the mutable once set_process_timestamps isn't const.
+ // TODO(ianswett): Remove the mutables once set_process_timestamps and
+ // set_receive_timestamp_exponent_ aren't const.
mutable bool process_timestamps_;
+ // The max number of receive timestamps to send per ACK frame.
+ mutable uint32_t max_receive_timestamps_per_ack_;
// The exponent to use when writing/reading ACK receive timestamps.
- uint32_t receive_timestamps_exponent_;
+ mutable uint32_t receive_timestamps_exponent_;
// The creation time of the connection, used to calculate timestamps.
QuicTime creation_time_;
// The last timestamp received if process_timestamps_ is true.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc
index 28b7c20345a..d24664dbded 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc
@@ -38,6 +38,8 @@
using testing::_;
using testing::ContainerEq;
+using testing::Eq;
+using testing::IsNull;
using testing::Return;
namespace quic {
@@ -105,10 +107,8 @@ class TestEncrypter : public QuicEncrypter {
bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
return true;
}
- bool EncryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view plaintext,
- char* output,
+ bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
+ absl::string_view plaintext, char* output,
size_t* output_length,
size_t /*max_output_length*/) override {
packet_number_ = QuicPacketNumber(packet_number);
@@ -162,10 +162,8 @@ class TestDecrypter : public QuicDecrypter {
bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
return true;
}
- bool DecryptPacket(uint64_t packet_number,
- absl::string_view associated_data,
- absl::string_view ciphertext,
- char* output,
+ bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
+ absl::string_view ciphertext, char* output,
size_t* output_length,
size_t /*max_output_length*/) override {
packet_number_ = QuicPacketNumber(packet_number);
@@ -197,9 +195,7 @@ class TestDecrypter : public QuicDecrypter {
};
std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
- const QuicPacket& packet,
- uint8_t tag,
- bool phase) {
+ const QuicPacket& packet, uint8_t tag, bool phase) {
std::string packet_data = std::string(packet.AsStringPiece());
if (phase) {
packet_data[0] |= FLAGS_KEY_PHASE_BIT;
@@ -692,9 +688,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
decrypter_(new test::TestDecrypter()),
version_(GetParam()),
start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
- framer_(AllSupportedVersions(),
- start_,
- Perspective::IS_SERVER,
+ framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
kQuicDefaultConnectionIdLength) {
framer_.set_version(version_);
if (framer_.version().KnowsWhichDecrypterToUse()) {
@@ -726,6 +720,19 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
}
+ // Helper functions to take a v1 long header packet and make it v2. These are
+ // not needed for short header packets, but if sent, this function will exit
+ // cleanly. It needs to be called twice for coalesced packets (see references
+ // to length_of_first_coalesced_packet below for examples of how to do this).
+ inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
+ if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
+ packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
+ }
+ }
+ inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
+ ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
+ }
+
bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
if (packet_number != encrypter_->packet_number_) {
QUIC_LOG(ERROR) << "Encrypted incorrect packet number. expected "
@@ -762,8 +769,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
}
bool CheckDecryption(
- const QuicEncryptedPacket& encrypted,
- bool includes_version,
+ const QuicEncryptedPacket& encrypted, bool includes_version,
bool includes_diversification_nonce,
QuicConnectionIdLength destination_connection_id_length,
QuicConnectionIdLength source_connection_id_length,
@@ -838,15 +844,13 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
}
}
- if (expected_error.empty())
- continue;
+ if (expected_error.empty()) continue;
CheckProcessingFails(*packet, i, expected_error, error_code);
}
}
- void CheckProcessingFails(const QuicEncryptedPacket& packet,
- size_t len,
+ void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
std::string expected_error,
QuicErrorCode error_code) {
QuicEncryptedPacket encrypted(packet.data(), len, false);
@@ -855,8 +859,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
}
- void CheckProcessingFails(unsigned char* packet,
- size_t len,
+ void CheckProcessingFails(unsigned char* packet, size_t len,
std::string expected_error,
QuicErrorCode error_code) {
QuicEncryptedPacket encrypted(AsChars(packet), len, false);
@@ -894,8 +897,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
// N starts at 1.
QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
- Perspective perspective,
- bool bidirectional,
+ Perspective perspective, bool bidirectional,
int n) {
if (bidirectional) {
return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
@@ -931,8 +933,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
GetQuicVersionByte(3)
// Run all framer tests with all supported versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicFramerTests,
- QuicFramerTest,
+INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
::testing::ValuesIn(AllSupportedVersions()),
::testing::PrintToStringParamName());
@@ -1273,6 +1274,7 @@ TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -1379,6 +1381,7 @@ TEST_P(QuicFramerTest, ParsePublicHeader) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -1669,6 +1672,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
};
// clang-format on
+ ReviseFirstByteByVersion(packet49);
PacketFragments& fragments =
framer_.version().HasLongHeaderLengths()
? packet49
@@ -2970,6 +2974,7 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
? VARIABLE_LENGTH_INTEGER_LENGTH_1
: VARIABLE_LENGTH_INTEGER_LENGTH_0;
+ ReviseFirstByteByVersion(packet_ietf);
PacketFragments& fragments =
VersionHasIetfQuicFrames(framer_.transport_version())
? packet_ietf
@@ -4113,7 +4118,7 @@ TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
// Timestamp range 2 (one packet).
{ "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x07 }},
+ { kVarInt62OneByte + 0x05 }},
{ "Unable to read receive timestamp count.",
{ kVarInt62OneByte + 0x01 }},
{ "Unable to read receive timestamp delta.",
@@ -4121,7 +4126,7 @@ TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
// Timestamp range 3 (two packets).
{ "Unable to read receive timestamp gap.",
- { kVarInt62OneByte + 0x0a }},
+ { kVarInt62OneByte + 0x08 }},
{ "Unable to read receive timestamp count.",
{ kVarInt62OneByte + 0x02 }},
{ "Unable to read receive timestamp delta.",
@@ -6420,6 +6425,7 @@ TEST_P(QuicFramerTest, ParseIetfRetryPacket) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().UsesTls()) {
+ ReviseFirstByteByVersion(packet_with_tag);
p = packet_with_tag;
p_length = ABSL_ARRAYSIZE(packet_with_tag);
} else if (framer_.version().HasLongHeaderLengths()) {
@@ -7115,6 +7121,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
unsigned char* p = packet;
size_t p_size = ABSL_ARRAYSIZE(packet);
if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+ ReviseFirstByteByVersion(packet_ietf);
p = packet_ietf;
p_size = ABSL_ARRAYSIZE(packet_ietf);
} else if (framer_.version().HasLongHeaderLengths()) {
@@ -7483,6 +7490,706 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
"constructed packet", data->data(), data->length(), AsChars(p), p_size);
}
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameMultipleRanges) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ // Timestamp Range 3.
+ {kSmallLargestObserved - 22, CreationTimePlus(0x29ffdddd)},
+ {kSmallLargestObserved - 21, CreationTimePlus(0x29ffdedd)},
+ // Timestamp Range 2.
+ {kSmallLargestObserved - 11, CreationTimePlus(0x29ffdeed)},
+ // Timestamp Range 1.
+ {kSmallLargestObserved - 4, CreationTimePlus(0x29ffeeed)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0x29ffeeee)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0x29ffffff)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ unsigned char packet_ietf[] = {
+ // type (short header, 4 byte packet number)
+ 0x43,
+ // connection_id
+ 0xFE,
+ 0xDC,
+ 0xBA,
+ 0x98,
+ 0x76,
+ 0x54,
+ 0x32,
+ 0x10,
+ // packet number
+ 0x12,
+ 0x34,
+ 0x56,
+ 0x78,
+
+ // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+ 0x22,
+ // largest acked
+ kVarInt62TwoBytes + 0x12,
+ 0x34, // = 4660
+ // Zero delta time.
+ kVarInt62OneByte + 0x00,
+ // number of additional ack blocks
+ kVarInt62OneByte + 0x00,
+ // first ack block length.
+ kVarInt62TwoBytes + 0x12,
+ 0x33,
+
+ // Receive Timestamps.
+
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x03,
+
+ // Timestamp range 1 (three packets).
+ // Gap
+ kVarInt62OneByte + 0x02,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x03,
+ // Timestamp Delta
+ kVarInt62FourBytes + 0x29,
+ 0xff,
+ 0xff,
+ 0xff,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x11,
+ 0x11,
+ // Timestamp Delta
+ kVarInt62OneByte + 0x01,
+
+ // Timestamp range 2 (one packet).
+ // Gap
+ kVarInt62OneByte + 0x05,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x01,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x10,
+ 0x00,
+
+ // Timestamp range 3 (two packets).
+ // Gap
+ kVarInt62OneByte + 0x08,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x02,
+ // Timestamp Delta
+ kVarInt62OneByte + 0x10,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x01,
+ 0x00,
+ };
+ // clang-format on
+
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ quiche::test::CompareCharArraysWithHexError(
+ "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+ ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameExceedsMaxTimestamps) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ // Timestamp Range 3 (not included because max receive timestamps = 4).
+ {kSmallLargestObserved - 20, CreationTimePlus(0x29ffdddd)},
+ // Timestamp Range 2.
+ {kSmallLargestObserved - 10, CreationTimePlus(0x29ffdedd)},
+ {kSmallLargestObserved - 9, CreationTimePlus(0x29ffdeed)},
+ // Timestamp Range 1.
+ {kSmallLargestObserved - 2, CreationTimePlus(0x29ffeeed)},
+ {kSmallLargestObserved - 1, CreationTimePlus(0x29ffeeee)},
+ {kSmallLargestObserved, CreationTimePlus(0x29ffffff)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ unsigned char packet_ietf[] = {
+ // type (short header, 4 byte packet number)
+ 0x43,
+ // connection_id
+ 0xFE,
+ 0xDC,
+ 0xBA,
+ 0x98,
+ 0x76,
+ 0x54,
+ 0x32,
+ 0x10,
+ // packet number
+ 0x12,
+ 0x34,
+ 0x56,
+ 0x78,
+
+ // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+ 0x22,
+ // largest acked
+ kVarInt62TwoBytes + 0x12,
+ 0x34, // = 4660
+ // Zero delta time.
+ kVarInt62OneByte + 0x00,
+ // number of additional ack blocks
+ kVarInt62OneByte + 0x00,
+ // first ack block length.
+ kVarInt62TwoBytes + 0x12,
+ 0x33,
+
+ // Receive Timestamps.
+
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x02,
+
+ // Timestamp range 1 (three packets).
+ // Gap
+ kVarInt62OneByte + 0x00,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x03,
+ // Timestamp Delta
+ kVarInt62FourBytes + 0x29,
+ 0xff,
+ 0xff,
+ 0xff,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x11,
+ 0x11,
+ // Timestamp Delta
+ kVarInt62OneByte + 0x01,
+
+ // Timestamp range 2 (one packet).
+ // Gap
+ kVarInt62OneByte + 0x05,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x01,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x10,
+ 0x00,
+ };
+ // clang-format on
+
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(4);
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ quiche::test::CompareCharArraysWithHexError(
+ "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+ ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameWithExponentEncoding) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ // Timestamp Range 2.
+ {kSmallLargestObserved - 12, CreationTimePlus((0x06c00 << 3) + 0x03)},
+ {kSmallLargestObserved - 11, CreationTimePlus((0x28e00 << 3) + 0x00)},
+ // Timestamp Range 1.
+ {kSmallLargestObserved - 5, CreationTimePlus((0x29f00 << 3) + 0x00)},
+ {kSmallLargestObserved - 4, CreationTimePlus((0x29f00 << 3) + 0x01)},
+ {kSmallLargestObserved - 3, CreationTimePlus((0x29f00 << 3) + 0x02)},
+ {kSmallLargestObserved - 2, CreationTimePlus((0x29f00 << 3) + 0x03)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ unsigned char packet_ietf[] = {
+ // type (short header, 4 byte packet number)
+ 0x43,
+ // connection_id
+ 0xFE,
+ 0xDC,
+ 0xBA,
+ 0x98,
+ 0x76,
+ 0x54,
+ 0x32,
+ 0x10,
+ // packet number
+ 0x12,
+ 0x34,
+ 0x56,
+ 0x78,
+
+ // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+ 0x22,
+ // largest acked
+ kVarInt62TwoBytes + 0x12,
+ 0x34, // = 4660
+ // Zero delta time.
+ kVarInt62OneByte + 0x00,
+ // number of additional ack blocks
+ kVarInt62OneByte + 0x00,
+ // first ack block length.
+ kVarInt62TwoBytes + 0x12,
+ 0x33,
+
+ // Receive Timestamps.
+
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x02,
+
+ // Timestamp range 1 (three packets).
+ // Gap
+ kVarInt62OneByte + 0x02,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x04,
+ // Timestamp Delta
+ kVarInt62FourBytes + 0x00,
+ 0x02,
+ 0x9f,
+ 0x01, // round up
+ // Timestamp Delta
+ kVarInt62OneByte + 0x00,
+ // Timestamp Delta
+ kVarInt62OneByte + 0x00,
+ // Timestamp Delta
+ kVarInt62OneByte + 0x01,
+
+ // Timestamp range 2 (one packet).
+ // Gap
+ kVarInt62OneByte + 0x04,
+ // Timestamp Range Count
+ kVarInt62OneByte + 0x02,
+ // Timestamp Delta
+ kVarInt62TwoBytes + 0x11,
+ 0x00,
+ // Timestamp Delta
+ kVarInt62FourBytes + 0x00,
+ 0x02,
+ 0x21,
+ 0xff,
+ };
+ // clang-format on
+
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ quiche::test::CompareCharArraysWithHexError(
+ "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+ ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAndProcessAckReceiveTimestampsWithMultipleRanges) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+ {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+ {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+ {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+ {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+ {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_THAT(frame.received_packet_times,
+ ContainerEq(PacketTimeVector{
+ {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+ {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+ {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+ {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+ {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+ {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+ }));
+}
+
+TEST_P(QuicFramerTest,
+ BuildAndProcessAckReceiveTimestampsExceedsMaxTimestamps) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(2);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+ {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+ {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+ {kSmallLargestObserved - 5, CreationTimePlus(0xabcdea125)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0xabcded124)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+ {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_THAT(frame.received_packet_times,
+ ContainerEq(PacketTimeVector{
+ {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+ }));
+}
+
+TEST_P(QuicFramerTest,
+ BuildAndProcessAckReceiveTimestampsWithExponentNoTruncation) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+ {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+ {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_THAT(frame.received_packet_times,
+ ContainerEq(PacketTimeVector{
+ {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+ {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+ {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+ }));
+}
+
+TEST_P(QuicFramerTest,
+ BuildAndProcessAckReceiveTimestampsWithExponentTruncation) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 10, CreationTimePlus((0x1001 << 3) + 1)},
+ {kSmallLargestObserved - 9, CreationTimePlus((0x2995 << 3) - 1)},
+ {kSmallLargestObserved - 8, CreationTimePlus((0x2995 << 3) + 0)},
+ {kSmallLargestObserved - 7, CreationTimePlus((0x2995 << 3) + 1)},
+ {kSmallLargestObserved - 6, CreationTimePlus((0x2995 << 3) + 2)},
+ {kSmallLargestObserved - 3, CreationTimePlus((0x2995 << 3) + 3)},
+ {kSmallLargestObserved - 2, CreationTimePlus((0x2995 << 3) + 4)},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_THAT(frame.received_packet_times,
+ ContainerEq(PacketTimeVector{
+ {kSmallLargestObserved - 2, CreationTimePlus(0x2996 << 3)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0x2996 << 3)},
+ {kSmallLargestObserved - 6, CreationTimePlus(0x2996 << 3)},
+ {kSmallLargestObserved - 7, CreationTimePlus(0x2996 << 3)},
+ {kSmallLargestObserved - 8, CreationTimePlus(0x2995 << 3)},
+ {kSmallLargestObserved - 9, CreationTimePlus(0x2995 << 3)},
+ {kSmallLargestObserved - 10, CreationTimePlus(0x1002 << 3)},
+ }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestamps) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ // Use kSmallLargestObserved to make this test finished in a short time.
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_THAT(frame.received_packet_times,
+ ContainerEq(PacketTimeVector{
+ {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+ {kSmallLargestObserved - 3, CreationTimePlus(0x29ff << 3)},
+ {kSmallLargestObserved - 4, CreationTimePlus(0x29ff << 3)},
+ {kSmallLargestObserved - 5, CreationTimePlus(0x29ff << 3)},
+ }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestampsPacketOutOfOrder) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ // Use kSmallLargestObserved to make this test finished in a short time.
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+
+ // The packet numbers below are out of order, this is impossible because we
+ // don't record out of order packets in received_packet_times. The test is
+ // intended to ensure this error is raised when it happens.
+ ack_frame.received_packet_times = PacketTimeVector{
+ {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+ {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+ };
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ EXPECT_QUIC_BUG(BuildDataPacket(header, frames),
+ "Packet number and/or receive time not in order.");
+}
+
+// If there's insufficient room for IETF ack receive timestamps, don't write any
+// timestamp ranges.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsTruncate) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+ framer_.SetKeyUpdateSupportForConnection(true);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8192);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ // Use kSmallLargestObserved to make this test finished in a short time.
+ QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+ for (QuicPacketNumber i(1); i <= kSmallLargestObserved; i += 2) {
+ ack_frame.received_packet_times.push_back(
+ {i, CreationTimePlus((0x29ff << 3))});
+ }
+
+ ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ EncryptPacketWithTagAndPhase(*data, 0, false));
+ ASSERT_TRUE(encrypted);
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+ EXPECT_TRUE(frame.received_packet_times.empty());
+}
+
+// If there are too many ack ranges, they will be truncated to make room for a
+// timestamp range count of 0.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsAckRangeTruncation) {
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+ framer_.set_process_timestamps(true);
+ framer_.set_max_receive_timestamps_per_ack(8);
+ framer_.set_receive_timestamps_exponent(3);
+
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrame ack_frame;
+ // Create a packet with just the ack.
+ ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
+ /*max_num_gaps=*/200,
+ /*largest_acked=*/kMaxIetfVarInt);
+ ack_frame.received_packet_times = PacketTimeVector{
+ {QuicPacketNumber(kMaxIetfVarInt) - 2, CreationTimePlus((0x29ff << 3))},
+ };
+ QuicFrames frames = {QuicFrame(&ack_frame)};
+ // Build an ACK packet.
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+ std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+ ASSERT_TRUE(raw_ack_packet != nullptr);
+ char buffer[kMaxOutgoingPacketSize];
+ size_t encrypted_length =
+ framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+ *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+ ASSERT_NE(0u, encrypted_length);
+ // Now make sure we can turn our ack packet back into an ack frame.
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+ ASSERT_TRUE(framer_.ProcessPacket(
+ QuicEncryptedPacket(buffer, encrypted_length, false)));
+ ASSERT_EQ(1u, visitor_.ack_frames_.size());
+ QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+ EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+ LargestAcked(processed_ack_frame));
+ // Verify ACK ranges in the frame gets truncated.
+ ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
+ ack_frame.packets.NumIntervals());
+ EXPECT_EQ(158u, processed_ack_frame.packets.NumPacketsSlow());
+ EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
+ ack_frame.packets.NumIntervals());
+ EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+ processed_ack_frame.packets.Max());
+ // But the receive timestamps are not truncated because they are small.
+ EXPECT_FALSE(processed_ack_frame.received_packet_times.empty());
+}
+
TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
QuicPacketHeader header;
@@ -13034,10 +13741,16 @@ TEST_P(QuicFramerTest, CoalescedPacket) {
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t first_packet_ietf_size = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13157,6 +13870,7 @@ TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13304,10 +14018,16 @@ TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) {
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t first_packet_ietf_size = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13415,6 +14135,7 @@ TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -13517,6 +14238,7 @@ TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
} else if (framer_.version().HasIetfInvariantHeader()) {
@@ -13677,10 +14399,15 @@ TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) {
};
// clang-format on
const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13844,10 +14571,16 @@ TEST_P(QuicFramerTest, MismatchedCoalescedPacket) {
'R', 'L', 'D', '?',
};
// clang-format on
+ const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -13949,10 +14682,16 @@ TEST_P(QuicFramerTest, InvalidCoalescedPacket) {
// version would be here but we cut off the invalid coalesced header.
};
// clang-format on
+ const size_t length_of_first_coalesced_packet = 46;
+ // If the first packet changes, the attempt to fix the first byte of the
+ // second packet will fail.
+ EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasIetfQuicFrames()) {
+ ReviseFirstByteByVersion(packet_ietf);
+ ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
p = packet_ietf;
p_length = ABSL_ARRAYSIZE(packet_ietf);
}
@@ -14180,6 +14919,7 @@ TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {
QuicEncryptedPacket(AsChars(long_header_packet),
ABSL_ARRAYSIZE(long_header_packet), false)));
} else {
+ ReviseFirstByteByVersion(long_header_packet_ietf);
EXPECT_TRUE(framer_.ProcessPacket(
QuicEncryptedPacket(AsChars(long_header_packet_ietf),
ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
@@ -14708,9 +15448,11 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) {
0x00,
};
// clang-format on
+
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -14776,6 +15518,7 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) {
unsigned char* p = packet;
size_t p_length = ABSL_ARRAYSIZE(packet);
if (framer_.version().HasLongHeaderLengths()) {
+ ReviseFirstByteByVersion(packet49);
p = packet49;
p_length = ABSL_ARRAYSIZE(packet49);
}
@@ -15615,6 +16358,7 @@ TEST_P(QuicFramerTest, ErrorWhenUnexpectedFrameTypeEncountered) {
};
// clang-format on
+ ReviseFirstByteByVersion(packet);
QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc
index 079778cd5d8..d0f1578fa79 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.cc
@@ -38,6 +38,7 @@ QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
max_ack_ranges_(0),
time_largest_observed_(QuicTime::Zero()),
save_timestamps_(false),
+ save_timestamps_for_in_order_packets_(false),
stats_(stats),
num_retransmittable_packets_received_since_last_ack_sent_(0),
min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
@@ -80,9 +81,12 @@ void QuicReceivedPacketManager::RecordPacketReceived(
}
ack_frame_updated_ = true;
+ // Whether |packet_number| is received out of order.
+ bool packet_reordered = false;
if (LargestAcked(ack_frame_).IsInitialized() &&
LargestAcked(ack_frame_) > packet_number) {
// Record how out of order stats.
+ packet_reordered = true;
++stats_->packets_reordered;
stats_->max_sequence_reordering =
std::max(stats_->max_sequence_reordering,
@@ -101,8 +105,11 @@ void QuicReceivedPacketManager::RecordPacketReceived(
if (save_timestamps_) {
// The timestamp format only handles packets in time order.
- if (!ack_frame_.received_packet_times.empty() &&
- ack_frame_.received_packet_times.back().second > receipt_time) {
+ if (save_timestamps_for_in_order_packets_ && packet_reordered) {
+ QUIC_DLOG(WARNING) << "Not saving receive timestamp for packet "
+ << packet_number;
+ } else if (!ack_frame_.received_packet_times.empty() &&
+ ack_frame_.received_packet_times.back().second > receipt_time) {
QUIC_LOG(WARNING)
<< "Receive time went backwards from: "
<< ack_frame_.received_packet_times.back().second.ToDebuggingValue()
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h
index 822725db6aa..21f7f045d4a 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager.h
@@ -103,8 +103,9 @@ class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
max_ack_ranges_ = max_ack_ranges;
}
- void set_save_timestamps(bool save_timestamps) {
+ void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) {
save_timestamps_ = save_timestamps;
+ save_timestamps_for_in_order_packets_ = in_order_packets_only;
}
size_t min_received_before_ack_decimation() const {
@@ -167,6 +168,10 @@ class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
// If true, save timestamps in the ack_frame_.
bool save_timestamps_;
+ // If true and |save_timestamps_|, only save timestamps for packets that are
+ // received in order.
+ bool save_timestamps_for_in_order_packets_;
+
// Least packet number received from peer.
QuicPacketNumber least_received_packet_number_;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc
index 9d6b6644421..cc0438140fe 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_received_packet_manager_test.cc
@@ -46,7 +46,7 @@ class QuicReceivedPacketManagerTest : public QuicTest {
QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
- received_manager_.set_save_timestamps(true);
+ received_manager_.set_save_timestamps(true, false);
}
void RecordPacketReceipt(uint64_t packet_number) {
@@ -189,6 +189,21 @@ TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
}
+TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderPackets) {
+ received_manager_.set_save_timestamps(true, true);
+ EXPECT_FALSE(received_manager_.ack_frame_updated());
+ RecordPacketReceipt(1, QuicTime::Zero());
+ EXPECT_TRUE(received_manager_.ack_frame_updated());
+ EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
+ RecordPacketReceipt(4,
+ QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+ EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+
+ RecordPacketReceipt(3,
+ QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(3));
+ EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+}
+
TEST_F(QuicReceivedPacketManagerTest, HasMissingPackets) {
EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
"No packets have been received yet");
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc
index 4c5026ca974..55dbe057887 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc
@@ -87,7 +87,6 @@ QuicSentPacketManager::QuicSentPacketManager(
pending_timer_transmission_count_(0),
max_tail_loss_probes_(kDefaultMaxTailLossProbes),
max_rto_packets_(kMaxRetransmissionsOnTimeout),
- enable_half_rtt_tail_loss_probe_(false),
using_pacing_(false),
use_new_rto_(false),
conservative_handshake_retransmits_(false),
@@ -209,12 +208,7 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
QUIC_CODE_COUNT(two_aggressive_ptos);
num_tlp_timeout_ptos_ = 2;
}
- if (GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_deprecate_tlpr, 2, 2);
- }
- if (config.HasClientSentConnectionOption(kPLE1, perspective) ||
- (config.HasClientSentConnectionOption(kTLPR, perspective) &&
- !GetQuicReloadableFlag(quic_deprecate_tlpr))) {
+ if (config.HasClientSentConnectionOption(kPLE1, perspective)) {
first_pto_srtt_multiplier_ = 0.5;
} else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
first_pto_srtt_multiplier_ = 1.5;
@@ -304,17 +298,6 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
max_rto_packets_ = 1;
}
- if (GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_deprecate_tlpr, 1, 2);
- }
- if (config.HasClientSentConnectionOption(kTLPR, perspective) &&
- !GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- enable_half_rtt_tail_loss_probe_ = true;
- }
- if (config.HasClientRequestedIndependentOption(kTLPR, perspective) &&
- !GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- enable_half_rtt_tail_loss_probe_ = true;
- }
if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
use_new_rto_ = true;
}
@@ -352,6 +335,15 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (network_change_visitor_ != nullptr) {
network_change_visitor_->OnCongestionChange();
}
+
+ if (debug_delegate_ != nullptr) {
+ DebugDelegate::SendParameters parameters;
+ parameters.congestion_control_type =
+ send_algorithm_->GetCongestionControlType();
+ parameters.use_pacing = using_pacing_;
+ parameters.initial_congestion_window = initial_congestion_window_;
+ debug_delegate_->OnConfigProcessed(parameters);
+ }
}
void QuicSentPacketManager::ApplyConnectionOptions(
@@ -392,6 +384,18 @@ void QuicSentPacketManager::ResumeConnectionState(
void QuicSentPacketManager::AdjustNetworkParameters(
const SendAlgorithmInterface::NetworkParams& params) {
+ if (params.burst_token != 0) {
+ if (using_pacing_) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_set_burst_token);
+ int old_burst_size = pacing_sender_.initial_burst_size();
+ pacing_sender_.SetBurstTokens(params.burst_token);
+ if (debug_delegate_ != nullptr) {
+ debug_delegate_->OnAdjustBurstSize(old_burst_size,
+ pacing_sender_.initial_burst_size());
+ }
+ }
+ return;
+ }
const QuicBandwidth& bandwidth = params.bandwidth;
const QuicTime::Delta& rtt = params.rtt;
if (!rtt.IsZero()) {
@@ -1393,12 +1397,6 @@ const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
- if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
- if (unacked_packets().HasUnackedStreamData()) {
- // Enable TLPR if there are pending data packets.
- return std::max(min_tlp_timeout_, srtt * 0.5);
- }
- }
if (!unacked_packets_.HasMultipleInFlightPackets()) {
// This expression really should be using the delayed ack time, but in TCP
// MinRTO was traditionally set to 2x the delayed ack timer and this
@@ -1444,10 +1442,6 @@ const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
(1 << consecutive_pto_count_);
}
- if (enable_half_rtt_tail_loss_probe_ && consecutive_pto_count_ == 0 &&
- handshake_finished_) {
- return std::max(min_tlp_timeout_, rtt_stats_.smoothed_rtt() * 0.5);
- }
const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
? rtt_stats_.GetStandardOrMeanDeviation()
: rtt_stats_.mean_deviation();
@@ -1769,18 +1763,11 @@ QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
num_timeouts -= num_tlps;
if (num_tlps > 0) {
- if (enable_half_rtt_tail_loss_probe_ &&
- unacked_packets().HasUnackedStreamData()) {
- total_delay = total_delay + std::max(min_tlp_timeout_, srtt * 0.5);
- --num_tlps;
- }
- if (num_tlps > 0) {
- const QuicTime::Delta tlp_delay =
- std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
- ? min_tlp_timeout_
- : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
- total_delay = total_delay + num_tlps * tlp_delay;
- }
+ const QuicTime::Delta tlp_delay =
+ std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
+ ? min_tlp_timeout_
+ : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
+ total_delay = total_delay + num_tlps * tlp_delay;
}
if (num_timeouts == 0) {
return total_delay;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h
index e4a7036e432..dac8ccf08d8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h
@@ -52,6 +52,12 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// the packet manager or connection as a result of these callbacks.
class QUIC_EXPORT_PRIVATE DebugDelegate {
public:
+ struct QUIC_EXPORT_PRIVATE SendParameters {
+ CongestionControlType congestion_control_type;
+ bool use_pacing;
+ QuicPacketCount initial_congestion_window;
+ };
+
virtual ~DebugDelegate() {}
// Called when a spurious retransmission is detected.
@@ -80,7 +86,12 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
QuicByteCount /*old_cwnd*/,
QuicByteCount /*new_cwnd*/) {}
+ virtual void OnAdjustBurstSize(int /*old_burst_size*/,
+ int /*new_burst_size*/) {}
+
virtual void OnOvershootingDetected() {}
+
+ virtual void OnConfigProcessed(const SendParameters& /*parameters*/) {}
};
// Interface which gets callbacks from the QuicSentPacketManager when
@@ -622,8 +633,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Maximum number of packets to send upon RTO.
QuicPacketCount max_rto_packets_;
// If true, send the TLP at 0.5 RTT.
- // TODO(renjietang): remove it once quic_deprecate_tlpr flag is deprecated.
- bool enable_half_rtt_tail_loss_probe_;
bool using_pacing_;
// If true, use the new RTO with loss based CWND reduction instead of the send
// algorithms's OnRetransmissionTimeout to reduce the congestion window.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc
index a09afc6b7b8..1ce3da8e396 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc
@@ -1463,112 +1463,6 @@ TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest, TLPRWithPendingStreamData) {
- if (GetQuicReloadableFlag(quic_default_on_pto) ||
- GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillOnce(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
-
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
- SendDataPacket(1);
- SendDataPacket(2);
-
- // Test with a standard smoothed RTT.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
- QuicTime::Delta srtt = rtt_stats->initial_rtt();
- // With pending stream data, TLPR is used.
- QuicTime::Delta expected_tlp_delay = 0.5 * srtt;
- EXPECT_CALL(notifier_, HasUnackedStreamData()).WillRepeatedly(Return(true));
-
- EXPECT_EQ(expected_tlp_delay,
- manager_.GetRetransmissionTime() - clock_.Now());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(expected_tlp_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
- EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
-
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
- // 2nd TLP.
- expected_tlp_delay = 2 * srtt;
- EXPECT_EQ(expected_tlp_delay,
- manager_.GetRetransmissionTime() - clock_.Now());
-}
-
-TEST_F(QuicSentPacketManagerTest, TLPRWithoutPendingStreamData) {
- if (GetQuicReloadableFlag(quic_default_on_pto) ||
- GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillOnce(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
- SendPingPacket(1, ENCRYPTION_INITIAL);
- SendPingPacket(2, ENCRYPTION_INITIAL);
-
- // Test with a standard smoothed RTT.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
- QuicTime::Delta srtt = rtt_stats->initial_rtt();
- QuicTime::Delta expected_tlp_delay = 0.5 * srtt;
- // With no pending stream data, TLPR is ignored.
- expected_tlp_delay = 2 * srtt;
- EXPECT_CALL(notifier_, HasUnackedStreamData()).WillRepeatedly(Return(false));
- EXPECT_EQ(expected_tlp_delay,
- manager_.GetRetransmissionTime() - clock_.Now());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(expected_tlp_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke(
- [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
- EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
- // 2nd TLP.
- expected_tlp_delay = 2 * srtt;
- EXPECT_EQ(expected_tlp_delay,
- manager_.GetRetransmissionTime() - clock_.Now());
-}
-
TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
if (GetQuicReloadableFlag(quic_default_on_pto)) {
return;
@@ -2125,41 +2019,6 @@ TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
}
-TEST_F(QuicSentPacketManagerTest, NegotiateTLPRttFromOptionsAtServer) {
- if (GetQuicReloadableFlag(quic_default_on_pto) ||
- GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateTLPRttFromOptionsAtClient) {
- if (GetQuicReloadableFlag(quic_default_on_pto) ||
- GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig client_config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(client_config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
-}
-
TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtServer) {
if (GetQuicReloadableFlag(quic_default_on_pto)) {
return;
@@ -4371,90 +4230,6 @@ TEST_F(QuicSentPacketManagerTest,
manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest, ClientOnlyTLPRServer) {
- if (GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- // No change if the server receives client options.
- EXPECT_FALSE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, ClientOnlyTLPR) {
- if (GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- config.SetClientConnectionOptions(options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoWithTlpr) {
- if (GetQuicReloadableFlag(quic_deprecate_tlpr)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kTLPR);
- options.push_back(k1PTO);
- options.push_back(kPTOS);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillOnce(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(config);
- EXPECT_TRUE(
- QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
- manager_.SetHandshakeConfirmed();
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay = 0.5 * srtt;
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(deadline - clock_.Now());
- manager_.OnRetransmissionTimeout();
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
-
- // Verify PTO period gets set correctly.
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- QuicTime sent_time = clock_.Now();
- EXPECT_EQ(sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
QuicPacketNumber packet_number(1);
EXPECT_CALL(*send_algorithm_,
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session.cc b/chromium/net/third_party/quiche/src/quic/core/quic_session.cc
index 14d549a3888..202bff43e1f 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_session.cc
@@ -147,10 +147,6 @@ void QuicSession::Initialize() {
connection_->OnSuccessfulVersionNegotiation();
}
- if (GetMutableCryptoStream()->KeyUpdateSupportedLocally()) {
- config_.SetKeyUpdateSupportedLocally();
- }
-
if (QuicVersionUsesCryptoFrames(transport_version())) {
return;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session.h b/chromium/net/third_party/quiche/src/quic/core/quic_session.h
index d06e1fe43a4..88ae992880d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_session.h
@@ -312,6 +312,7 @@ class QUIC_EXPORT_PRIVATE QuicSession
std::string* error_details) override;
void OnHandshakeCallbackDone() override;
bool PacketFlusherAttached() const override;
+ ParsedQuicVersion parsed_version() const override { return version(); }
// Implement StreamDelegateInterface.
void OnStreamError(QuicErrorCode error_code,
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc
index 8d5e477237a..256865d9e7b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc
@@ -159,7 +159,6 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
}
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- MOCK_METHOD(bool, KeyUpdateSupportedLocally, (), (const, override));
MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
AdvanceKeysAndCreateCurrentOneRttDecrypter,
(),
@@ -235,8 +234,6 @@ class TestSession : public QuicSession {
writev_consumes_all_data_(false),
uses_pending_streams_(false),
num_incoming_streams_created_(0) {
- EXPECT_CALL(*GetMutableCryptoStream(), KeyUpdateSupportedLocally())
- .WillRepeatedly(Return(false));
Initialize();
this->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
@@ -2294,20 +2291,6 @@ TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) {
ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
}
-TEST_P(QuicSessionTestClient, KeyUpdateNotSupportedLocally) {
- EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally())
- .WillOnce(Return(false));
- session_.Initialize();
- EXPECT_FALSE(session_.config()->KeyUpdateSupportedLocally());
-}
-
-TEST_P(QuicSessionTestClient, KeyUpdateSupportedLocally) {
- EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally())
- .WillOnce(Return(true));
- session_.Initialize();
- EXPECT_TRUE(session_.config()->KeyUpdateSupportedLocally());
-}
-
TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc
index f055bdf2e9f..6237dae2f62 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream.cc
@@ -506,13 +506,7 @@ bool QuicStream::OnStopSending(QuicResetStreamError error) {
}
stream_error_ = error;
- if (GetQuicReloadableFlag(quic_match_ietf_reset_code)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_match_ietf_reset_code);
- MaybeSendRstStream(error);
- } else {
- MaybeSendRstStream(
- QuicResetStreamError::FromInternal(error.internal_code()));
- }
+ MaybeSendRstStream(error);
return true;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc b/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc
index 32b7bf9cd76..b5f64f1a775 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_tag.cc
@@ -66,7 +66,7 @@ std::string QuicTagToString(QuicTag tag) {
reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
}
-uint32_t MakeQuicTag(char a, char b, char c, char d) {
+uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag.h b/chromium/net/third_party/quiche/src/quic/core/quic_tag.h
index c77219eb321..1dfc754f870 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_tag.h
@@ -5,6 +5,7 @@
#ifndef QUICHE_QUIC_CORE_QUIC_TAG_H_
#define QUICHE_QUIC_CORE_QUIC_TAG_H_
+#include <cstdint>
#include <map>
#include <string>
#include <vector>
@@ -28,7 +29,8 @@ using QuicTagVector = std::vector<QuicTag>;
// MakeQuicTag returns a value given the four bytes. For example:
// MakeQuicTag('C', 'H', 'L', 'O');
-QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(char a, char b, char c, char d);
+QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(uint8_t a, uint8_t b, uint8_t c,
+ uint8_t d);
// Returns true if |tag_vector| contains |tag|.
QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_types.h b/chromium/net/third_party/quiche/src/quic/core/quic_types.h
index 200e843f826..a437c9ae731 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_types.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_types.h
@@ -13,11 +13,12 @@
#include <vector>
#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#include "quic/core/quic_connection_id.h"
#include "quic/core/quic_error_codes.h"
#include "quic/core/quic_packet_number.h"
#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_containers.h"
#include "quic/platform/api/quic_export.h"
#include "quic/platform/api/quic_flags.h"
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc
index 3aa821c1cd4..13094564258 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc
@@ -30,21 +30,17 @@ QuicVersionManager::GetSupportedVersionsWithOnlyHttp3() {
return filtered_supported_versions_with_http3_;
}
-const ParsedQuicVersionVector&
-QuicVersionManager::GetSupportedVersionsWithQuicCrypto() {
- MaybeRefilterSupportedVersions();
- return filtered_supported_versions_with_quic_crypto_;
-}
-
const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
MaybeRefilterSupportedVersions();
return filtered_supported_alpns_;
}
void QuicVersionManager::MaybeRefilterSupportedVersions() {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
- if (disable_version_rfcv1_ !=
+ if (enable_version_2_draft_01_ !=
+ GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
+ disable_version_rfcv1_ !=
GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
disable_version_draft_29_ !=
GetQuicReloadableFlag(quic_disable_version_draft_29) ||
@@ -54,6 +50,8 @@ void QuicVersionManager::MaybeRefilterSupportedVersions() {
GetQuicReloadableFlag(quic_disable_version_q046) ||
disable_version_q043_ !=
GetQuicReloadableFlag(quic_disable_version_q043)) {
+ enable_version_2_draft_01_ =
+ GetQuicReloadableFlag(quic_enable_version_2_draft_01);
disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
disable_version_draft_29_ =
GetQuicReloadableFlag(quic_disable_version_draft_29);
@@ -69,7 +67,6 @@ void QuicVersionManager::RefilterSupportedVersions() {
filtered_supported_versions_ =
FilterSupportedVersions(allowed_supported_versions_);
filtered_supported_versions_with_http3_.clear();
- filtered_supported_versions_with_quic_crypto_.clear();
filtered_transport_versions_.clear();
filtered_supported_alpns_.clear();
for (const ParsedQuicVersion& version : filtered_supported_versions_) {
@@ -82,10 +79,11 @@ void QuicVersionManager::RefilterSupportedVersions() {
if (version.UsesHttp3()) {
filtered_supported_versions_with_http3_.push_back(version);
}
- if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- filtered_supported_versions_with_quic_crypto_.push_back(version);
+ if (std::find(filtered_supported_alpns_.begin(),
+ filtered_supported_alpns_.end(),
+ AlpnForVersion(version)) == filtered_supported_alpns_.end()) {
+ filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
}
- filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
}
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
index a3ae7194ad4..44e134ac363 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
@@ -25,9 +25,6 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager {
// Returns currently supported versions using HTTP/3.
const ParsedQuicVersionVector& GetSupportedVersionsWithOnlyHttp3();
- // Returns currently supported versions using QUIC crypto.
- const ParsedQuicVersionVector& GetSupportedVersionsWithQuicCrypto();
-
// Returns the list of supported ALPNs, based on the current supported
// versions and any custom additions by subclasses.
const std::vector<std::string>& GetSupportedAlpns();
@@ -58,6 +55,8 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager {
private:
// Cached value of reloadable flags.
+ // quic_enable_version_2_draft_01 flag
+ bool enable_version_2_draft_01_ = false;
// quic_disable_version_rfcv1 flag
bool disable_version_rfcv1_ = true;
// quic_disable_version_draft_29 flag
@@ -82,8 +81,6 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager {
ParsedQuicVersionVector filtered_supported_versions_;
// Currently supported versions using HTTP/3.
ParsedQuicVersionVector filtered_supported_versions_with_http3_;
- // Currently supported versions using QUIC crypto.
- ParsedQuicVersionVector filtered_supported_versions_with_quic_crypto_;
// This vector contains the transport versions from
// |filtered_supported_versions_|. No guarantees are made that the same
// transport version isn't repeated.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
index 8960bced5c0..da87c4a1d53 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
@@ -18,11 +18,12 @@ namespace {
class QuicVersionManagerTest : public QuicTest {};
TEST_F(QuicVersionManagerTest, QuicVersionManager) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicEnableVersion(version);
}
+ QuicDisableVersion(ParsedQuicVersion::V2Draft01());
QuicDisableVersion(ParsedQuicVersion::RFCv1());
QuicDisableVersion(ParsedQuicVersion::Draft29());
QuicVersionManager manager(AllSupportedVersions());
@@ -37,8 +38,6 @@ TEST_F(QuicVersionManagerTest, QuicVersionManager) {
EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
manager.GetSupportedVersions());
EXPECT_TRUE(manager.GetSupportedVersionsWithOnlyHttp3().empty());
- EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
- manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
ElementsAre("h3-Q050", "h3-Q046", "h3-Q043"));
@@ -47,15 +46,11 @@ TEST_F(QuicVersionManagerTest, QuicVersionManager) {
expected_parsed_versions.insert(expected_parsed_versions.begin(),
ParsedQuicVersion::Draft29());
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions.size() - 1 - offset,
- manager.GetSupportedVersionsWithQuicCrypto().size());
EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
manager.GetSupportedVersions());
EXPECT_EQ(1u, manager.GetSupportedVersionsWithOnlyHttp3().size());
EXPECT_EQ(CurrentSupportedHttp3Versions(),
manager.GetSupportedVersionsWithOnlyHttp3());
- EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
- manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
ElementsAre("h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
@@ -64,17 +59,27 @@ TEST_F(QuicVersionManagerTest, QuicVersionManager) {
expected_parsed_versions.insert(expected_parsed_versions.begin(),
ParsedQuicVersion::RFCv1());
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions.size() - 1 - offset,
- manager.GetSupportedVersionsWithQuicCrypto().size());
EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
manager.GetSupportedVersions());
EXPECT_EQ(2u, manager.GetSupportedVersionsWithOnlyHttp3().size());
EXPECT_EQ(CurrentSupportedHttp3Versions(),
manager.GetSupportedVersionsWithOnlyHttp3());
- EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
- manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+ offset++;
+ QuicEnableVersion(ParsedQuicVersion::V2Draft01());
+ expected_parsed_versions.insert(expected_parsed_versions.begin(),
+ ParsedQuicVersion::V2Draft01());
+ EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+ EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+ manager.GetSupportedVersions());
+ EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+ EXPECT_EQ(CurrentSupportedHttp3Versions(),
+ manager.GetSupportedVersionsWithOnlyHttp3());
+ EXPECT_THAT(
+ manager.GetSupportedAlpns(),
+ ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc b/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
index 4c9e661fa41..21ec163807c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
@@ -23,12 +23,6 @@
namespace quic {
namespace {
-// Constructs a version label from the 4 bytes such that the on-the-wire
-// order will be: d, c, b, a.
-QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
- return MakeQuicTag(d, c, b, a);
-}
-
QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
QuicVersionLabel result;
if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
@@ -42,11 +36,13 @@ QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
}
void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
const bool enable = should_enable;
const bool disable = !should_enable;
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
+ } else if (version == ParsedQuicVersion::RFCv1()) {
SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
} else if (version == ParsedQuicVersion::Draft29()) {
SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
@@ -182,6 +178,16 @@ bool ParsedQuicVersion::UsesQuicCrypto() const {
return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
}
+bool ParsedQuicVersion::UsesV2PacketTypes() const {
+ QUICHE_DCHECK(IsKnown());
+ return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
+bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
+ QUICHE_DCHECK(IsKnown());
+ return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
bool VersionHasLengthPrefixedConnectionIds(
QuicTransportVersion transport_version) {
QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
@@ -200,6 +206,10 @@ std::ostream& operator<<(std::ostream& os,
return os;
}
+QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+ return MakeQuicTag(d, c, b, a);
+}
+
std::ostream& operator<<(std::ostream& os,
const QuicVersionLabelVector& version_labels) {
os << QuicVersionLabelVectorToString(version_labels);
@@ -213,9 +223,11 @@ std::ostream& operator<<(std::ostream& os,
}
QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
- if (parsed_version == ParsedQuicVersion::RFCv1()) {
+ if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+ return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
+ } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
} else if (parsed_version == ParsedQuicVersion::Draft29()) {
return MakeVersionLabel(0xff, 0x00, 0x00, 29);
@@ -333,25 +345,11 @@ ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
if (version_string.empty()) {
return UnsupportedQuicVersion();
}
- int quic_version_number = 0;
const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
- if (absl::SimpleAtoi(version_string, &quic_version_number) &&
- quic_version_number > 0) {
- QuicTransportVersion transport_version =
- static_cast<QuicTransportVersion>(quic_version_number);
- if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
- return UnsupportedQuicVersion();
- }
- ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
- if (std::find(supported_versions.begin(), supported_versions.end(),
- version) != supported_versions.end()) {
- return version;
- }
- return UnsupportedQuicVersion();
- }
for (const ParsedQuicVersion& version : supported_versions) {
if (version_string == ParsedQuicVersionToString(version) ||
- version_string == AlpnForVersion(version) ||
+ (version_string == AlpnForVersion(version) &&
+ !version.AlpnDeferToRFCv1()) ||
(version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
version_string == QuicVersionToString(version.transport_version))) {
return version;
@@ -364,6 +362,21 @@ ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
return version;
}
}
+ int quic_version_number = 0;
+ if (absl::SimpleAtoi(version_string, &quic_version_number) &&
+ quic_version_number > 0) {
+ QuicTransportVersion transport_version =
+ static_cast<QuicTransportVersion>(quic_version_number);
+ if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
+ return UnsupportedQuicVersion();
+ }
+ ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
+ if (std::find(supported_versions.begin(), supported_versions.end(),
+ version) != supported_versions.end()) {
+ return version;
+ }
+ return UnsupportedQuicVersion();
+ }
// Reading from the client so this should not be considered an ERROR.
QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
<< "\".";
@@ -411,10 +424,16 @@ ParsedQuicVersionVector CurrentSupportedVersions() {
ParsedQuicVersionVector FilterSupportedVersions(
ParsedQuicVersionVector versions) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
ParsedQuicVersionVector filtered_versions;
filtered_versions.reserve(versions.size());
for (const ParsedQuicVersion& version : versions) {
- if (version == ParsedQuicVersion::RFCv1()) {
+ if (version == ParsedQuicVersion::V2Draft01()) {
+ if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
+ filtered_versions.push_back(version);
+ }
+ } else if (version == ParsedQuicVersion::RFCv1()) {
if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
filtered_versions.push_back(version);
}
@@ -444,8 +463,7 @@ ParsedQuicVersionVector FilterSupportedVersions(
}
ParsedQuicVersionVector ParsedVersionOfIndex(
- const ParsedQuicVersionVector& versions,
- int index) {
+ const ParsedQuicVersionVector& versions, int index) {
ParsedQuicVersionVector version;
int version_count = versions.size();
if (index >= 0 && index < version_count) {
@@ -460,9 +478,20 @@ std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
}
+ParsedQuicVersion ParseQuicVersionLabelString(
+ absl::string_view version_label_string) {
+ const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ for (const ParsedQuicVersion& version : supported_versions) {
+ if (version_label_string ==
+ QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
+ return version;
+ }
+ }
+ return UnsupportedQuicVersion();
+}
+
std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels,
- const std::string& separator,
+ const QuicVersionLabelVector& version_labels, const std::string& separator,
size_t skip_after_nth_version) {
std::string result;
for (size_t i = 0; i < version_labels.size(); ++i) {
@@ -490,6 +519,7 @@ std::string QuicVersionToString(QuicTransportVersion transport_version) {
RETURN_STRING_LITERAL(QUIC_VERSION_50);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
+ RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
}
@@ -508,10 +538,13 @@ std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
}
std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
- static_assert(SupportedVersions().size() == 5u,
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
if (version == UnsupportedQuicVersion()) {
return "0";
+ } else if (version == ParsedQuicVersion::V2Draft01()) {
+ QUICHE_DCHECK(version.UsesHttp3());
+ return "v2draft01";
} else if (version == ParsedQuicVersion::RFCv1()) {
QUICHE_DCHECK(version.UsesHttp3());
return "RFCv1";
@@ -536,8 +569,7 @@ std::string QuicTransportVersionVectorToString(
}
std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions,
- const std::string& separator,
+ const ParsedQuicVersionVector& versions, const std::string& separator,
size_t skip_after_nth_version) {
std::string result;
for (size_t i = 0; i < versions.size(); ++i) {
@@ -604,7 +636,9 @@ ParsedQuicVersion LegacyVersionForEncapsulation() {
}
std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
- if (parsed_version == ParsedQuicVersion::RFCv1()) {
+ if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+ return "h3";
+ } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
return "h3";
} else if (parsed_version == ParsedQuicVersion::Draft29()) {
return "h3-29";
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions.h b/chromium/net/third_party/quiche/src/quic/core/quic_versions.h
index 331a99c9759..59bf7532f3a 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_versions.h
@@ -23,6 +23,7 @@
#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+#include <cstdint>
#include <string>
#include <vector>
@@ -122,8 +123,9 @@ enum QuicTransportVersion {
// Number 70 used to represent draft-ietf-quic-transport-25.
// Number 71 used to represent draft-ietf-quic-transport-27.
// Number 72 used to represent draft-ietf-quic-transport-28.
- QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
- QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
+ QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
+ QUIC_VERSION_IETF_RFC_V1 = 80, // RFC 9000.
+ QUIC_VERSION_IETF_2_DRAFT_01 = 81, // draft-ietf-quic-v2-01.
// Version 99 was a dumping ground for IETF QUIC changes which were not yet
// ready for production between 2018-02 and 2020-02.
@@ -171,6 +173,7 @@ QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
QuicTransportVersion transport_version) {
bool transport_version_is_valid = false;
constexpr QuicTransportVersion valid_transport_versions[] = {
+ QUIC_VERSION_IETF_2_DRAFT_01,
QUIC_VERSION_IETF_RFC_V1,
QUIC_VERSION_IETF_DRAFT_29,
QUIC_VERSION_50,
@@ -195,7 +198,8 @@ QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
return transport_version != QUIC_VERSION_UNSUPPORTED &&
transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
- transport_version != QUIC_VERSION_IETF_RFC_V1;
+ transport_version != QUIC_VERSION_IETF_RFC_V1 &&
+ transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
case PROTOCOL_TLS1_3:
return transport_version != QUIC_VERSION_UNSUPPORTED &&
transport_version != QUIC_VERSION_50 &&
@@ -245,6 +249,10 @@ struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
transport_version != other.transport_version;
}
+ static constexpr ParsedQuicVersion V2Draft01() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
+ }
+
static constexpr ParsedQuicVersion RFCv1() {
return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
}
@@ -361,6 +369,14 @@ struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
// Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
bool UsesQuicCrypto() const;
+
+ // Returns whether this version uses the QUICv2 Long Header Packet Types.
+ bool UsesV2PacketTypes() const;
+
+ // Returns true if this shares ALPN codes with RFCv1, and endpoints should
+ // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
+ // RFCv1.
+ bool AlpnDeferToRFCv1() const;
};
QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
@@ -377,36 +393,38 @@ QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const ParsedQuicVersionVector& versions);
+ std::ostream& os, const ParsedQuicVersionVector& versions);
// Representation of the on-the-wire QUIC version number. Will be written/read
// to the wire in network-byte-order.
using QuicVersionLabel = uint32_t;
using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
+// Constructs a version label from the 4 bytes such that the on-the-wire
+// order will be: d, c, b, a.
+QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
+ uint8_t c, uint8_t d);
+
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicVersionLabelVector& version_labels);
+ std::ostream& os, const QuicVersionLabelVector& version_labels);
// This vector contains all crypto handshake protocols that are supported.
constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
}
-constexpr std::array<ParsedQuicVersion, 5> SupportedVersions() {
+constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
return {
- ParsedQuicVersion::RFCv1(), ParsedQuicVersion::Draft29(),
- ParsedQuicVersion::Q050(), ParsedQuicVersion::Q046(),
- ParsedQuicVersion::Q043(),
+ ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
+ ParsedQuicVersion::Draft29(), ParsedQuicVersion::Q050(),
+ ParsedQuicVersion::Q046(), ParsedQuicVersion::Q043(),
};
}
using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os,
- const QuicTransportVersionVector& transport_versions);
+ std::ostream& os, const QuicTransportVersionVector& transport_versions);
// Returns a vector of supported QUIC versions.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
@@ -490,12 +508,20 @@ CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
QuicVersionLabel version_label);
+// Helper function which translates from a QuicVersionLabel string to a
+// ParsedQuicVersion. The version label string must be of the form returned
+// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
+// "51303433" (the hex encoding of the Q064 version label). Returns
+// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
+// otherwise.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionLabelString(absl::string_view version_label_string);
+
// Returns |separator|-separated list of string representations of
// QuicVersionLabel values in the supplied |version_labels| vector. The values
// after the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
- const QuicVersionLabelVector& version_labels,
- const std::string& separator,
+ const QuicVersionLabelVector& version_labels, const std::string& separator,
size_t skip_after_nth_version);
// Returns comma separated list of string representations of QuicVersionLabel
@@ -529,8 +555,7 @@ QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
// ParsedQuicVersion values in the supplied |versions| vector. The values after
// the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
- const ParsedQuicVersionVector& versions,
- const std::string& separator,
+ const ParsedQuicVersionVector& versions, const std::string& separator,
size_t skip_after_nth_version);
// Returns comma separated list of string representations of ParsedQuicVersion
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc
index 60790d61ece..8d420acaf3d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc
@@ -15,24 +15,16 @@ namespace quic {
namespace test {
namespace {
-using ::testing::_;
using ::testing::ElementsAre;
using ::testing::IsEmpty;
-class QuicVersionsTest : public QuicTest {
- protected:
- QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
- return MakeQuicTag(d, c, b, a);
- }
-};
-
-TEST_F(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
+TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
EXPECT_QUIC_BUG(
CreateQuicVersionLabel(UnsupportedQuicVersion()),
"Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
}
-TEST_F(QuicVersionsTest, KnownAndValid) {
+TEST(QuicVersionsTest, KnownAndValid) {
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
EXPECT_TRUE(version.IsKnown());
EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
@@ -59,7 +51,7 @@ TEST_F(QuicVersionsTest, KnownAndValid) {
static_cast<QuicTransportVersion>(99)));
}
-TEST_F(QuicVersionsTest, Features) {
+TEST(QuicVersionsTest, Features) {
ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
@@ -110,7 +102,9 @@ TEST_F(QuicVersionsTest, Features) {
EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
}
-TEST_F(QuicVersionsTest, ParseQuicVersionLabel) {
+TEST(QuicVersionsTest, ParseQuicVersionLabel) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
EXPECT_EQ(ParsedQuicVersion::Q043(),
ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
EXPECT_EQ(ParsedQuicVersion::Q046(),
@@ -121,15 +115,25 @@ TEST_F(QuicVersionsTest, ParseQuicVersionLabel) {
ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
EXPECT_EQ(ParsedQuicVersion::RFCv1(),
ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
- EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::RFCv1(),
+ EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+ ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
+ EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
+ ParsedQuicVersion::RFCv1(),
ParsedQuicVersion::Draft29()}),
ParseQuicVersionLabelVector(QuicVersionLabelVector{
+ MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
+
+ for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+ EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
+ }
}
-TEST_F(QuicVersionsTest, ParseQuicVersionString) {
+TEST(QuicVersionsTest, ParseQuicVersionString) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
EXPECT_EQ(ParsedQuicVersion::Q046(),
ParseQuicVersionString("QUIC_VERSION_46"));
@@ -149,13 +153,23 @@ TEST_F(QuicVersionsTest, ParseQuicVersionString) {
EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
+ EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
+ EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
+
+ // QUICv2 will never be the result for "h3".
+
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
EXPECT_EQ(version,
ParseQuicVersionString(ParsedQuicVersionToString(version)));
+ EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
+ CreateQuicVersionLabel(version))));
+ if (!version.AlpnDeferToRFCv1()) {
+ EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
+ }
}
}
-TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
+TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
@@ -207,53 +221,101 @@ TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
ElementsAre(version_draft_29));
}
-TEST_F(QuicVersionsTest, CreateQuicVersionLabel) {
- EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '3'),
- CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
- EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '6'),
- CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
- EXPECT_EQ(MakeVersionLabel('Q', '0', '5', '0'),
- CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
- EXPECT_EQ(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d),
- CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
- EXPECT_EQ(MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
- CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
+// Do not use MakeVersionLabel() to generate expectations, because
+// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
+// in case it has a bug.
+TEST(QuicVersionsTest, CreateQuicVersionLabel) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
+ EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
+ EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
+ EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
+ EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
+ EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ(0x709a50c4u,
+ CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
// Make sure the negotiation reserved version is in the IETF reserved space.
EXPECT_EQ(
- MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a) & 0x0f0f0f0f,
+ 0xda5a3a3au & 0x0f0f0f0f,
CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
0x0f0f0f0f);
// Make sure that disabling randomness works.
SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
- EXPECT_EQ(
- MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a),
- CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()));
+ EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
+ ParsedQuicVersion::ReservedForNegotiation()));
}
-TEST_F(QuicVersionsTest, QuicVersionLabelToString) {
+TEST(QuicVersionsTest, QuicVersionLabelToString) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
+ EXPECT_EQ("Q043", QuicVersionLabelToString(
+ CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
+ EXPECT_EQ("Q046", QuicVersionLabelToString(
+ CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
+ EXPECT_EQ("Q050", QuicVersionLabelToString(
+ CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
+ EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
+ ParsedQuicVersion::Draft29())));
+ EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
+ ParsedQuicVersion::RFCv1())));
+ EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
+ ParsedQuicVersion::V2Draft01())));
+
QuicVersionLabelVector version_labels = {
MakeVersionLabel('Q', '0', '3', '5'),
- MakeVersionLabel('Q', '0', '3', '7'),
MakeVersionLabel('T', '0', '3', '8'),
+ MakeVersionLabel(0xff, 0, 0, 7),
};
EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
- EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[2]));
+ EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
+ EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
- EXPECT_EQ("Q035,Q037,T038", QuicVersionLabelVectorToString(version_labels));
- EXPECT_EQ("Q035:Q037:T038",
+ EXPECT_EQ("Q035,T038,ff000007",
+ QuicVersionLabelVectorToString(version_labels));
+ EXPECT_EQ("Q035:T038:ff000007",
QuicVersionLabelVectorToString(version_labels, ":", 2));
- EXPECT_EQ("Q035|Q037|...",
+ EXPECT_EQ("Q035|T038|...",
QuicVersionLabelVectorToString(version_labels, "|", 1));
std::ostringstream os;
os << version_labels;
- EXPECT_EQ("Q035,Q037,T038", os.str());
+ EXPECT_EQ("Q035,T038,ff000007", os.str());
}
-TEST_F(QuicVersionsTest, QuicVersionToString) {
+TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
+ static_assert(SupportedVersions().size() == 6u,
+ "Supported versions out of sync");
+ // Explicitly test known QUIC version label strings.
+ EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
+ EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
+ EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
+ EXPECT_EQ(ParsedQuicVersion::Draft29(),
+ ParseQuicVersionLabelString("ff00001d"));
+ EXPECT_EQ(ParsedQuicVersion::RFCv1(),
+ ParseQuicVersionLabelString("00000001"));
+ EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+ ParseQuicVersionLabelString("709a50c4"));
+
+ // Sanity check that a variety of other serialization formats are ignored.
+ EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
+ EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
+ EXPECT_EQ(UnsupportedQuicVersion(),
+ ParseQuicVersionLabelString("QUIC_VERSION_46"));
+ EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
+ EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
+
+ // Test round-trips between QuicVersionLabelToString and
+ // ParseQuicVersionLabelString.
+ for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+ EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
+ CreateQuicVersionLabel(version))));
+ }
+}
+
+TEST(QuicVersionsTest, QuicVersionToString) {
EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
@@ -285,13 +347,15 @@ TEST_F(QuicVersionsTest, QuicVersionToString) {
EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
}
-TEST_F(QuicVersionsTest, ParsedQuicVersionToString) {
+TEST(QuicVersionsTest, ParsedQuicVersionToString) {
EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ("v2draft01",
+ ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
@@ -314,7 +378,7 @@ TEST_F(QuicVersionsTest, ParsedQuicVersionToString) {
EXPECT_EQ("0,Q043", os.str());
}
-TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
+TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicEnableVersion(version);
}
@@ -327,7 +391,7 @@ TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
}
-TEST_F(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
+TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicEnableVersion(version);
}
@@ -341,7 +405,7 @@ TEST_F(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
FilterSupportedVersions(AllSupportedVersions()));
}
-TEST_F(QuicVersionsTest, LookUpParsedVersionByIndex) {
+TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
ParsedQuicVersionVector all_versions = AllSupportedVersions();
int version_count = all_versions.size();
for (int i = -5; i <= version_count + 1; ++i) {
@@ -357,27 +421,29 @@ TEST_F(QuicVersionsTest, LookUpParsedVersionByIndex) {
// This test may appear to be so simplistic as to be unnecessary,
// yet a typo was made in doing the #defines and it was caught
// only in some test far removed from here... Better safe than sorry.
-TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
- static_assert(SupportedVersions().size() == 5u,
+TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
EXPECT_EQ(QUIC_VERSION_43, 43);
EXPECT_EQ(QUIC_VERSION_46, 46);
EXPECT_EQ(QUIC_VERSION_50, 50);
EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
+ EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
}
-TEST_F(QuicVersionsTest, AlpnForVersion) {
- static_assert(SupportedVersions().size() == 5u,
+TEST(QuicVersionsTest, AlpnForVersion) {
+ static_assert(SupportedVersions().size() == 6u,
"Supported versions out of sync");
EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
+ EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
}
-TEST_F(QuicVersionsTest, QuicVersionEnabling) {
+TEST(QuicVersionsTest, QuicVersionEnabling) {
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicFlagSaver flag_saver;
QuicDisableVersion(version);
@@ -387,7 +453,7 @@ TEST_F(QuicVersionsTest, QuicVersionEnabling) {
}
}
-TEST_F(QuicVersionsTest, ReservedForNegotiation) {
+TEST(QuicVersionsTest, ReservedForNegotiation) {
EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
QuicVersionReservedForNegotiation().transport_version);
// QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
@@ -396,7 +462,7 @@ TEST_F(QuicVersionsTest, ReservedForNegotiation) {
}
}
-TEST_F(QuicVersionsTest, SupportedVersionsHasCorrectList) {
+TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
size_t index = 0;
for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
@@ -414,7 +480,7 @@ TEST_F(QuicVersionsTest, SupportedVersionsHasCorrectList) {
EXPECT_EQ(SupportedVersions().size(), index);
}
-TEST_F(QuicVersionsTest, SupportedVersionsAllDistinct) {
+TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
ParsedQuicVersion version1 = SupportedVersions()[index1];
for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
@@ -424,13 +490,17 @@ TEST_F(QuicVersionsTest, SupportedVersionsAllDistinct) {
EXPECT_NE(CreateQuicVersionLabel(version1),
CreateQuicVersionLabel(version2))
<< version1 << " " << version2;
- EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
- << version1 << " " << version2;
+ // The one pair where ALPNs are the same.
+ if ((version1 != ParsedQuicVersion::V2Draft01()) &&
+ (version2 != ParsedQuicVersion::RFCv1())) {
+ EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
+ << version1 << " " << version2;
+ }
}
}
}
-TEST_F(QuicVersionsTest, CurrentSupportedHttp3Versions) {
+TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
ParsedQuicVersionVector all_current_supported_versions =
CurrentSupportedVersions();
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc
index c8306a83590..3cd47ad04c4 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc
@@ -209,15 +209,17 @@ bool TlsClientHandshaker::SetAlpn() {
// Enable ALPS only for versions that use HTTP/3 frames.
for (const std::string& alpn_string : alpns) {
- ParsedQuicVersion version = ParseQuicVersionString(alpn_string);
- if (!version.IsKnown() || !version.UsesHttp3()) {
- continue;
- }
- if (SSL_add_application_settings(
- ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
- alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
- QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
- return false;
+ for (const ParsedQuicVersion& version : session()->supported_versions()) {
+ if (!version.UsesHttp3() || AlpnForVersion(version) != alpn_string) {
+ continue;
+ }
+ if (SSL_add_application_settings(
+ ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
+ alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
+ QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
+ return false;
+ }
+ break;
}
}
@@ -240,9 +242,6 @@ bool TlsClientHandshaker::SetTransportParameters() {
if (!handshaker_delegate()->FillTransportParameters(&params)) {
return false;
}
- if (!user_agent_id_.empty()) {
- params.user_agent_id = user_agent_id_;
- }
// Notify QuicConnectionDebugVisitor.
session()->connection()->OnTransportParametersSent(params);
@@ -395,10 +394,6 @@ size_t TlsClientHandshaker::BufferSizeLimitForLevel(
return TlsHandshaker::BufferSizeLimitForLevel(level);
}
-bool TlsClientHandshaker::KeyUpdateSupportedLocally() const {
- return true;
-}
-
std::unique_ptr<QuicDecrypter>
TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h
index 4543f9b2007..c7db0edd36d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h
@@ -61,7 +61,6 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
CryptoMessageParser* crypto_message_parser() override;
HandshakeState GetHandshakeState() const override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- bool KeyUpdateSupportedLocally() const override;
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc
index ac959f251d4..2eee1cc7559 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.cc
@@ -25,8 +25,7 @@ TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
void TlsHandshaker::ProofVerifierCallbackImpl::Run(
- bool ok,
- const std::string& /*error_details*/,
+ bool ok, const std::string& /*error_details*/,
std::unique_ptr<ProofVerifyDetails>* details) {
if (parent_ == nullptr) {
return;
@@ -42,9 +41,7 @@ void TlsHandshaker::ProofVerifierCallbackImpl::Run(
parent_->AdvanceHandshake();
}
-void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() {
- parent_ = nullptr;
-}
+void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
: stream_(stream), handshaker_delegate_(session) {}
@@ -243,10 +240,13 @@ void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
std::unique_ptr<QuicEncrypter> encrypter =
QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, write_secret, encrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, write_secret,
+ handshaker_delegate_->parsed_version(),
+ encrypter.get());
std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(prf, write_secret,
- encrypter->GetKeySize());
+ CryptoUtils::GenerateHeaderProtectionKey(
+ prf, write_secret, handshaker_delegate_->parsed_version(),
+ encrypter->GetKeySize());
encrypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -266,10 +266,13 @@ bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
std::unique_ptr<QuicDecrypter> decrypter =
QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
const EVP_MD* prf = Prf(cipher);
- CryptoUtils::SetKeyAndIV(prf, read_secret, decrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, read_secret,
+ handshaker_delegate_->parsed_version(),
+ decrypter.get());
std::vector<uint8_t> header_protection_key =
- CryptoUtils::GenerateHeaderProtectionKey(prf, read_secret,
- decrypter->GetKeySize());
+ CryptoUtils::GenerateHeaderProtectionKey(
+ prf, read_secret, handshaker_delegate_->parsed_version(),
+ decrypter->GetKeySize());
decrypter->SetHeaderProtectionKey(
absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
header_protection_key.size()));
@@ -296,14 +299,16 @@ TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
}
const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
const EVP_MD* prf = Prf(cipher);
- latest_read_secret_ =
- CryptoUtils::GenerateNextKeyPhaseSecret(prf, latest_read_secret_);
- latest_write_secret_ =
- CryptoUtils::GenerateNextKeyPhaseSecret(prf, latest_write_secret_);
+ latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+ prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
+ latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+ prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
std::unique_ptr<QuicDecrypter> decrypter =
QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(prf, latest_read_secret_, decrypter.get());
+ CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
+ handshaker_delegate_->parsed_version(),
+ decrypter.get());
decrypter->SetHeaderProtectionKey(absl::string_view(
reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
one_rtt_read_header_protection_key_.size()));
@@ -322,7 +327,9 @@ std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
std::unique_ptr<QuicEncrypter> encrypter =
QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
- CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_, encrypter.get());
+ CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
+ handshaker_delegate_->parsed_version(),
+ encrypter.get());
encrypter->SetHeaderProtectionKey(absl::string_view(
reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
one_rtt_write_header_protection_key_.size()));
@@ -333,9 +340,7 @@ bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
absl::string_view context,
size_t result_len,
std::string* result) {
- // TODO(haoyuewang) Adding support of keying material export when 0-RTT is
- // accepted.
- if (SSL_in_init(ssl())) {
+ if (result == nullptr) {
return false;
}
result->resize(result_len);
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc
index 15eed38605e..a16e72956b1 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc
@@ -419,10 +419,6 @@ size_t TlsServerHandshaker::BufferSizeLimitForLevel(
return TlsHandshaker::BufferSizeLimitForLevel(level);
}
-bool TlsServerHandshaker::KeyUpdateSupportedLocally() const {
- return true;
-}
-
std::unique_ptr<QuicDecrypter>
TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
@@ -483,24 +479,6 @@ bool TlsServerHandshaker::ProcessTransportParameters(
// Notify QuicConnectionDebugVisitor.
session()->connection()->OnTransportParametersReceived(client_params);
- if (GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_key_update_not_yet_supported, 2,
- 2);
- } else {
- // Chrome clients before 86.0.4233.0 did not send the
- // key_update_not_yet_supported transport parameter, but they did send a
- // Google-internal transport parameter with identifier 0x4751. We treat
- // reception of 0x4751 as having received key_update_not_yet_supported to
- // ensure we do not use key updates with those older clients.
- // TODO(dschinazi) remove this workaround once all of our QUIC+TLS Finch
- // experiments have a min_version greater than 86.0.4233.0.
- if (client_params.custom_parameters.find(
- static_cast<TransportParameters::TransportParameterId>(0x4751)) !=
- client_params.custom_parameters.end()) {
- client_params.key_update_not_yet_supported = true;
- }
- }
-
if (client_params.legacy_version_information.has_value() &&
CryptoUtils::ValidateClientHelloVersion(
client_params.legacy_version_information.value().version,
@@ -524,10 +502,6 @@ bool TlsServerHandshaker::ProcessTransportParameters(
}
ProcessAdditionalTransportParameters(client_params);
- if (!session()->user_agent_id().has_value() &&
- client_params.user_agent_id.has_value()) {
- session()->SetUserAgentId(client_params.user_agent_id.value());
- }
return true;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h
index 01cf19b1107..d2f37b0eb26 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h
@@ -80,7 +80,6 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> state) override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
- bool KeyUpdateSupportedLocally() const override;
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc
index 214866c5fab..01fb7ab2ee4 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc
@@ -10,6 +10,7 @@
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
+#include "quic/core/crypto/certificate_util.h"
#include "quic/core/crypto/client_proof_source.h"
#include "quic/core/crypto/proof_source.h"
#include "quic/core/crypto/quic_random.h"
@@ -49,21 +50,6 @@ namespace {
const char kServerHostname[] = "test.example.com";
const uint16_t kServerPort = 443;
-QuicReferenceCountedPointer<ClientProofSource::Chain> TestClientCertChain() {
- return QuicReferenceCountedPointer<ClientProofSource::Chain>(
- new ClientProofSource::Chain({std::string(kTestCertificate)}));
-}
-
-CertificatePrivateKey TestClientCertPrivateKey() {
- CBS private_key_cbs;
- CBS_init(&private_key_cbs,
- reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
- kTestCertificatePrivateKey.size());
-
- return CertificatePrivateKey(
- bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
-}
-
struct TestParams {
ParsedQuicVersion version;
bool disable_resumption;
@@ -400,6 +386,34 @@ class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> {
}
protected:
+ // Setup the client to send a (self-signed) client cert to the server, if
+ // requested. InitializeFakeClient() must be called after this to take effect.
+ bool SetupClientCert() {
+ auto client_proof_source = std::make_unique<DefaultClientProofSource>();
+
+ CertificatePrivateKey client_cert_key(
+ MakeKeyPairForSelfSignedCertificate());
+
+ CertificateOptions options;
+ options.subject = "CN=subject";
+ options.serial_number = 0x12345678;
+ options.validity_start = {2020, 1, 1, 0, 0, 0};
+ options.validity_end = {2049, 12, 31, 0, 0, 0};
+ std::string der_cert =
+ CreateSelfSignedCertificate(*client_cert_key.private_key(), options);
+
+ QuicReferenceCountedPointer<ClientProofSource::Chain> client_cert_chain(
+ new ClientProofSource::Chain({der_cert}));
+
+ if (!client_proof_source->AddCertAndKey({"*"}, client_cert_chain,
+ std::move(client_cert_key))) {
+ return false;
+ }
+
+ client_crypto_config_->set_proof_source(std::move(client_proof_source));
+ return true;
+ }
+
// Every connection gets its own MockQuicConnectionHelper and
// MockAlarmFactory, tracked separately from the server and client state so
// their lifetimes persist through the whole test.
@@ -901,10 +915,7 @@ TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
}
TEST_P(TlsServerHandshakerTest, RequestClientCert) {
- auto client_proof_source = std::make_unique<DefaultClientProofSource>();
- ASSERT_TRUE(client_proof_source->AddCertAndKey({"*"}, TestClientCertChain(),
- TestClientCertPrivateKey()));
- client_crypto_config_->set_proof_source(std::move(client_proof_source));
+ ASSERT_TRUE(SetupClientCert());
InitializeFakeClient();
initial_client_cert_mode_ = ClientCertMode::kRequest;
@@ -924,10 +935,7 @@ TEST_P(TlsServerHandshakerTest, RequestClientCert) {
}
TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
- auto client_proof_source = std::make_unique<DefaultClientProofSource>();
- ASSERT_TRUE(client_proof_source->AddCertAndKey({"*"}, TestClientCertChain(),
- TestClientCertPrivateKey()));
- client_crypto_config_->set_proof_source(std::move(client_proof_source));
+ ASSERT_TRUE(SetupClientCert());
InitializeFakeClient();
QuicDelayedSSLConfig delayed_ssl_config;
@@ -966,10 +974,7 @@ TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
}
TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
- auto client_proof_source = std::make_unique<DefaultClientProofSource>();
- ASSERT_TRUE(client_proof_source->AddCertAndKey({"*"}, TestClientCertChain(),
- TestClientCertPrivateKey()));
- client_crypto_config_->set_proof_source(std::move(client_proof_source));
+ ASSERT_TRUE(SetupClientCert());
InitializeFakeClient();
initial_client_cert_mode_ = ClientCertMode::kRequire;
@@ -990,10 +995,7 @@ TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
}
TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
- auto client_proof_source = std::make_unique<DefaultClientProofSource>();
- ASSERT_TRUE(client_proof_source->AddCertAndKey({"*"}, TestClientCertChain(),
- TestClientCertPrivateKey()));
- client_crypto_config_->set_proof_source(std::move(client_proof_source));
+ ASSERT_TRUE(SetupClientCert());
InitializeFakeClient();
QuicDelayedSSLConfig delayed_ssl_config;
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc
index 8f20b33c183..c25329c5fc8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.cc
@@ -228,7 +228,8 @@ void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
for (auto& received_packet_manager : received_packet_managers_) {
- received_packet_manager.set_save_timestamps(save_timestamps);
+ received_packet_manager.set_save_timestamps(
+ save_timestamps, supports_multiple_packet_number_spaces_);
}
}
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc
index 8af288fd37a..fb6a61d5b5a 100644
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/masque/masque_client_bin.cc
@@ -23,17 +23,15 @@
#include "quic/platform/api/quic_socket_address.h"
#include "quic/platform/api/quic_system_event_loop.h"
#include "quic/tools/fake_proof_verifier.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- disable_certificate_verification,
- false,
- "If true, don't verify the server certificate.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, disable_certificate_verification, false,
+ "If true, don't verify the server certificate.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- masque_mode,
- "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
+ "Allows setting MASQUE mode, valid values are "
+ "open and legacy. Defaults to open.");
namespace quic {
@@ -48,9 +46,10 @@ int RunMasqueClient(int argc, char* argv[]) {
// Note that the URI template expansion currently only supports string
// replacement of {target_host} and {target_port}, not
// {?target_host,target_port}.
- std::vector<std::string> urls = QuicParseCommandLineFlags(usage, argc, argv);
+ std::vector<std::string> urls =
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (urls.empty()) {
- QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc
index aaccda3722e..666f67f5bf0 100644
--- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/masque/masque_server_bin.cc
@@ -15,40 +15,33 @@
#include "quic/platform/api/quic_logging.h"
#include "quic/platform/api/quic_socket_address.h"
#include "quic/platform/api/quic_system_event_loop.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
- port,
- 9661,
- "The port the MASQUE server will listen on.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 9661,
+ "The port the MASQUE server will listen on.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- cache_dir,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, cache_dir, "",
"Specifies the directory used during QuicHttpResponseCache "
"construction to seed the cache. Cache directory can be "
"generated using `wget -p --save-headers <url>`");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- server_authority,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, server_authority, "",
"Specifies the authority over which the server will accept MASQUE "
"requests. Defaults to empty which allows all authorities.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- masque_mode,
- "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
+ "Allows setting MASQUE mode, valid values are "
+ "open and legacy. Defaults to open.");
int main(int argc, char* argv[]) {
QuicSystemEventLoop event_loop("masque_server");
const char* usage = "Usage: masque_server [options]";
std::vector<std::string> non_option_args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (!non_option_args.empty()) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
return 0;
}
diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h
index 1a9f2d99fa2..762e5907645 100644
--- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h
+++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_flags.h
@@ -8,8 +8,7 @@
#include <string>
#include <vector>
-#include "net/quic/platform/impl/quic_flags_impl.h"
-
+#include "quiche_platform_impl/quic_flags_impl.h"
#include "common/platform/api/quiche_flags.h"
#define GetQuicReloadableFlag(flag) GetQuicheReloadableFlag(quic, flag)
@@ -20,31 +19,4 @@
#define GetQuicFlag(flag) GetQuicheFlag(flag)
#define SetQuicFlag(flag, value) SetQuicheFlag(flag, value)
-// Define a command-line flag that can be automatically set via
-// QuicParseCommandLineFlags().
-#define DEFINE_QUIC_COMMAND_LINE_FLAG(type, name, default_value, help) \
- DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL(type, name, default_value, help)
-
-namespace quic {
-
-// Parses command-line flags, setting flag variables defined using
-// DEFINE_QUIC_COMMAND_LINE_FLAG if they appear in the command line, and
-// returning a list of any non-flag arguments specified in the command line. If
-// the command line specifies '-h' or '--help', prints a usage message with flag
-// descriptions to stdout and exits with status 0. If a flag has an unparsable
-// value, writes an error message to stderr and exits with status 1.
-inline std::vector<std::string> QuicParseCommandLineFlags(
- const char* usage,
- int argc,
- const char* const* argv) {
- return QuicParseCommandLineFlagsImpl(usage, argc, argv);
-}
-
-// Prints a usage message with flag descriptions to stdout.
-inline void QuicPrintCommandLineFlagHelp(const char* usage) {
- QuicPrintCommandLineFlagHelpImpl(usage);
-}
-
-} // namespace quic
-
#endif // QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc
index fce08d290ea..87cfb2d5266 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc
@@ -9,8 +9,9 @@
#include "absl/strings/string_view.h"
#include "quic/core/quic_types.h"
#include "quic/qbone/qbone_constants.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
bool, qbone_client_defer_control_stream_creation, true,
"If true, control stream in QBONE client session is created after "
"encryption established.");
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc
index 7303b06091a..61a9afe4de9 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.cc
@@ -6,6 +6,7 @@
#include <cstdint>
#include <limits>
+
#include "absl/strings/string_view.h"
#include "quic/core/quic_session.h"
#include "quic/platform/api/quic_bug_tracker.h"
@@ -25,6 +26,14 @@ QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
BIDIRECTIONAL),
pending_message_size_(0) {}
+QboneControlStreamBase::QboneControlStreamBase(quic::PendingStream* pending,
+ QuicSession* session)
+ : QuicStream(pending, session, /*is_static=*/true),
+ pending_message_size_(0) {
+ QUICHE_DCHECK_EQ(pending->id(), QboneConstants::GetControlStreamId(
+ session->transport_version()));
+}
+
void QboneControlStreamBase::OnDataAvailable() {
sequencer()->Read(&buffer_);
while (true) {
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h
index d0c2b1a1ed4..c38697dd2c6 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_control_stream.h
@@ -16,6 +16,7 @@ class QboneSessionBase;
class QUIC_EXPORT_PRIVATE QboneControlStreamBase : public QuicStream {
public:
explicit QboneControlStreamBase(QuicSession* session);
+ QboneControlStreamBase(quic::PendingStream* pending, QuicSession* session);
void OnDataAvailable() override;
@@ -46,6 +47,9 @@ class QUIC_EXPORT_PRIVATE QboneControlStream : public QboneControlStreamBase {
QboneControlStream(QuicSession* session, Handler* handler)
: QboneControlStreamBase(session), handler_(handler) {}
+ QboneControlStream(quic::PendingStream* pending, QuicSession* session,
+ Handler* handler)
+ : QboneControlStreamBase(pending, session), handler_(handler) {}
bool SendRequest(const Outgoing& request) { return SendMessage(request); }
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc
index 2ddb8e4454b..bc2d8e53a3c 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.cc
@@ -12,8 +12,9 @@
#include "quic/core/quic_types.h"
#include "quic/core/quic_utils.h"
#include "quic/qbone/qbone_constants.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
bool, qbone_server_defer_control_stream_creation, true,
"If true, control stream in QBONE server session is created after "
"encryption established.");
@@ -72,6 +73,17 @@ void QboneServerSession::CreateControlStream() {
ActivateStream(std::move(control_stream));
}
+QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
+ PendingStream* pending) {
+ QUICHE_DCHECK(control_stream_ == nullptr);
+ // Register the reserved control stream.
+ auto control_stream =
+ std::make_unique<QboneServerControlStream>(pending, this, handler_);
+ control_stream_ = control_stream.get();
+ ActivateStream(std::move(control_stream));
+ return control_stream_;
+}
+
void QboneServerSession::Initialize() {
QboneSessionBase::Initialize();
if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h
index f5af8b43d33..d206e4d7012 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_server_session.h
@@ -76,15 +76,20 @@ class QUIC_EXPORT_PRIVATE QboneServerSession
// QboneSessionBase interface implementation.
std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
- // Instantiate QboneServerControlStream.
+ // Instantiates QboneServerControlStream.
void CreateControlStream();
+ // Instantiates QboneServerControlStream from the pending stream and returns a
+ // pointer to it.
+ QuicStream* CreateControlStreamFromPendingStream(PendingStream* pending);
+
// The packet processor.
QbonePacketProcessor processor_;
- private:
// Config for QUIC crypto server stream, used by the server.
const QuicCryptoServerConfig* quic_crypto_server_config_;
+
+ private:
// Used by QUIC crypto server stream to track most recently compressed certs.
QuicCompressedCertsCache* compressed_certs_cache_;
// This helper is needed when create QuicCryptoServerStream.
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc
index 2f2f31e3239..702f185e2e2 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.cc
@@ -18,11 +18,10 @@
#include "quic/platform/api/quic_testvalue.h"
#include "quic/qbone/platform/icmp_packet.h"
#include "quic/qbone/qbone_constants.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- qbone_close_ephemeral_frames,
- true,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, qbone_close_ephemeral_frames, true,
"If true, we'll call CloseStream even when we receive ephemeral frames.");
namespace quic {
@@ -108,7 +107,7 @@ bool QboneSessionBase::ShouldKeepConnectionAlive() const {
std::unique_ptr<QuicStream> QboneSessionBase::CreateDataStream(
QuicStreamId id) {
- if (crypto_stream_ == nullptr || !crypto_stream_->encryption_established()) {
+ if (!IsEncryptionEstablished()) {
// Encryption not active so no stream created
return nullptr;
}
diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc
index 5aac3e73ada..39012336662 100644
--- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc
+++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.cc
@@ -10,11 +10,10 @@
#include "quic/core/quic_types.h"
#include "quic/qbone/qbone_constants.h"
#include "quic/qbone/qbone_session_base.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(int,
- qbone_stream_ttl_secs,
- 3,
- "The QBONE Stream TTL in seconds.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int, qbone_stream_ttl_secs, 3,
+ "The QBONE Stream TTL in seconds.");
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
index ec58386cfba..649406a914d 100644
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
+++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
@@ -158,6 +158,14 @@ QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
return QUIC_FAILURE;
}
+ if (!IsKeyTypeAllowedByPolicy(*view)) {
+ *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
+ *error_details =
+ absl::StrCat("Certificate uses a disallowed public key type (",
+ PublicKeyTypeToString(view->public_key_type()), ")");
+ return QUIC_FAILURE;
+ }
+
*details = std::make_unique<Details>(Status::kValidCertificate);
return QUIC_SUCCESS;
}
@@ -201,4 +209,21 @@ bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
now.IsBefore(certificate.validity_end());
}
+bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy(
+ const CertificateView& certificate) {
+ switch (certificate.public_key_type()) {
+ // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI
+ // algorithm, and prohibits RSA. We also allow P-384 and Ed25519.
+ case PublicKeyType::kP256:
+ case PublicKeyType::kP384:
+ case PublicKeyType::kEd25519:
+ return true;
+ case PublicKeyType::kRsa:
+ // TODO(b/213614428): this should be false by default.
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
index 76323d50428..9a03c665818 100644
--- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
+++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
@@ -61,8 +61,9 @@ class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
kExpiryTooLong = 3,
kExpired = 4,
kInternalError = 5,
+ kDisallowedKeyAlgorithm = 6,
- kMaxValue = kInternalError,
+ kMaxValue = kDisallowedKeyAlgorithm,
};
class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
@@ -115,6 +116,9 @@ class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
std::unique_ptr<ProofVerifierCallback> callback) override;
std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
+ protected:
+ virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
+
private:
bool HasKnownFingerprint(absl::string_view der_certificate);
bool HasValidExpiry(const CertificateView& certificate);
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc
index 634c16ff009..cbf4fe2aa7e 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc
@@ -393,6 +393,53 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
}
}
+bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
+ QuicCryptoStream* client,
+ std::function<bool()> client_condition,
+ PacketSavingConnection* server_conn,
+ QuicCryptoStream* server,
+ std::function<bool()> server_condition) {
+ size_t client_next_packet_to_deliver =
+ client_conn->number_of_packets_delivered_;
+ size_t server_next_packet_to_deliver =
+ server_conn->number_of_packets_delivered_;
+ while (
+ client_conn->connected() && server_conn->connected() &&
+ (!client_condition() || !server_condition()) &&
+ (client_conn->encrypted_packets_.size() > client_next_packet_to_deliver ||
+ server_conn->encrypted_packets_.size() >
+ server_next_packet_to_deliver)) {
+ if (!server_condition()) {
+ QUIC_LOG(INFO) << "Processing "
+ << client_conn->encrypted_packets_.size() -
+ client_next_packet_to_deliver
+ << " packets client->server";
+ MovePackets(client_conn, &client_next_packet_to_deliver, server,
+ server_conn, Perspective::IS_SERVER);
+ }
+ if (!client_condition()) {
+ QUIC_LOG(INFO) << "Processing "
+ << server_conn->encrypted_packets_.size() -
+ server_next_packet_to_deliver
+ << " packets server->client";
+ MovePackets(server_conn, &server_next_packet_to_deliver, client,
+ client_conn, Perspective::IS_CLIENT);
+ }
+ }
+ client_conn->number_of_packets_delivered_ = client_next_packet_to_deliver;
+ server_conn->number_of_packets_delivered_ = server_next_packet_to_deliver;
+ bool result = client_condition() && server_condition();
+ if (!result) {
+ QUIC_LOG(INFO) << "CommunicateHandshakeMessagesUnti failed with state: "
+ "client connected? "
+ << client_conn->connected() << " server connected? "
+ << server_conn->connected() << " client condition met? "
+ << client_condition() << " server condition met? "
+ << server_condition();
+ }
+ return result;
+}
+
std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
QuicCryptoStream* client,
size_t client_i,
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h
index 87e354a9f79..b4d772adb68 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h
@@ -109,6 +109,19 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
PacketSavingConnection* server_conn,
QuicCryptoStream* server);
+// CommunicateHandshakeMessagesUntil:
+// 1) Moves messages from |client| to |server| until |server_condition| is met.
+// 2) Moves messages from |server| to |client| until |client_condition| is met.
+// 3) Returns true if both conditions are met.
+// 4) Returns false if either connection is closed or there is no more packet to
+// deliver before both conditions are met.
+bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
+ QuicCryptoStream* client,
+ std::function<bool()> client_condition,
+ PacketSavingConnection* server_conn,
+ QuicCryptoStream* server,
+ std::function<bool()> server_condition);
+
// AdvanceHandshake attempts to moves messages from |client| to |server| and
// |server| to |client|. Returns the number of messages moved.
std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h
index 23d54aab638..2230fbec940 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h
@@ -33,6 +33,7 @@ class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
~MockQpackStreamSenderDelegate() override = default;
MOCK_METHOD(void, WriteStreamData, (absl::string_view data), (override));
+ MOCK_METHOD(uint64_t, NumBytesBuffered, (), (const, override));
};
class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
@@ -40,6 +41,8 @@ class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
~NoopQpackStreamSenderDelegate() override = default;
void WriteStreamData(absl::string_view /*data*/) override {}
+
+ uint64_t NumBytesBuffered() const override { return 0; }
};
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h
index 6f0c667eb59..227a48de075 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_client_session_cache_peer.h
@@ -20,6 +20,11 @@ class QuicClientSessionCachePeer {
}
return iter->second->token;
}
+
+ static bool HasEntry(QuicClientSessionCache* cache,
+ const QuicServerId& server_id) {
+ return cache->cache_.Lookup(server_id) != cache->cache_.end();
+ }
};
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
index b5119498c74..207582f738a 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
@@ -57,6 +57,12 @@ QuicTime::Delta QuicConnectionPeer::GetNetworkTimeout(
}
// static
+QuicTime::Delta QuicConnectionPeer::GetHandshakeTimeout(
+ QuicConnection* connection) {
+ return connection->idle_network_detector_.handshake_timeout_;
+}
+
+// static
void QuicConnectionPeer::SetPerspective(QuicConnection* connection,
Perspective perspective) {
connection->perspective_ = perspective;
@@ -407,12 +413,6 @@ size_t QuicConnectionPeer::NumUndecryptablePackets(QuicConnection* connection) {
return connection->undecryptable_packets_.size();
}
-// static
-size_t QuicConnectionPeer::NumPendingPathChallengesToResponse(
- QuicConnection* connection) {
- return connection->pending_path_challenge_payloads_.size();
-}
-
void QuicConnectionPeer::SetConnectionClose(QuicConnection* connection) {
connection->connected_ = false;
}
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h
index aa30c2417ee..62ed60e2bef 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h
@@ -50,6 +50,8 @@ class QuicConnectionPeer {
static QuicTime::Delta GetNetworkTimeout(QuicConnection* connection);
+ static QuicTime::Delta GetHandshakeTimeout(QuicConnection* connection);
+
static void SetPerspective(QuicConnection* connection,
Perspective perspective);
@@ -166,8 +168,6 @@ class QuicConnectionPeer {
static size_t NumUndecryptablePackets(QuicConnection* connection);
- static size_t NumPendingPathChallengesToResponse(QuicConnection* connection);
-
static void SetConnectionClose(QuicConnection* connection);
static void SendPing(QuicConnection* connection);
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc
index 7d1ba86c666..8689535ecff 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -27,12 +27,6 @@ void QuicSentPacketManagerPeer::SetMaxTailLossProbes(
}
// static
-bool QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->enable_half_rtt_tail_loss_probe_;
-}
-
-// static
bool QuicSentPacketManagerPeer::GetUseNewRto(
QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->use_new_rto_;
@@ -180,6 +174,12 @@ void QuicSentPacketManagerPeer::DisablePacerBursts(
}
// static
+int QuicSentPacketManagerPeer::GetPacerInitialBurstSize(
+ QuicSentPacketManager* sent_packet_manager) {
+ return sent_packet_manager->pacing_sender_.initial_burst_size_;
+}
+
+// static
void QuicSentPacketManagerPeer::SetNextPacedPacketTime(
QuicSentPacketManager* sent_packet_manager,
QuicTime time) {
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h
index a39915f15be..ef0af1e4654 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -24,9 +24,6 @@ class QuicSentPacketManagerPeer {
static void SetMaxTailLossProbes(QuicSentPacketManager* sent_packet_manager,
size_t max_tail_loss_probes);
- static bool GetEnableHalfRttTailLossProbe(
- QuicSentPacketManager* sent_packet_manager);
-
static bool GetUseNewRto(QuicSentPacketManager* sent_packet_manager);
static void SetPerspective(QuicSentPacketManager* sent_packet_manager,
@@ -85,6 +82,9 @@ class QuicSentPacketManagerPeer {
static void DisablePacerBursts(QuicSentPacketManager* sent_packet_manager);
+ static int GetPacerInitialBurstSize(
+ QuicSentPacketManager* sent_packet_manager);
+
static void SetNextPacedPacketTime(QuicSentPacketManager* sent_packet_manager,
QuicTime time);
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc
index 6db9a4a96c1..ea21081d36c 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.cc
@@ -28,5 +28,10 @@ bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
return stream->use_datagram_contexts_;
}
+// static
+bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
+ return stream->OnHeadersFrameEnd();
+}
+
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h
index 8a5042689a0..692cbc38c20 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h
@@ -24,6 +24,7 @@ class QuicSpdyStreamPeer {
static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
QuicSpdyStream* stream);
static bool use_datagram_contexts(QuicSpdyStream* stream);
+ static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
};
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h
index b064a4abd9c..d8d09796162 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h
@@ -745,6 +745,9 @@ class PacketSavingConnection : public MockQuicConnection {
MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));
std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
+ // Number of packets in encrypted_packets that has been delivered to the peer
+ // connection.
+ size_t number_of_packets_delivered_ = 0;
MockClock clock_;
};
@@ -845,7 +848,6 @@ class MockQuicCryptoStream : public QuicCryptoStream {
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {}
- bool KeyUpdateSupportedLocally() const override { return false; }
std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
override {
return nullptr;
@@ -1464,7 +1466,7 @@ void CreateClientSessionForTest(
// start time, otherwise nonce verification will fail.
// supported_versions: Set of QUIC versions this server supports.
// helper: Pointer to the MockQuicConnectionHelper to use for the session.
-// crypto_server_config: Pointer to the crypto server config.
+// server_crypto_config: Pointer to the crypto server config.
// server_connection: Pointer reference for newly created
// connection. This object will be owned by the
// server_session.
@@ -1474,7 +1476,7 @@ void CreateServerSessionForTest(
QuicServerId server_id, QuicTime::Delta connection_start_time,
ParsedQuicVersionVector supported_versions,
MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
- QuicCryptoServerConfig* crypto_server_config,
+ QuicCryptoServerConfig* server_crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
PacketSavingConnection** server_connection,
TestQuicSpdyServerSession** server_session);
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc
index 0b981255200..deeddddbd9d 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_client_bin.cc
@@ -47,6 +47,7 @@
#include "quic/platform/api/quic_system_event_loop.h"
#include "quic/tools/quic_epoll_client_factory.h"
#include "quic/tools/quic_toy_client.h"
+#include "common/platform/api/quiche_command_line_flags.h"
int main(int argc, char* argv[]) {
QuicSystemEventLoop event_loop("quic_client");
@@ -54,9 +55,9 @@ int main(int argc, char* argv[]) {
// All non-flag arguments should be interpreted as URLs to fetch.
std::vector<std::string> urls =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (urls.size() != 1) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
exit(0);
}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc
index c90c8dd4c26..6c14cc3e308 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc
@@ -19,19 +19,16 @@
#include "quic/tools/fake_proof_verifier.h"
#include "quic/tools/quic_client.h"
#include "quic/tools/quic_url.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- host,
- "",
- "The IP or hostname to connect to.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, host, "",
+ "The IP or hostname to connect to.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_version,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_version, "",
"The QUIC version to use. Defaults to most recent IETF QUIC version.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
namespace quic {
@@ -403,9 +400,9 @@ int main(int argc, char* argv[]) {
const char* usage = "Usage: quic_client_interop_test [options] [url]";
std::vector<std::string> args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (args.size() > 1) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
exit(1);
}
std::string dns_host = GetQuicFlag(FLAGS_host);
@@ -426,7 +423,7 @@ int main(int argc, char* argv[]) {
port = 443;
}
if (dns_host.empty()) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
exit(1);
}
if (url_host.empty()) {
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h
index b8d28103ced..72c57843d60 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h
@@ -154,9 +154,9 @@ class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
void FetchResponseFromBackend(
const spdy::Http2HeaderBlock& request_headers,
const std::string& request_body,
- QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
+ QuicSimpleServerBackend::RequestHandler* quic_stream) override;
void CloseBackendResponseStream(
- QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
+ QuicSimpleServerBackend::RequestHandler* quic_stream) override;
WebTransportResponse ProcessWebTransportRequest(
const spdy::Http2HeaderBlock& request_headers,
WebTransportSession* session) override;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc
index ad357e9b43c..8ffae272ffe 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc
@@ -34,12 +34,11 @@
#include "quic/core/quic_types.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_flags.h"
+#include "common/platform/api/quiche_command_line_flags.h"
#include "common/quiche_text_utils.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- quic_version,
- "",
- "If set, specify the QUIC version to use.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, quic_version, "",
+ "If set, specify the QUIC version to use.");
namespace quic {
@@ -248,10 +247,10 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface {
int main(int argc, char* argv[]) {
const char* usage = "Usage: quic_packet_printer client|server <hex>";
std::vector<std::string> args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (args.size() < 2) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
return 1;
}
@@ -263,7 +262,7 @@ int main(int argc, char* argv[]) {
perspective = quic::Perspective::IS_SERVER;
} else {
std::cerr << "Invalid perspective" << std::endl;
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
return 1;
}
std::string hex = absl::HexStringToBytes(args[1]);
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc
index 68443f37d1a..ed83d278b7d 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_reject_reason_decoder_bin.cc
@@ -11,6 +11,7 @@
#include "quic/core/crypto/crypto_handshake.h"
#include "quic/core/crypto/crypto_utils.h"
#include "quic/platform/api/quic_flags.h"
+#include "common/platform/api/quiche_command_line_flags.h"
#include "common/quiche_text_utils.h"
using quic::CryptoUtils;
@@ -20,7 +21,7 @@ using quic::MAX_FAILURE_REASON;
int main(int argc, char* argv[]) {
const char* usage = "Usage: quic_reject_reason_decoder <packed_reason>";
std::vector<std::string> args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (args.size() != 1) {
std::cerr << usage << std::endl;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc
index c9713670a9c..5d3ed7202f4 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_server_bin.cc
@@ -12,14 +12,15 @@
#include "quic/platform/api/quic_system_event_loop.h"
#include "quic/tools/quic_epoll_server_factory.h"
#include "quic/tools/quic_toy_server.h"
+#include "common/platform/api/quiche_command_line_flags.h"
int main(int argc, char* argv[]) {
QuicSystemEventLoop event_loop("quic_server");
const char* usage = "Usage: quic_server [options]";
std::vector<std::string> non_option_args =
- quic::QuicParseCommandLineFlags(usage, argc, argv);
+ quiche::QuicheParseCommandLineFlags(usage, argc, argv);
if (!non_option_args.empty()) {
- quic::QuicPrintCommandLineFlagHelp(usage);
+ quiche::QuichePrintCommandLineFlagHelp(usage);
exit(0);
}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc
index d23ba5d53c4..9cc7bfda17c 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session_test.cc
@@ -39,7 +39,6 @@
#include "quic/tools/quic_simple_server_stream.h"
using testing::_;
-using testing::AnyNumber;
using testing::AtLeast;
using testing::InSequence;
using testing::Invoke;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc
index 59fe4ec229b..7b6b760a6bb 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc
@@ -63,171 +63,129 @@
#include "quic/platform/api/quic_system_event_loop.h"
#include "quic/tools/fake_proof_verifier.h"
#include "quic/tools/quic_url.h"
+#include "common/platform/api/quiche_command_line_flags.h"
#include "common/quiche_text_utils.h"
namespace {
-using quic::QuicUrl;
using quiche::QuicheTextUtils;
} // namespace
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- host,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, host, "",
"The IP or hostname to connect to. If not provided, the host "
"will be derived from the provided URL.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- ip_version_for_host_lookup,
- "",
- "Only used if host address lookup is needed. "
- "4=ipv4; 6=ipv6; otherwise=don't care.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, ip_version_for_host_lookup, "",
+ "Only used if host address lookup is needed. "
+ "4=ipv4; 6=ipv6; otherwise=don't care.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
- body,
- "",
- "If set, send a POST with this body.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, body, "",
+ "If set, send a POST with this body.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- body_hex,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, body_hex, "",
"If set, contents are converted from hex to ascii, before "
"sending as body of a POST. e.g. --body_hex=\"68656c6c6f\"");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- headers,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, headers, "",
"A semicolon separated list of key:value pairs to "
"add to request headers.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- quiet,
- false,
- "Set to true for a quieter output experience.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quiet, false,
+ "Set to true for a quieter output experience.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_version,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_version, "",
"QUIC version to speak, e.g. 21. If not set, then all available "
"versions are offered in the handshake. Also supports wire versions "
"such as Q043 or T099.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- connection_options,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, connection_options, "",
"Connection options as ASCII tags separated by commas, "
"e.g. \"ABCD,EFGH\"");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- client_connection_options,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, client_connection_options, "",
"Client connection options as ASCII tags separated by commas, "
"e.g. \"ABCD,EFGH\"");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- quic_ietf_draft,
- false,
- "Use the IETF draft version. This also enables "
- "required internal QUIC flags.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
+ "Use the IETF draft version. This also enables "
+ "required internal QUIC flags.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- version_mismatch_ok,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, version_mismatch_ok, false,
"If true, a version mismatch in the handshake is not considered a "
"failure. Useful for probing a server to determine if it speaks "
"any version of QUIC.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- force_version_negotiation,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, force_version_negotiation, false,
"If true, start by proposing a version that is reserved for version "
"negotiation.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- multi_packet_chlo,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, multi_packet_chlo, false,
"If true, add a transport parameter to make the ClientHello span two "
"packets. Only works with QUIC+TLS.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- redirect_is_success,
- true,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, redirect_is_success, true,
"If true, an HTTP response code of 3xx is considered to be a "
"successful response, otherwise a failure.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
- initial_mtu,
- 0,
- "Initial MTU of the connection.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, initial_mtu, 0,
+ "Initial MTU of the connection.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- int32_t,
- num_requests,
- 1,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ int32_t, num_requests, 1,
"How many sequential requests to make on a single connection.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- disable_certificate_verification,
- false,
- "If true, don't verify the server certificate.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, disable_certificate_verification, false,
+ "If true, don't verify the server certificate.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
std::string, default_client_cert, "",
"The path to the file containing PEM-encoded client default certificate to "
"be sent to the server, if server requested client certs.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
std::string, default_client_cert_key, "",
"The path to the file containing PEM-encoded private key of the client's "
"default certificate for signing, if server requested client certs.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- drop_response_body,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, drop_response_body, false,
"If true, drop response body immediately after it is received.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- disable_port_changes,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, disable_port_changes, false,
"If true, do not change local port after each request.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- one_connection_per_request,
- false,
- "If true, close the connection after each "
- "request. This allows testing 0-RTT.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, one_connection_per_request, false,
+ "If true, close the connection after each "
+ "request. This allows testing 0-RTT.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
- server_connection_id_length,
- -1,
- "Length of the server connection ID used.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, server_connection_id_length, -1,
+ "Length of the server connection ID used.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
- client_connection_id_length,
- -1,
- "Length of the client connection ID used.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, client_connection_id_length, -1,
+ "Length of the client connection ID used.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, max_time_before_crypto_handshake_ms,
- 10000,
- "Max time to wait before handshake completes.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, max_time_before_crypto_handshake_ms,
+ 10000,
+ "Max time to wait before handshake completes.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, max_inbound_header_list_size, 128 * 1024,
- "Max inbound header list size. 0 means default.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ int32_t, max_inbound_header_list_size, 128 * 1024,
+ "Max inbound header list size. 0 means default.");
namespace quic {
namespace {
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc
index e7b4e1ecd7a..cdbe9b3bce9 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_server.cc
@@ -12,44 +12,33 @@
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_socket_address.h"
#include "quic/tools/quic_memory_cache_backend.h"
+#include "common/platform/api/quiche_command_line_flags.h"
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
- port,
- 6121,
- "The port the quic server will listen on.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 6121,
+ "The port the quic server will listen on.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_response_cache_dir,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_response_cache_dir, "",
"Specifies the directory used during QuicHttpResponseCache "
"construction to seed the cache. Cache directory can be "
"generated using `wget -p --save-headers <url>`");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- bool,
- generate_dynamic_responses,
- false,
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ bool, generate_dynamic_responses, false,
"If true, then URLs which have a numeric path will send a dynamically "
"generated response of that many bytes.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- quic_ietf_draft,
- false,
- "Only enable IETF draft versions. This also "
- "enables required internal QUIC flags.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
+ "Only enable IETF draft versions. This also "
+ "enables required internal QUIC flags.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(
- std::string,
- quic_versions,
- "",
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, quic_versions, "",
"QUIC versions to enable, e.g. \"h3-25,h3-27\". If not set, then all "
"available versions are enabled.");
-DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
- enable_webtransport,
- false,
- "If true, WebTransport support is enabled.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, enable_webtransport, false,
+ "If true, WebTransport support is enabled.");
namespace quic {