diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-12 09:13:00 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-16 09:58:26 +0000 |
commit | 03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch) | |
tree | cc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/net/third_party | |
parent | fa98118a45f7e169f8846086dc2c22c49a8ba310 (diff) | |
download | qtwebengine-chromium-03561cae90f1d99b5c54b1ef3be69f10e882b25e.tar.gz |
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/third_party')
681 files changed, 14874 insertions, 8499 deletions
diff --git a/chromium/net/third_party/nss/DIR_METADATA b/chromium/net/third_party/nss/DIR_METADATA new file mode 100644 index 00000000000..b64db52841e --- /dev/null +++ b/chromium/net/third_party/nss/DIR_METADATA @@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Network>SSL" +}
\ No newline at end of file diff --git a/chromium/net/third_party/nss/OWNERS b/chromium/net/third_party/nss/OWNERS index d3322186508..e6478b3b4fd 100644 --- a/chromium/net/third_party/nss/OWNERS +++ b/chromium/net/third_party/nss/OWNERS @@ -2,5 +2,3 @@ agl@chromium.org davidben@chromium.org rsleevi@chromium.org wtc@chromium.org - -# COMPONENT: Internals>Network>SSL diff --git a/chromium/net/third_party/nss/README.chromium b/chromium/net/third_party/nss/README.chromium index 68395c729e2..87108826e11 100644 --- a/chromium/net/third_party/nss/README.chromium +++ b/chromium/net/third_party/nss/README.chromium @@ -4,6 +4,7 @@ Version: 3.23 RTM Security Critical: Yes License: MPL 2 License File: LICENSE +CPEPrefix: cpe:/a:mozilla:nss:3.23 This directory includes a file derived from NSS's libssl, from the hg repo at: https://hg.mozilla.org/projects/nss diff --git a/chromium/net/third_party/quiche/BUILD.gn b/chromium/net/third_party/quiche/BUILD.gn index ffab81e2122..4ee51a779e3 100644 --- a/chromium/net/third_party/quiche/BUILD.gn +++ b/chromium/net/third_party/quiche/BUILD.gn @@ -23,12 +23,8 @@ source_set("quiche") { if (!is_nacl) { sources += [ - "src/common/platform/api/quiche_arraysize.h", - "src/common/platform/api/quiche_endian.h", "src/common/platform/api/quiche_export.h", "src/common/platform/api/quiche_logging.h", - "src/common/platform/api/quiche_optional.h", - "src/common/platform/api/quiche_ptr_util.h", "src/common/platform/api/quiche_str_cat.h", "src/common/platform/api/quiche_string_piece.h", "src/common/platform/api/quiche_text_utils.h", @@ -38,6 +34,7 @@ source_set("quiche") { "src/common/quiche_data_reader.h", "src/common/quiche_data_writer.cc", "src/common/quiche_data_writer.h", + "src/common/quiche_endian.h", "src/common/simple_linked_hash_map.h", "src/http2/decoder/decode_buffer.cc", "src/http2/decoder/decode_buffer.h", @@ -458,6 +455,7 @@ source_set("quiche") { "src/quic/core/quic_packet_writer.h", "src/quic/core/quic_packets.cc", "src/quic/core/quic_packets.h", + "src/quic/core/quic_protocol_flags_list.h", "src/quic/core/quic_received_packet_manager.cc", "src/quic/core/quic_received_packet_manager.h", "src/quic/core/quic_sent_packet_manager.cc", @@ -514,7 +512,6 @@ source_set("quiche") { "src/quic/core/uber_quic_stream_id_manager.h", "src/quic/core/uber_received_packet_manager.cc", "src/quic/core/uber_received_packet_manager.h", - "src/quic/platform/api/quic_aligned.h", "src/quic/platform/api/quic_bug_tracker.h", "src/quic/platform/api/quic_cert_utils.h", "src/quic/platform/api/quic_client_stats.h", @@ -523,7 +520,6 @@ source_set("quiche") { "src/quic/platform/api/quic_estimate_memory_usage.h", "src/quic/platform/api/quic_export.h", "src/quic/platform/api/quic_exported_stats.h", - "src/quic/platform/api/quic_fallthrough.h", "src/quic/platform/api/quic_file_utils.cc", "src/quic/platform/api/quic_file_utils.h", "src/quic/platform/api/quic_flag_utils.h", @@ -535,7 +531,6 @@ source_set("quiche") { "src/quic/platform/api/quic_ip_address.h", "src/quic/platform/api/quic_ip_address_family.h", "src/quic/platform/api/quic_logging.h", - "src/quic/platform/api/quic_macros.h", "src/quic/platform/api/quic_map_util.h", "src/quic/platform/api/quic_mem_slice.h", "src/quic/platform/api/quic_mem_slice_span.h", @@ -586,6 +581,8 @@ source_set("quiche") { "src/spdy/core/http2_priority_write_scheduler.h", "src/spdy/core/lifo_write_scheduler.h", "src/spdy/core/priority_write_scheduler.h", + "src/spdy/core/recording_headers_handler.cc", + "src/spdy/core/recording_headers_handler.h", "src/spdy/core/spdy_alt_svc_wire_format.cc", "src/spdy/core/spdy_alt_svc_wire_format.h", "src/spdy/core/spdy_bitmasks.h", @@ -613,7 +610,6 @@ source_set("quiche") { "src/spdy/core/zero_copy_output_buffer.h", "src/spdy/platform/api/spdy_bug_tracker.h", "src/spdy/platform/api/spdy_containers.h", - "src/spdy/platform/api/spdy_endianness_util.h", "src/spdy/platform/api/spdy_estimate_memory_usage.h", "src/spdy/platform/api/spdy_flags.h", "src/spdy/platform/api/spdy_logging.h", @@ -1243,10 +1239,10 @@ source_set("quiche_tests") { # TODO(rch): Re-enable once the SLOW_TEST annotation is added. # "src/quic/core/congestion_control/bbr2_simulator_test.cc", - "src/common/platform/api/quiche_endian_test.cc", "src/common/platform/api/quiche_str_cat_test.cc", "src/common/platform/api/quiche_text_utils_test.cc", "src/common/platform/api/quiche_time_utils_test.cc", + "src/common/quiche_endian_test.cc", "src/quic/core/congestion_control/bbr_sender_test.cc", "src/quic/core/congestion_control/cubic_bytes_test.cc", "src/quic/core/congestion_control/general_loss_algorithm_test.cc", @@ -1455,7 +1451,7 @@ source_set("quiche_tests") { ] public_deps = [] - if (is_desktop_linux) { + if (is_linux) { public_deps += [ "//net:epoll_quic_tools" ] } if (is_linux || is_chromeos) { diff --git a/chromium/net/third_party/quiche/DIR_METADATA b/chromium/net/third_party/quiche/DIR_METADATA new file mode 100644 index 00000000000..123352d107a --- /dev/null +++ b/chromium/net/third_party/quiche/DIR_METADATA @@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Network>QUIC" +}
\ No newline at end of file diff --git a/chromium/net/third_party/quiche/OWNERS b/chromium/net/third_party/quiche/OWNERS index e001b80c961..f1264ac8371 100644 --- a/chromium/net/third_party/quiche/OWNERS +++ b/chromium/net/third_party/quiche/OWNERS @@ -1,4 +1,2 @@ file://net/quic/OWNERS -# COMPONENT: Internals>Network>QUIC - diff --git a/chromium/net/third_party/quiche/src/README.md b/chromium/net/third_party/quiche/src/README.md index 51b6acc89b2..53707ec949f 100644 --- a/chromium/net/third_party/quiche/src/README.md +++ b/chromium/net/third_party/quiche/src/README.md @@ -2,4 +2,4 @@ QUICHE (QUIC, Http/2, Etc) is Google's implementation of QUIC and related protocols. It powers Chromium as well as Google's QUIC servers and some other -projects. +projects. QUICHE is only supported on little-endian platforms. diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_arraysize.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_arraysize.h deleted file mode 100644 index 9e50d17d825..00000000000 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_arraysize.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 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_COMMON_PLATFORM_API_QUICHE_ARRAYSIZE_H_ -#define QUICHE_COMMON_PLATFORM_API_QUICHE_ARRAYSIZE_H_ - -#include "net/quiche/common/platform/impl/quiche_arraysize_impl.h" - -#define QUICHE_ARRAYSIZE(array) QUICHE_ARRAYSIZE_IMPL(array) - -#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_ARRAYSIZE_H_ diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_optional.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_optional.h deleted file mode 100644 index d5d3dac3538..00000000000 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_optional.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 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_COMMON_PLATFORM_API_QUICHE_OPTIONAL_H_ -#define QUICHE_COMMON_PLATFORM_API_QUICHE_OPTIONAL_H_ - -#include <utility> - -#include "net/quiche/common/platform/impl/quiche_optional_impl.h" - -namespace quiche { - -template <typename T> -using QuicheOptional = QuicheOptionalImpl<T>; - -#define QUICHE_NULLOPT QUICHE_NULLOPT_IMPL - -} // namespace quiche - -#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_OPTIONAL_H_ diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_ptr_util.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_ptr_util.h deleted file mode 100644 index a59a595813c..00000000000 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_ptr_util.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 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_COMMON_PLATFORM_API_QUICHE_PTR_UTIL_H_ -#define QUICHE_COMMON_PLATFORM_API_QUICHE_PTR_UTIL_H_ - -#include <memory> - -#include "absl/memory/memory.h" -#include "net/quiche/common/platform/impl/quiche_ptr_util_impl.h" - -namespace quiche { - -template <typename T> -std::unique_ptr<T> QuicheWrapUnique(T* ptr) { - // TODO(b/166325009): replace this in code with absl::WrapUnique and delete - // this function. - return absl::WrapUnique<T>(ptr); -} - -} // namespace quiche - -#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_PTR_UTIL_H_ diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_str_cat_test.cc b/chromium/net/third_party/quiche/src/common/platform/api/quiche_str_cat_test.cc index 7085b8a3c6e..c9a5bfc7512 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_str_cat_test.cc +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_str_cat_test.cc @@ -6,7 +6,7 @@ #include <string> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace quiche { @@ -46,7 +46,7 @@ TEST_F(QuicheStrCatTest, Basics) { std::string strs[] = {"Hello", "Cruel", "World"}; - QuicheStringPiece pieces[] = {"Hello", "Cruel", "World"}; + absl::string_view pieces[] = {"Hello", "Cruel", "World"}; const char* c_strs[] = {"Hello", "Cruel", "World"}; diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_string_piece.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_string_piece.h index 35d50216edb..ca58aae6d68 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_string_piece.h +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_string_piece.h @@ -5,15 +5,12 @@ #ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_STRING_PIECE_H_ #define QUICHE_COMMON_PLATFORM_API_QUICHE_STRING_PIECE_H_ +#include "absl/strings/string_view.h" #include "net/quiche/common/platform/impl/quiche_string_piece_impl.h" namespace quiche { -using QuicheStringPiece = QuicheStringPieceImpl; - -using QuicheStringPieceHash = QuicheStringPieceHashImpl; - -inline size_t QuicheHashStringPair(QuicheStringPiece a, QuicheStringPiece b) { +inline size_t QuicheHashStringPair(absl::string_view a, absl::string_view b) { return QuicheHashStringPairImpl(a, b); } diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils.h index 2cf920f2c2a..44a8a05b685 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils.h +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils.h @@ -7,9 +7,10 @@ #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/quiche/common/platform/impl/quiche_text_utils_impl.h" namespace quiche { @@ -17,90 +18,27 @@ namespace quiche { // Various utilities for manipulating text. class QUICHE_EXPORT QuicheTextUtils { public: - // Returns true if |data| starts with |prefix|, case sensitively. - static bool StartsWith(quiche::QuicheStringPiece data, - quiche::QuicheStringPiece prefix) { - return quiche::QuicheTextUtilsImpl::StartsWith(data, prefix); - } - - // Returns true if |data| ends with |suffix|, case sensitively. - static bool EndsWith(quiche::QuicheStringPiece data, - quiche::QuicheStringPiece suffix) { - return quiche::QuicheTextUtilsImpl::EndsWith(data, suffix); - } - - // Returns true if |data| ends with |suffix|, case insensitively. - static bool EndsWithIgnoreCase(quiche::QuicheStringPiece data, - quiche::QuicheStringPiece suffix) { - return quiche::QuicheTextUtilsImpl::EndsWithIgnoreCase(data, suffix); - } - // Returns a new string in which |data| has been converted to lower case. - static std::string ToLower(quiche::QuicheStringPiece data) { + static std::string ToLower(absl::string_view data) { return quiche::QuicheTextUtilsImpl::ToLower(data); } // Removes leading and trailing whitespace from |data|. - static void RemoveLeadingAndTrailingWhitespace( - quiche::QuicheStringPiece* data) { + static void RemoveLeadingAndTrailingWhitespace(absl::string_view* data) { quiche::QuicheTextUtilsImpl::RemoveLeadingAndTrailingWhitespace(data); } - // Returns true if |in| represents a valid uint64, and stores that value in - // |out|. - static bool StringToUint64(quiche::QuicheStringPiece in, uint64_t* out) { - return quiche::QuicheTextUtilsImpl::StringToUint64(in, out); - } - - // Returns true if |in| represents a valid int, and stores that value in - // |out|. - static bool StringToInt(quiche::QuicheStringPiece in, int* out) { - return quiche::QuicheTextUtilsImpl::StringToInt(in, out); - } - - // Returns true if |in| represents a valid uint32, and stores that value in - // |out|. - static bool StringToUint32(quiche::QuicheStringPiece in, uint32_t* out) { - return quiche::QuicheTextUtilsImpl::StringToUint32(in, out); - } - - // Returns true if |in| represents a valid size_t, and stores that value in - // |out|. - static bool StringToSizeT(quiche::QuicheStringPiece in, size_t* out) { - return quiche::QuicheTextUtilsImpl::StringToSizeT(in, out); - } - // Returns a new string representing |in|. static std::string Uint64ToString(uint64_t in) { return quiche::QuicheTextUtilsImpl::Uint64ToString(in); } - // This converts |length| bytes of binary to a 2*|length|-character - // hexadecimal representation. - // Return value: 2*|length| characters of ASCII string. - static std::string HexEncode(const char* data, size_t length) { - return HexEncode(quiche::QuicheStringPiece(data, length)); - } - - // This converts |data.length()| bytes of binary to a - // 2*|data.length()|-character hexadecimal representation. - // Return value: 2*|data.length()| characters of ASCII string. - static std::string HexEncode(quiche::QuicheStringPiece data) { - return quiche::QuicheTextUtilsImpl::HexEncode(data); - } - // This converts a uint32 into an 8-character hexidecimal // representation. Return value: 8 characters of ASCII string. static std::string Hex(uint32_t v) { return quiche::QuicheTextUtilsImpl::Hex(v); } - // Converts |data| from a hexadecimal ASCII string to a binary string - // that is |data.length()/2| bytes long. - static std::string HexDecode(quiche::QuicheStringPiece data) { - return quiche::QuicheTextUtilsImpl::HexDecode(data); - } - // Base64 encodes with no padding |data_len| bytes of |data| into |output|. static void Base64Encode(const uint8_t* data, size_t data_len, @@ -110,7 +48,7 @@ class QUICHE_EXPORT QuicheTextUtils { // Decodes a base64-encoded |input|. Returns nullopt when the input is // invalid. - static QuicheOptional<std::string> Base64Decode(QuicheStringPiece input) { + static absl::optional<std::string> Base64Decode(absl::string_view input) { return quiche::QuicheTextUtilsImpl::Base64Decode(input); } @@ -119,26 +57,19 @@ class QUICHE_EXPORT QuicheTextUtils { // printed as '.' in the ASCII output. // For example, given the input "Hello, QUIC!\01\02\03\04", returns: // "0x0000: 4865 6c6c 6f2c 2051 5549 4321 0102 0304 Hello,.QUIC!...." - static std::string HexDump(quiche::QuicheStringPiece binary_data) { + static std::string HexDump(absl::string_view binary_data) { return quiche::QuicheTextUtilsImpl::HexDump(binary_data); } // Returns true if |data| contains any uppercase characters. - static bool ContainsUpperCase(quiche::QuicheStringPiece data) { + static bool ContainsUpperCase(absl::string_view data) { return quiche::QuicheTextUtilsImpl::ContainsUpperCase(data); } // Returns true if |data| contains only decimal digits. - static bool IsAllDigits(quiche::QuicheStringPiece data) { + static bool IsAllDigits(absl::string_view data) { return quiche::QuicheTextUtilsImpl::IsAllDigits(data); } - - // Splits |data| into a vector of pieces delimited by |delim|. - static std::vector<quiche::QuicheStringPiece> Split( - quiche::QuicheStringPiece data, - char delim) { - return quiche::QuicheTextUtilsImpl::Split(data, delim); - } }; } // namespace quiche diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils_test.cc b/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils_test.cc index 1ca75d2d3d5..9d2c4fb2d0f 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils_test.cc +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_text_utils_test.cc @@ -6,6 +6,7 @@ #include <string> +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace quiche { @@ -13,28 +14,6 @@ namespace test { class QuicheTextUtilsTest : public QuicheTest {}; -TEST_F(QuicheTextUtilsTest, StartsWith) { - EXPECT_TRUE(quiche::QuicheTextUtils::StartsWith("hello world", "hello")); - EXPECT_TRUE( - quiche::QuicheTextUtils::StartsWith("hello world", "hello world")); - EXPECT_TRUE(quiche::QuicheTextUtils::StartsWith("hello world", "")); - EXPECT_FALSE(quiche::QuicheTextUtils::StartsWith("hello world", "Hello")); - EXPECT_FALSE(quiche::QuicheTextUtils::StartsWith("hello world", "world")); - EXPECT_FALSE(quiche::QuicheTextUtils::StartsWith("hello world", "bar")); -} - -TEST_F(QuicheTextUtilsTest, EndsWithIgnoreCase) { - EXPECT_TRUE( - quiche::QuicheTextUtils::EndsWithIgnoreCase("hello world", "world")); - EXPECT_TRUE(quiche::QuicheTextUtils::EndsWithIgnoreCase("hello world", - "hello world")); - EXPECT_TRUE(quiche::QuicheTextUtils::EndsWithIgnoreCase("hello world", "")); - EXPECT_TRUE( - quiche::QuicheTextUtils::EndsWithIgnoreCase("hello world", "WORLD")); - EXPECT_FALSE( - quiche::QuicheTextUtils::EndsWithIgnoreCase("hello world", "hello")); -} - TEST_F(QuicheTextUtilsTest, ToLower) { EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("LOWER")); EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("lower")); @@ -48,115 +27,17 @@ TEST_F(QuicheTextUtilsTest, RemoveLeadingAndTrailingWhitespace) { for (auto* input : {"text", " text", " text", "text ", "text ", " text ", " text ", "\r\n\ttext", "text\n\r\t"}) { - quiche::QuicheStringPiece piece(input); + absl::string_view piece(input); quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&piece); EXPECT_EQ("text", piece); } } -TEST_F(QuicheTextUtilsTest, StringToNumbers) { - const std::string kMaxInt32Plus1 = "2147483648"; - const std::string kMinInt32Minus1 = "-2147483649"; - const std::string kMaxUint32Plus1 = "4294967296"; - - { - // StringToUint64 - uint64_t uint64_val = 0; - EXPECT_TRUE(quiche::QuicheTextUtils::StringToUint64("123", &uint64_val)); - EXPECT_EQ(123u, uint64_val); - EXPECT_TRUE(quiche::QuicheTextUtils::StringToUint64("1234", &uint64_val)); - EXPECT_EQ(1234u, uint64_val); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToUint64("", &uint64_val)); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToUint64("-123", &uint64_val)); - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToUint64("-123.0", &uint64_val)); - EXPECT_TRUE( - quiche::QuicheTextUtils::StringToUint64(kMaxUint32Plus1, &uint64_val)); - EXPECT_EQ(4294967296u, uint64_val); - } - - { - // StringToint - int int_val = 0; - EXPECT_TRUE(quiche::QuicheTextUtils::StringToInt("123", &int_val)); - EXPECT_EQ(123, int_val); - EXPECT_TRUE(quiche::QuicheTextUtils::StringToInt("1234", &int_val)); - EXPECT_EQ(1234, int_val); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToInt("", &int_val)); - EXPECT_TRUE(quiche::QuicheTextUtils::StringToInt("-123", &int_val)); - EXPECT_EQ(-123, int_val); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToInt("-123.0", &int_val)); - if (sizeof(int) > 4) { - EXPECT_TRUE( - quiche::QuicheTextUtils::StringToInt(kMinInt32Minus1, &int_val)); - EXPECT_EQ(-2147483649ll, int_val); - EXPECT_TRUE( - quiche::QuicheTextUtils::StringToInt(kMaxInt32Plus1, &int_val)); - EXPECT_EQ(2147483648ll, int_val); - } else { - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToInt(kMinInt32Minus1, &int_val)); - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToInt(kMaxInt32Plus1, &int_val)); - } - } - - { - // StringToUint32 - uint32_t uint32_val = 0; - EXPECT_TRUE(quiche::QuicheTextUtils::StringToUint32("123", &uint32_val)); - EXPECT_EQ(123u, uint32_val); - EXPECT_TRUE(quiche::QuicheTextUtils::StringToUint32("1234", &uint32_val)); - EXPECT_EQ(1234u, uint32_val); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToUint32("", &uint32_val)); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToUint32("-123", &uint32_val)); - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToUint32("-123.0", &uint32_val)); - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToUint32(kMaxUint32Plus1, &uint32_val)); - } - - { - // StringToSizeT - size_t size_t_val = 0; - EXPECT_TRUE(quiche::QuicheTextUtils::StringToSizeT("123", &size_t_val)); - EXPECT_EQ(123u, size_t_val); - EXPECT_TRUE(quiche::QuicheTextUtils::StringToSizeT("1234", &size_t_val)); - EXPECT_EQ(1234u, size_t_val); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToSizeT("", &size_t_val)); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToSizeT("-123", &size_t_val)); - EXPECT_FALSE(quiche::QuicheTextUtils::StringToSizeT("-123.0", &size_t_val)); - if (sizeof(size_t) > 4) { - EXPECT_TRUE( - quiche::QuicheTextUtils::StringToSizeT(kMaxUint32Plus1, &size_t_val)); - EXPECT_EQ(4294967296ull, size_t_val); - } else { - EXPECT_FALSE( - quiche::QuicheTextUtils::StringToSizeT(kMaxUint32Plus1, &size_t_val)); - } - } -} - TEST_F(QuicheTextUtilsTest, Uint64ToString) { EXPECT_EQ("123", quiche::QuicheTextUtils::Uint64ToString(123)); EXPECT_EQ("1234", quiche::QuicheTextUtils::Uint64ToString(1234)); } -TEST_F(QuicheTextUtilsTest, HexEncode) { - EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello", 5)); - EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello World", 5)); - EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello")); - EXPECT_EQ("0102779cfa", - quiche::QuicheTextUtils::HexEncode("\x01\x02\x77\x9c\xfa")); -} - -TEST_F(QuicheTextUtilsTest, HexDecode) { - EXPECT_EQ("Hello", quiche::QuicheTextUtils::HexDecode("48656c6c6f")); - EXPECT_EQ("", quiche::QuicheTextUtils::HexDecode("")); - EXPECT_EQ("\x01\x02\x77\x9c\xfa", - quiche::QuicheTextUtils::HexDecode("0102779cfa")); -} - TEST_F(QuicheTextUtilsTest, HexDump) { // Verify output of the HexDump method is as expected. char packet[] = { @@ -177,14 +58,13 @@ TEST_F(QuicheTextUtilsTest, HexDump) { "0x0040: 6c69 6e65 7320 6f66 206f 7574 7075 742e lines.of.output.\n" "0x0050: 0102 03 ...\n"); // Verify that 0x21 and 0x7e are printable, 0x20 and 0x7f are not. - EXPECT_EQ("0x0000: 2021 7e7f .!~.\n", - quiche::QuicheTextUtils::HexDump( - quiche::QuicheTextUtils::HexDecode("20217e7f"))); + EXPECT_EQ( + "0x0000: 2021 7e7f .!~.\n", + quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("20217e7f"))); // Verify that values above numeric_limits<unsigned char>::max() are formatted // properly on platforms where char is unsigned. EXPECT_EQ("0x0000: 90aa ff ...\n", - quiche::QuicheTextUtils::HexDump( - quiche::QuicheTextUtils::HexDecode("90aaff"))); + quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("90aaff"))); } TEST_F(QuicheTextUtilsTest, Base64Encode) { @@ -213,19 +93,5 @@ TEST_F(QuicheTextUtilsTest, ContainsUpperCase) { EXPECT_TRUE(quiche::QuicheTextUtils::ContainsUpperCase("aBc")); } -TEST_F(QuicheTextUtilsTest, Split) { - EXPECT_EQ(std::vector<quiche::QuicheStringPiece>({"a", "b", "c"}), - quiche::QuicheTextUtils::Split("a,b,c", ',')); - EXPECT_EQ(std::vector<quiche::QuicheStringPiece>({"a", "b", "c"}), - quiche::QuicheTextUtils::Split("a:b:c", ':')); - EXPECT_EQ(std::vector<quiche::QuicheStringPiece>({"a:b:c"}), - quiche::QuicheTextUtils::Split("a:b:c", ',')); - // Leading and trailing whitespace is preserved. - EXPECT_EQ(std::vector<quiche::QuicheStringPiece>({"a", "b", "c"}), - quiche::QuicheTextUtils::Split("a,b,c", ',')); - EXPECT_EQ(std::vector<quiche::QuicheStringPiece>({" a", "b ", " c "}), - quiche::QuicheTextUtils::Split(" a:b : c ", ':')); -} - } // namespace test } // namespace quiche diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h index 7319568172b..e1e59f0c158 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h @@ -16,7 +16,7 @@ namespace quiche { // instance, it will reject February 29 on non-leap years, or 25 hours in a day. // As a notable exception, 60 seconds is accepted to deal with potential leap // seconds. If the date predates Unix epoch, nullopt will be returned. -inline QuicheOptional<int64_t> QuicheUtcDateTimeToUnixSeconds(int year, +inline absl::optional<int64_t> QuicheUtcDateTimeToUnixSeconds(int year, int month, int day, int hour, diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc index 3ae296dbd81..e32b8b253f1 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc +++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc @@ -4,7 +4,7 @@ #include "net/third_party/quiche/src/common/platform/api/quiche_time_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace quiche { @@ -19,26 +19,24 @@ TEST(QuicheTimeUtilsTest, Basic) { QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56)); EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21)); - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1)); - EXPECT_NE(QUICHE_NULLOPT, + EXPECT_NE(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1)); } TEST(QuicheTimeUtilsTest, Bounds) { - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1)); - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1)); - EXPECT_EQ(QUICHE_NULLOPT, - QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1)); - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1)); + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1)); - EXPECT_EQ(QUICHE_NULLOPT, - QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1)); - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1)); + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0)); - EXPECT_EQ(QUICHE_NULLOPT, + EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0)); } @@ -46,7 +44,7 @@ TEST(QuicheTimeUtilsTest, LeapSecond) { EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 23, 59, 60), QuicheUtcDateTimeToUnixSeconds(2015, 7, 1, 0, 0, 0)); EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 25, 59, 60), - QUICHE_NULLOPT); + absl::nullopt); } } // namespace diff --git a/chromium/net/third_party/quiche/src/common/quiche_data_reader.cc b/chromium/net/third_party/quiche/src/common/quiche_data_reader.cc index 2242fea6437..bbb4b87e484 100644 --- a/chromium/net/third_party/quiche/src/common/quiche_data_reader.cc +++ b/chromium/net/third_party/quiche/src/common/quiche_data_reader.cc @@ -6,15 +6,16 @@ #include <cstring> -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quiche { -QuicheDataReader::QuicheDataReader(quiche::QuicheStringPiece data) +QuicheDataReader::QuicheDataReader(absl::string_view data) : QuicheDataReader(data.data(), data.length(), quiche::NETWORK_BYTE_ORDER) { } @@ -77,7 +78,7 @@ bool QuicheDataReader::ReadBytesToUInt64(size_t num_bytes, uint64_t* result) { return true; } -bool QuicheDataReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { +bool QuicheDataReader::ReadStringPiece16(absl::string_view* result) { // Read resultant length. uint16_t result_len; if (!ReadUInt16(&result_len)) { @@ -88,7 +89,7 @@ bool QuicheDataReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { return ReadStringPiece(result, result_len); } -bool QuicheDataReader::ReadStringPiece8(quiche::QuicheStringPiece* result) { +bool QuicheDataReader::ReadStringPiece8(absl::string_view* result) { // Read resultant length. uint8_t result_len; if (!ReadUInt8(&result_len)) { @@ -99,8 +100,7 @@ bool QuicheDataReader::ReadStringPiece8(quiche::QuicheStringPiece* result) { return ReadStringPiece(result, result_len); } -bool QuicheDataReader::ReadStringPiece(quiche::QuicheStringPiece* result, - size_t size) { +bool QuicheDataReader::ReadStringPiece(absl::string_view* result, size_t size) { // Make sure that we have enough data to read. if (!CanRead(size)) { OnFailure(); @@ -108,7 +108,7 @@ bool QuicheDataReader::ReadStringPiece(quiche::QuicheStringPiece* result, } // Set result. - *result = quiche::QuicheStringPiece(data_ + pos_, size); + *result = absl::string_view(data_ + pos_, size); // Iterate. pos_ += size; @@ -121,30 +121,30 @@ bool QuicheDataReader::ReadTag(uint32_t* tag) { } bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) { - quiche::QuicheStringPiece digits; + absl::string_view digits; if (!ReadStringPiece(&digits, num_digits)) { return false; } - return QuicheTextUtils::StringToUint64(digits, result); + return absl::SimpleAtoi(digits, result); } -quiche::QuicheStringPiece QuicheDataReader::ReadRemainingPayload() { - quiche::QuicheStringPiece payload = PeekRemainingPayload(); +absl::string_view QuicheDataReader::ReadRemainingPayload() { + absl::string_view payload = PeekRemainingPayload(); pos_ = len_; return payload; } -quiche::QuicheStringPiece QuicheDataReader::PeekRemainingPayload() const { - return quiche::QuicheStringPiece(data_ + pos_, len_ - pos_); +absl::string_view QuicheDataReader::PeekRemainingPayload() const { + return absl::string_view(data_ + pos_, len_ - pos_); } -quiche::QuicheStringPiece QuicheDataReader::FullPayload() const { - return quiche::QuicheStringPiece(data_, len_); +absl::string_view QuicheDataReader::FullPayload() const { + return absl::string_view(data_, len_); } -quiche::QuicheStringPiece QuicheDataReader::PreviouslyReadPayload() const { - return quiche::QuicheStringPiece(data_, pos_); +absl::string_view QuicheDataReader::PreviouslyReadPayload() const { + return absl::string_view(data_, pos_); } bool QuicheDataReader::ReadBytes(void* result, size_t size) { diff --git a/chromium/net/third_party/quiche/src/common/quiche_data_reader.h b/chromium/net/third_party/quiche/src/common/quiche_data_reader.h index f74f90d19e2..ddd825ceb79 100644 --- a/chromium/net/third_party/quiche/src/common/quiche_data_reader.h +++ b/chromium/net/third_party/quiche/src/common/quiche_data_reader.h @@ -9,10 +9,10 @@ #include <cstdint> #include <limits> -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" #include "net/third_party/quiche/src/common/platform/api/quiche_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quiche { @@ -30,7 +30,7 @@ class QUICHE_EXPORT_PRIVATE QuicheDataReader { public: // Constructs a reader using NETWORK_BYTE_ORDER endianness. // Caller must provide an underlying buffer to work on. - explicit QuicheDataReader(quiche::QuicheStringPiece data); + explicit QuicheDataReader(absl::string_view data); // Constructs a reader using NETWORK_BYTE_ORDER endianness. // Caller must provide an underlying buffer to work on. QuicheDataReader(const char* data, const size_t len); @@ -64,7 +64,7 @@ class QUICHE_EXPORT_PRIVATE QuicheDataReader { // // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPiece16(quiche::QuicheStringPiece* result); + bool ReadStringPiece16(absl::string_view* result); // Reads a string prefixed with 8-bit length into the given output parameter. // @@ -73,13 +73,13 @@ class QUICHE_EXPORT_PRIVATE QuicheDataReader { // // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPiece8(quiche::QuicheStringPiece* result); + bool ReadStringPiece8(absl::string_view* result); // Reads a given number of bytes into the given buffer. The buffer // must be of adequate size. // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPiece(quiche::QuicheStringPiece* result, size_t size); + bool ReadStringPiece(absl::string_view* result, size_t size); // Reads tag represented as 32-bit unsigned integer into given output // parameter. Tags are in big endian on the wire (e.g., CHLO is @@ -92,38 +92,38 @@ class QUICHE_EXPORT_PRIVATE QuicheDataReader { // iterator on success, may forward it even in case of failure. bool ReadDecimal64(size_t num_digits, uint64_t* result); - // Returns the remaining payload as a quiche::QuicheStringPiece. + // Returns the remaining payload as a absl::string_view. // // NOTE: Does not copy but rather references strings in the underlying buffer. // This should be kept in mind when handling memory management! // // Forwards the internal iterator. - quiche::QuicheStringPiece ReadRemainingPayload(); + absl::string_view ReadRemainingPayload(); - // Returns the remaining payload as a quiche::QuicheStringPiece. + // Returns the remaining payload as a absl::string_view. // // NOTE: Does not copy but rather references strings in the underlying buffer. // This should be kept in mind when handling memory management! // // DOES NOT forward the internal iterator. - quiche::QuicheStringPiece PeekRemainingPayload() const; + absl::string_view PeekRemainingPayload() const; - // Returns the entire payload as a quiche::QuicheStringPiece. + // Returns the entire payload as a absl::string_view. // // NOTE: Does not copy but rather references strings in the underlying buffer. // This should be kept in mind when handling memory management! // // DOES NOT forward the internal iterator. - quiche::QuicheStringPiece FullPayload() const; + absl::string_view FullPayload() const; // Returns the part of the payload that has been already read as a - // quiche::QuicheStringPiece. + // absl::string_view. // // NOTE: Does not copy but rather references strings in the underlying buffer. // This should be kept in mind when handling memory management! // // DOES NOT forward the internal iterator. - quiche::QuicheStringPiece PreviouslyReadPayload() const; + absl::string_view PreviouslyReadPayload() const; // Reads a given number of bytes into the given buffer. The buffer // must be of adequate size. diff --git a/chromium/net/third_party/quiche/src/common/quiche_data_writer.cc b/chromium/net/third_party/quiche/src/common/quiche_data_writer.cc index 4488f722ec5..5d80933661c 100644 --- a/chromium/net/third_party/quiche/src/common/quiche_data_writer.cc +++ b/chromium/net/third_party/quiche/src/common/quiche_data_writer.cc @@ -7,9 +7,9 @@ #include <algorithm> #include <limits> -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quiche { @@ -65,7 +65,7 @@ bool QuicheDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) { num_bytes); } -bool QuicheDataWriter::WriteStringPiece16(quiche::QuicheStringPiece val) { +bool QuicheDataWriter::WriteStringPiece16(absl::string_view val) { if (val.size() > std::numeric_limits<uint16_t>::max()) { return false; } @@ -75,7 +75,7 @@ bool QuicheDataWriter::WriteStringPiece16(quiche::QuicheStringPiece val) { return WriteBytes(val.data(), val.size()); } -bool QuicheDataWriter::WriteStringPiece(quiche::QuicheStringPiece val) { +bool QuicheDataWriter::WriteStringPiece(absl::string_view val) { return WriteBytes(val.data(), val.size()); } diff --git a/chromium/net/third_party/quiche/src/common/quiche_data_writer.h b/chromium/net/third_party/quiche/src/common/quiche_data_writer.h index cded0fa16c8..ffa1ea6f9dc 100644 --- a/chromium/net/third_party/quiche/src/common/quiche_data_writer.h +++ b/chromium/net/third_party/quiche/src/common/quiche_data_writer.h @@ -10,10 +10,10 @@ #include <cstring> #include <limits> -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" #include "net/third_party/quiche/src/common/platform/api/quiche_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quiche { @@ -54,8 +54,8 @@ class QUICHE_EXPORT_PRIVATE QuicheDataWriter { // correct byte order. bool WriteBytesToUInt64(size_t num_bytes, uint64_t value); - bool WriteStringPiece(quiche::QuicheStringPiece val); - bool WriteStringPiece16(quiche::QuicheStringPiece val); + bool WriteStringPiece(absl::string_view val); + bool WriteStringPiece16(absl::string_view val); bool WriteBytes(const void* data, size_t data_len); bool WriteRepeatedByte(uint8_t byte, size_t count); // Fills the remaining buffer with null characters. diff --git a/chromium/net/third_party/quiche/src/common/quiche_data_writer_test.cc b/chromium/net/third_party/quiche/src/common/quiche_data_writer_test.cc index 343e6eaa702..22e8c08dfe4 100644 --- a/chromium/net/third_party/quiche/src/common/quiche_data_writer_test.cc +++ b/chromium/net/third_party/quiche/src/common/quiche_data_writer_test.cc @@ -7,12 +7,12 @@ #include <cstdint> #include <cstring> -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/common/quiche_data_reader.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" namespace quiche { @@ -332,24 +332,24 @@ TEST_P(QuicheDataWriterTest, WriteIntegers) { TEST_P(QuicheDataWriterTest, WriteBytes) { char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - char buf[QUICHE_ARRAYSIZE(bytes)]; - QuicheDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness); - EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes))); - for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) { + char buf[ABSL_ARRAYSIZE(bytes)]; + QuicheDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness); + EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes))); + for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) { EXPECT_EQ(bytes[i], buf[i]); } } TEST_P(QuicheDataWriterTest, Seek) { char buffer[3] = {}; - QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.WriteUInt8(42)); EXPECT_TRUE(writer.Seek(1)); EXPECT_TRUE(writer.WriteUInt8(3)); char expected[] = {42, 0, 3}; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) { EXPECT_EQ(buffer[i], expected[i]); } } @@ -359,7 +359,7 @@ TEST_P(QuicheDataWriterTest, SeekTooFarFails) { // Check that one can seek to the end of the writer, but not past. { - QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.Seek(20)); EXPECT_FALSE(writer.Seek(1)); @@ -367,14 +367,14 @@ TEST_P(QuicheDataWriterTest, SeekTooFarFails) { // Seeking several bytes past the end fails. { - QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_FALSE(writer.Seek(100)); } // Seeking so far that arithmetic overflow could occur also fails. { - QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.Seek(10)); EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max())); @@ -386,43 +386,38 @@ TEST_P(QuicheDataWriterTest, PayloadReads) { char expected_first_read[4] = {1, 2, 3, 4}; char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; QuicheDataReader reader(buffer, sizeof(buffer)); - quiche::QuicheStringPiece previously_read_payload1 = - reader.PreviouslyReadPayload(); + absl::string_view previously_read_payload1 = reader.PreviouslyReadPayload(); EXPECT_TRUE(previously_read_payload1.empty()); char first_read_buffer[4] = {}; EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer))); test::CompareCharArraysWithHexError( "first read", first_read_buffer, sizeof(first_read_buffer), expected_first_read, sizeof(expected_first_read)); - quiche::QuicheStringPiece peeked_remaining_payload = - reader.PeekRemainingPayload(); + absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload(); test::CompareCharArraysWithHexError( "peeked_remaining_payload", peeked_remaining_payload.data(), peeked_remaining_payload.length(), expected_remaining, sizeof(expected_remaining)); - quiche::QuicheStringPiece full_payload = reader.FullPayload(); + absl::string_view full_payload = reader.FullPayload(); test::CompareCharArraysWithHexError("full_payload", full_payload.data(), full_payload.length(), buffer, sizeof(buffer)); - quiche::QuicheStringPiece previously_read_payload2 = - reader.PreviouslyReadPayload(); + absl::string_view previously_read_payload2 = reader.PreviouslyReadPayload(); test::CompareCharArraysWithHexError( "previously_read_payload2", previously_read_payload2.data(), previously_read_payload2.length(), first_read_buffer, sizeof(first_read_buffer)); - quiche::QuicheStringPiece read_remaining_payload = - reader.ReadRemainingPayload(); + absl::string_view read_remaining_payload = reader.ReadRemainingPayload(); test::CompareCharArraysWithHexError( "read_remaining_payload", read_remaining_payload.data(), read_remaining_payload.length(), expected_remaining, sizeof(expected_remaining)); EXPECT_TRUE(reader.IsDoneReading()); - quiche::QuicheStringPiece full_payload2 = reader.FullPayload(); + absl::string_view full_payload2 = reader.FullPayload(); test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(), full_payload2.length(), buffer, sizeof(buffer)); - quiche::QuicheStringPiece previously_read_payload3 = - reader.PreviouslyReadPayload(); + absl::string_view previously_read_payload3 = reader.PreviouslyReadPayload(); test::CompareCharArraysWithHexError( "previously_read_payload3", previously_read_payload3.data(), previously_read_payload3.length(), buffer, sizeof(buffer)); diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_endian.h b/chromium/net/third_party/quiche/src/common/quiche_endian.h index 69bdc5bf029..9928ff5aa7a 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_endian.h +++ b/chromium/net/third_party/quiche/src/common/quiche_endian.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_ENDIAN_H_ -#define QUICHE_COMMON_PLATFORM_API_QUICHE_ENDIAN_H_ +#ifndef QUICHE_COMMON_QUICHE_ENDIAN_H_ +#define QUICHE_COMMON_QUICHE_ENDIAN_H_ #include <algorithm> #include <cstdint> @@ -60,4 +60,4 @@ class QUICHE_EXPORT_PRIVATE QuicheEndian { } // namespace quiche -#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_ENDIAN_H_ +#endif // QUICHE_COMMON_QUICHE_ENDIAN_H_ diff --git a/chromium/net/third_party/quiche/src/common/platform/api/quiche_endian_test.cc b/chromium/net/third_party/quiche/src/common/quiche_endian_test.cc index 2f21938b087..81945ffd41b 100644 --- a/chromium/net/third_party/quiche/src/common/platform/api/quiche_endian_test.cc +++ b/chromium/net/third_party/quiche/src/common/quiche_endian_test.cc @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" + #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace quiche { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer.h b/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer.h index 241c55356d9..2bf8243d62f 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer.h +++ b/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer.h @@ -17,9 +17,9 @@ #include <algorithm> #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { class DecodeBufferSubset; @@ -35,7 +35,7 @@ class QUICHE_EXPORT_PRIVATE DecodeBuffer { const size_t kMaxDecodeBufferLength = 1 << 25; DCHECK_LE(len, kMaxDecodeBufferLength); } - explicit DecodeBuffer(quiche::QuicheStringPiece s) + explicit DecodeBuffer(absl::string_view s) : DecodeBuffer(s.data(), s.size()) {} // Constructor for character arrays, typically in tests. For example: // const char input[] = { 0x11 }; diff --git a/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer_test.cc index 24953ef5591..908442ef0da 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/decode_buffer_test.cc @@ -9,6 +9,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -43,7 +44,7 @@ struct TestStruct { TestEnum8 f8; }; -class DecodeBufferTest : public ::testing::Test { +class DecodeBufferTest : public QuicheTest { protected: Http2Random random_; uint32_t decode_offset_; diff --git a/chromium/net/third_party/quiche/src/http2/decoder/decode_http2_structures_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/decode_http2_structures_test.cc index 7ef145d87d9..58736dc6e2d 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/decode_http2_structures_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/decode_http2_structures_test.cc @@ -11,6 +11,7 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,7 +20,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; @@ -28,9 +29,8 @@ namespace test { namespace { template <typename T, size_t N> -quiche::QuicheStringPiece ToStringPiece(T (&data)[N]) { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(data), - N * sizeof(T)); +absl::string_view ToStringPiece(T (&data)[N]) { + return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T)); } template <class S> @@ -42,7 +42,7 @@ std::string SerializeStructure(const S& s) { } template <class S> -class StructureDecoderTest : public ::testing::Test { +class StructureDecoderTest : public QuicheTest { protected: typedef S Structure; @@ -53,8 +53,7 @@ class StructureDecoderTest : public ::testing::Test { // Fully decodes the Structure at the start of data, and confirms it matches // *expected (if provided). - void DecodeLeadingStructure(const S* expected, - quiche::QuicheStringPiece data) { + void DecodeLeadingStructure(const S* expected, absl::string_view data) { ASSERT_LE(S::EncodedSize(), data.size()); DecodeBuffer db(data); Randomize(&structure_); @@ -67,7 +66,7 @@ class StructureDecoderTest : public ::testing::Test { template <size_t N> void DecodeLeadingStructure(const char (&data)[N]) { - DecodeLeadingStructure(nullptr, quiche::QuicheStringPiece(data, N)); + DecodeLeadingStructure(nullptr, absl::string_view(data, N)); } // Encode the structure |in_s| into bytes, then decode the bytes @@ -293,7 +292,7 @@ TEST_F(PingFieldsDecoderTest, DecodesLiteral) { }; DecodeLeadingStructure(kData); if (!HasFailure()) { - EXPECT_EQ(quiche::QuicheStringPiece(kData, 8), + EXPECT_EQ(absl::string_view(kData, 8), ToStringPiece(structure_.opaque_bytes)); } } @@ -304,7 +303,7 @@ TEST_F(PingFieldsDecoderTest, DecodesLiteral) { }; DecodeLeadingStructure(kData); if (!HasFailure()) { - EXPECT_EQ(quiche::QuicheStringPiece(kData, 8), + EXPECT_EQ(absl::string_view(kData, 8), ToStringPiece(structure_.opaque_bytes)); } } @@ -314,7 +313,7 @@ TEST_F(PingFieldsDecoderTest, DecodesLiteral) { }; DecodeLeadingStructure(kData); if (!HasFailure()) { - EXPECT_EQ(quiche::QuicheStringPiece(kData, 8), + EXPECT_EQ(absl::string_view(kData, 8), ToStringPiece(structure_.opaque_bytes)); } } diff --git a/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener_test_util.cc b/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener_test_util.cc index dd2e7b0ea45..aca1cc306c3 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener_test_util.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener_test_util.cc @@ -4,11 +4,11 @@ #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/http2_structures.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_test.cc index 9ed3138822e..cf0015d987b 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/http2_frame_decoder_test.cc @@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -114,9 +114,8 @@ class Http2FrameDecoderTest : public RandomDecoderTest { VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*collector_.frame(0))); } - AssertionResult DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece payload, - Validator validator) { + AssertionResult DecodePayloadAndValidateSeveralWays(absl::string_view payload, + Validator validator) { DecodeBuffer db(payload); bool start_decoding_requires_non_empty = false; return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, @@ -128,7 +127,7 @@ class Http2FrameDecoderTest : public RandomDecoderTest { // payload will be decoded several times with different partitionings // of the payload, and after each the validator will be called. AssertionResult DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece payload, + absl::string_view payload, const FrameParts& expected) { auto validator = [&expected, this](const DecodeBuffer& /*input*/, DecodeStatus status) -> AssertionResult { @@ -159,16 +158,16 @@ class Http2FrameDecoderTest : public RandomDecoderTest { AssertionResult DecodePayloadAndValidateSeveralWays( const char (&buf)[N], const FrameParts& expected) { - return DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece(buf, N), expected); + return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N), + expected); } template <size_t N> AssertionResult DecodePayloadAndValidateSeveralWays( const char (&buf)[N], const Http2FrameHeader& header) { - return DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece(buf, N), FrameParts(header)); + return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N), + FrameParts(header)); } template <size_t N> diff --git a/chromium/net/third_party/quiche/src/http2/decoder/http2_structure_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/http2_structure_decoder_test.cc index dc7f3dedb24..0242061377f 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/http2_structure_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/http2_structure_decoder_test.cc @@ -23,6 +23,7 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -31,7 +32,6 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; @@ -93,7 +93,7 @@ class Http2StructureDecoderTest : public RandomDecoderTest { // Fully decodes the Structure at the start of data, and confirms it matches // *expected (if provided). AssertionResult DecodeLeadingStructure(const S* expected, - quiche::QuicheStringPiece data) { + absl::string_view data) { VERIFY_LE(S::EncodedSize(), data.size()); DecodeBuffer original(data); @@ -145,7 +145,7 @@ class Http2StructureDecoderTest : public RandomDecoderTest { template <size_t N> AssertionResult DecodeLeadingStructure(const char (&data)[N]) { VERIFY_AND_RETURN_SUCCESS( - DecodeLeadingStructure(nullptr, quiche::QuicheStringPiece(data, N))); + DecodeLeadingStructure(nullptr, absl::string_view(data, N))); } template <size_t N> diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc index 354fdae0621..59cc6efc10b 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,6 +18,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc index 125e16fc7c9..0873fd04185 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc @@ -9,7 +9,6 @@ #include <string> #include <type_traits> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -18,6 +17,7 @@ #include "net/third_party/quiche/src/http2/test_tools/frame_parts.h" #include "net/third_party/quiche/src/http2/test_tools/frame_parts_collector.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/data_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/data_payload_decoder_test.cc index f1dc017c9da..b30eb9823d8 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/data_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/data_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -21,6 +20,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc index b2d96fb2d71..21a0459eb52 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,6 +18,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/headers_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/headers_payload_decoder_test.cc index 4e0f2e307bb..65ff074db25 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/headers_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/headers_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,6 +18,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc index 32969efbf85..12dc5770d20 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/frame_decoder_state_test_util.h" #include "net/third_party/quiche/src/http2/http2_structures_test_util.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -76,7 +76,7 @@ DecodeStatus PayloadDecoderBaseTest::ResumeDecoding(DecodeBuffer* db) { ::testing::AssertionResult PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece payload, + absl::string_view payload, Validator validator) { VERIFY_TRUE(frame_header_is_set_); // Cap the payload to be decoded at the declared payload length. This is @@ -86,8 +86,7 @@ PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays( // Note that it is OK if the payload is too short; the validator may be // designed to check for that. if (payload.size() > frame_header_.payload_length) { - payload = - quiche::QuicheStringPiece(payload.data(), frame_header_.payload_length); + payload = absl::string_view(payload.data(), frame_header_.payload_length); } DecodeBuffer db(payload); ResetDecodeSpeedCounters(); diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h index c5a97a5b37c..c907714089a 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h @@ -11,7 +11,7 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/decoder/frame_decoder_state.h" @@ -23,7 +23,6 @@ #include "net/third_party/quiche/src/http2/test_tools/frame_parts.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { namespace test { @@ -81,7 +80,7 @@ class PayloadDecoderBaseTest : public RandomDecoderTest { // Given the specified payload (without the common frame header), decode // it with several partitionings of the payload. ::testing::AssertionResult DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece payload, + absl::string_view payload, Validator validator); // TODO(jamessynge): Add helper method for verifying these are both non-zero, @@ -190,7 +189,7 @@ class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest { // will be decoded several times with different partitionings of the payload, // and after each the validator will be called. AssertionResult DecodePayloadAndValidateSeveralWays( - quiche::QuicheStringPiece payload, + absl::string_view payload, const FrameParts& expected) { auto validator = [&expected, this]() -> AssertionResult { VERIFY_FALSE(listener_.IsInProgress()); @@ -209,7 +208,7 @@ class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest { // std::nullptr_t (not extra validation). template <typename WrappedValidator> ::testing::AssertionResult VerifyDetectsFrameSizeError( - quiche::QuicheStringPiece payload, + absl::string_view payload, const Http2FrameHeader& header, WrappedValidator wrapped_validator) { set_frame_header(header); @@ -248,7 +247,7 @@ class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest { // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding. ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors( uint8_t required_flags, - quiche::QuicheStringPiece unpadded_payload, + absl::string_view unpadded_payload, ApproveSize approve_size, int total_pad_length) { // required_flags should come from those that are defined for the frame @@ -306,7 +305,7 @@ class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest { // As above, but for frames without padding. ::testing::AssertionResult VerifyDetectsFrameSizeError( uint8_t required_flags, - quiche::QuicheStringPiece unpadded_payload, + absl::string_view unpadded_payload, const ApproveSize& approve_size) { Http2FrameType frame_type = DecoderPeer::FrameType(); uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type); @@ -379,7 +378,7 @@ class AbstractPaddablePayloadDecoderTest // amount of missing padding is as specified. header.IsPadded must be true, // and the payload must be empty or the PadLength field must be too large. ::testing::AssertionResult VerifyDetectsPaddingTooLong( - quiche::QuicheStringPiece payload, + absl::string_view payload, const Http2FrameHeader& header, size_t expected_missing_length) { set_frame_header(header); diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/ping_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/ping_payload_decoder_test.cc index 932149f0da0..a80df798e40 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/ping_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/ping_payload_decoder_test.cc @@ -6,7 +6,6 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -17,6 +16,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/priority_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/priority_payload_decoder_test.cc index 3b0ac156637..97551c8eb1e 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/priority_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/priority_payload_decoder_test.cc @@ -6,7 +6,6 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -17,6 +16,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc index 0561aa4b96b..3022f59b761 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <string> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,6 +18,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc index 6e00e804bcb..105fbe1c81a 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc @@ -6,7 +6,6 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -18,6 +17,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/settings_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/settings_payload_decoder_test.cc index d3f116b8006..6cc908b762e 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/settings_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/settings_payload_decoder_test.cc @@ -8,7 +8,6 @@ #include <vector> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -20,6 +19,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc index 10759329c0f..e0fb1003c2e 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc @@ -9,7 +9,6 @@ #include <string> #include <type_traits> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -19,6 +18,7 @@ #include "net/third_party/quiche/src/http2/test_tools/frame_parts_collector.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc index 66d7d7eb05d..279d893677b 100644 --- a/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc @@ -6,7 +6,6 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/decoder/payload_decoders/payload_decoder_base_test_util.h" #include "net/third_party/quiche/src/http2/http2_constants.h" @@ -17,6 +16,7 @@ #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/http2_frame_builder.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.cc index 325a60c0067..88e0a9a9882 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.cc @@ -112,7 +112,7 @@ AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader( HpackEntryType expected_type, size_t expected_index, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const { + absl::string_view expected_value) const { VERIFY_TRUE(pending_entry_.IsClear()); VERIFY_EQ(1u, entries_.size()); VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader( @@ -122,9 +122,9 @@ AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader( AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader( HpackEntryType expected_type, bool expected_name_huffman, - quiche::QuicheStringPiece expected_name, + absl::string_view expected_name, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const { + absl::string_view expected_value) const { VERIFY_TRUE(pending_entry_.IsClear()); VERIFY_EQ(1u, entries_.size()); VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader( diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h index 8246de45a68..55d9449642c 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h @@ -18,13 +18,12 @@ #include <string> #include <vector> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { namespace test { @@ -97,16 +96,16 @@ class HpackBlockCollector : public HpackEntryDecoderListener { HpackEntryType expected_type, size_t expected_index, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const; + absl::string_view expected_value) const; // Return AssertionSuccess if there is just one entry, and it is a Header // with a literal name and literal value. ::testing::AssertionResult ValidateSoleLiteralNameValueHeader( HpackEntryType expected_type, bool expected_name_huffman, - quiche::QuicheStringPiece expected_name, + absl::string_view expected_name, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const; + absl::string_view expected_value) const; bool IsNotPending() const { return pending_entry_.IsClear(); } bool IsClear() const { return IsNotPending() && entries_.empty(); } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_decoder_test.cc index aeb6c48caca..e392ffa4e42 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_block_decoder_test.cc @@ -9,7 +9,7 @@ #include <cstdint> #include <string> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" @@ -18,7 +18,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionSuccess; @@ -66,7 +66,7 @@ class HpackBlockDecoderTest : public RandomDecoderTest { } AssertionResult DecodeHpackExampleAndValidateSeveralWays( - quiche::QuicheStringPiece hpack_example, + absl::string_view hpack_example, Validator validator) { std::string input = HpackExampleToStringOrDie(hpack_example); DecodeBuffer db(input); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.cc index c1f7c8e248c..c2c8308c153 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.cc @@ -17,7 +17,7 @@ void HpackDecoderNoOpListener::OnHeader(const HpackString& /*name*/, const HpackString& /*value*/) {} void HpackDecoderNoOpListener::OnHeaderListEnd() {} void HpackDecoderNoOpListener::OnHeaderErrorDetected( - quiche::QuicheStringPiece /*error_message*/) {} + absl::string_view /*error_message*/) {} // static HpackDecoderNoOpListener* HpackDecoderNoOpListener::NoOpListener() { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h index f1b76db3678..9b67012c70d 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h @@ -8,10 +8,10 @@ #ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_ #define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/hpack_string.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -37,8 +37,7 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderListener { // OnHeaderErrorDetected is called if an error is detected while decoding. // error_message may be used in a GOAWAY frame as the Opaque Data. - virtual void OnHeaderErrorDetected( - quiche::QuicheStringPiece error_message) = 0; + virtual void OnHeaderErrorDetected(absl::string_view error_message) = 0; }; // A no-op implementation of HpackDecoderListener, useful for ignoring @@ -52,7 +51,7 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderNoOpListener void OnHeaderListStart() override; void OnHeader(const HpackString& name, const HpackString& value) override; void OnHeaderListEnd() override; - void OnHeaderErrorDetected(quiche::QuicheStringPiece error_message) override; + void OnHeaderErrorDetected(absl::string_view error_message) override; // Returns a listener that ignores all the calls. static HpackDecoderNoOpListener* NoOpListener(); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h index 3854a6c362e..6478a463d17 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h @@ -16,6 +16,7 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables.h" @@ -23,7 +24,6 @@ #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state_test.cc index eff1420f4ff..3ceaea2b432 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state_test.cc @@ -9,14 +9,13 @@ #include <utility> #include <vector> -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/hpack_string.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -41,13 +40,15 @@ class MockHpackDecoderListener : public HpackDecoderListener { MOCK_METHOD2(OnHeader, void(const HpackString& name, const HpackString& value)); MOCK_METHOD0(OnHeaderListEnd, void()); - MOCK_METHOD1(OnHeaderErrorDetected, - void(quiche::QuicheStringPiece error_message)); + MOCK_METHOD(void, + OnHeaderErrorDetected, + (absl::string_view error_message), + (override)); }; enum StringBacking { STATIC, UNBUFFERED, BUFFERED }; -class HpackDecoderStateTest : public ::testing::Test { +class HpackDecoderStateTest : public QuicheTest { protected: HpackDecoderStateTest() : decoder_state_(&listener_) {} diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.cc index f461c1e1625..2e476b0ffa2 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.cc @@ -60,8 +60,7 @@ void HpackDecoderStringBuffer::Reset() { state_ = State::RESET; } -void HpackDecoderStringBuffer::Set(quiche::QuicheStringPiece value, - bool is_static) { +void HpackDecoderStringBuffer::Set(absl::string_view value, bool is_static) { HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::Set"; DCHECK_EQ(state_, State::RESET); value_ = value; @@ -101,7 +100,7 @@ void HpackDecoderStringBuffer::OnStart(bool huffman_encoded, size_t len) { backing_ = Backing::RESET; // OnData is not called for empty (zero length) strings, so make sure that // value_ is cleared. - value_ = quiche::QuicheStringPiece(); + value_ = absl::string_view(); } } @@ -114,7 +113,7 @@ bool HpackDecoderStringBuffer::OnData(const char* data, size_t len) { if (is_huffman_encoded_) { DCHECK_EQ(backing_, Backing::BUFFERED); - return decoder_.Decode(quiche::QuicheStringPiece(data, len), &buffer_); + return decoder_.Decode(absl::string_view(data, len), &buffer_); } if (backing_ == Backing::RESET) { @@ -122,7 +121,7 @@ bool HpackDecoderStringBuffer::OnData(const char* data, size_t len) { // don't copy the string. If we later find that the HPACK entry is split // across input buffers, then we'll copy the string into buffer_. if (remaining_len_ == 0) { - value_ = quiche::QuicheStringPiece(data, len); + value_ = absl::string_view(data, len); backing_ = Backing::UNBUFFERED; return true; } @@ -188,14 +187,13 @@ size_t HpackDecoderStringBuffer::BufferedLength() const { return IsBuffered() ? buffer_.size() : 0; } -quiche::QuicheStringPiece HpackDecoderStringBuffer::str() const { +absl::string_view HpackDecoderStringBuffer::str() const { HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::str"; DCHECK_EQ(state_, State::COMPLETE); return value_; } -quiche::QuicheStringPiece HpackDecoderStringBuffer::GetStringIfComplete() - const { +absl::string_view HpackDecoderStringBuffer::GetStringIfComplete() const { if (state_ != State::COMPLETE) { return {}; } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h index 1341e79161e..b11d50fe472 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h @@ -14,9 +14,9 @@ #include <ostream> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -32,7 +32,7 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer { HpackDecoderStringBuffer& operator=(const HpackDecoderStringBuffer&) = delete; void Reset(); - void Set(quiche::QuicheStringPiece value, bool is_static); + void Set(absl::string_view value, bool is_static); // Note that for Huffman encoded strings the length of the string after // decoding may be larger (expected), the same or even smaller; the latter @@ -47,14 +47,14 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer { // Accessors for the completely collected string (i.e. Set or OnEnd has just // been called, and no reset of the state has occurred). - // Returns a QuicheStringPiece pointing to the backing store for the string, + // Returns a string_view pointing to the backing store for the string, // either the internal buffer or the original transport buffer (e.g. for a // literal value that wasn't Huffman encoded, and that wasn't split across // transport buffers). - quiche::QuicheStringPiece str() const; + absl::string_view str() const; // Same as str() if state_ is COMPLETE. Otherwise, returns empty string piece. - quiche::QuicheStringPiece GetStringIfComplete() const; + absl::string_view GetStringIfComplete() const; // Returns the completely collected string by value, using std::move in an // effort to avoid unnecessary copies. ReleaseString() must not be called @@ -75,10 +75,10 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer { // (e.g. if Huffman encoded, buffer_ is storage for the decoded string). std::string buffer_; - // The QuicheStringPiece to be returned by HpackDecoderStringBuffer::str(). If + // The string_view to be returned by HpackDecoderStringBuffer::str(). If // a string has been collected, but not buffered, value_ points to that // string. - quiche::QuicheStringPiece value_; + absl::string_view value_; // The decoder to use if the string is Huffman encoded. HpackHuffmanDecoder decoder_; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc index 9f3e2d3a368..51747e7cdf4 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc @@ -11,6 +11,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -20,7 +21,7 @@ namespace http2 { namespace test { namespace { -class HpackDecoderStringBufferTest : public ::testing::Test { +class HpackDecoderStringBufferTest : public QuicheTest { protected: typedef HpackDecoderStringBuffer::State State; typedef HpackDecoderStringBuffer::Backing Backing; @@ -45,7 +46,7 @@ class HpackDecoderStringBufferTest : public ::testing::Test { }; TEST_F(HpackDecoderStringBufferTest, SetStatic) { - quiche::QuicheStringPiece data("static string"); + absl::string_view data("static string"); EXPECT_EQ(state(), State::RESET); EXPECT_TRUE(VerifyLogHasSubstrs({"state=RESET"})); @@ -70,7 +71,7 @@ TEST_F(HpackDecoderStringBufferTest, SetStatic) { } TEST_F(HpackDecoderStringBufferTest, PlainWhole) { - quiche::QuicheStringPiece data("some text."); + absl::string_view data("some text."); HTTP2_LOG(INFO) << buf_; EXPECT_EQ(state(), State::RESET); @@ -92,7 +93,7 @@ TEST_F(HpackDecoderStringBufferTest, PlainWhole) { {"state=COMPLETE", "backing=UNBUFFERED", "value: some text."})); // We expect that the string buffer points to the passed in - // QuicheStringPiece's backing store. + // string_view's backing store. EXPECT_EQ(data.data(), buf_.str().data()); // Now force it to buffer the string, after which it will still have the same @@ -108,9 +109,9 @@ TEST_F(HpackDecoderStringBufferTest, PlainWhole) { } TEST_F(HpackDecoderStringBufferTest, PlainSplit) { - quiche::QuicheStringPiece data("some text."); - quiche::QuicheStringPiece part1 = data.substr(0, 1); - quiche::QuicheStringPiece part2 = data.substr(1); + absl::string_view data("some text."); + absl::string_view part1 = data.substr(0, 1); + absl::string_view part2 = data.substr(1); EXPECT_EQ(state(), State::RESET); buf_.OnStart(/*huffman_encoded*/ false, data.size()); @@ -136,7 +137,7 @@ TEST_F(HpackDecoderStringBufferTest, PlainSplit) { EXPECT_EQ(buf_.BufferedLength(), data.size()); HTTP2_LOG(INFO) << buf_; - quiche::QuicheStringPiece buffered = buf_.str(); + absl::string_view buffered = buf_.str(); EXPECT_EQ(data, buffered); EXPECT_NE(data.data(), buffered.data()); @@ -151,7 +152,7 @@ TEST_F(HpackDecoderStringBufferTest, PlainSplit) { TEST_F(HpackDecoderStringBufferTest, HuffmanWhole) { std::string encoded = Http2HexDecode("f1e3c2e5f23a6ba0ab90f4ff"); - quiche::QuicheStringPiece decoded("www.example.com"); + absl::string_view decoded("www.example.com"); EXPECT_EQ(state(), State::RESET); buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); @@ -178,7 +179,7 @@ TEST_F(HpackDecoderStringBufferTest, HuffmanSplit) { std::string encoded = Http2HexDecode("f1e3c2e5f23a6ba0ab90f4ff"); std::string part1 = encoded.substr(0, 5); std::string part2 = encoded.substr(5); - quiche::QuicheStringPiece decoded("www.example.com"); + absl::string_view decoded("www.example.com"); EXPECT_EQ(state(), State::RESET); buf_.OnStart(/*huffman_encoded*/ true, encoded.size()); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables_test.cc index 5722c707235..610c74af0e0 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables_test.cc @@ -9,13 +9,12 @@ #include <tuple> #include <vector> -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_util.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -55,7 +54,7 @@ void ShuffleCollection(C* collection, Http2Random* r) { std::shuffle(collection->begin(), collection->end(), *r); } -class HpackDecoderStaticTableTest : public ::testing::Test { +class HpackDecoderStaticTableTest : public QuicheTest { protected: HpackDecoderStaticTableTest() = default; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_test.cc index 7d6242d588f..eb142767fd1 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_test.cc @@ -11,8 +11,6 @@ #include <utility> #include <vector> -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h" @@ -26,6 +24,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_util.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; @@ -68,11 +67,13 @@ class MockHpackDecoderListener : public HpackDecoderListener { MOCK_METHOD2(OnHeader, void(const HpackString& name, const HpackString& value)); MOCK_METHOD0(OnHeaderListEnd, void()); - MOCK_METHOD1(OnHeaderErrorDetected, - void(quiche::QuicheStringPiece error_message)); + MOCK_METHOD(void, + OnHeaderErrorDetected, + (absl::string_view error_message), + (override)); }; -class HpackDecoderTest : public ::testing::TestWithParam<bool>, +class HpackDecoderTest : public QuicheTestWithParam<bool>, public HpackDecoderListener { protected: // Note that we initialize the random number generator with the same seed @@ -114,7 +115,7 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool>, // OnHeaderErrorDetected is called if an error is detected while decoding. // error_message may be used in a GOAWAY frame as the Opaque Data. - void OnHeaderErrorDetected(quiche::QuicheStringPiece error_message) override { + void OnHeaderErrorDetected(absl::string_view error_message) override { ASSERT_TRUE(saw_start_); error_messages_.push_back(std::string(error_message)); // No further callbacks should be made at this point, so replace 'this' as @@ -124,7 +125,7 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool>, HpackDecoderPeer::GetDecoderState(&decoder_), &mock_listener_); } - AssertionResult DecodeBlock(quiche::QuicheStringPiece block) { + AssertionResult DecodeBlock(absl::string_view block) { HTTP2_VLOG(1) << "HpackDecoderTest::DecodeBlock"; VERIFY_FALSE(decoder_.DetectError()); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.cc index 3e231b5ae52..4b106a9edbd 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.cc @@ -7,7 +7,7 @@ namespace http2 { // static -quiche::QuicheStringPiece HpackDecodingErrorToString(HpackDecodingError error) { +absl::string_view HpackDecodingErrorToString(HpackDecodingError error) { switch (error) { case HpackDecodingError::kOk: return "No error detected"; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h index e3465499ce2..3536b971728 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h @@ -5,8 +5,8 @@ #ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_ #define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -43,7 +43,7 @@ enum class HpackDecodingError { kCompressedHeaderSizeExceedsLimit, }; -QUICHE_EXPORT_PRIVATE quiche::QuicheStringPiece HpackDecodingErrorToString( +QUICHE_EXPORT_PRIVATE absl::string_view HpackDecodingErrorToString( HpackDecodingError error); } // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.cc index 80d4f9295c2..b39382881e0 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.cc @@ -4,12 +4,12 @@ #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; @@ -166,7 +166,7 @@ AssertionResult HpackEntryCollector::ValidateLiteralValueHeader( HpackEntryType expected_type, size_t expected_index, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const { + absl::string_view expected_value) const { VERIFY_TRUE(started_); VERIFY_TRUE(ended_); VERIFY_EQ(expected_type, header_type_); @@ -179,9 +179,9 @@ AssertionResult HpackEntryCollector::ValidateLiteralValueHeader( AssertionResult HpackEntryCollector::ValidateLiteralNameValueHeader( HpackEntryType expected_type, bool expected_name_huffman, - quiche::QuicheStringPiece expected_name, + absl::string_view expected_name, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const { + absl::string_view expected_value) const { VERIFY_TRUE(started_); VERIFY_TRUE(ended_); VERIFY_EQ(expected_type, header_type_); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h index abf9d97ec1c..e333789ebe4 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h @@ -15,12 +15,12 @@ #include <iosfwd> #include <string> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -85,16 +85,16 @@ class HpackEntryCollector : public HpackEntryDecoderListener { HpackEntryType expected_type, size_t expected_index, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const; + absl::string_view expected_value) const; // Returns success if collected a Header with an literal name and literal // value. ::testing::AssertionResult ValidateLiteralNameValueHeader( HpackEntryType expected_type, bool expected_name_huffman, - quiche::QuicheStringPiece expected_name, + absl::string_view expected_name, bool expected_value_huffman, - quiche::QuicheStringPiece expected_value) const; + absl::string_view expected_value) const; // Returns success if collected a Dynamic Table Size Update, // with the specified size. diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_test.cc index d4113f8004e..415511e2d12 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_test.cc @@ -8,12 +8,12 @@ #include <cstdint> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_type_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_type_decoder_test.cc index 60248f3326f..c5c7f521bda 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_type_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_type_decoder_test.cc @@ -6,11 +6,11 @@ #include <vector> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.cc index 0b18178d167..8300d57680d 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.cc @@ -9,9 +9,9 @@ #include <iosfwd> #include <ostream> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -66,7 +66,7 @@ void HpackStringCollector::OnStringStart(bool huffman, size_t length) { } void HpackStringCollector::OnStringData(const char* data, size_t length) { - quiche::QuicheStringPiece sp(data, length); + absl::string_view sp(data, length); EXPECT_TRUE(IsInProgress()) << ToString(); EXPECT_LE(sp.size(), len) << ToString(); Http2StrAppend(&s, sp); @@ -80,7 +80,7 @@ void HpackStringCollector::OnStringEnd() { } ::testing::AssertionResult HpackStringCollector::Collected( - quiche::QuicheStringPiece str, + absl::string_view str, bool is_huffman_encoded) const { VERIFY_TRUE(HasEnded()); VERIFY_EQ(str.size(), len); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h index 8326a57851d..9ba65c46ea7 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h @@ -12,9 +12,9 @@ #include <iosfwd> #include <string> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_listener.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -40,7 +40,7 @@ struct HpackStringCollector : public HpackStringDecoderListener { void OnStringData(const char* data, size_t length) override; void OnStringEnd() override; - ::testing::AssertionResult Collected(quiche::QuicheStringPiece str, + ::testing::AssertionResult Collected(absl::string_view str, bool is_huffman_encoded) const; std::string ToString() const; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_test.cc index a5f6166a161..bc6137c5b88 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_test.cc @@ -6,14 +6,14 @@ // Tests of HpackStringDecoder. -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; @@ -43,13 +43,13 @@ class HpackStringDecoderTest : public RandomDecoderTest { return decoder_.Resume(b, &listener_); } - AssertionResult Collected(quiche::QuicheStringPiece s, bool huffman_encoded) { + AssertionResult Collected(absl::string_view s, bool huffman_encoded) { HTTP2_VLOG(1) << collector_; return collector_.Collected(s, huffman_encoded); } // expected_str is a std::string rather than a const std::string& or - // QuicheStringPiece so that the lambda makes a copy of the string, and thus + // absl::string_view so that the lambda makes a copy of the string, and thus // the string to be passed to Collected outlives the call to MakeValidator. Validator MakeValidator(const std::string& expected_str, bool expected_huffman) { @@ -112,7 +112,7 @@ TEST_F(HpackStringDecoderTest, DecodeShortString) { { Validator validator = ValidateDoneAndOffset(11, MakeValidator("start end.", kUncompressed)); - quiche::QuicheStringPiece data("\x0astart end."); + absl::string_view data("\x0astart end."); DecodeBuffer b(data); EXPECT_TRUE( DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator)); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.cc index f8d5e9dc47d..ecdcdc90cee 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.cc @@ -70,7 +70,7 @@ void HpackWholeEntryBuffer::OnNameStart(bool huffman_encoded, size_t len) { void HpackWholeEntryBuffer::OnNameData(const char* data, size_t len) { HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameData: len=" << len << " data:\n" - << Http2HexDump(quiche::QuicheStringPiece(data, len)); + << Http2HexDump(absl::string_view(data, len)); DCHECK_EQ(maybe_name_index_, 0u); if (!error_detected_ && !name_.OnData(data, len)) { ReportError(HpackDecodingError::kNameHuffmanError, ""); @@ -107,7 +107,7 @@ void HpackWholeEntryBuffer::OnValueStart(bool huffman_encoded, size_t len) { void HpackWholeEntryBuffer::OnValueData(const char* data, size_t len) { HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueData: len=" << len << " data:\n" - << Http2HexDump(quiche::QuicheStringPiece(data, len)); + << Http2HexDump(absl::string_view(data, len)); if (!error_detected_ && !value_.OnData(data, len)) { ReportError(HpackDecodingError::kValueHuffmanError, ""); HTTP2_CODE_COUNT_N(decompress_failure_3, 22, 23); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.h index afca3b83812..f7b81c589d2 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.h @@ -12,13 +12,13 @@ #include <stddef.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc index 70e13501f2c..c3a005a98af 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc @@ -7,9 +7,8 @@ // Tests of HpackWholeEntryBuffer: does it buffer correctly, and does it // detect Huffman decoding errors and oversize string errors? -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::_; using ::testing::AllOf; @@ -47,7 +46,7 @@ class MockHpackWholeEntryListener : public HpackWholeEntryListener { (override)); }; -class HpackWholeEntryBufferTest : public ::testing::Test { +class HpackWholeEntryBufferTest : public QuicheTest { protected: HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {} ~HpackWholeEntryBufferTest() override = default; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h index ec2ae524656..92135f9c2c0 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_listener.h @@ -11,11 +11,11 @@ #include <stddef.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_string_buffer.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoding_error.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.cc b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.cc index cb22f51528b..a68bd8b88b5 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.cc @@ -12,33 +12,32 @@ namespace http2 { HpackString::HpackString(const char* data) : str_(data) {} -HpackString::HpackString(quiche::QuicheStringPiece str) - : str_(std::string(str)) {} +HpackString::HpackString(absl::string_view str) : str_(std::string(str)) {} HpackString::HpackString(std::string str) : str_(std::move(str)) {} HpackString::HpackString(const HpackString& other) = default; HpackString::~HpackString() = default; -quiche::QuicheStringPiece HpackString::ToStringPiece() const { +absl::string_view HpackString::ToStringPiece() const { return str_; } bool HpackString::operator==(const HpackString& other) const { return str_ == other.str_; } -bool HpackString::operator==(quiche::QuicheStringPiece str) const { +bool HpackString::operator==(absl::string_view str) const { return str == str_; } -bool operator==(quiche::QuicheStringPiece a, const HpackString& b) { +bool operator==(absl::string_view a, const HpackString& b) { return b == a; } -bool operator!=(quiche::QuicheStringPiece a, const HpackString& b) { +bool operator!=(absl::string_view a, const HpackString& b) { return !(b == a); } bool operator!=(const HpackString& a, const HpackString& b) { return !(a == b); } -bool operator!=(const HpackString& a, quiche::QuicheStringPiece b) { +bool operator!=(const HpackString& a, absl::string_view b) { return !(a == b); } std::ostream& operator<<(std::ostream& out, const HpackString& v) { @@ -51,8 +50,8 @@ HpackStringPair::HpackStringPair(const HpackString& name, HTTP2_DVLOG(3) << DebugString() << " ctor"; } -HpackStringPair::HpackStringPair(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) +HpackStringPair::HpackStringPair(absl::string_view name, + absl::string_view value) : name(name), value(value) { HTTP2_DVLOG(3) << DebugString() << " ctor"; } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.h b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.h index 678918713e7..3af2348e66c 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string.h @@ -15,15 +15,15 @@ #include <iosfwd> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { class QUICHE_EXPORT_PRIVATE HpackString { public: explicit HpackString(const char* data); - explicit HpackString(quiche::QuicheStringPiece str); + explicit HpackString(absl::string_view str); explicit HpackString(std::string str); HpackString(const HpackString& other); @@ -34,31 +34,30 @@ class QUICHE_EXPORT_PRIVATE HpackString { size_t size() const { return str_.size(); } const std::string& ToString() const { return str_; } - quiche::QuicheStringPiece ToStringPiece() const; + absl::string_view ToStringPiece() const; bool operator==(const HpackString& other) const; - bool operator==(quiche::QuicheStringPiece str) const; + bool operator==(absl::string_view str) const; private: std::string str_; }; -QUICHE_EXPORT_PRIVATE bool operator==(quiche::QuicheStringPiece a, +QUICHE_EXPORT_PRIVATE bool operator==(absl::string_view a, const HpackString& b); -QUICHE_EXPORT_PRIVATE bool operator!=(quiche::QuicheStringPiece a, +QUICHE_EXPORT_PRIVATE bool operator!=(absl::string_view a, const HpackString& b); QUICHE_EXPORT_PRIVATE bool operator!=(const HpackString& a, const HpackString& b); QUICHE_EXPORT_PRIVATE bool operator!=(const HpackString& a, - quiche::QuicheStringPiece b); + absl::string_view b); QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, const HpackString& v); struct QUICHE_EXPORT_PRIVATE HpackStringPair { HpackStringPair(const HpackString& name, const HpackString& value); - HpackStringPair(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + HpackStringPair(absl::string_view name, absl::string_view value); ~HpackStringPair(); // Returns the size of a header entry with this name and value, per the RFC: diff --git a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string_test.cc index 399d09fbb17..ee24115e626 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/hpack_string_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/hpack_string_test.cc @@ -10,6 +10,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; @@ -22,12 +23,12 @@ namespace { const char kStr0[] = "s0: Some string to be copied into another string."; const char kStr1[] = "S1 - some string to be copied into yet another string."; -class HpackStringTest : public ::testing::Test { +class HpackStringTest : public QuicheTest { protected: AssertionResult VerifyNotEqual(HpackString* actual, const std::string& not_expected_str) { const char* not_expected_ptr = not_expected_str.c_str(); - quiche::QuicheStringPiece not_expected_sp(not_expected_str); + absl::string_view not_expected_sp(not_expected_str); VERIFY_NE(*actual, not_expected_ptr); VERIFY_NE(*actual, not_expected_sp); @@ -55,7 +56,7 @@ class HpackStringTest : public ::testing::Test { VERIFY_EQ(actual->size(), expected_str.size()); const char* expected_ptr = expected_str.c_str(); - const quiche::QuicheStringPiece expected_sp(expected_str); + const absl::string_view expected_sp(expected_str); VERIFY_EQ(*actual, expected_ptr); VERIFY_EQ(*actual, expected_sp); @@ -90,12 +91,12 @@ TEST_F(HpackStringTest, CharArrayConstructor) { } TEST_F(HpackStringTest, StringPieceConstructor) { - quiche::QuicheStringPiece sp0(kStr0); + absl::string_view sp0(kStr0); HpackString hs0(sp0); EXPECT_TRUE(VerifyEqual(&hs0, kStr0)); EXPECT_TRUE(VerifyNotEqual(&hs0, kStr1)); - quiche::QuicheStringPiece sp1(kStr1); + absl::string_view sp1(kStr1); HpackString hs1(sp1); EXPECT_TRUE(VerifyEqual(&hs1, kStr1)); EXPECT_TRUE(VerifyNotEqual(&hs1, kStr0)); @@ -114,7 +115,7 @@ TEST_F(HpackStringTest, MoveStringConstructor) { } TEST_F(HpackStringTest, CopyConstructor) { - quiche::QuicheStringPiece sp0(kStr0); + absl::string_view sp0(kStr0); HpackString hs0(sp0); HpackString hs1(hs0); EXPECT_EQ(hs0, hs1); @@ -127,7 +128,7 @@ TEST_F(HpackStringTest, CopyConstructor) { } TEST_F(HpackStringTest, MoveConstructor) { - quiche::QuicheStringPiece sp0(kStr0); + absl::string_view sp0(kStr0); HpackString hs0(sp0); EXPECT_TRUE(VerifyEqual(&hs0, kStr0)); EXPECT_TRUE(VerifyNotEqual(&hs0, "")); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.cc index 18bff72d2b0..d21624cf6d7 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.cc @@ -26,8 +26,6 @@ // is 5 bits long, and the last canonical is EOS, which is the last // of the symbols whose code is 30 bits long. -// TODO(jamessynge): Remove use of binary literals, that is a C++ 14 feature. - namespace http2 { namespace { @@ -356,7 +354,7 @@ void HuffmanBitBuffer::Reset() { count_ = 0; } -size_t HuffmanBitBuffer::AppendBytes(quiche::QuicheStringPiece input) { +size_t HuffmanBitBuffer::AppendBytes(absl::string_view input) { HuffmanAccumulatorBitCount free_cnt = free_count(); size_t bytes_available = input.size(); if (free_cnt < 8 || bytes_available == 0) { @@ -414,8 +412,7 @@ HpackHuffmanDecoder::HpackHuffmanDecoder() = default; HpackHuffmanDecoder::~HpackHuffmanDecoder() = default; -bool HpackHuffmanDecoder::Decode(quiche::QuicheStringPiece input, - std::string* output) { +bool HpackHuffmanDecoder::Decode(absl::string_view input, std::string* output) { HTTP2_DVLOG(1) << "HpackHuffmanDecoder::Decode"; // Fill bit_buffer_ from input. diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h index 229bb586f3a..fe312d83c84 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h @@ -18,8 +18,8 @@ #include <iosfwd> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -47,7 +47,7 @@ class QUICHE_EXPORT_PRIVATE HuffmanBitBuffer { // Add as many whole bytes to the accumulator (accumulator_) as possible, // returning the number of bytes added. - size_t AppendBytes(quiche::QuicheStringPiece input); + size_t AppendBytes(absl::string_view input); // Get the bits of the accumulator. HuffmanAccumulator value() const { return accumulator_; } @@ -109,7 +109,7 @@ class QUICHE_EXPORT_PRIVATE HpackHuffmanDecoder { // will contain the leading bits of the code for that symbol, but not the // final bits of that code. // Note that output should be empty, but that it is not cleared by Decode(). - bool Decode(quiche::QuicheStringPiece input, std::string* output); + bool Decode(absl::string_view input, std::string* output); // Is what remains in the bit_buffer_ valid at the end of an encoded string? // Call after passing the the final portion of a Huffman string to Decode, diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder_test.cc index 482d39c4c8b..0ff34132f69 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder_test.cc @@ -8,13 +8,13 @@ #include <iostream> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; @@ -36,7 +36,7 @@ TEST(HuffmanBitBufferTest, AppendBytesAligned) { s.push_back('\x11'); s.push_back('\x22'); s.push_back('\x33'); - quiche::QuicheStringPiece sp(s); + absl::string_view sp(s); HuffmanBitBuffer bb; sp.remove_prefix(bb.AppendBytes(sp)); @@ -85,7 +85,7 @@ TEST(HuffmanBitBufferTest, ConsumeBits) { s.push_back('\x11'); s.push_back('\x22'); s.push_back('\x33'); - quiche::QuicheStringPiece sp(s); + absl::string_view sp(s); HuffmanBitBuffer bb; sp.remove_prefix(bb.AppendBytes(sp)); @@ -117,7 +117,7 @@ TEST(HuffmanBitBufferTest, AppendBytesUnaligned) { s.push_back('\xbb'); s.push_back('\xcc'); s.push_back('\xdd'); - quiche::QuicheStringPiece sp(s); + absl::string_view sp(s); HuffmanBitBuffer bb; sp.remove_prefix(bb.AppendBytes(sp)); @@ -161,10 +161,10 @@ class HpackHuffmanDecoderTest : public RandomDecoderTest { DecodeStatus ResumeDecoding(DecodeBuffer* b) override { input_bytes_seen_ += b->Remaining(); - quiche::QuicheStringPiece sp(b->cursor(), b->Remaining()); + absl::string_view sp(b->cursor(), b->Remaining()); if (decoder_.Decode(sp, &output_buffer_)) { b->AdvanceCursor(b->Remaining()); - // Successfully decoded (or buffered) the bytes in QuicheStringPiece. + // Successfully decoded (or buffered) the bytes in absl::string_view. EXPECT_LE(input_bytes_seen_, input_bytes_expected_); // Have we reached the end of the encoded string? if (input_bytes_expected_ == input_bytes_seen_) { @@ -197,7 +197,7 @@ TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) { Http2HexDecode("25a849e95bb8e8b4bf"), "custom-value", }; - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& huffman_encoded(test_table[i]); const std::string& plain_string(test_table[i + 1]); std::string buffer; @@ -228,7 +228,7 @@ TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) { "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", }; // clang-format on - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& huffman_encoded(test_table[i]); const std::string& plain_string(test_table[i + 1]); std::string buffer; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.cc index 8b3f29fc69a..c4492df0aec 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.cc @@ -7,11 +7,9 @@ #include "net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" -// TODO(jamessynge): Remove use of binary literals, that is a C++ 14 feature. - namespace http2 { -size_t ExactHuffmanSize(quiche::QuicheStringPiece plain) { +size_t HuffmanSize(absl::string_view plain) { size_t bits = 0; for (const uint8_t c : plain) { bits += HuffmanSpecTables::kCodeLengths[c]; @@ -19,51 +17,11 @@ size_t ExactHuffmanSize(quiche::QuicheStringPiece plain) { return (bits + 7) / 8; } -size_t BoundedHuffmanSize(quiche::QuicheStringPiece plain) { - // TODO(jamessynge): Determine whether we should set the min size for Huffman - // encoding much higher (i.e. if less than N, then the savings isn't worth - // the cost of encoding and decoding). Of course, we need to decide on a - // value function, which might be throughput on a full load test, or a - // microbenchmark of the time to encode and then decode a HEADERS frame, - // possibly with the cost of crypto included (i.e. crypto is going to have - // a fairly constant per-byte cost, so reducing the number of bytes in-transit - // reduces the number that must be encrypted and later decrypted). - if (plain.size() < 3) { - // Huffman encoded string can't be smaller than the plain size for very - // short strings. - return plain.size(); - } - // TODO(jamessynge): Measure whether this can be done more efficiently with - // nested loops (e.g. make exact measurement of 8 bytes, then check if min - // remaining is too long). - // Compute the number of bits in an encoding that is shorter than the plain - // string (i.e. the number of bits in a string 1 byte shorter than plain), - // and use this as the limit of the size of the encoding. - const size_t limit_bits = (plain.size() - 1) * 8; - // The shortest code length in the Huffman table of the HPACK spec has 5 bits - // (e.g. for 0, 1, a and e). - const size_t min_code_length = 5; - // We can therefore say that all plain text bytes whose code length we've not - // yet looked up will take at least 5 bits. - size_t min_bits_remaining = plain.size() * min_code_length; - size_t bits = 0; - for (const uint8_t c : plain) { - bits += HuffmanSpecTables::kCodeLengths[c]; - min_bits_remaining -= min_code_length; - // If our minimum estimate of the total number of bits won't yield an - // encoding shorter the plain text, let's bail. - const size_t minimum_bits_total = bits + min_bits_remaining; - if (minimum_bits_total > limit_bits) { - bits += min_bits_remaining; - break; - } - } - return (bits + 7) / 8; -} - -void HuffmanEncode(quiche::QuicheStringPiece plain, std::string* huffman) { +void HuffmanEncode(absl::string_view plain, + size_t encoded_size, + std::string* huffman) { DCHECK(huffman != nullptr); - huffman->clear(); // Note that this doesn't release memory. + huffman->reserve(huffman->size() + encoded_size); uint64_t bit_buffer = 0; // High-bit is next bit to output. Not clear if that // is more performant than having the low-bit be the // last to be output. @@ -107,4 +65,65 @@ void HuffmanEncode(quiche::QuicheStringPiece plain, std::string* huffman) { } } +void HuffmanEncodeFast(absl::string_view input, + size_t encoded_size, + std::string* output) { + const size_t original_size = output->size(); + const size_t final_size = original_size + encoded_size; + // Reserve an extra four bytes to avoid accessing unallocated memory (even + // though it would only be OR'd with zeros and thus not modified). + output->resize(final_size + 4, 0); + + // Pointer to first appended byte. + char* const first = &*output->begin() + original_size; + size_t bit_counter = 0; + for (uint8_t c : input) { + // Align the Huffman code to byte boundaries as it needs to be written. + // The longest Huffman code is 30 bits long, and it can be shifted by up to + // 7 bits, requiring 37 bits in total. The most significant 25 bits and + // least significant 2 bits of |code| are always zero. + uint64_t code = static_cast<uint64_t>(HuffmanSpecTables::kLeftCodes[c]) + << (8 - (bit_counter % 8)); + // The byte where the first bit of |code| needs to be written. + char* const current = first + (bit_counter / 8); + + bit_counter += HuffmanSpecTables::kCodeLengths[c]; + + *current |= code >> 32; + + // Do not check if this write is zero before executing it, because with + // uniformly random shifts and an ideal random input distribution + // corresponding to the Huffman tree it would only be zero in 29% of the + // cases. + *(current + 1) |= (code >> 24) & 0xff; + + // Continue to next input character if there is nothing else to write. + // (If next byte is zero, then rest must also be zero.) + if ((code & 0xff0000) == 0) { + continue; + } + *(current + 2) |= (code >> 16) & 0xff; + + // Continue to next input character if there is nothing else to write. + // (If next byte is zero, then rest must also be zero.) + if ((code & 0xff00) == 0) { + continue; + } + *(current + 3) |= (code >> 8) & 0xff; + + // Do not check if this write is zero, because the check would probably be + // as expensive as the write. + *(current + 4) |= code & 0xff; + } + + DCHECK_EQ(encoded_size, (bit_counter + 7) / 8); + + // EOF + if (bit_counter % 8 != 0) { + *(first + encoded_size - 1) |= 0xff >> (bit_counter & 7); + } + + output->resize(final_size); +} + } // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h index 2ee4de21a70..fb79fb19a8a 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h @@ -11,31 +11,30 @@ #include <cstddef> // For size_t #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { // Returns the size of the Huffman encoding of |plain|, which may be greater -// than plain.size(). Mostly present for testing. -QUICHE_EXPORT_PRIVATE size_t ExactHuffmanSize(quiche::QuicheStringPiece plain); - -// Returns the size of the Huffman encoding of |plain|, unless it is greater -// than or equal to plain.size(), in which case a value greater than or equal to -// plain.size() is returned. The advantage of this over ExactHuffmanSize is that -// it doesn't read as much of the input string in the event that the string is -// not compressible by HuffmanEncode (i.e. when the encoding is longer than the -// original string, it stops reading the input string as soon as it knows that). -QUICHE_EXPORT_PRIVATE size_t -BoundedHuffmanSize(quiche::QuicheStringPiece plain); - -// Encode the plain text string |plain| with the Huffman encoding defined in -// the HPACK RFC, 7541. |*huffman| does not have to be empty, it is cleared at -// the beginning of this function. This allows reusing the same string object -// across multiple invocations. -QUICHE_EXPORT_PRIVATE void HuffmanEncode(quiche::QuicheStringPiece plain, +// than plain.size(). +QUICHE_EXPORT_PRIVATE size_t HuffmanSize(absl::string_view plain); + +// Encode the plain text string |plain| with the Huffman encoding defined in the +// HPACK RFC, 7541. |encoded_size| is used to pre-allocate storage and it +// should be the value returned by HuffmanSize(). Appends the result to +// |*huffman|. +QUICHE_EXPORT_PRIVATE void HuffmanEncode(absl::string_view plain, + size_t encoded_size, std::string* huffman); +// Encode |input| with the Huffman encoding defined RFC7541, used in HPACK and +// QPACK. |encoded_size| must be the value returned by HuffmanSize(). +// Appends the result to the end of |*output|. +QUICHE_EXPORT_PRIVATE void HuffmanEncodeFast(absl::string_view input, + size_t encoded_size, + std::string* output); + } // namespace http2 #endif // QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_ diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_benchmark.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_benchmark.cc deleted file mode 100644 index 1f365c6b0da..00000000000 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_benchmark.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2020 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. - -// -// $ blaze run -c opt --dynamic_mode=off \ -// -- //net/third_party/quiche/src/http2/hpack/huffman:hpack_huffman_encoder_benchmark \ -// --benchmarks=all --benchmark_memory_usage --benchmark_repetitions=1 -// -// Benchmark Time(ns) CPU(ns) Allocs Iterations -// ----------------------------------------------------------------------------- -// BM_EncodeSmallStrings 239 239 0 2456085 0.000B peak-mem -// BM_EncodeLargeString/1k 4560 4561 5 153325 1.125kB peak-mem -// BM_EncodeLargeString/4k 18787 18788 7 38430 4.500kB peak-mem -// BM_EncodeLargeString/32k 147680 147657 10 4664 36.000kB peak-mem -// BM_EncodeLargeString/256k 1161688 1161511 13 601 288.000kB peak-mem -// BM_EncodeLargeString/2M 10042722 10036764 16 75 2.250MB peak-mem -// BM_EncodeLargeString/16M 76127338 76138839 19 9 18.000MB peak-mem -// BM_EncodeLargeString/128M 640008098 640154859 22 1 144.000MB peak-mem -// - -#include <string> - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" -// This header has multiple DCHECK_* macros with signed-unsigned comparison. -#include "testing/base/public/benchmark.h" -#pragma clang diagnostic pop - -#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" - -namespace http2 { -namespace { - -void BM_EncodeSmallStrings(benchmark::State& state) { - const std::vector<const std::string> inputs{ - ":method", ":path", "cookie", "set-cookie", "vary", "accept-encoding"}; - for (auto s : state) { - for (const auto& input : inputs) { - std::string result; - ExactHuffmanSize(input); - HuffmanEncode(input, &result); - } - } -} - -void BM_EncodeLargeString(benchmark::State& state) { - const std::string input(state.range(0), 'a'); - for (auto s : state) { - std::string result; - ExactHuffmanSize(input); - HuffmanEncode(input, &result); - } -} - -BENCHMARK(BM_EncodeSmallStrings); -BENCHMARK(BM_EncodeLargeString)->Range(1024, 128 * 1024 * 1024); - -} // namespace -} // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_test.cc index d729d0ec138..c9743f5f270 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder_test.cc @@ -4,14 +4,41 @@ #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace { -TEST(HuffmanEncoderTest, SpecRequestExamples) { +class HuffmanEncoderTest : public ::testing::TestWithParam<bool> { + protected: + HuffmanEncoderTest() : use_fast_encoder_(GetParam()) {} + virtual ~HuffmanEncoderTest() = default; + + void Encode(absl::string_view input, + size_t encoded_size, + std::string* output) { + use_fast_encoder_ ? HuffmanEncodeFast(input, encoded_size, output) + : HuffmanEncode(input, encoded_size, output); + } + + const bool use_fast_encoder_; +}; + +INSTANTIATE_TEST_SUITE_P(TwoEncoders, HuffmanEncoderTest, ::testing::Bool()); + +TEST_P(HuffmanEncoderTest, Empty) { + std::string empty(""); + size_t encoded_size = HuffmanSize(empty); + EXPECT_EQ(0u, encoded_size); + + std::string buffer; + Encode(empty, encoded_size, &buffer); + EXPECT_EQ("", buffer); +} + +TEST_P(HuffmanEncoderTest, SpecRequestExamples) { std::string test_table[] = { Http2HexDecode("f1e3c2e5f23a6ba0ab90f4ff"), "www.example.com", @@ -22,19 +49,19 @@ TEST(HuffmanEncoderTest, SpecRequestExamples) { Http2HexDecode("25a849e95bb8e8b4bf"), "custom-value", }; - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& huffman_encoded(test_table[i]); const std::string& plain_string(test_table[i + 1]); - EXPECT_EQ(ExactHuffmanSize(plain_string), huffman_encoded.size()); - EXPECT_EQ(BoundedHuffmanSize(plain_string), huffman_encoded.size()); + size_t encoded_size = HuffmanSize(plain_string); + EXPECT_EQ(huffman_encoded.size(), encoded_size); std::string buffer; buffer.reserve(); - HuffmanEncode(plain_string, &buffer); + Encode(plain_string, encoded_size, &buffer); EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string; } } -TEST(HuffmanEncoderTest, SpecResponseExamples) { +TEST_P(HuffmanEncoderTest, SpecResponseExamples) { // clang-format off std::string test_table[] = { Http2HexDecode("6402"), @@ -53,21 +80,18 @@ TEST(HuffmanEncoderTest, SpecResponseExamples) { "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", }; // clang-format on - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& huffman_encoded(test_table[i]); const std::string& plain_string(test_table[i + 1]); - EXPECT_EQ(ExactHuffmanSize(plain_string), huffman_encoded.size()); - EXPECT_EQ(BoundedHuffmanSize(plain_string), huffman_encoded.size()); + size_t encoded_size = HuffmanSize(plain_string); + EXPECT_EQ(huffman_encoded.size(), encoded_size); std::string buffer; - buffer.reserve(huffman_encoded.size()); - const size_t capacity = buffer.capacity(); - HuffmanEncode(plain_string, &buffer); + Encode(plain_string, encoded_size, &buffer); EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string; - EXPECT_EQ(capacity, buffer.capacity()); } } -TEST(HuffmanEncoderTest, EncodedSizeAgreesWithEncodeString) { +TEST_P(HuffmanEncoderTest, EncodedSizeAgreesWithEncodeString) { std::string test_table[] = { "", "Mon, 21 Oct 2013 20:13:21 GMT", @@ -79,18 +103,29 @@ TEST(HuffmanEncoderTest, EncodedSizeAgreesWithEncodeString) { }; // Modify last |test_table| entry to cover all codes. for (size_t i = 0; i != 256; ++i) { - test_table[QUICHE_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i); + test_table[ABSL_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i); } - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); ++i) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); ++i) { const std::string& plain_string = test_table[i]; + size_t encoded_size = HuffmanSize(plain_string); std::string huffman_encoded; - HuffmanEncode(plain_string, &huffman_encoded); - EXPECT_EQ(huffman_encoded.size(), ExactHuffmanSize(plain_string)); - EXPECT_LE(BoundedHuffmanSize(plain_string), plain_string.size()); - EXPECT_LE(BoundedHuffmanSize(plain_string), ExactHuffmanSize(plain_string)); + Encode(plain_string, encoded_size, &huffman_encoded); + EXPECT_EQ(encoded_size, huffman_encoded.size()); } } +// Test that encoding appends to output without overwriting it. +TEST_P(HuffmanEncoderTest, AppendToOutput) { + size_t encoded_size = HuffmanSize("foo"); + std::string buffer; + Encode("foo", encoded_size, &buffer); + EXPECT_EQ(Http2HexDecode("94e7"), buffer); + + encoded_size = HuffmanSize("bar"); + Encode("bar", encoded_size, &buffer); + EXPECT_EQ(Http2HexDecode("94e78c767f"), buffer); +} + } // namespace } // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_transcoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_transcoder_test.cc index b7407a3ed17..087f3740bdc 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_transcoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_transcoder_test.cc @@ -6,14 +6,14 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -52,10 +52,10 @@ class HpackHuffmanTranscoderTest : public RandomDecoderTest { DecodeStatus ResumeDecoding(DecodeBuffer* b) override { input_bytes_seen_ += b->Remaining(); - quiche::QuicheStringPiece sp(b->cursor(), b->Remaining()); + absl::string_view sp(b->cursor(), b->Remaining()); if (decoder_.Decode(sp, &output_buffer_)) { b->AdvanceCursor(b->Remaining()); - // Successfully decoded (or buffered) the bytes in QuicheStringPiece. + // Successfully decoded (or buffered) the bytes in absl::string_view. EXPECT_LE(input_bytes_seen_, input_bytes_expected_); // Have we reached the end of the encoded string? if (input_bytes_expected_ == input_bytes_seen_) { @@ -71,10 +71,12 @@ class HpackHuffmanTranscoderTest : public RandomDecoderTest { } AssertionResult TranscodeAndValidateSeveralWays( - quiche::QuicheStringPiece plain, - quiche::QuicheStringPiece expected_huffman) { + absl::string_view plain, + absl::string_view expected_huffman) { + size_t encoded_size = HuffmanSize(plain); std::string encoded; - HuffmanEncode(plain, &encoded); + HuffmanEncode(plain, encoded_size, &encoded); + VERIFY_EQ(encoded_size, encoded.size()); if (expected_huffman.size() > 0 || plain.empty()) { VERIFY_EQ(encoded, expected_huffman); } @@ -90,8 +92,7 @@ class HpackHuffmanTranscoderTest : public RandomDecoderTest { ValidateDoneAndEmpty(validator)); } - AssertionResult TranscodeAndValidateSeveralWays( - quiche::QuicheStringPiece plain) { + AssertionResult TranscodeAndValidateSeveralWays(absl::string_view plain) { return TranscodeAndValidateSeveralWays(plain, ""); } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.cc b/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.cc index 27707b98120..f93d9a56dad 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.cc @@ -44,11 +44,6 @@ const uint8_t HuffmanSpecTables::kCodeLengths[] = { 30, // 256 }; -// TODO(jamessynge): Remove use of binary literals, that is a C++ 14 feature. - -// Uncomment these codes if needed for generating Huffman output, as opposed -// to decoding Huffman input. -/* // The encoding of each symbol, left justified (as printed), which means that // the first bit of the encoding is the high-order bit of the uint32. // static @@ -311,7 +306,6 @@ const uint32_t HuffmanSpecTables::kLeftCodes[] = { 0b11111111111111111111101110000000, // 0xff 0b11111111111111111111111111111100, // 0x100 }; -*/ // static const uint32_t HuffmanSpecTables::kRightCodes[] = { diff --git a/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.h b/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.h index 6cd8726d7b4..d1b144b1358 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/huffman/huffman_spec_tables.h @@ -18,6 +18,10 @@ struct HuffmanSpecTables { // The encoding of each symbol, right justified (as printed), which means that // the last bit of the encoding is the low-order bit of the uint32. static const uint32_t kRightCodes[257]; + + // The encoding of each symbol, left justified (as printed), which means that + // the first bit of the encoding is the high-order bit of the uint32. + static const uint32_t kLeftCodes[257]; }; } // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.cc b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.cc index 3175c1d4bb2..fa0ec4d3cc0 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.cc @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_bug_tracker.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -55,7 +55,7 @@ void HpackBlockBuilder::AppendEntryTypeAndVarint(HpackEntryType entry_type, } void HpackBlockBuilder::AppendString(bool is_huffman_encoded, - quiche::QuicheStringPiece str) { + absl::string_view str) { uint8_t high_bits = is_huffman_encoded ? 0x80 : 0; uint8_t prefix_length = 7; AppendHighBitsAndVarint(high_bits, prefix_length, str.size()); diff --git a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h index b96d262ee32..46da803f871 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h @@ -20,16 +20,16 @@ #include <cstdint> #include <string> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { class HpackBlockBuilder { public: - explicit HpackBlockBuilder(quiche::QuicheStringPiece initial_contents) + explicit HpackBlockBuilder(absl::string_view initial_contents) : buffer_(initial_contents.data(), initial_contents.size()) {} HpackBlockBuilder() {} ~HpackBlockBuilder() {} @@ -51,7 +51,7 @@ class HpackBlockBuilder { void AppendNameIndexAndLiteralValue(HpackEntryType entry_type, uint64_t name_index, bool value_is_huffman_encoded, - quiche::QuicheStringPiece value) { + absl::string_view value) { // name_index==0 would indicate that the entry includes a literal name. // Call AppendLiteralNameAndValue in that case. EXPECT_NE(0u, name_index); @@ -61,9 +61,9 @@ class HpackBlockBuilder { void AppendLiteralNameAndValue(HpackEntryType entry_type, bool name_is_huffman_encoded, - quiche::QuicheStringPiece name, + absl::string_view name, bool value_is_huffman_encoded, - quiche::QuicheStringPiece value) { + absl::string_view value) { AppendEntryTypeAndVarint(entry_type, 0); AppendString(name_is_huffman_encoded, name); AppendString(value_is_huffman_encoded, value); @@ -84,7 +84,7 @@ class HpackBlockBuilder { // Append a header string (i.e. a header name or value) in HPACK format. // Does NOT perform Huffman encoding. - void AppendString(bool is_huffman_encoded, quiche::QuicheStringPiece str); + void AppendString(bool is_huffman_encoded, absl::string_view str); private: std::string buffer_; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder_test.cc index 21f161e5335..d162fba6530 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder_test.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -120,8 +120,7 @@ TEST(HpackBlockBuilderTest, ExamplesFromSpecC4) { '\xab', '\x90', '\xf4', '\xff'}; b.AppendNameIndexAndLiteralValue( HpackEntryType::kIndexedLiteralHeader, 1, kCompressed, - quiche::QuicheStringPiece(kHuffmanWwwExampleCom, - sizeof kHuffmanWwwExampleCom)); + absl::string_view(kHuffmanWwwExampleCom, sizeof kHuffmanWwwExampleCom)); EXPECT_EQ(17u, b.size()); // Hex dump of encoded data (copied from RFC): @@ -141,7 +140,7 @@ TEST(HpackBlockBuilderTest, DynamicTableSizeUpdate) { EXPECT_EQ(1u, b.size()); const char kData[] = {'\x20'}; - quiche::QuicheStringPiece expected(kData, sizeof kData); + absl::string_view expected(kData, sizeof kData); EXPECT_EQ(expected, b.buffer()); } { @@ -150,7 +149,7 @@ TEST(HpackBlockBuilderTest, DynamicTableSizeUpdate) { EXPECT_EQ(3u, b.size()); const char kData[] = {'\x3f', '\xe1', '\x1f'}; - quiche::QuicheStringPiece expected(kData, sizeof kData); + absl::string_view expected(kData, sizeof kData); EXPECT_EQ(expected, b.buffer()); } { @@ -160,7 +159,7 @@ TEST(HpackBlockBuilderTest, DynamicTableSizeUpdate) { const char kData[] = {'\x3f', '\xe1', '\x9f', '\x94', '\xa5', '\x8d', '\x1d'}; - quiche::QuicheStringPiece expected(kData, sizeof kData); + absl::string_view expected(kData, sizeof kData); EXPECT_EQ(expected, b.buffer()); } } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.cc b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.cc index 31de86ddc95..1087875d0ff 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.cc @@ -15,8 +15,7 @@ namespace http2 { namespace test { namespace { -void HpackExampleToStringOrDie(quiche::QuicheStringPiece example, - std::string* output) { +void HpackExampleToStringOrDie(absl::string_view example, std::string* output) { while (!example.empty()) { const char c0 = example[0]; if (isxdigit(c0)) { @@ -34,7 +33,7 @@ void HpackExampleToStringOrDie(quiche::QuicheStringPiece example, if (!example.empty() && example[0] == '|') { // Start of a comment. Skip to end of line or of input. auto pos = example.find('\n'); - if (pos == quiche::QuicheStringPiece::npos) { + if (pos == absl::string_view::npos) { // End of input. break; } @@ -50,7 +49,7 @@ void HpackExampleToStringOrDie(quiche::QuicheStringPiece example, } // namespace -std::string HpackExampleToStringOrDie(quiche::QuicheStringPiece example) { +std::string HpackExampleToStringOrDie(absl::string_view example) { std::string output; HpackExampleToStringOrDie(example, &output); return output; diff --git a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.h b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.h index e86c11692c4..de203cccbde 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.h +++ b/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_example.h @@ -7,7 +7,7 @@ #include <string> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" // Parses HPACK examples in the format seen in the HPACK specification, // RFC 7541. For example: @@ -24,7 +24,7 @@ namespace http2 { namespace test { -std::string HpackExampleToStringOrDie(quiche::QuicheStringPiece example); +std::string HpackExampleToStringOrDie(absl::string_view example); } // namespace test } // namespace http2 diff --git a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder_test.cc index 450751fdfc4..7be271000e8 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder_test.cc @@ -8,12 +8,12 @@ #include <stddef.h> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionSuccess; @@ -31,7 +31,7 @@ class HpackVarintDecoderTest : public RandomDecoderTest, suffix_(Http2HexDecode(::testing::get<1>(GetParam()))), prefix_length_(0) {} - void DecodeExpectSuccess(quiche::QuicheStringPiece data, + void DecodeExpectSuccess(absl::string_view data, uint32_t prefix_length, uint64_t expected_value) { Validator validator = [expected_value, this]( @@ -52,8 +52,7 @@ class HpackVarintDecoderTest : public RandomDecoderTest, EXPECT_EQ(expected_value, decoder_.value()); } - void DecodeExpectError(quiche::QuicheStringPiece data, - uint32_t prefix_length) { + void DecodeExpectError(absl::string_view data, uint32_t prefix_length) { Validator validator = [](const DecodeBuffer& /*db*/, DecodeStatus status) -> AssertionResult { VERIFY_EQ(DecodeStatus::kDecodeError, status); @@ -64,7 +63,7 @@ class HpackVarintDecoderTest : public RandomDecoderTest, } private: - AssertionResult Decode(quiche::QuicheStringPiece data, + AssertionResult Decode(absl::string_view data, uint32_t prefix_length, const Validator validator) { prefix_length_ = prefix_length; @@ -261,7 +260,7 @@ struct { }; TEST_P(HpackVarintDecoderTest, Success) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kSuccessTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kSuccessTestData); ++i) { DecodeExpectSuccess(Http2HexDecode(kSuccessTestData[i].data), kSuccessTestData[i].prefix_length, kSuccessTestData[i].expected_value); @@ -302,7 +301,7 @@ struct { {"ff80feffffffffffffff8100", 8}}; TEST_P(HpackVarintDecoderTest, Error) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kErrorTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kErrorTestData); ++i) { DecodeExpectError(Http2HexDecode(kErrorTestData[i].data), kErrorTestData[i].prefix_length); } diff --git a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder_test.cc index 22de704c55f..979ffc56658 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder_test.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "testing/gtest/include/gtest/gtest.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -30,7 +30,7 @@ struct { // Encode integers that fit in the prefix. TEST(HpackVarintEncoderTest, Short) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kShortTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kShortTestData); ++i) { std::string output; HpackVarintEncoder::Encode(kShortTestData[i].high_bits, kShortTestData[i].prefix_length, @@ -103,7 +103,7 @@ struct { TEST(HpackVarintEncoderTest, Long) { // Test encoding byte by byte, also test encoding in // a single ResumeEncoding() call. - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kLongTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kLongTestData); ++i) { std::string expected_encoding = Http2HexDecode(kLongTestData[i].expected_encoding); @@ -130,7 +130,7 @@ struct { // Make sure that the encoder outputs the last byte even when it is zero. This // happens exactly when encoding the value 2^prefix_length - 1. TEST(HpackVarintEncoderTest, LastByteIsZero) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kLastByteIsZeroTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kLastByteIsZeroTestData); ++i) { std::string output; HpackVarintEncoder::Encode(kLastByteIsZeroTestData[i].high_bits, kLastByteIsZeroTestData[i].prefix_length, diff --git a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_round_trip_test.cc b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_round_trip_test.cc index 77e5fe8e451..957683f5b3c 100644 --- a/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_round_trip_test.cc +++ b/chromium/net/third_party/quiche/src/http2/hpack/varint/hpack_varint_round_trip_test.cc @@ -13,13 +13,13 @@ #include <set> #include <vector> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/tools/random_decoder_test.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionSuccess; @@ -292,7 +292,7 @@ TEST_F(HpackVarintRoundTripTest, Encode) { } TEST_F(HpackVarintRoundTripTest, FromSpec1337) { - DecodeBuffer b(quiche::QuicheStringPiece("\x1f\x9a\x0a")); + DecodeBuffer b(absl::string_view("\x1f\x9a\x0a")); uint32_t prefix_length = 5; uint8_t p = b.DecodeUInt8(); EXPECT_EQ(1u, b.Offset()); diff --git a/chromium/net/third_party/quiche/src/http2/http2_constants.cc b/chromium/net/third_party/quiche/src/http2/http2_constants.cc index daed778e718..08351c44b24 100644 --- a/chromium/net/third_party/quiche/src/http2/http2_constants.cc +++ b/chromium/net/third_party/quiche/src/http2/http2_constants.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/http2/http2_constants.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -47,8 +47,7 @@ std::string Http2FrameFlagsToString(Http2FrameType type, uint8_t flags) { std::string s; // Closure to append flag name |v| to the std::string |s|, // and to clear |bit| from |flags|. - auto append_and_clear = [&s, &flags](quiche::QuicheStringPiece v, - uint8_t bit) { + auto append_and_clear = [&s, &flags](absl::string_view v, uint8_t bit) { if (!s.empty()) { s.push_back('|'); } diff --git a/chromium/net/third_party/quiche/src/http2/http2_constants_test.cc b/chromium/net/third_party/quiche/src/http2/http2_constants_test.cc index 389c698ba31..807854e4a21 100644 --- a/chromium/net/third_party/quiche/src/http2/http2_constants_test.cc +++ b/chromium/net/third_party/quiche/src/http2/http2_constants_test.cc @@ -5,12 +5,13 @@ #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { namespace { -class Http2ConstantsTest : public testing::Test {}; +class Http2ConstantsTest : public QuicheTest {}; TEST(Http2ConstantsTest, Http2FrameType) { EXPECT_EQ(Http2FrameType::DATA, static_cast<Http2FrameType>(0)); diff --git a/chromium/net/third_party/quiche/src/http2/http2_structures_test.cc b/chromium/net/third_party/quiche/src/http2/http2_structures_test.cc index 20dd0ec1cdc..6b060cf6e77 100644 --- a/chromium/net/third_party/quiche/src/http2/http2_structures_test.cc +++ b/chromium/net/third_party/quiche/src/http2/http2_structures_test.cc @@ -24,6 +24,7 @@ #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionResult; using ::testing::AssertionSuccess; @@ -151,8 +152,7 @@ TEST(Http2FrameHeaderTest, Eq) { // The tests of the valid frame types include EXPECT_DEBUG_DEATH, which is // quite slow, so using value parameterized tests in order to allow sharding. class Http2FrameHeaderTypeAndFlagTest - : public ::testing::TestWithParam< - std::tuple<Http2FrameType, Http2FrameFlag>> { + : public QuicheTestWithParam<std::tuple<Http2FrameType, Http2FrameFlag>> { protected: Http2FrameHeaderTypeAndFlagTest() : type_(std::get<0>(GetParam())), flags_(std::get<1>(GetParam())) { diff --git a/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils.h b/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils.h index f14d93ae87f..ec421b7efb9 100644 --- a/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils.h +++ b/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils.h @@ -9,8 +9,8 @@ #include <type_traits> #include <utility> +#include "absl/strings/string_view.h" #include "net/http2/platform/impl/http2_string_utils_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { @@ -28,15 +28,15 @@ inline std::string Http2HexEncode(const void* bytes, size_t size) { return Http2HexEncodeImpl(bytes, size); } -inline std::string Http2HexDecode(quiche::QuicheStringPiece data) { +inline std::string Http2HexDecode(absl::string_view data) { return Http2HexDecodeImpl(data); } -inline std::string Http2HexDump(quiche::QuicheStringPiece data) { +inline std::string Http2HexDump(absl::string_view data) { return Http2HexDumpImpl(data); } -inline std::string Http2HexEscape(quiche::QuicheStringPiece data) { +inline std::string Http2HexEscape(absl::string_view data) { return Http2HexEscapeImpl(data); } diff --git a/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils_test.cc b/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils_test.cc index bff55ccd541..5cb019d2637 100644 --- a/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils_test.cc +++ b/chromium/net/third_party/quiche/src/http2/platform/api/http2_string_utils_test.cc @@ -6,9 +6,9 @@ #include <cstdint> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -23,7 +23,7 @@ TEST(Http2StringUtilsTest, Http2StrAppend) { // Single string-like argument. const char kFoo[] = "foo"; const std::string string_foo(kFoo); - const quiche::QuicheStringPiece stringpiece_foo(string_foo); + const absl::string_view stringpiece_foo(string_foo); Http2StrAppend(&output, kFoo); EXPECT_EQ("foo", output); Http2StrAppend(&output, string_foo); @@ -39,7 +39,7 @@ TEST(Http2StringUtilsTest, Http2StrAppend) { // Two string-like arguments. const char kBar[] = "bar"; - const quiche::QuicheStringPiece stringpiece_bar(kBar); + const absl::string_view stringpiece_bar(kBar); const std::string string_bar(kBar); Http2StrAppend(&output, kFoo, kBar); EXPECT_EQ("foobar", output); diff --git a/chromium/net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h b/chromium/net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h index 4a616f7f6ab..107b49b1170 100644 --- a/chromium/net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h +++ b/chromium/net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h @@ -5,13 +5,7 @@ // an AssertionResult if the condition is not satisfied. #include "net/http2/platform/impl/http2_test_helpers_impl.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" - -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" // For AssertionSuccess - -#pragma clang diagnostic pop +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #define VERIFY_AND_RETURN_SUCCESS(expression) \ { \ diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.cc b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.cc index 7d5c2180b23..bb975e26d89 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.cc +++ b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.cc @@ -6,12 +6,11 @@ #include <type_traits> -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/http2_structures_test_util.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; @@ -52,14 +51,14 @@ FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) { } FrameParts::FrameParts(const Http2FrameHeader& header, - quiche::QuicheStringPiece payload) + absl::string_view payload) : FrameParts(header) { HTTP2_VLOG(1) << "FrameParts with payload.size() = " << payload.size(); this->payload_.append(payload.data(), payload.size()); opt_payload_length_ = payload.size(); } FrameParts::FrameParts(const Http2FrameHeader& header, - quiche::QuicheStringPiece payload, + absl::string_view payload, size_t total_pad_length) : FrameParts(header, payload) { HTTP2_VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length; @@ -118,8 +117,8 @@ void FrameParts::SetTotalPadLength(size_t total_pad_length) { } } -void FrameParts::SetAltSvcExpected(quiche::QuicheStringPiece origin, - quiche::QuicheStringPiece value) { +void FrameParts::SetAltSvcExpected(absl::string_view origin, + absl::string_view value) { altsvc_origin_.append(origin.data(), origin.size()); altsvc_value_.append(value.data(), value.size()); opt_altsvc_origin_length_ = origin.size(); @@ -141,7 +140,7 @@ void FrameParts::OnDataPayload(const char* data, size_t len) { HTTP2_VLOG(1) << "OnDataPayload: len=" << len << "; frame_header_: " << frame_header_; ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this; - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), &payload_, + ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_, &opt_payload_length_)); } @@ -173,7 +172,7 @@ void FrameParts::OnHpackFragment(const char* data, size_t len) { ASSERT_TRUE(got_start_callback_); ASSERT_FALSE(got_end_callback_); ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this; - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), &payload_, + ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_, &opt_payload_length_)); } @@ -217,8 +216,8 @@ void FrameParts::OnPadding(const char* pad, size_t skipped_length) { HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length; ASSERT_TRUE(InPaddedFrame()) << *this; ASSERT_TRUE(opt_pad_length_); - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(pad, skipped_length), - &padding_, &opt_pad_length_)); + ASSERT_TRUE(AppendString(absl::string_view(pad, skipped_length), &padding_, + &opt_pad_length_)); } void FrameParts::OnRstStream(const Http2FrameHeader& header, @@ -314,7 +313,7 @@ void FrameParts::OnGoAwayStart(const Http2FrameHeader& header, void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) { HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len; ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this; - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), &payload_, + ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_, &opt_payload_length_)); } @@ -349,14 +348,14 @@ void FrameParts::OnAltSvcStart(const Http2FrameHeader& header, void FrameParts::OnAltSvcOriginData(const char* data, size_t len) { HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len; ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), - &altsvc_origin_, &opt_altsvc_origin_length_)); + ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_origin_, + &opt_altsvc_origin_length_)); } void FrameParts::OnAltSvcValueData(const char* data, size_t len) { HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len; ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), &altsvc_value_, + ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_value_, &opt_altsvc_value_length_)); } @@ -379,7 +378,7 @@ void FrameParts::OnUnknownPayload(const char* data, size_t len) { ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this; ASSERT_TRUE(got_start_callback_); ASSERT_FALSE(got_end_callback_); - ASSERT_TRUE(AppendString(quiche::QuicheStringPiece(data, len), &payload_, + ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_, &opt_payload_length_)); } @@ -507,10 +506,9 @@ AssertionResult FrameParts::InPaddedFrame() { return AssertionSuccess(); } -AssertionResult FrameParts::AppendString( - quiche::QuicheStringPiece source, - std::string* target, - quiche::QuicheOptional<size_t>* opt_length) { +AssertionResult FrameParts::AppendString(absl::string_view source, + std::string* target, + absl::optional<size_t>* opt_length) { target->append(source.data(), source.size()); if (opt_length != nullptr) { VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this; diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.h b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.h index bd6d939a57a..349d499cbc9 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.h +++ b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts.h @@ -16,13 +16,13 @@ #include <string> #include <vector> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/http2_structures.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -34,12 +34,12 @@ class FrameParts : public Http2FrameDecoderListener { explicit FrameParts(const Http2FrameHeader& header); // For use in tests where the expected frame has a variable size payload. - FrameParts(const Http2FrameHeader& header, quiche::QuicheStringPiece payload); + FrameParts(const Http2FrameHeader& header, absl::string_view payload); // For use in tests where the expected frame has a variable size payload // and may be padded. FrameParts(const Http2FrameHeader& header, - quiche::QuicheStringPiece payload, + absl::string_view payload, size_t total_pad_length); // Copy constructor. @@ -58,8 +58,7 @@ class FrameParts : public Http2FrameDecoderListener { void SetTotalPadLength(size_t total_pad_length); // Set the origin and value expected in an ALTSVC frame. - void SetAltSvcExpected(quiche::QuicheStringPiece origin, - quiche::QuicheStringPiece value); + void SetAltSvcExpected(absl::string_view origin, absl::string_view value); // Http2FrameDecoderListener methods: bool OnFrameHeader(const Http2FrameHeader& header) override; @@ -115,78 +114,70 @@ class FrameParts : public Http2FrameDecoderListener { const Http2FrameHeader& GetFrameHeader() const { return frame_header_; } - quiche::QuicheOptional<Http2PriorityFields> GetOptPriority() const { + absl::optional<Http2PriorityFields> GetOptPriority() const { return opt_priority_; } - quiche::QuicheOptional<Http2ErrorCode> GetOptRstStreamErrorCode() const { + absl::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const { return opt_rst_stream_error_code_; } - quiche::QuicheOptional<Http2PushPromiseFields> GetOptPushPromise() const { + absl::optional<Http2PushPromiseFields> GetOptPushPromise() const { return opt_push_promise_; } - quiche::QuicheOptional<Http2PingFields> GetOptPing() const { - return opt_ping_; - } - quiche::QuicheOptional<Http2GoAwayFields> GetOptGoaway() const { - return opt_goaway_; - } - quiche::QuicheOptional<size_t> GetOptPadLength() const { - return opt_pad_length_; - } - quiche::QuicheOptional<size_t> GetOptPayloadLength() const { + absl::optional<Http2PingFields> GetOptPing() const { return opt_ping_; } + absl::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; } + absl::optional<size_t> GetOptPadLength() const { return opt_pad_length_; } + absl::optional<size_t> GetOptPayloadLength() const { return opt_payload_length_; } - quiche::QuicheOptional<size_t> GetOptMissingLength() const { + absl::optional<size_t> GetOptMissingLength() const { return opt_missing_length_; } - quiche::QuicheOptional<size_t> GetOptAltsvcOriginLength() const { + absl::optional<size_t> GetOptAltsvcOriginLength() const { return opt_altsvc_origin_length_; } - quiche::QuicheOptional<size_t> GetOptAltsvcValueLength() const { + absl::optional<size_t> GetOptAltsvcValueLength() const { return opt_altsvc_value_length_; } - quiche::QuicheOptional<size_t> GetOptWindowUpdateIncrement() const { + absl::optional<size_t> GetOptWindowUpdateIncrement() const { return opt_window_update_increment_; } bool GetHasFrameSizeError() const { return has_frame_size_error_; } - void SetOptPriority( - quiche::QuicheOptional<Http2PriorityFields> opt_priority) { + void SetOptPriority(absl::optional<Http2PriorityFields> opt_priority) { opt_priority_ = opt_priority; } void SetOptRstStreamErrorCode( - quiche::QuicheOptional<Http2ErrorCode> opt_rst_stream_error_code) { + absl::optional<Http2ErrorCode> opt_rst_stream_error_code) { opt_rst_stream_error_code_ = opt_rst_stream_error_code; } void SetOptPushPromise( - quiche::QuicheOptional<Http2PushPromiseFields> opt_push_promise) { + absl::optional<Http2PushPromiseFields> opt_push_promise) { opt_push_promise_ = opt_push_promise; } - void SetOptPing(quiche::QuicheOptional<Http2PingFields> opt_ping) { + void SetOptPing(absl::optional<Http2PingFields> opt_ping) { opt_ping_ = opt_ping; } - void SetOptGoaway(quiche::QuicheOptional<Http2GoAwayFields> opt_goaway) { + void SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway) { opt_goaway_ = opt_goaway; } - void SetOptPadLength(quiche::QuicheOptional<size_t> opt_pad_length) { + void SetOptPadLength(absl::optional<size_t> opt_pad_length) { opt_pad_length_ = opt_pad_length; } - void SetOptPayloadLength(quiche::QuicheOptional<size_t> opt_payload_length) { + void SetOptPayloadLength(absl::optional<size_t> opt_payload_length) { opt_payload_length_ = opt_payload_length; } - void SetOptMissingLength(quiche::QuicheOptional<size_t> opt_missing_length) { + void SetOptMissingLength(absl::optional<size_t> opt_missing_length) { opt_missing_length_ = opt_missing_length; } void SetOptAltsvcOriginLength( - quiche::QuicheOptional<size_t> opt_altsvc_origin_length) { + absl::optional<size_t> opt_altsvc_origin_length) { opt_altsvc_origin_length_ = opt_altsvc_origin_length; } - void SetOptAltsvcValueLength( - quiche::QuicheOptional<size_t> opt_altsvc_value_length) { + void SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length) { opt_altsvc_value_length_ = opt_altsvc_value_length; } void SetOptWindowUpdateIncrement( - quiche::QuicheOptional<size_t> opt_window_update_increment) { + absl::optional<size_t> opt_window_update_increment) { opt_window_update_increment_ = opt_window_update_increment; } @@ -216,10 +207,9 @@ class FrameParts : public Http2FrameDecoderListener { // Append source to target. If opt_length is not nullptr, then verifies that // the optional has a value (i.e. that the necessary On*Start method has been // called), and that target is not longer than opt_length->value(). - ::testing::AssertionResult AppendString( - quiche::QuicheStringPiece source, - std::string* target, - quiche::QuicheOptional<size_t>* opt_length); + ::testing::AssertionResult AppendString(absl::string_view source, + std::string* target, + absl::optional<size_t>* opt_length); const Http2FrameHeader frame_header_; @@ -228,19 +218,19 @@ class FrameParts : public Http2FrameDecoderListener { std::string altsvc_origin_; std::string altsvc_value_; - quiche::QuicheOptional<Http2PriorityFields> opt_priority_; - quiche::QuicheOptional<Http2ErrorCode> opt_rst_stream_error_code_; - quiche::QuicheOptional<Http2PushPromiseFields> opt_push_promise_; - quiche::QuicheOptional<Http2PingFields> opt_ping_; - quiche::QuicheOptional<Http2GoAwayFields> opt_goaway_; + absl::optional<Http2PriorityFields> opt_priority_; + absl::optional<Http2ErrorCode> opt_rst_stream_error_code_; + absl::optional<Http2PushPromiseFields> opt_push_promise_; + absl::optional<Http2PingFields> opt_ping_; + absl::optional<Http2GoAwayFields> opt_goaway_; - quiche::QuicheOptional<size_t> opt_pad_length_; - quiche::QuicheOptional<size_t> opt_payload_length_; - quiche::QuicheOptional<size_t> opt_missing_length_; - quiche::QuicheOptional<size_t> opt_altsvc_origin_length_; - quiche::QuicheOptional<size_t> opt_altsvc_value_length_; + absl::optional<size_t> opt_pad_length_; + absl::optional<size_t> opt_payload_length_; + absl::optional<size_t> opt_missing_length_; + absl::optional<size_t> opt_altsvc_origin_length_; + absl::optional<size_t> opt_altsvc_value_length_; - quiche::QuicheOptional<size_t> opt_window_update_increment_; + absl::optional<size_t> opt_window_update_increment_; bool has_frame_size_error_ = false; diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector.cc b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector.cc index 083bbe1bc6b..b5fdcb79c18 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector.cc +++ b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector.cc @@ -6,9 +6,9 @@ #include <utility> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/http2_structures_test_util.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.cc b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.cc index a7c3eccb171..3969b5b24e6 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.cc +++ b/chromium/net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/http2/test_tools/frame_parts_collector_listener.h" -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.cc b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.cc index df2036475ec..5fb2f7d3b5d 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.cc +++ b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.cc @@ -16,7 +16,7 @@ Http2Random::Http2Random() { HTTP2_LOG(INFO) << "Initialized test RNG with the following key: " << Key(); } -Http2Random::Http2Random(quiche::QuicheStringPiece key) { +Http2Random::Http2Random(absl::string_view key) { std::string decoded_key = Http2HexDecode(key); CHECK_EQ(sizeof(key_), decoded_key.size()); memcpy(key_, decoded_key.data(), sizeof(key_)); @@ -58,9 +58,8 @@ double Http2Random::RandDouble() { return value.f - 1.0; } -std::string Http2Random::RandStringWithAlphabet( - int length, - quiche::QuicheStringPiece alphabet) { +std::string Http2Random::RandStringWithAlphabet(int length, + absl::string_view alphabet) { std::string result; result.resize(length); for (int i = 0; i < length; i++) { diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.h b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.h index 9f046a1c300..4fe2a51fd49 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.h +++ b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random.h @@ -11,7 +11,7 @@ #include <random> #include <string> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace http2 { namespace test { @@ -28,7 +28,7 @@ class Http2Random { // Reproducible random number generation: by using the same key, the same // sequence of results is obtained. - explicit Http2Random(quiche::QuicheStringPiece key); + explicit Http2Random(absl::string_view key); std::string Key() const; void FillRandom(void* buffer, size_t buffer_size); @@ -67,8 +67,7 @@ class Http2Random { // Return a random string consisting of the characters from the specified // alphabet. - std::string RandStringWithAlphabet(int length, - quiche::QuicheStringPiece alphabet); + std::string RandStringWithAlphabet(int length, absl::string_view alphabet); // STL UniformRandomNumberGenerator implementation. using result_type = uint64_t; diff --git a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random_test.cc b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random_test.cc index c9490bdb2ba..55d627fb517 100644 --- a/chromium/net/third_party/quiche/src/http2/test_tools/http2_random_test.cc +++ b/chromium/net/third_party/quiche/src/http2/test_tools/http2_random_test.cc @@ -2,8 +2,7 @@ #include <set> -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { diff --git a/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.cc b/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.cc index 1f1af169551..2ba87788989 100644 --- a/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.cc +++ b/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.cc @@ -11,8 +11,8 @@ #include <netinet/in.h> // for htonl, htons #endif -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -30,12 +30,12 @@ Http2FrameBuilder::Http2FrameBuilder(const Http2FrameHeader& v) { Append(v); } -void Http2FrameBuilder::Append(quiche::QuicheStringPiece s) { +void Http2FrameBuilder::Append(absl::string_view s) { Http2StrAppend(&buffer_, s); } void Http2FrameBuilder::AppendBytes(const void* data, uint32_t num_bytes) { - Append(quiche::QuicheStringPiece(static_cast<const char*>(data), num_bytes)); + Append(absl::string_view(static_cast<const char*>(data), num_bytes)); } void Http2FrameBuilder::AppendZeroes(size_t num_zero_bytes) { @@ -143,7 +143,7 @@ void Http2FrameBuilder::Append(const Http2AltSvcFields& v) { // Methods for changing existing buffer contents. -void Http2FrameBuilder::WriteAt(quiche::QuicheStringPiece s, size_t offset) { +void Http2FrameBuilder::WriteAt(absl::string_view s, size_t offset) { ASSERT_LE(offset, buffer_.size()); size_t len = offset + s.size(); if (len > buffer_.size()) { @@ -157,8 +157,7 @@ void Http2FrameBuilder::WriteAt(quiche::QuicheStringPiece s, size_t offset) { void Http2FrameBuilder::WriteBytesAt(const void* data, uint32_t num_bytes, size_t offset) { - WriteAt(quiche::QuicheStringPiece(static_cast<const char*>(data), num_bytes), - offset); + WriteAt(absl::string_view(static_cast<const char*>(data), num_bytes), offset); } void Http2FrameBuilder::WriteUInt24At(uint32_t value, size_t offset) { diff --git a/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.h b/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.h index 724c2b2e15e..a4062ded488 100644 --- a/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.h +++ b/chromium/net/third_party/quiche/src/http2/tools/http2_frame_builder.h @@ -18,9 +18,9 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/http2_structures.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace http2 { namespace test { @@ -39,7 +39,7 @@ class Http2FrameBuilder { // Methods for appending to the end of the buffer. // Append a sequence of bytes from various sources. - void Append(quiche::QuicheStringPiece s); + void Append(absl::string_view s); void AppendBytes(const void* data, uint32_t num_bytes); // Append an array of type T[N] to the string. Intended for tests with arrays @@ -80,7 +80,7 @@ class Http2FrameBuilder { // Methods for changing existing buffer contents (mostly focused on updating // the payload length). - void WriteAt(quiche::QuicheStringPiece s, size_t offset); + void WriteAt(absl::string_view s, size_t offset); void WriteBytesAt(const void* data, uint32_t num_bytes, size_t offset); void WriteUInt24At(uint32_t value, size_t offset); diff --git a/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.cc b/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.cc index 5842bd089e7..4c7d71ab5d6 100644 --- a/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.cc @@ -9,12 +9,12 @@ #include <algorithm> #include <memory> -#include "testing/gtest/include/gtest/gtest.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" using ::testing::AssertionFailure; using ::testing::AssertionResult; diff --git a/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.h b/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.h index 60a9081f3da..4e87c49ea1b 100644 --- a/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.h +++ b/chromium/net/third_party/quiche/src/http2/tools/random_decoder_test.h @@ -17,13 +17,13 @@ #include <memory> #include <type_traits> -#include "testing/gtest/include/gtest/gtest.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace http2 { namespace test { @@ -31,9 +31,8 @@ namespace test { // Some helpers. template <typename T, size_t N> -quiche::QuicheStringPiece ToStringPiece(T (&data)[N]) { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(data), - N * sizeof(T)); +absl::string_view ToStringPiece(T (&data)[N]) { + return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T)); } // Overwrite the enum with some random value, probably not a valid value for @@ -55,7 +54,7 @@ void CorruptEnum(T* out, Http2Random* rng) { // Base class for tests of the ability to decode a sequence of bytes with // various boundaries between the DecodeBuffers provided to the decoder. -class RandomDecoderTest : public ::testing::Test { +class RandomDecoderTest : public QuicheTest { public: // SelectSize returns the size of the next DecodeBuffer to be passed to the // decoder. Note that RandomDecoderTest allows that size to be zero, though diff --git a/chromium/net/third_party/quiche/src/http2/tools/random_util.cc b/chromium/net/third_party/quiche/src/http2/tools/random_util.cc index a0af07a4eae..01571ed2780 100644 --- a/chromium/net/third_party/quiche/src/http2/tools/random_util.cc +++ b/chromium/net/third_party/quiche/src/http2/tools/random_util.cc @@ -12,7 +12,7 @@ namespace test { // Here "word" means something that starts with a lower-case letter, and has // zero or more additional characters that are numbers or lower-case letters. std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng) { - quiche::QuicheStringPiece alpha_lc = "abcdefghijklmnopqrstuvwxyz"; + absl::string_view alpha_lc = "abcdefghijklmnopqrstuvwxyz"; // If the name is short, just make it one word. if (len < 8) { return rng->RandStringWithAlphabet(len, alpha_lc); @@ -20,8 +20,7 @@ std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng) { // If the name is longer, ensure it starts with a word, and after that may // have any character in alphanumdash_lc. 4 is arbitrary, could be as low // as 1. - quiche::QuicheStringPiece alphanumdash_lc = - "abcdefghijklmnopqrstuvwxyz0123456789-"; + absl::string_view alphanumdash_lc = "abcdefghijklmnopqrstuvwxyz0123456789-"; return rng->RandStringWithAlphabet(4, alpha_lc) + rng->RandStringWithAlphabet(len - 4, alphanumdash_lc); } diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h index b55e63c1147..88183f366b3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h +++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h @@ -5,10 +5,10 @@ #ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_ #define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_ +#include "absl/base/optimization.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h" #include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" @@ -86,7 +86,7 @@ class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer { // Whether the invariants of the buffer are upheld. For debug & test only. bool Invariants() const; const char* buffer_end() const { return buffer_ + sizeof(buffer_); } - QUIC_CACHELINE_ALIGNED char buffer_[kBufferSize]; + ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize]; QuicCircularDeque<BufferedWrite> buffered_writes_; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h index 26a728e676a..3b80395412a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h +++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h @@ -25,7 +25,7 @@ class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter { FlushImplResult FlushImpl() override; protected: - typedef QuicMMsgHdr::ControlBufferInitializer CmsgBuilder; + using CmsgBuilder = QuicMMsgHdr::ControlBufferInitializer; FlushImplResult InternalFlushImpl(size_t cmsg_space, const CmsgBuilder& cmsg_builder); }; diff --git a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc index 1605b264c63..851967a977f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc +++ b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc @@ -4,6 +4,8 @@ #include "net/third_party/quiche/src/quic/core/chlo_extractor.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" @@ -14,7 +16,6 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -39,10 +40,9 @@ class ChloFramerVisitor : public QuicFramerVisitorInterface, const QuicVersionNegotiationPacket& /*packet*/) override {} void OnRetryPacket(QuicConnectionId /*original_connection_id*/, QuicConnectionId /*new_connection_id*/, - quiche::QuicheStringPiece /*retry_token*/, - quiche::QuicheStringPiece /*retry_integrity_tag*/, - quiche::QuicheStringPiece /*retry_without_tag*/) override { - } + absl::string_view /*retry_token*/, + absl::string_view /*retry_integrity_tag*/, + absl::string_view /*retry_without_tag*/) override {} bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override; bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override; void OnDecryptedPacket(EncryptionLevel /*level*/) override {} @@ -83,13 +83,18 @@ class ChloFramerVisitor : public QuicFramerVisitorInterface, bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override; + void OnDecryptedFirstPacketInKeyPhase() override; + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override; + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; // CryptoFramerVisitorInterface implementation. void OnError(CryptoFramer* framer) override; void OnHandshakeMessage(const CryptoHandshakeMessage& message) override; // Shared implementation between OnStreamFrame and OnCryptoFrame. - bool OnHandshakeData(quiche::QuicheStringPiece data); + bool OnHandshakeData(absl::string_view data); bool found_chlo() { return found_chlo_; } bool chlo_contains_tags() { return chlo_contains_tags_; } @@ -153,10 +158,10 @@ bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) { // CHLO will be sent in CRYPTO frames in v47 and above. return false; } - quiche::QuicheStringPiece data(frame.data_buffer, frame.data_length); + absl::string_view data(frame.data_buffer, frame.data_length); if (QuicUtils::IsCryptoStreamId(framer_->transport_version(), frame.stream_id) && - frame.offset == 0 && quiche::QuicheTextUtils::StartsWith(data, "CHLO")) { + frame.offset == 0 && absl::StartsWith(data, "CHLO")) { return OnHandshakeData(data); } return true; @@ -167,14 +172,14 @@ bool ChloFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& frame) { // CHLO will be in stream frames before v47. return false; } - quiche::QuicheStringPiece data(frame.data_buffer, frame.data_length); - if (frame.offset == 0 && quiche::QuicheTextUtils::StartsWith(data, "CHLO")) { + absl::string_view data(frame.data_buffer, frame.data_length); + if (frame.offset == 0 && absl::StartsWith(data, "CHLO")) { return OnHandshakeData(data); } return true; } -bool ChloFramerVisitor::OnHandshakeData(quiche::QuicheStringPiece data) { +bool ChloFramerVisitor::OnHandshakeData(absl::string_view data) { CryptoFramer crypto_framer; crypto_framer.set_visitor(this); if (!crypto_framer.ProcessInput(data)) { @@ -311,6 +316,20 @@ bool ChloFramerVisitor::OnStreamsBlockedFrame( return true; } +void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {} + +void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {} + +std::unique_ptr<QuicDecrypter> +ChloFramerVisitor::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + return nullptr; +} + +std::unique_ptr<QuicEncrypter> +ChloFramerVisitor::CreateCurrentOneRttEncrypter() { + return nullptr; +} + void ChloFramerVisitor::OnError(CryptoFramer* /*framer*/) {} void ChloFramerVisitor::OnHandshakeMessage( diff --git a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc index 1b6a6164234..f051b9a821f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/chlo_extractor_test.cc @@ -8,14 +8,14 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/first_flight.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -33,7 +33,7 @@ class TestDelegate : public ChloExtractor::Delegate { version_ = version; connection_id_ = connection_id; chlo_ = chlo.DebugString(); - quiche::QuicheStringPiece alpn_value; + absl::string_view alpn_value; if (chlo.GetStringPiece(kALPN, &alpn_value)) { alpn_ = std::string(alpn_value); } @@ -55,7 +55,7 @@ class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> { public: ChloExtractorTest() : version_(GetParam()) {} - void MakePacket(quiche::QuicheStringPiece data, + void MakePacket(absl::string_view data, bool munge_offset, bool munge_stream_id) { QuicPacketHeader header; @@ -95,7 +95,7 @@ class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> { EXPECT_TRUE(packet != nullptr); size_t encrypted_length = framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet, - buffer_, QUICHE_ARRAYSIZE(buffer_)); + buffer_, ABSL_ARRAYSIZE(buffer_)); ASSERT_NE(0u, encrypted_length); packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length); EXPECT_TRUE(packet_ != nullptr); diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h index f32eabf0694..2d06560f2bc 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h @@ -129,11 +129,10 @@ class QUIC_EXPORT_PRIVATE MaxAckHeightTracker { private: // Tracks the maximum number of bytes acked faster than the estimated // bandwidth. - typedef WindowedFilter<QuicByteCount, - MaxFilter<QuicByteCount>, - QuicRoundTripCount, - QuicRoundTripCount> - MaxAckHeightFilter; + using MaxAckHeightFilter = WindowedFilter<QuicByteCount, + MaxFilter<QuicByteCount>, + QuicRoundTripCount, + QuicRoundTripCount>; MaxAckHeightFilter max_ack_height_filter_; // The time this aggregation started and the number of bytes acked during it. diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc index 605318589e3..3e3937a4e52 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc @@ -148,6 +148,18 @@ void Bbr2NetworkModel::OnCongestionEventStart( loss_events_in_round_++; } + if (GetQuicReloadableFlag(quic_bbr2_startup_loss_exit_use_max_delivered) && + congestion_event->bytes_acked > 0 && + congestion_event->last_packet_send_state.is_valid && + total_bytes_acked() > + congestion_event->last_packet_send_state.total_bytes_acked) { + QuicByteCount bytes_delivered = + total_bytes_acked() - + congestion_event->last_packet_send_state.total_bytes_acked; + max_bytes_delivered_in_round_ = + std::max(max_bytes_delivered_in_round_, bytes_delivered); + } + // |bandwidth_latest_| and |inflight_latest_| only increased within a round. if (sample.sample_max_bandwidth > bandwidth_latest_) { bandwidth_latest_ = sample.sample_max_bandwidth; @@ -243,21 +255,29 @@ bool Bbr2NetworkModel::IsCongestionWindowLimited( } bool Bbr2NetworkModel::IsInflightTooHigh( - const Bbr2CongestionEvent& congestion_event) const { + const Bbr2CongestionEvent& congestion_event, + int64_t max_loss_events) const { const SendTimeState& send_state = congestion_event.last_packet_send_state; if (!send_state.is_valid) { // Not enough information. return false; } + if (loss_events_in_round() < max_loss_events) { + return false; + } + const QuicByteCount inflight_at_send = BytesInFlight(send_state); // TODO(wub): Consider total_bytes_lost() - send_state.total_bytes_lost, which // is the total bytes lost when the largest numbered packet was inflight. // bytes_lost_in_round_, OTOH, is the total bytes lost in the "current" round. const QuicByteCount bytes_lost_in_round = bytes_lost_in_round_; - QUIC_DVLOG(3) << "IsInflightTooHigh: bytes_lost_in_round:" - << bytes_lost_in_round << ", lost_in_round_threshold:" + QUIC_DVLOG(3) << "IsInflightTooHigh: loss_events_in_round:" + << loss_events_in_round() + + << " bytes_lost_in_round:" << bytes_lost_in_round + << ", lost_in_round_threshold:" << inflight_at_send * Params().loss_threshold; if (inflight_at_send > 0 && bytes_lost_in_round > 0) { @@ -274,6 +294,9 @@ bool Bbr2NetworkModel::IsInflightTooHigh( void Bbr2NetworkModel::RestartRound() { bytes_lost_in_round_ = 0; loss_events_in_round_ = 0; + if (GetQuicReloadableFlag(quic_bbr2_startup_loss_exit_use_max_delivered)) { + max_bytes_delivered_in_round_ = 0; + } round_trip_counter_.RestartRound(); } diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h index 8732118049e..1109e08c673 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h @@ -76,8 +76,8 @@ struct QUIC_EXPORT_PRIVATE Bbr2Params { */ // The gain for both CWND and PacingRate at startup. + float startup_cwnd_gain = 2.0; // TODO(wub): Maybe change to the newly derived value of 2.773 (4 * ln(2)). - float startup_cwnd_gain = 2.885; float startup_pacing_gain = 2.885; // Full bandwidth is declared if the total bandwidth growth is less than @@ -91,10 +91,14 @@ struct QUIC_EXPORT_PRIVATE Bbr2Params { int64_t startup_full_loss_count = GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count); + // If true, always exit STARTUP on loss, even if bandwidth exceeds threshold. + // If false, exit STARTUP on loss only if bandwidth is below threshold. + bool always_exit_startup_on_excess_loss = true; + /* * DRAIN parameters. */ - float drain_cwnd_gain = 2.885; + float drain_cwnd_gain = 2.0; float drain_pacing_gain = 1.0 / 2.885; /* @@ -167,10 +171,6 @@ struct QUIC_EXPORT_PRIVATE Bbr2Params { * Experimental flags from QuicConfig. */ - // Indicates app-limited calls should be ignored as long as there's - // enough data inflight to see more bandwidth when necessary. - bool flexible_app_limited = false; - // Can be disabled by connection option 'B2NA'. bool add_ack_height_to_queueing_threshold = true; @@ -184,8 +184,11 @@ struct QUIC_EXPORT_PRIVATE Bbr2Params { // Can be enabled by connection option 'B2LO'. bool ignore_inflight_lo = false; - // Can be enabled by connection optoin 'B2HI'. - bool limit_inflight_hi_by_cwnd = false; + // Can be enabled by connection option 'B2H2'. + bool limit_inflight_hi_by_max_delivered = false; + + // Can be enabled by connection option 'B2SL'. + bool startup_loss_exit_use_max_delivered_for_inflight_hi = false; }; class QUIC_EXPORT_PRIVATE RoundTripCounter { @@ -392,9 +395,10 @@ class QUIC_EXPORT_PRIVATE Bbr2NetworkModel { bool IsCongestionWindowLimited( const Bbr2CongestionEvent& congestion_event) const; - // TODO(wub): Replace this by a new version which takes two thresholds, one - // is the number of loss events, the other is the percentage of bytes lost. - bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event) const; + // Return true if the number of loss events exceeds max_loss_events and + // fraction of bytes lost exceed the loss threshold. + bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event, + int64_t max_loss_events) const; QuicPacketNumber last_sent_packet() const { return round_trip_counter_.last_sent_packet(); @@ -414,6 +418,10 @@ class QUIC_EXPORT_PRIVATE Bbr2NetworkModel { int64_t loss_events_in_round() const { return loss_events_in_round_; } + QuicByteCount max_bytes_delivered_in_round() const { + return max_bytes_delivered_in_round_; + } + QuicPacketNumber end_of_app_limited_phase() const { return bandwidth_sampler_.end_of_app_limited_phase(); } @@ -466,6 +474,12 @@ class QUIC_EXPORT_PRIVATE Bbr2NetworkModel { // Number of loss marking events in the current round. int64_t loss_events_in_round_ = 0; + // A max of bytes delivered among all congestion events in the current round. + // A congestions event's bytes delivered is the total bytes acked between time + // Ts and Ta, which is the time when the largest acked packet(within the + // congestion event) was sent and acked, respectively. + QuicByteCount max_bytes_delivered_in_round_ = 0; + // Max bandwidth in the current round. Updated once per congestion event. QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero(); // Max bandwidth of recent rounds. Updated once per round. diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc index 172911817aa..0b8991cb86b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc @@ -199,10 +199,8 @@ Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds( return NOT_ADAPTED_INVALID_SAMPLE; } - const bool has_enough_loss_events = - model_->loss_events_in_round() >= Params().probe_bw_full_loss_count; - - if (has_enough_loss_events && model_->IsInflightTooHigh(congestion_event)) { + if (model_->IsInflightTooHigh(congestion_event, + Params().probe_bw_full_loss_count)) { if (cycle_.is_sample_from_probing) { cycle_.is_sample_from_probing = false; @@ -218,17 +216,24 @@ Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds( // The new code actually cuts inflight_hi slower than before. QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect); } - if (Params().limit_inflight_hi_by_cwnd) { - const QuicByteCount cwnd_target = - sender_->GetCongestionWindow() * (1.0 - Params().beta); - if (inflight_at_send >= cwnd_target) { - // The new code does not change behavior. - QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_cwnd_noop); + if (Params().limit_inflight_hi_by_max_delivered) { + QuicByteCount new_inflight_hi = + std::max(inflight_at_send, inflight_target); + if (new_inflight_hi >= model_->max_bytes_delivered_in_round()) { + QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_noop); } else { - // The new code actually cuts inflight_hi slower than before. - QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_cwnd_in_effect); + QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_in_effect); + new_inflight_hi = model_->max_bytes_delivered_in_round(); } - model_->set_inflight_hi(std::max(inflight_at_send, cwnd_target)); + QUIC_DVLOG(3) << sender_ + << " Setting inflight_hi due to loss. new_inflight_hi:" + << new_inflight_hi + << ", inflight_at_send:" << inflight_at_send + << ", inflight_target:" << inflight_target + << ", max_bytes_delivered_in_round:" + << model_->max_bytes_delivered_in_round() << " @ " + << congestion_event.event_time; + model_->set_inflight_hi(new_inflight_hi); } else { model_->set_inflight_hi(std::max(inflight_at_send, inflight_target)); } diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc index fe32835fb8f..c3abffec147 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc @@ -11,6 +11,7 @@ #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" +#include "net/third_party/quiche/src/quic/core/quic_tag.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" @@ -99,9 +100,6 @@ Bbr2Sender::Bbr2Sender(QuicTime now, void Bbr2Sender::SetFromConfig(const QuicConfig& config, Perspective perspective) { - if (config.HasClientRequestedIndependentOption(kBBR9, perspective)) { - params_.flexible_app_limited = true; - } if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) { params_.add_ack_height_to_queueing_threshold = false; } @@ -125,16 +123,16 @@ void Bbr2Sender::SetFromConfig(const QuicConfig& config, if (config.HasClientRequestedIndependentOption(kB2LO, perspective)) { params_.ignore_inflight_lo = true; } - if (GetQuicReloadableFlag(quic_bbr2_limit_inflight_hi) && - config.HasClientRequestedIndependentOption(kB2HI, perspective)) { - QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_limit_inflight_hi); - params_.limit_inflight_hi_by_cwnd = true; - } if (GetQuicReloadableFlag(quic_bbr2_use_tcp_inflight_hi_headroom) && config.HasClientRequestedIndependentOption(kB2HR, perspective)) { QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_use_tcp_inflight_hi_headroom); params_.inflight_hi_headroom = 0.15; } + if (GetQuicReloadableFlag(quic_bbr2_support_max_bootstrap_cwnd) && + config.HasClientRequestedIndependentOption(kICW1, perspective)) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_support_max_bootstrap_cwnd, 1, 4); + max_cwnd_when_network_parameters_adjusted_ = 100 * kDefaultTCPMSS; + } ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective)); } @@ -142,9 +140,22 @@ void Bbr2Sender::SetFromConfig(const QuicConfig& config, void Bbr2Sender::ApplyConnectionOptions( const QuicTagVector& connection_options) { if (ContainsQuicTag(connection_options, kBBQ2)) { - // 2 is the lower, derived gain for CWND. - params_.startup_cwnd_gain = 2; - params_.drain_cwnd_gain = 2; + params_.startup_cwnd_gain = 2.885; + params_.drain_cwnd_gain = 2.885; + } + if (GetQuicReloadableFlag(quic_bbr2_no_exit_startup_on_loss_with_bw_growth) && + ContainsQuicTag(connection_options, kB2NE)) { + QUIC_RELOADABLE_FLAG_COUNT( + quic_bbr2_no_exit_startup_on_loss_with_bw_growth); + params_.always_exit_startup_on_excess_loss = false; + } + if (GetQuicReloadableFlag(quic_bbr2_startup_loss_exit_use_max_delivered) && + ContainsQuicTag(connection_options, kB2SL)) { + params_.startup_loss_exit_use_max_delivered_for_inflight_hi = true; + } + if (GetQuicReloadableFlag(quic_bbr2_startup_loss_exit_use_max_delivered) && + ContainsQuicTag(connection_options, kB2H2)) { + params_.limit_inflight_hi_by_max_delivered = true; } if (ContainsQuicTag(connection_options, kBSAO)) { model_.EnableOverestimateAvoidance(); @@ -179,7 +190,24 @@ void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) { QuicBandwidth effective_bandwidth = std::max(params.bandwidth, model_.BandwidthEstimate()); - cwnd_ = cwnd_limits().ApplyLimits(model_.BDP(effective_bandwidth)); + connection_stats_->cwnd_bootstrapping_rtt_us = + model_.MinRtt().ToMicroseconds(); + if (GetQuicReloadableFlag(quic_bbr2_support_max_bootstrap_cwnd)) { + if (params.max_initial_congestion_window > 0) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_support_max_bootstrap_cwnd, 2, + 4); + max_cwnd_when_network_parameters_adjusted_ = + params.max_initial_congestion_window * kDefaultTCPMSS; + } else { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_support_max_bootstrap_cwnd, 3, + 4); + } + cwnd_ = cwnd_limits().ApplyLimits( + std::min(max_cwnd_when_network_parameters_adjusted_, + model_.BDP(effective_bandwidth))); + } else { + cwnd_ = cwnd_limits().ApplyLimits(model_.BDP(effective_bandwidth)); + } if (!params.allow_cwnd_to_decrease) { cwnd_ = std::max(cwnd_, prior_cwnd); @@ -371,9 +399,6 @@ void Bbr2Sender::OnApplicationLimited(QuicByteCount bytes_in_flight) { if (bytes_in_flight >= GetCongestionWindow()) { return; } - if (params().flexible_app_limited && IsPipeSufficientlyFull()) { - return; - } model_.OnApplicationLimited(); QUIC_DVLOG(2) << this << " Becoming application limited. Last sent packet: " @@ -409,41 +434,7 @@ void Bbr2Sender::OnExitQuiescence(QuicTime now) { bool Bbr2Sender::ShouldSendProbingPacket() const { // TODO(wub): Implement ShouldSendProbingPacket properly. - if (!BBR2_MODE_DISPATCH(IsProbingForBandwidth())) { - return false; - } - - // TODO(b/77975811): If the pipe is highly under-utilized, consider not - // sending a probing transmission, because the extra bandwidth is not needed. - // If flexible_app_limited is enabled, check if the pipe is sufficiently full. - if (params().flexible_app_limited) { - const bool is_pipe_sufficiently_full = IsPipeSufficientlyFull(); - QUIC_DVLOG(3) << this << " CWND: " << GetCongestionWindow() - << ", inflight: " << unacked_packets_->bytes_in_flight() - << ", pacing_rate: " << PacingRate(0) - << ", flexible_app_limited: true, ShouldSendProbingPacket: " - << !is_pipe_sufficiently_full; - return !is_pipe_sufficiently_full; - } else { - return true; - } -} - -bool Bbr2Sender::IsPipeSufficientlyFull() const { - QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight(); - // See if we need more bytes in flight to see more bandwidth. - if (mode_ == Bbr2Mode::STARTUP) { - // STARTUP exits if it doesn't observe a 25% bandwidth increase, so the CWND - // must be more than 25% above the target. - return bytes_in_flight >= GetTargetCongestionWindow(1.5); - } - if (model_.pacing_gain() > 1) { - // Super-unity PROBE_BW doesn't exit until 1.25 * BDP is achieved. - return bytes_in_flight >= GetTargetCongestionWindow(model_.pacing_gain()); - } - // If bytes_in_flight are above the target congestion window, it should be - // possible to observe the same or more bandwidth if it's available. - return bytes_in_flight >= GetTargetCongestionWindow(1.1); + return BBR2_MODE_DISPATCH(IsProbingForBandwidth()); } std::string Bbr2Sender::GetDebugState() const { diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h index 39964a0ab00..6a83184cc93 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h @@ -160,10 +160,6 @@ class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface { return random_->RandUint64() % max; } - // Returns true if there are enough bytes in flight to ensure more bandwidth - // will be observed if present. - bool IsPipeSufficientlyFull() const; - // Cwnd limits imposed by the current Bbr2 mode. Limits<QuicByteCount> GetCwndLimitsByMode() const; @@ -183,6 +179,10 @@ class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface { // Instead, use params() to get read-only access. Bbr2Params params_; + // Max congestion window when adjusting network parameters. + QuicByteCount max_cwnd_when_network_parameters_adjusted_ = + kMaxInitialCongestionWindow * kDefaultTCPMSS; + Bbr2NetworkModel model_; const QuicByteCount initial_cwnd_; 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 1f5db20c892..f446ab577df 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 @@ -6,6 +6,7 @@ #include <sstream> #include <utility> +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h" #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h" #include "net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h" @@ -27,7 +28,6 @@ #include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/traffic_policer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" using testing::AllOf; @@ -91,7 +91,7 @@ class DefaultTopologyParams { // Network switch queue capacity, in number of BDPs. float switch_queue_capacity_in_bdp = 2; - quiche::QuicheOptional<TrafficPolicerParams> sender_policer_params; + absl::optional<TrafficPolicerParams> sender_policer_params; QuicBandwidth BottleneckBandwidth() const { return std::min(local_link.bandwidth, test_link.bandwidth); @@ -413,6 +413,25 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) { EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f); } +TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2NE) { + SetConnectionOption(kB2NE); + DefaultTopologyParams params; + CreateNetwork(params); + + // Transfer 12MB. + DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35)); + EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT})); + + EXPECT_APPROX_EQ(params.BottleneckBandwidth(), + sender_->ExportDebugState().bandwidth_hi, 0.01f); + + EXPECT_LE(sender_loss_rate_in_packets(), 0.05); + // The margin here is high, because the aggregation greatly increases + // smoothed rtt. + EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt()); + EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f); +} + TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) { DefaultTopologyParams params; params.switch_queue_capacity_in_bdp = 0.5; @@ -426,6 +445,20 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) { EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); } +TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) { + SetConnectionOption(kB2H2); + DefaultTopologyParams params; + params.switch_queue_capacity_in_bdp = 0.5; + CreateNetwork(params); + + DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30)); + EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT})); + EXPECT_APPROX_EQ(params.BottleneckBandwidth(), + sender_->ExportDebugState().bandwidth_hi, 0.02f); + EXPECT_GE(sender_connection_stats().packets_lost, 0u); + EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); +} + TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) { SetConnectionOption(kBSAO); DefaultTopologyParams params; @@ -441,9 +474,9 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) { sender_->ExportDebugState().bandwidth_hi, 0.01f); EXPECT_LE(sender_loss_rate_in_packets(), 0.05); - // The margin here is high, because the aggregation greatly increases - // smoothed rtt. - EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt()); + // The margin here is high, because both link level aggregation and ack + // decimation can greatly increase smoothed rtt. + EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt()); EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f); } @@ -589,10 +622,10 @@ TEST_F(Bbr2DefaultTopologyTest, Drain) { ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode); EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f), sender_->PacingRate(0), 0.01f); - // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer - // with approximately 1.88 BDPs. Here, we use 1.5 to give some margin for - // error. - EXPECT_GE(queue->bytes_queued(), 1.5 * params.BDP()); + + // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with + // approximately 1 BDP. Here, we use 0.95 to give some margin for error. + EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP()); // Observe increased RTT due to bufferbloat. const QuicTime::Delta queueing_delay = @@ -707,6 +740,44 @@ TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) { EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); } +// Test exiting STARTUP earlier upon loss due to loss when connection option +// B2SL is used. +TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) { + SetConnectionOption(kB2SL); + DefaultTopologyParams params; + params.switch_queue_capacity_in_bdp = 0.5; + CreateNetwork(params); + + // Run until the full bandwidth is reached and check how many rounds it was. + sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024); + QuicRoundTripCount max_bw_round = 0; + QuicBandwidth max_bw(QuicBandwidth::Zero()); + bool simulator_result = simulator_.RunUntilOrTimeout( + [this, &max_bw, &max_bw_round]() { + if (max_bw < sender_->ExportDebugState().bandwidth_hi) { + max_bw = sender_->ExportDebugState().bandwidth_hi; + max_bw_round = sender_->ExportDebugState().round_trip_count; + } + return sender_->ExportDebugState().startup.full_bandwidth_reached; + }, + QuicTime::Delta::FromSeconds(5)); + ASSERT_TRUE(simulator_result); + EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode); + EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round); + EXPECT_EQ( + 1u, + sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth); + EXPECT_NE(0u, sender_connection_stats().packets_lost); + EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); + + if (GetQuicReloadableFlag(quic_bbr2_startup_loss_exit_use_max_delivered)) { + EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP()); + } else { + EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), + 0.1f); + } +} + TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) { DefaultTopologyParams params; params.sender_policer_params = TrafficPolicerParams(); @@ -906,7 +977,7 @@ TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) { min_rtt_timestamp_after_idle); } -// Regression test for http://shortn/_Jt1QWtshAM. +// Regression test for http://go/switchtobbr2midconnection. TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) { QuicTime now = QuicTime::Zero(); BbrSender old_sender(sender_connection()->clock()->Now(), @@ -1017,6 +1088,87 @@ TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) { DriveOutOfStartup(params); } +TEST_F(Bbr2DefaultTopologyTest, + 200InitialCongestionWindowWithNetworkParameterAdjusted) { + DefaultTopologyParams params; + CreateNetwork(params); + + sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024); + + // Wait until an ACK comes back. + const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5); + bool simulator_result = simulator_.RunUntilOrTimeout( + [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); }, + timeout); + ASSERT_TRUE(simulator_result); + + // Bootstrap cwnd by a overly large bandwidth sample. + sender_connection()->AdjustNetworkParameters( + SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(), + QuicTime::Delta::Zero(), false)); + + if (GetQuicReloadableFlag(quic_bbr2_support_max_bootstrap_cwnd)) { + // Verify cwnd is capped at 200. + EXPECT_EQ(200 * kDefaultTCPMSS, + sender_->ExportDebugState().congestion_window); + EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0)); + } +} + +TEST_F(Bbr2DefaultTopologyTest, + 100InitialCongestionWindowFromNetworkParameter) { + DefaultTopologyParams params; + CreateNetwork(params); + + sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024); + // Wait until an ACK comes back. + const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5); + bool simulator_result = simulator_.RunUntilOrTimeout( + [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); }, + timeout); + ASSERT_TRUE(simulator_result); + + // Bootstrap cwnd by a overly large bandwidth sample. + SendAlgorithmInterface::NetworkParams network_params( + 1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false); + network_params.max_initial_congestion_window = 100; + sender_connection()->AdjustNetworkParameters(network_params); + + if (GetQuicReloadableFlag(quic_bbr2_support_max_bootstrap_cwnd)) { + // Verify cwnd is capped at 100. + EXPECT_EQ(100 * kDefaultTCPMSS, + sender_->ExportDebugState().congestion_window); + EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0)); + } +} + +TEST_F(Bbr2DefaultTopologyTest, + 100InitialCongestionWindowWithNetworkParameterAdjusted) { + SetConnectionOption(kICW1); + DefaultTopologyParams params; + CreateNetwork(params); + + sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024); + // Wait until an ACK comes back. + const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5); + bool simulator_result = simulator_.RunUntilOrTimeout( + [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); }, + timeout); + ASSERT_TRUE(simulator_result); + + // Bootstrap cwnd by a overly large bandwidth sample. + sender_connection()->AdjustNetworkParameters( + SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(), + QuicTime::Delta::Zero(), false)); + + if (GetQuicReloadableFlag(quic_bbr2_support_max_bootstrap_cwnd)) { + // Verify cwnd is capped at 100. + EXPECT_EQ(100 * kDefaultTCPMSS, + sender_->ExportDebugState().congestion_window); + EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0)); + } +} + // All Bbr2MultiSenderTests uses the following network topology: // // Sender 0 (A Bbr2Sender) diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc index 1141ca09e05..5c47adb8426 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.cc @@ -43,9 +43,15 @@ Bbr2Mode Bbr2StartupMode::OnCongestionEvent( const AckedPacketVector& /*acked_packets*/, const LostPacketVector& /*lost_packets*/, const Bbr2CongestionEvent& congestion_event) { - CheckFullBandwidthReached(congestion_event); - - CheckExcessiveLosses(congestion_event); + if (!full_bandwidth_reached_ && congestion_event.end_of_round_trip) { + // TCP BBR always exits upon excessive losses. QUIC BBRv1 does not exits + // upon excessive losses, if enough bandwidth growth is observed. + bool has_enough_bw_growth = CheckBandwidthGrowth(congestion_event); + + if (Params().always_exit_startup_on_excess_loss || !has_enough_bw_growth) { + CheckExcessiveLosses(congestion_event); + } + } model_->set_pacing_gain(Params().startup_pacing_gain); model_->set_cwnd_gain(Params().startup_cwnd_gain); @@ -54,68 +60,68 @@ Bbr2Mode Bbr2StartupMode::OnCongestionEvent( return full_bandwidth_reached_ ? Bbr2Mode::DRAIN : Bbr2Mode::STARTUP; } -void Bbr2StartupMode::CheckFullBandwidthReached( +bool Bbr2StartupMode::CheckBandwidthGrowth( const Bbr2CongestionEvent& congestion_event) { DCHECK(!full_bandwidth_reached_); - if (full_bandwidth_reached_ || !congestion_event.end_of_round_trip || - congestion_event.last_sample_is_app_limited) { - return; + DCHECK(congestion_event.end_of_round_trip); + if (congestion_event.last_sample_is_app_limited) { + // Return true such that when Params().always_exit_startup_on_excess_loss is + // false, we'll not check excess loss, which is the behavior of QUIC BBRv1. + return true; } QuicBandwidth threshold = full_bandwidth_baseline_ * Params().startup_full_bw_threshold; if (model_->MaxBandwidth() >= threshold) { - QUIC_DVLOG(3) - << sender_ - << " CheckFullBandwidthReached at end of round. max_bandwidth:" - << model_->MaxBandwidth() << ", threshold:" << threshold - << " (Still growing) @ " << congestion_event.event_time; + QUIC_DVLOG(3) << sender_ + << " CheckBandwidthGrowth at end of round. max_bandwidth:" + << model_->MaxBandwidth() << ", threshold:" << threshold + << " (Still growing) @ " << congestion_event.event_time; full_bandwidth_baseline_ = model_->MaxBandwidth(); rounds_without_bandwidth_growth_ = 0; - return; + return true; } ++rounds_without_bandwidth_growth_; full_bandwidth_reached_ = rounds_without_bandwidth_growth_ >= Params().startup_full_bw_rounds; QUIC_DVLOG(3) << sender_ - << " CheckFullBandwidthReached at end of round. max_bandwidth:" + << " CheckBandwidthGrowth at end of round. max_bandwidth:" << model_->MaxBandwidth() << ", threshold:" << threshold << " rounds_without_growth:" << rounds_without_bandwidth_growth_ << " full_bw_reached:" << full_bandwidth_reached_ << " @ " << congestion_event.event_time; + + return false; } void Bbr2StartupMode::CheckExcessiveLosses( const Bbr2CongestionEvent& congestion_event) { - if (full_bandwidth_reached_) { - return; - } - - const int64_t loss_events_in_round = model_->loss_events_in_round(); + DCHECK(congestion_event.end_of_round_trip); - // TODO(wub): In TCP, loss based exit only happens at end of a loss round, in - // QUIC we use the end of the normal round here. It is possible to exit after - // any congestion event, using information of the "rolling round". - if (!congestion_event.end_of_round_trip) { + if (full_bandwidth_reached_) { return; } - QUIC_DVLOG(3) - << sender_ - << " CheckExcessiveLosses at end of round. loss_events_in_round:" - << loss_events_in_round - << ", threshold:" << Params().startup_full_loss_count << " @ " - << congestion_event.event_time; - // At the end of a round trip. Check if loss is too high in this round. - if (loss_events_in_round >= Params().startup_full_loss_count && - model_->IsInflightTooHigh(congestion_event)) { - const QuicByteCount bdp = model_->BDP(model_->MaxBandwidth()); - QUIC_DVLOG(3) << sender_ - << " Exiting STARTUP due to loss. inflight_hi:" << bdp; - model_->set_inflight_hi(bdp); + if (model_->IsInflightTooHigh(congestion_event, + Params().startup_full_loss_count)) { + QuicByteCount new_inflight_hi = model_->BDP(model_->MaxBandwidth()); + if (Params().startup_loss_exit_use_max_delivered_for_inflight_hi) { + if (new_inflight_hi < model_->max_bytes_delivered_in_round()) { + QUIC_RELOADABLE_FLAG_COUNT_N( + quic_bbr2_startup_loss_exit_use_max_delivered, 1, 2); + new_inflight_hi = model_->max_bytes_delivered_in_round(); + } else { + QUIC_RELOADABLE_FLAG_COUNT_N( + quic_bbr2_startup_loss_exit_use_max_delivered, 2, 2); + } + } + QUIC_DVLOG(3) << sender_ << " Exiting STARTUP due to loss. inflight_hi:" + << new_inflight_hi; + // TODO(ianswett): Add a shared method to set inflight_hi in the model. + model_->set_inflight_hi(new_inflight_hi); full_bandwidth_reached_ = true; sender_->connection_stats_->bbr_exit_startup_due_to_loss = true; diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h index 378a4fd83fd..75ec71ecd25 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_startup.h @@ -58,7 +58,12 @@ class QUIC_EXPORT_PRIVATE Bbr2StartupMode final : public Bbr2ModeBase { private: const Bbr2Params& Params() const; - void CheckFullBandwidthReached(const Bbr2CongestionEvent& congestion_event); + // Check bandwidth growth in the past round. Must be called at the end of a + // round. + // Return true if the bandwidth growed as expected. + // Return false otherwise, if enough rounds have elapsed without expected + // growth, also sets |full_bandwidth_reached_| to true. + bool CheckBandwidthGrowth(const Bbr2CongestionEvent& congestion_event); void CheckExcessiveLosses(const Bbr2CongestionEvent& congestion_event); diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc index 2948272d737..7ce3ab586af 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc @@ -8,12 +8,12 @@ #include <sstream> #include <string> +#include "absl/base/attributes.h" #include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_time_accumulator.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" @@ -221,24 +221,6 @@ bool BbrSender::ShouldSendProbingPacket() const { return true; } -bool BbrSender::IsPipeSufficientlyFull() const { - // See if we need more bytes in flight to see more bandwidth. - if (mode_ == STARTUP) { - // STARTUP exits if it doesn't observe a 25% bandwidth increase, so the CWND - // must be more than 25% above the target. - return unacked_packets_->bytes_in_flight() >= - GetTargetCongestionWindow(1.5); - } - if (pacing_gain_ > 1) { - // Super-unity PROBE_BW doesn't exit until 1.25 * BDP is achieved. - return unacked_packets_->bytes_in_flight() >= - GetTargetCongestionWindow(pacing_gain_); - } - // If bytes_in_flight are above the target congestion window, it should be - // possible to observe the same or more bandwidth if it's available. - return unacked_packets_->bytes_in_flight() >= GetTargetCongestionWindow(1.1); -} - void BbrSender::SetFromConfig(const QuicConfig& config, Perspective perspective) { if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) { @@ -734,7 +716,7 @@ void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet, if (is_round_start) { recovery_state_ = GROWTH; } - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case GROWTH: // Exit recovery if appropriate. @@ -814,15 +796,11 @@ void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked, // Instead of immediately setting the target CWND as the new one, BBR grows // the CWND towards |target_window| by only increasing it |bytes_acked| at a // time. - const bool add_bytes_acked = - !GetQuicReloadableFlag(quic_bbr_no_bytes_acked_in_startup_recovery) || - !InRecovery(); if (is_at_full_bandwidth_) { congestion_window_ = std::min(target_window, congestion_window_ + bytes_acked); - } else if (add_bytes_acked && - (congestion_window_ < target_window || - sampler_.total_bytes_acked() < initial_congestion_window_)) { + } else if (congestion_window_ < target_window || + sampler_.total_bytes_acked() < initial_congestion_window_) { // If the connection is not yet out of startup phase, do not decrease the // window. congestion_window_ = congestion_window_ + bytes_acked; diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h index ae6cce9a393..586ef1afc2e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h @@ -175,17 +175,15 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface { // For switching send algorithm mid connection. friend class Bbr2Sender; - typedef WindowedFilter<QuicBandwidth, - MaxFilter<QuicBandwidth>, - QuicRoundTripCount, - QuicRoundTripCount> - MaxBandwidthFilter; - - typedef WindowedFilter<QuicByteCount, - MaxFilter<QuicByteCount>, - QuicRoundTripCount, - QuicRoundTripCount> - MaxAckHeightFilter; + using MaxBandwidthFilter = WindowedFilter<QuicBandwidth, + MaxFilter<QuicBandwidth>, + QuicRoundTripCount, + QuicRoundTripCount>; + + using MaxAckHeightFilter = WindowedFilter<QuicByteCount, + MaxFilter<QuicByteCount>, + QuicRoundTripCount, + QuicRoundTripCount>; // Returns whether the connection has achieved full bandwidth required to exit // the slow start. @@ -244,10 +242,6 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface { void CalculateRecoveryWindow(QuicByteCount bytes_acked, QuicByteCount bytes_lost); - // Returns true if there are enough bytes in flight to ensure more bandwidth - // will be observed if present. - bool IsPipeSufficientlyFull() const; - // Called right before exiting STARTUP. void OnExitStartup(QuicTime now); 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 b476b557a47..c0000e78699 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 @@ -436,7 +436,10 @@ TEST_F(BbrSenderTest, SimpleTransferAckDecimation) { } // Test a simple long data transfer with 2 rtts of aggregation. -TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) { +// TODO(b/172302465) Re-enable this test. +TEST_F(BbrSenderTest, + QUIC_TEST_DISABLED_IN_CHROME( + SimpleTransfer2RTTAggregationBytes20RTTWindow)) { SetConnectionOption(kBSAO); CreateDefaultSetup(); SetConnectionOption(kBBR4); @@ -728,7 +731,8 @@ TEST_F(BbrSenderTest, ProbeRtt) { // Ensure that a connection that is app-limited and is at sufficiently low // bandwidth will not exit high gain phase, and similarly ensure that the // connection will exit low gain early if the number of bytes in flight is low. -TEST_F(BbrSenderTest, InFlightAwareGainCycling) { +// TODO(crbug.com/1145095): Re-enable this test. +TEST_F(BbrSenderTest, QUIC_TEST_DISABLED_IN_CHROME(InFlightAwareGainCycling)) { CreateDefaultSetup(); DriveOutOfStartup(); diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc index 42b97bf89f8..6d89cb93f06 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc @@ -62,16 +62,15 @@ class GeneralLossAlgorithmTest : public QuicTest { const AckedPacketVector& packets_acked, const std::vector<uint64_t>& losses_expected) { return VerifyLosses(largest_newly_acked, packets_acked, losses_expected, - quiche::QuicheOptional<QuicPacketCount>(), - quiche::QuicheOptional<QuicPacketCount>()); + absl::nullopt, absl::nullopt); } void VerifyLosses( uint64_t largest_newly_acked, const AckedPacketVector& packets_acked, const std::vector<uint64_t>& losses_expected, - quiche::QuicheOptional<QuicPacketCount> max_sequence_reordering_expected, - quiche::QuicheOptional<QuicPacketCount> + absl::optional<QuicPacketCount> max_sequence_reordering_expected, + absl::optional<QuicPacketCount> num_borderline_time_reorderings_expected) { unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace( APPLICATION_DATA, QuicPacketNumber(largest_newly_acked)); diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc index 9d003c59a66..4b36e4a378e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.cc @@ -4,12 +4,12 @@ #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" +#include "absl/base/attributes.h" #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h" #include "net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h" #include "net/third_party/quiche/src/quic/core/congestion_control/tcp_cubic_sender_bytes.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_pcc_sender.h" @@ -46,7 +46,7 @@ SendAlgorithmInterface* SendAlgorithmInterface::Create( : nullptr); case kPCC: // PCC is work has stalled, fall back to CUBIC instead. - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case kCubicBytes: return new TcpCubicSenderBytes( clock, rtt_stats, false /* don't use Reno */, 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 e3fc5e6b3f6..533bf4cc14d 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 @@ -24,7 +24,7 @@ namespace quic { -typedef uint64_t QuicRoundTripCount; +using QuicRoundTripCount = uint64_t; class CachedNetworkParameters; class RttStats; diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h index c20cb78a5f1..169972e1439 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h @@ -5,10 +5,10 @@ #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_ #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_ +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" namespace quic { @@ -20,8 +20,8 @@ class QuicSentPacketManagerPeer; struct QUIC_EXPORT_PRIVATE LossDetectionParameters { // See GeneralLossAlgorithm for the meaning of reordering_(shift|threshold). - quiche::QuicheOptional<int> reordering_shift; - quiche::QuicheOptional<QuicPacketCount> reordering_threshold; + absl::optional<int> reordering_shift; + absl::optional<QuicPacketCount> reordering_threshold; }; class QUIC_EXPORT_PRIVATE LossDetectionTunerInterface { diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc index 7a9d37ee107..788d1013439 100644 --- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc @@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -14,7 +15,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" namespace quic { namespace test { @@ -69,14 +69,14 @@ class UberLossAlgorithmTest : public QuicTest { const AckedPacketVector& packets_acked, const std::vector<uint64_t>& losses_expected) { return VerifyLosses(largest_newly_acked, packets_acked, losses_expected, - quiche::QuicheOptional<QuicPacketCount>()); + absl::nullopt); } - void VerifyLosses(uint64_t largest_newly_acked, - const AckedPacketVector& packets_acked, - const std::vector<uint64_t>& losses_expected, - quiche::QuicheOptional<QuicPacketCount> - max_sequence_reordering_expected) { + void VerifyLosses( + uint64_t largest_newly_acked, + const AckedPacketVector& packets_acked, + const std::vector<uint64_t>& losses_expected, + absl::optional<QuicPacketCount> max_sequence_reordering_expected) { LostPacketVector lost_packets; LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses( *unacked_packets_, clock_.Now(), rtt_stats_, diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc index f3be16e1d18..f31720a82a8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.cc @@ -7,14 +7,14 @@ #include <cstdint> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/crypto.h" #include "third_party/boringssl/src/include/openssl/err.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -34,7 +34,7 @@ void DLogOpenSslErrors() { #else while (uint32_t error = ERR_get_error()) { char buf[120]; - ERR_error_string_n(error, buf, QUICHE_ARRAYSIZE(buf)); + ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf)); QUIC_DLOG(ERROR) << "OpenSSL error: " << buf; } #endif @@ -69,7 +69,7 @@ AeadBaseDecrypter::AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(), AeadBaseDecrypter::~AeadBaseDecrypter() {} -bool AeadBaseDecrypter::SetKey(quiche::QuicheStringPiece key) { +bool AeadBaseDecrypter::SetKey(absl::string_view key) { DCHECK_EQ(key.size(), key_size_); if (key.size() != key_size_) { return false; @@ -86,7 +86,7 @@ bool AeadBaseDecrypter::SetKey(quiche::QuicheStringPiece key) { return true; } -bool AeadBaseDecrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { +bool AeadBaseDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) { if (use_ietf_nonce_construction_) { QUIC_BUG << "Attempted to set nonce prefix on IETF QUIC crypter"; return false; @@ -99,7 +99,7 @@ bool AeadBaseDecrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { return true; } -bool AeadBaseDecrypter::SetIV(quiche::QuicheStringPiece iv) { +bool AeadBaseDecrypter::SetIV(absl::string_view iv) { if (!use_ietf_nonce_construction_) { QUIC_BUG << "Attempted to set IV on Google QUIC crypter"; return false; @@ -112,7 +112,7 @@ bool AeadBaseDecrypter::SetIV(quiche::QuicheStringPiece iv) { return true; } -bool AeadBaseDecrypter::SetPreliminaryKey(quiche::QuicheStringPiece key) { +bool AeadBaseDecrypter::SetPreliminaryKey(absl::string_view key) { DCHECK(!have_preliminary_key_); SetKey(key); have_preliminary_key_ = true; @@ -132,10 +132,9 @@ bool AeadBaseDecrypter::SetDiversificationNonce( prefix_size -= sizeof(QuicPacketNumber); } DiversifyPreliminaryKey( - quiche::QuicheStringPiece(reinterpret_cast<const char*>(key_), key_size_), - quiche::QuicheStringPiece(reinterpret_cast<const char*>(iv_), - prefix_size), - nonce, key_size_, prefix_size, &key, &nonce_prefix); + absl::string_view(reinterpret_cast<const char*>(key_), key_size_), + absl::string_view(reinterpret_cast<const char*>(iv_), prefix_size), nonce, + key_size_, prefix_size, &key, &nonce_prefix); if (!SetKey(key) || (!use_ietf_nonce_construction_ && !SetNoncePrefix(nonce_prefix)) || @@ -149,8 +148,8 @@ bool AeadBaseDecrypter::SetDiversificationNonce( } bool AeadBaseDecrypter::DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) { @@ -201,14 +200,13 @@ size_t AeadBaseDecrypter::GetIVSize() const { return nonce_size_; } -quiche::QuicheStringPiece AeadBaseDecrypter::GetKey() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(key_), - key_size_); +absl::string_view AeadBaseDecrypter::GetKey() const { + return absl::string_view(reinterpret_cast<const char*>(key_), key_size_); } -quiche::QuicheStringPiece AeadBaseDecrypter::GetNoncePrefix() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(iv_), - nonce_size_ - sizeof(QuicPacketNumber)); +absl::string_view AeadBaseDecrypter::GetNoncePrefix() const { + return absl::string_view(reinterpret_cast<const char*>(iv_), + nonce_size_ - sizeof(QuicPacketNumber)); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h index e69b0edddc8..c4c04fe8f1b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h @@ -7,10 +7,10 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aead.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,22 +29,22 @@ class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter { ~AeadBaseDecrypter() override; // QuicDecrypter implementation - bool SetKey(quiche::QuicheStringPiece key) override; - bool SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) override; - bool SetIV(quiche::QuicheStringPiece iv) override; - bool SetPreliminaryKey(quiche::QuicheStringPiece key) override; + bool SetKey(absl::string_view key) override; + bool SetNoncePrefix(absl::string_view nonce_prefix) override; + bool SetIV(absl::string_view iv) override; + bool SetPreliminaryKey(absl::string_view key) override; bool SetDiversificationNonce(const DiversificationNonce& nonce) override; bool DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) override; size_t GetKeySize() const override; size_t GetNoncePrefixSize() const override; size_t GetIVSize() const override; - quiche::QuicheStringPiece GetKey() const override; - quiche::QuicheStringPiece GetNoncePrefix() const override; + absl::string_view GetKey() const override; + absl::string_view GetNoncePrefix() const override; protected: // Make these constants available to the subclasses so that the subclasses diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc index 14aca267927..b87ea50aede 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc @@ -4,15 +4,14 @@ #include "net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/crypto.h" #include "third_party/boringssl/src/include/openssl/err.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -27,7 +26,7 @@ void DLogOpenSslErrors() { #else while (unsigned long error = ERR_get_error()) { char buf[120]; - ERR_error_string_n(error, buf, QUICHE_ARRAYSIZE(buf)); + ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf)); QUIC_DLOG(ERROR) << "OpenSSL error: " << buf; } #endif @@ -59,7 +58,7 @@ AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(), AeadBaseEncrypter::~AeadBaseEncrypter() {} -bool AeadBaseEncrypter::SetKey(quiche::QuicheStringPiece key) { +bool AeadBaseEncrypter::SetKey(absl::string_view key) { DCHECK_EQ(key.size(), key_size_); if (key.size() != key_size_) { return false; @@ -77,7 +76,7 @@ bool AeadBaseEncrypter::SetKey(quiche::QuicheStringPiece key) { return true; } -bool AeadBaseEncrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { +bool AeadBaseEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) { if (use_ietf_nonce_construction_) { QUIC_BUG << "Attempted to set nonce prefix on IETF QUIC crypter"; return false; @@ -90,7 +89,7 @@ bool AeadBaseEncrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { return true; } -bool AeadBaseEncrypter::SetIV(quiche::QuicheStringPiece iv) { +bool AeadBaseEncrypter::SetIV(absl::string_view iv) { if (!use_ietf_nonce_construction_) { QUIC_BUG << "Attempted to set IV on Google QUIC crypter"; return false; @@ -103,9 +102,9 @@ bool AeadBaseEncrypter::SetIV(quiche::QuicheStringPiece iv) { return true; } -bool AeadBaseEncrypter::Encrypt(quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, +bool AeadBaseEncrypter::Encrypt(absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext, unsigned char* output) { DCHECK_EQ(nonce.size(), nonce_size_); @@ -125,8 +124,8 @@ bool AeadBaseEncrypter::Encrypt(quiche::QuicheStringPiece nonce, } bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) { @@ -136,7 +135,7 @@ bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number, } // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the // same packet number twice. - QUIC_ALIGNED(4) char nonce_buffer[kMaxNonceSize]; + alignas(4) char nonce_buffer[kMaxNonceSize]; memcpy(nonce_buffer, iv_, nonce_size_); size_t prefix_len = nonce_size_ - sizeof(packet_number); if (use_ietf_nonce_construction_) { @@ -148,9 +147,8 @@ bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number, memcpy(nonce_buffer + prefix_len, &packet_number, sizeof(packet_number)); } - if (!Encrypt(quiche::QuicheStringPiece(nonce_buffer, nonce_size_), - associated_data, plaintext, - reinterpret_cast<unsigned char*>(output))) { + if (!Encrypt(absl::string_view(nonce_buffer, nonce_size_), associated_data, + plaintext, reinterpret_cast<unsigned char*>(output))) { return false; } *output_length = ciphertext_size; @@ -177,14 +175,13 @@ size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const { return plaintext_size + auth_tag_size_; } -quiche::QuicheStringPiece AeadBaseEncrypter::GetKey() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(key_), - key_size_); +absl::string_view AeadBaseEncrypter::GetKey() const { + return absl::string_view(reinterpret_cast<const char*>(key_), key_size_); } -quiche::QuicheStringPiece AeadBaseEncrypter::GetNoncePrefix() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(iv_), - GetNoncePrefixSize()); +absl::string_view AeadBaseEncrypter::GetNoncePrefix() const { + return absl::string_view(reinterpret_cast<const char*>(iv_), + GetNoncePrefixSize()); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h index 5209a023caa..5ef8b96d11a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h @@ -7,10 +7,10 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aead.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,12 +29,12 @@ class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter { ~AeadBaseEncrypter() override; // QuicEncrypter implementation - bool SetKey(quiche::QuicheStringPiece key) override; - bool SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) override; - bool SetIV(quiche::QuicheStringPiece iv) override; + bool SetKey(absl::string_view key) override; + bool SetNoncePrefix(absl::string_view nonce_prefix) override; + bool SetIV(absl::string_view iv) override; bool EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) override; @@ -43,14 +43,14 @@ class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter { size_t GetIVSize() const override; size_t GetMaxPlaintextSize(size_t ciphertext_size) const override; size_t GetCiphertextSize(size_t plaintext_size) const override; - quiche::QuicheStringPiece GetKey() const override; - quiche::QuicheStringPiece GetNoncePrefix() const override; + absl::string_view GetKey() const override; + absl::string_view GetNoncePrefix() const override; // Necessary so unit tests can explicitly specify a nonce, instead of an IV // (or nonce prefix) and packet number. - bool Encrypt(quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + bool Encrypt(absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext, unsigned char* output); protected: diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc index 0319d4280f0..aba1001b6ea 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc @@ -7,11 +7,12 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -202,12 +203,12 @@ namespace test { // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing // in an nonce and also to allocate the buffer needed for the plaintext. QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view ciphertext) { uint64_t packet_number; - quiche::QuicheStringPiece nonce_prefix(nonce.data(), - nonce.size() - sizeof(packet_number)); + absl::string_view nonce_prefix(nonce.data(), + nonce.size() - sizeof(packet_number)); decrypter->SetNoncePrefix(nonce_prefix); memcpy(&packet_number, nonce.data() + nonce_prefix.size(), sizeof(packet_number)); @@ -225,7 +226,7 @@ QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter, class Aes128Gcm12DecrypterTest : public QuicTest {}; TEST_F(Aes128Gcm12DecrypterTest, Decrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; @@ -234,14 +235,14 @@ TEST_F(Aes128Gcm12DecrypterTest, Decrypt) { bool has_pt = test_vectors[j].pt; // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); std::string pt; if (has_pt) { - pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); + pt = absl::HexStringToBytes(test_vectors[j].pt); } // The test vector's lengths should look sane. Note that the lengths @@ -270,7 +271,7 @@ TEST_F(Aes128Gcm12DecrypterTest, Decrypt) { // This deliberately tests that the decrypter can // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), ciphertext)); + aad.length() ? aad : absl::string_view(), ciphertext)); if (!decrypted) { EXPECT_FALSE(has_pt); continue; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc index bc3f6112867..1495fd08be1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc @@ -7,11 +7,12 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -160,9 +161,9 @@ namespace test { // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing // in an nonce and also to allocate the buffer needed for the ciphertext. QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext) { size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]); @@ -177,18 +178,18 @@ QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter, class Aes128Gcm12EncrypterTest : public QuicTest {}; TEST_F(Aes128Gcm12EncrypterTest, Encrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; for (size_t j = 0; test_vectors[j].key != nullptr; j++) { // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string pt = absl::HexStringToBytes(test_vectors[j].pt); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); // The test vector's lengths should look sane. Note that the lengths // in |test_info| are in bits. @@ -201,12 +202,12 @@ TEST_F(Aes128Gcm12EncrypterTest, Encrypt) { Aes128Gcm12Encrypter encrypter; ASSERT_TRUE(encrypter.SetKey(key)); - std::unique_ptr<QuicData> encrypted(EncryptWithNonce( - &encrypter, iv, - // This deliberately tests that the encrypter can - // handle an AAD that is set to nullptr, as opposed - // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), pt)); + std::unique_ptr<QuicData> encrypted( + EncryptWithNonce(&encrypter, iv, + // This deliberately tests that the encrypter can + // handle an AAD that is set to nullptr, as opposed + // to a zero-length, non-nullptr pointer. + aad.length() ? aad : absl::string_view(), pt)); ASSERT_TRUE(encrypted.get()); // The test vectors have 16 byte authenticators but this code only uses diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc index a444284618f..d4f38b90019 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc @@ -7,10 +7,11 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -201,9 +202,9 @@ namespace test { // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing // in an nonce and also to allocate the buffer needed for the plaintext. QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view ciphertext) { decrypter->SetIV(nonce); std::unique_ptr<char[]> output(new char[ciphertext.length()]); size_t output_length = 0; @@ -219,7 +220,7 @@ QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter, class Aes128GcmDecrypterTest : public QuicTest {}; TEST_F(Aes128GcmDecrypterTest, Decrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; @@ -228,14 +229,14 @@ TEST_F(Aes128GcmDecrypterTest, Decrypt) { bool has_pt = test_vectors[j].pt; // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); std::string pt; if (has_pt) { - pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); + pt = absl::HexStringToBytes(test_vectors[j].pt); } // The test vector's lengths should look sane. Note that the lengths @@ -258,7 +259,7 @@ TEST_F(Aes128GcmDecrypterTest, Decrypt) { // This deliberately tests that the decrypter can // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), ciphertext)); + aad.length() ? aad : absl::string_view(), ciphertext)); if (!decrypted) { EXPECT_FALSE(has_pt); continue; @@ -274,15 +275,14 @@ TEST_F(Aes128GcmDecrypterTest, Decrypt) { TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) { Aes128GcmDecrypter decrypter; - std::string key = - quiche::QuicheTextUtils::HexDecode("d9132370cb18476ab833649cf080d970"); + std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970"); std::string sample = - quiche::QuicheTextUtils::HexDecode("d1d7998068517adb769b48b924a32c47"); + absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47"); QuicDataReader sample_reader(sample.data(), sample.size()); ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key)); std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader); std::string expected_mask = - quiche::QuicheTextUtils::HexDecode("b132c37d6164da4ea4dc9b763aceec27"); + absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc index 69f8c4d0f3e..c7c096f2b88 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_encrypter_test.cc @@ -7,10 +7,11 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -159,9 +160,9 @@ namespace test { // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing // in an nonce and also to allocate the buffer needed for the ciphertext. QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext) { size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]); @@ -176,18 +177,18 @@ QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter, class Aes128GcmEncrypterTest : public QuicTest {}; TEST_F(Aes128GcmEncrypterTest, Encrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; for (size_t j = 0; test_vectors[j].key != nullptr; j++) { // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string pt = absl::HexStringToBytes(test_vectors[j].pt); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); // The test vector's lengths should look sane. Note that the lengths // in |test_info| are in bits. @@ -200,12 +201,12 @@ TEST_F(Aes128GcmEncrypterTest, Encrypt) { Aes128GcmEncrypter encrypter; ASSERT_TRUE(encrypter.SetKey(key)); - std::unique_ptr<QuicData> encrypted(EncryptWithNonce( - &encrypter, iv, - // This deliberately tests that the encrypter can - // handle an AAD that is set to nullptr, as opposed - // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), pt)); + std::unique_ptr<QuicData> encrypted( + EncryptWithNonce(&encrypter, iv, + // This deliberately tests that the encrypter can + // handle an AAD that is set to nullptr, as opposed + // to a zero-length, non-nullptr pointer. + aad.length() ? aad : absl::string_view(), pt)); ASSERT_TRUE(encrypted.get()); ASSERT_EQ(ct.length() + tag.length(), encrypted->length()); @@ -219,16 +220,13 @@ TEST_F(Aes128GcmEncrypterTest, Encrypt) { } TEST_F(Aes128GcmEncrypterTest, EncryptPacket) { - std::string key = - quiche::QuicheTextUtils::HexDecode("d95a145250826c25a77b6a84fd4d34fc"); - std::string iv = - quiche::QuicheTextUtils::HexDecode("50c4431ebb18283448e276e2"); + std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc"); + std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2"); uint64_t packet_num = 0x13278f44; std::string aad = - quiche::QuicheTextUtils::HexDecode("875d49f64a70c9cbe713278f44ff000005"); - std::string pt = - quiche::QuicheTextUtils::HexDecode("aa0003a250bd000000000001"); - std::string ct = quiche::QuicheTextUtils::HexDecode( + absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005"); + std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001"); + std::string ct = absl::HexStringToBytes( "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0"); std::vector<char> out(ct.size()); @@ -260,14 +258,13 @@ TEST_F(Aes128GcmEncrypterTest, GetCiphertextSize) { TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) { Aes128GcmEncrypter encrypter; - std::string key = - quiche::QuicheTextUtils::HexDecode("d9132370cb18476ab833649cf080d970"); + std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970"); std::string sample = - quiche::QuicheTextUtils::HexDecode("d1d7998068517adb769b48b924a32c47"); + absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47"); ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key)); std::string mask = encrypter.GenerateHeaderProtectionMask(sample); std::string expected_mask = - quiche::QuicheTextUtils::HexDecode("b132c37d6164da4ea4dc9b763aceec27"); + absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc index 7c6972489e4..c688ce45ca8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc @@ -7,11 +7,12 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -206,9 +207,9 @@ namespace test { // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing // in an nonce and also to allocate the buffer needed for the plaintext. QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view ciphertext) { decrypter->SetIV(nonce); std::unique_ptr<char[]> output(new char[ciphertext.length()]); size_t output_length = 0; @@ -224,7 +225,7 @@ QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter, class Aes256GcmDecrypterTest : public QuicTest {}; TEST_F(Aes256GcmDecrypterTest, Decrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; @@ -233,14 +234,14 @@ TEST_F(Aes256GcmDecrypterTest, Decrypt) { bool has_pt = test_vectors[j].pt; // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); std::string pt; if (has_pt) { - pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); + pt = absl::HexStringToBytes(test_vectors[j].pt); } // The test vector's lengths should look sane. Note that the lengths @@ -263,7 +264,7 @@ TEST_F(Aes256GcmDecrypterTest, Decrypt) { // This deliberately tests that the decrypter can // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), ciphertext)); + aad.length() ? aad : absl::string_view(), ciphertext)); if (!decrypted) { EXPECT_FALSE(has_pt); continue; @@ -279,15 +280,15 @@ TEST_F(Aes256GcmDecrypterTest, Decrypt) { TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) { Aes256GcmDecrypter decrypter; - std::string key = quiche::QuicheTextUtils::HexDecode( + std::string key = absl::HexStringToBytes( "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788"); std::string sample = - quiche::QuicheTextUtils::HexDecode("4d190c474be2b8babafb49ec4e38e810"); + absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810"); QuicDataReader sample_reader(sample.data(), sample.size()); ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key)); std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader); std::string expected_mask = - quiche::QuicheTextUtils::HexDecode("db9ed4e6ccd033af2eae01407199c56e"); + absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc index 089926261d8..c09f8a84638 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_encrypter_test.cc @@ -7,11 +7,12 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -167,9 +168,9 @@ namespace test { // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing // in an nonce and also to allocate the buffer needed for the ciphertext. QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext) { size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]); @@ -184,18 +185,18 @@ QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter, class Aes256GcmEncrypterTest : public QuicTest {}; TEST_F(Aes256GcmEncrypterTest, Encrypt) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_group_array); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) { SCOPED_TRACE(i); const TestVector* test_vectors = test_group_array[i]; const TestGroupInfo& test_info = test_group_info[i]; for (size_t j = 0; test_vectors[j].key != nullptr; j++) { // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv); - std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct); - std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag); + std::string key = absl::HexStringToBytes(test_vectors[j].key); + std::string iv = absl::HexStringToBytes(test_vectors[j].iv); + std::string pt = absl::HexStringToBytes(test_vectors[j].pt); + std::string aad = absl::HexStringToBytes(test_vectors[j].aad); + std::string ct = absl::HexStringToBytes(test_vectors[j].ct); + std::string tag = absl::HexStringToBytes(test_vectors[j].tag); // The test vector's lengths should look sane. Note that the lengths // in |test_info| are in bits. @@ -208,12 +209,12 @@ TEST_F(Aes256GcmEncrypterTest, Encrypt) { Aes256GcmEncrypter encrypter; ASSERT_TRUE(encrypter.SetKey(key)); - std::unique_ptr<QuicData> encrypted(EncryptWithNonce( - &encrypter, iv, - // This deliberately tests that the encrypter can - // handle an AAD that is set to nullptr, as opposed - // to a zero-length, non-nullptr pointer. - aad.length() ? aad : quiche::QuicheStringPiece(), pt)); + std::unique_ptr<QuicData> encrypted( + EncryptWithNonce(&encrypter, iv, + // This deliberately tests that the encrypter can + // handle an AAD that is set to nullptr, as opposed + // to a zero-length, non-nullptr pointer. + aad.length() ? aad : absl::string_view(), pt)); ASSERT_TRUE(encrypted.get()); ASSERT_EQ(ct.length() + tag.length(), encrypted->length()); @@ -242,14 +243,14 @@ TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) { TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) { Aes256GcmEncrypter encrypter; - std::string key = quiche::QuicheTextUtils::HexDecode( + std::string key = absl::HexStringToBytes( "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788"); std::string sample = - quiche::QuicheTextUtils::HexDecode("4d190c474be2b8babafb49ec4e38e810"); + absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810"); ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key)); std::string mask = encrypter.GenerateHeaderProtectionMask(sample); std::string expected_mask = - quiche::QuicheTextUtils::HexDecode("db9ed4e6ccd033af2eae01407199c56e"); + absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc index f8c83f3118a..464e7656783 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.cc @@ -4,13 +4,13 @@ #include "net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { -bool AesBaseDecrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { +bool AesBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) { if (key.size() != GetKeySize()) { QUIC_BUG << "Invalid key size for header protection"; return false; @@ -25,7 +25,7 @@ bool AesBaseDecrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { std::string AesBaseDecrypter::GenerateHeaderProtectionMask( QuicDataReader* sample_reader) { - quiche::QuicheStringPiece sample; + absl::string_view sample; if (!sample_reader->ReadStringPiece(&sample, AES_BLOCK_SIZE)) { return std::string(); } @@ -36,4 +36,17 @@ std::string AesBaseDecrypter::GenerateHeaderProtectionMask( return out; } +QuicPacketCount AesBaseDecrypter::GetIntegrityLimit() const { + // For AEAD_AES_128_GCM ... endpoints that do not attempt to remove + // protection from packets larger than 2^11 bytes can attempt to remove + // protection from at most 2^57 packets. + // For AEAD_AES_256_GCM [the limit] is substantially larger than the limit for + // AEAD_AES_128_GCM. However, this document recommends that the same limit be + // applied to both functions as either limit is acceptably large. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-integrity-limit + static_assert(kMaxIncomingPacketSize <= 2048, + "This key limit requires limits on decryption payload sizes"); + return 144115188075855872U; +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h index 2ff63a7ab2c..ced98103b90 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_decrypter.h @@ -7,10 +7,10 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,9 +18,10 @@ class QUIC_EXPORT_PRIVATE AesBaseDecrypter : public AeadBaseDecrypter { public: using AeadBaseDecrypter::AeadBaseDecrypter; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; + bool SetHeaderProtectionKey(absl::string_view key) override; std::string GenerateHeaderProtectionMask( QuicDataReader* sample_reader) override; + QuicPacketCount GetIntegrityLimit() const override; private: // The key used for packet number encryption. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc index c620329e226..6e998f8451e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.cc @@ -4,13 +4,13 @@ #include "net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { -bool AesBaseEncrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { +bool AesBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) { if (key.size() != GetKeySize()) { QUIC_BUG << "Invalid key size for header protection: " << key.size(); return false; @@ -24,7 +24,7 @@ bool AesBaseEncrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { } std::string AesBaseEncrypter::GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) { + absl::string_view sample) { if (sample.size() != AES_BLOCK_SIZE) { return std::string(); } @@ -35,4 +35,13 @@ std::string AesBaseEncrypter::GenerateHeaderProtectionMask( return out; } +QuicPacketCount AesBaseEncrypter::GetConfidentialityLimit() const { + // For AEAD_AES_128_GCM and AEAD_AES_256_GCM ... endpoints that do not send + // packets larger than 2^11 bytes cannot protect more than 2^28 packets. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-confidentiality-limit + static_assert(kMaxOutgoingPacketSize <= 2048, + "This key limit requires limits on encryption payload sizes"); + return 268435456U; +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h index ba518fe5593..6b1c98c7566 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_base_encrypter.h @@ -7,10 +7,10 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aes.h" #include "net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,9 +18,9 @@ class QUIC_EXPORT_PRIVATE AesBaseEncrypter : public AeadBaseEncrypter { public: using AeadBaseEncrypter::AeadBaseEncrypter; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; - std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) override; + bool SetHeaderProtectionKey(absl::string_view key) override; + std::string GenerateHeaderProtectionMask(absl::string_view sample) override; + QuicPacketCount GetConfidentialityLimit() const override; private: // The key used for packet number encryption. 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 5af87ae2c5c..9de61f4d896 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 @@ -5,19 +5,18 @@ #ifndef QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_ #define QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_ +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { -inline QUIC_EXPORT_PRIVATE quiche::QuicheStringPiece CbsToStringPiece(CBS cbs) { - return quiche::QuicheStringPiece( - reinterpret_cast<const char*>(CBS_data(&cbs)), CBS_len(&cbs)); +inline QUIC_EXPORT_PRIVATE absl::string_view CbsToStringPiece(CBS cbs) { + return absl::string_view(reinterpret_cast<const char*>(CBS_data(&cbs)), + CBS_len(&cbs)); } -inline QUIC_EXPORT_PRIVATE CBS -StringPieceToCbs(quiche::QuicheStringPiece piece) { +inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) { CBS result; CBS_init(&result, reinterpret_cast<const uint8_t*>(piece.data()), piece.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc index a1ba748730e..ec5ebacbb08 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.cc @@ -9,8 +9,8 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "third_party/zlib/zlib.h" namespace quic { @@ -175,11 +175,10 @@ struct CertEntry { // efficiently represent |certs| to a peer who has the common sets identified // by |client_common_set_hashes| and who has cached the certificates with the // 64-bit, FNV-1a hashes in |client_cached_cert_hashes|. -std::vector<CertEntry> MatchCerts( - const std::vector<std::string>& certs, - quiche::QuicheStringPiece client_common_set_hashes, - quiche::QuicheStringPiece client_cached_cert_hashes, - const CommonCertSets* common_sets) { +std::vector<CertEntry> MatchCerts(const std::vector<std::string>& certs, + absl::string_view client_common_set_hashes, + absl::string_view client_cached_cert_hashes, + const CommonCertSets* common_sets) { std::vector<CertEntry> entries; entries.reserve(certs.size()); @@ -330,12 +329,12 @@ std::vector<uint64_t> HashCerts(const std::vector<std::string>& certs) { // |in_out| and writes them to |out_entries|. CACHED and COMMON entries are // resolved using |cached_certs| and |common_sets| and written to |out_certs|. // |in_out| is updated to contain the trailing data. -bool ParseEntries(quiche::QuicheStringPiece* in_out, +bool ParseEntries(absl::string_view* in_out, const std::vector<std::string>& cached_certs, const CommonCertSets* common_sets, std::vector<CertEntry>* out_entries, std::vector<std::string>* out_certs) { - quiche::QuicheStringPiece in = *in_out; + absl::string_view in = *in_out; std::vector<uint64_t> cached_hashes; out_entries->clear(); @@ -394,7 +393,7 @@ bool ParseEntries(quiche::QuicheStringPiece* in_out, memcpy(&entry.index, in.data(), sizeof(uint32_t)); in.remove_prefix(sizeof(uint32_t)); - quiche::QuicheStringPiece cert = + absl::string_view cert = common_sets->GetCert(entry.set_hash, entry.index); if (cert.empty()) { return false; @@ -452,8 +451,8 @@ class ScopedZLib { // static std::string CertCompressor::CompressChain( const std::vector<std::string>& certs, - quiche::QuicheStringPiece client_common_set_hashes, - quiche::QuicheStringPiece client_cached_cert_hashes, + absl::string_view client_common_set_hashes, + absl::string_view client_cached_cert_hashes, const CommonCertSets* common_sets) { const std::vector<CertEntry> entries = MatchCerts( certs, client_common_set_hashes, client_cached_cert_hashes, common_sets); @@ -553,7 +552,7 @@ std::string CertCompressor::CompressChain( // static bool CertCompressor::DecompressChain( - quiche::QuicheStringPiece in, + absl::string_view in, const std::vector<std::string>& cached_certs, const CommonCertSets* common_sets, std::vector<std::string>* out_certs) { @@ -564,7 +563,7 @@ bool CertCompressor::DecompressChain( DCHECK_EQ(entries.size(), out_certs->size()); std::unique_ptr<uint8_t[]> uncompressed_data; - quiche::QuicheStringPiece uncompressed; + absl::string_view uncompressed; if (!in.empty()) { if (in.size() < sizeof(uint32_t)) { @@ -609,7 +608,7 @@ bool CertCompressor::DecompressChain( return false; } - uncompressed = quiche::QuicheStringPiece( + uncompressed = absl::string_view( reinterpret_cast<char*>(uncompressed_data.get()), uncompressed_size); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h index dfb4d21c916..a9e9ec90520 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor.h @@ -8,10 +8,10 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/common_cert_set.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,17 +36,16 @@ class QUIC_EXPORT_PRIVATE CertCompressor { // sets known locally and |client_common_set_hashes| contains the hashes of // the common sets known to the peer. |client_cached_cert_hashes| contains // 64-bit, FNV-1a hashes of certificates that the peer already possesses. - static std::string CompressChain( - const std::vector<std::string>& certs, - quiche::QuicheStringPiece client_common_set_hashes, - quiche::QuicheStringPiece client_cached_cert_hashes, - const CommonCertSets* common_sets); + static std::string CompressChain(const std::vector<std::string>& certs, + absl::string_view client_common_set_hashes, + absl::string_view client_cached_cert_hashes, + const CommonCertSets* common_sets); // DecompressChain decompresses the result of |CompressChain|, given in |in|, // into a series of certificates that are written to |out_certs|. // |cached_certs| contains certificates that the peer may have omitted and // |common_sets| contains the common certificate sets known locally. - static bool DecompressChain(quiche::QuicheStringPiece in, + static bool DecompressChain(absl::string_view in, const std::vector<std::string>& cached_certs, const CommonCertSets* common_sets, std::vector<std::string>* out_certs); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc index a7517f4c180..87446acf86a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/cert_compressor_test.cc @@ -7,10 +7,11 @@ #include <memory> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -21,8 +22,8 @@ class CertCompressorTest : public QuicTest {}; TEST_F(CertCompressorTest, EmptyChain) { std::vector<std::string> chain; const std::string compressed = CertCompressor::CompressChain( - chain, quiche::QuicheStringPiece(), quiche::QuicheStringPiece(), nullptr); - EXPECT_EQ("00", quiche::QuicheTextUtils::HexEncode(compressed)); + chain, absl::string_view(), absl::string_view(), nullptr); + EXPECT_EQ("00", absl::BytesToHexString(compressed)); std::vector<std::string> chain2, cached_certs; ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr, @@ -34,10 +35,9 @@ TEST_F(CertCompressorTest, Compressed) { std::vector<std::string> chain; chain.push_back("testcert"); const std::string compressed = CertCompressor::CompressChain( - chain, quiche::QuicheStringPiece(), quiche::QuicheStringPiece(), nullptr); + chain, absl::string_view(), absl::string_view(), nullptr); ASSERT_GE(compressed.size(), 2u); - EXPECT_EQ("0100", - quiche::QuicheTextUtils::HexEncode(compressed.substr(0, 2))); + EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2))); std::vector<std::string> chain2, cached_certs; ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr, @@ -54,15 +54,15 @@ TEST_F(CertCompressorTest, Common) { crypto_test_utils::MockCommonCertSets(chain[0], set_hash, 1)); const std::string compressed = CertCompressor::CompressChain( chain, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(&set_hash), - sizeof(set_hash)), - quiche::QuicheStringPiece(), common_sets.get()); + absl::string_view(reinterpret_cast<const char*>(&set_hash), + sizeof(set_hash)), + absl::string_view(), common_sets.get()); EXPECT_EQ( "03" /* common */ "2a00000000000000" /* set hash 42 */ "01000000" /* index 1 */ "00" /* end of list */, - quiche::QuicheTextUtils::HexEncode(compressed)); + absl::BytesToHexString(compressed)); std::vector<std::string> chain2, cached_certs; ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, @@ -75,14 +75,13 @@ TEST_F(CertCompressorTest, Cached) { std::vector<std::string> chain; chain.push_back("testcert"); uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0]); - quiche::QuicheStringPiece hash_bytes(reinterpret_cast<char*>(&hash), - sizeof(hash)); + absl::string_view hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash)); const std::string compressed = CertCompressor::CompressChain( - chain, quiche::QuicheStringPiece(), hash_bytes, nullptr); + chain, absl::string_view(), hash_bytes, nullptr); - EXPECT_EQ("02" /* cached */ + quiche::QuicheTextUtils::HexEncode(hash_bytes) + + EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) + "00" /* end of list */, - quiche::QuicheTextUtils::HexEncode(compressed)); + absl::BytesToHexString(compressed)); std::vector<std::string> cached_certs, chain2; cached_certs.push_back(chain[0]); @@ -96,37 +95,37 @@ TEST_F(CertCompressorTest, BadInputs) { std::vector<std::string> cached_certs, chain; EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("04") /* bad entry type */, - cached_certs, nullptr, &chain)); + absl::BytesToHexString("04") /* bad entry type */, cached_certs, nullptr, + &chain)); EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("01") /* no terminator */, - cached_certs, nullptr, &chain)); + absl::BytesToHexString("01") /* no terminator */, cached_certs, nullptr, + &chain)); EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("0200") /* hash truncated */, - cached_certs, nullptr, &chain)); + absl::BytesToHexString("0200") /* hash truncated */, cached_certs, + nullptr, &chain)); EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("0300") /* hash and index truncated */, + absl::BytesToHexString("0300") /* hash and index truncated */, cached_certs, nullptr, &chain)); /* without a CommonCertSets */ - EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("03" - "0000000000000000" - "00000000"), - cached_certs, nullptr, &chain)); + EXPECT_FALSE( + CertCompressor::DecompressChain(absl::BytesToHexString("03" + "0000000000000000" + "00000000"), + cached_certs, nullptr, &chain)); std::unique_ptr<CommonCertSets> common_sets( crypto_test_utils::MockCommonCertSets("foo", 42, 1)); /* incorrect hash and index */ - EXPECT_FALSE(CertCompressor::DecompressChain( - quiche::QuicheTextUtils::HexEncode("03" - "a200000000000000" - "00000000"), - cached_certs, nullptr, &chain)); + EXPECT_FALSE( + CertCompressor::DecompressChain(absl::BytesToHexString("03" + "a200000000000000" + "00000000"), + cached_certs, nullptr, &chain)); } } // namespace test 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 36b6d3f693e..6042b9e7cc4 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 @@ -9,6 +9,11 @@ #include <memory> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/match.h" +#include "absl/strings/str_join.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/digest.h" @@ -24,17 +29,14 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_time_utils.h" #include "net/third_party/quiche/src/common/quiche_data_reader.h" +namespace quic { namespace { -using ::quiche::QuicheOptional; -using ::quiche::QuicheStringPiece; using ::quiche::QuicheTextUtils; // The literals below were encoded using `ascii2der | xxd -i`. The comments @@ -101,15 +103,84 @@ PublicKeyType PublicKeyTypeFromSignatureAlgorithm( } } +std::string AttributeNameToString(const CBS& oid_cbs) { + absl::string_view oid = CbsToStringPiece(oid_cbs); + + // We only handle OIDs of form 2.5.4.N, which have binary encoding of + // "55 04 0N". + if (oid.length() == 3 && absl::StartsWith(oid, "\x55\x04")) { + // clang-format off + switch (oid[2]) { + case '\x3': return "CN"; + case '\x7': return "L"; + case '\x8': return "ST"; + case '\xa': return "O"; + case '\xb': return "OU"; + case '\x6': return "C"; + } + // clang-format on + } + + bssl::UniquePtr<char> oid_representation(CBS_asn1_oid_to_text(&oid_cbs)); + if (oid_representation == nullptr) { + return quiche::QuicheStrCat("(", absl::BytesToHexString(oid), ")"); + } + return std::string(oid_representation.get()); +} + } // namespace -namespace quic { +absl::optional<std::string> X509NameAttributeToString(CBS input) { + CBS name, value; + unsigned value_tag; + if (!CBS_get_asn1(&input, &name, CBS_ASN1_OBJECT) || + !CBS_get_any_asn1(&input, &value, &value_tag) || CBS_len(&input) != 0) { + return absl::nullopt; + } + // Note that this does not process encoding of |input| in any way. This works + // fine for the most cases. + return quiche::QuicheStrCat(AttributeNameToString(name), "=", + absl::CHexEscape(CbsToStringPiece(value))); +} + +namespace { + +template <unsigned inner_tag, + char separator, + absl::optional<std::string> (*parser)(CBS)> +absl::optional<std::string> ParseAndJoin(CBS input) { + std::vector<std::string> pieces; + while (CBS_len(&input) != 0) { + CBS attribute; + if (!CBS_get_asn1(&input, &attribute, inner_tag)) { + return absl::nullopt; + } + absl::optional<std::string> formatted = parser(attribute); + if (!formatted.has_value()) { + return absl::nullopt; + } + pieces.push_back(*formatted); + } + + return absl::StrJoin(pieces, std::string({separator})); +} -QuicheOptional<quic::QuicWallTime> ParseDerTime(unsigned tag, - QuicheStringPiece payload) { +absl::optional<std::string> RelativeDistinguishedNameToString(CBS input) { + return ParseAndJoin<CBS_ASN1_SEQUENCE, '+', X509NameAttributeToString>(input); +} + +absl::optional<std::string> DistinguishedNameToString(CBS input) { + return ParseAndJoin<CBS_ASN1_SET, ',', RelativeDistinguishedNameToString>( + input); +} + +} // namespace + +absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag, + absl::string_view payload) { if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) { - QUIC_BUG << "Invalid tag supplied for a DER timestamp"; - return QUICHE_NULLOPT; + QUIC_DLOG(WARNING) << "Invalid tag supplied for a DER timestamp"; + return absl::nullopt; } const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2; @@ -121,7 +192,7 @@ QuicheOptional<quic::QuicWallTime> ParseDerTime(unsigned tag, !reader.ReadDecimal64(2, &second) || reader.ReadRemainingPayload() != "Z") { QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp"; - return QUICHE_NULLOPT; + return absl::nullopt; } if (tag == CBS_ASN1_UTCTIME) { @@ -129,30 +200,30 @@ QuicheOptional<quic::QuicWallTime> ParseDerTime(unsigned tag, year += (year >= 50) ? 1900 : 2000; } - const QuicheOptional<int64_t> unix_time = + const absl::optional<int64_t> unix_time = quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute, second); if (!unix_time.has_value() || *unix_time < 0) { - return QUICHE_NULLOPT; + return absl::nullopt; } return QuicWallTime::FromUNIXSeconds(*unix_time); } PemReadResult ReadNextPemMessage(std::istream* input) { - constexpr QuicheStringPiece kPemBegin = "-----BEGIN "; - constexpr QuicheStringPiece kPemEnd = "-----END "; - constexpr QuicheStringPiece kPemDashes = "-----"; + constexpr absl::string_view kPemBegin = "-----BEGIN "; + constexpr absl::string_view kPemEnd = "-----END "; + constexpr absl::string_view kPemDashes = "-----"; std::string line_buffer, encoded_message_contents, expected_end; bool pending_message = false; PemReadResult result; while (std::getline(*input, line_buffer)) { - QuicheStringPiece line(line_buffer); + absl::string_view line(line_buffer); QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line); // Handle BEGIN lines. - if (!pending_message && QuicheTextUtils::StartsWith(line, kPemBegin) && - QuicheTextUtils::EndsWith(line, kPemDashes)) { + if (!pending_message && absl::StartsWith(line, kPemBegin) && + absl::EndsWith(line, kPemDashes)) { result.type = std::string( line.substr(kPemBegin.size(), line.size() - kPemDashes.size() - kPemBegin.size())); @@ -163,7 +234,7 @@ PemReadResult ReadNextPemMessage(std::istream* input) { // Handle END lines. if (pending_message && line == expected_end) { - QuicheOptional<std::string> data = + absl::optional<std::string> data = QuicheTextUtils::Base64Decode(encoded_message_contents); if (data.has_value()) { result.status = PemReadResult::kOk; @@ -184,7 +255,7 @@ PemReadResult ReadNextPemMessage(std::istream* input) { } std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate( - QuicheStringPiece certificate) { + absl::string_view certificate) { std::unique_ptr<CertificateView> result(new CertificateView()); CBS top = StringPieceToCbs(certificate); @@ -258,6 +329,8 @@ std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate( return nullptr; } + result->subject_der_ = CbsToStringPiece(subject); + unsigned not_before_tag, not_after_tag; CBS not_before, not_after; if (!CBS_get_any_asn1(&validity, ¬_before, ¬_before_tag) || @@ -266,9 +339,9 @@ std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate( QUIC_DLOG(WARNING) << "Failed to extract the validity dates"; return nullptr; } - QuicheOptional<QuicWallTime> not_before_parsed = + absl::optional<QuicWallTime> not_before_parsed = ParseDerTime(not_before_tag, CbsToStringPiece(not_before)); - QuicheOptional<QuicWallTime> not_after_parsed = + absl::optional<QuicWallTime> not_after_parsed = ParseDerTime(not_after_tag, CbsToStringPiece(not_after)); if (!not_before_parsed.has_value() || !not_after_parsed.has_value()) { QUIC_DLOG(WARNING) << "Failed to parse validity dates"; @@ -348,7 +421,7 @@ bool CertificateView::ParseExtensions(CBS extensions) { return false; } - QuicheStringPiece alt_name = CbsToStringPiece(alt_name_cbs); + absl::string_view alt_name = CbsToStringPiece(alt_name_cbs); QuicIpAddress ip_address; // GeneralName ::= CHOICE { switch (alt_name_tag) { @@ -417,8 +490,8 @@ bool CertificateView::ValidatePublicKeyParameters() { } } -bool CertificateView::VerifySignature(QuicheStringPiece data, - QuicheStringPiece signature, +bool CertificateView::VerifySignature(absl::string_view data, + absl::string_view signature, uint16_t signature_algorithm) const { if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) != PublicKeyTypeFromKey(public_key_.get())) { @@ -447,8 +520,13 @@ bool CertificateView::VerifySignature(QuicheStringPiece data, data.size()); } +absl::optional<std::string> CertificateView::GetHumanReadableSubject() const { + CBS input = StringPieceToCbs(subject_der_); + return DistinguishedNameToString(input); +} + std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer( - QuicheStringPiece private_key) { + absl::string_view private_key) { std::unique_ptr<CertificatePrivateKey> result(new CertificatePrivateKey()); CBS private_key_cbs = StringPieceToCbs(private_key); result->private_key_.reset(EVP_parse_private_key(&private_key_cbs)); @@ -506,7 +584,7 @@ skip: return nullptr; } -std::string CertificatePrivateKey::Sign(QuicheStringPiece input, +std::string CertificatePrivateKey::Sign(absl::string_view input, uint16_t signature_algorithm) { if (!ValidForSignatureAlgorithm(signature_algorithm)) { QUIC_BUG << "Mismatch between the requested signature algorithm and the " 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 d06ff78530a..7439ee64401 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 @@ -9,6 +9,8 @@ #include <memory> #include <vector> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/evp.h" @@ -17,8 +19,6 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -43,7 +43,7 @@ class QUIC_EXPORT_PRIVATE CertificateView { // Parses a single DER-encoded X.509 certificate. Returns nullptr on parse // error. static std::unique_ptr<CertificateView> ParseSingleCertificate( - quiche::QuicheStringPiece certificate); + absl::string_view certificate); // Loads all PEM-encoded X.509 certificates found in the |input| stream // without parsing them. Returns an empty vector if any parsing error occurs. @@ -53,17 +53,20 @@ class QUIC_EXPORT_PRIVATE CertificateView { QuicWallTime validity_end() const { return validity_end_; } const EVP_PKEY* public_key() const { return public_key_.get(); } - const std::vector<quiche::QuicheStringPiece>& subject_alt_name_domains() - const { + const std::vector<absl::string_view>& subject_alt_name_domains() const { return subject_alt_name_domains_; } const std::vector<QuicIpAddress>& subject_alt_name_ips() const { return subject_alt_name_ips_; } + // Returns a human-readable representation of the Subject field. The format + // is similar to RFC 2253, but does not match it exactly. + absl::optional<std::string> GetHumanReadableSubject() const; + // |signature_algorithm| is a TLS signature algorithm ID. - bool VerifySignature(quiche::QuicheStringPiece data, - quiche::QuicheStringPiece signature, + bool VerifySignature(absl::string_view data, + absl::string_view signature, uint16_t signature_algorithm) const; private: @@ -71,12 +74,13 @@ class QUIC_EXPORT_PRIVATE CertificateView { QuicWallTime validity_start_ = QuicWallTime::Zero(); QuicWallTime validity_end_ = QuicWallTime::Zero(); + absl::string_view subject_der_; // Public key parsed from SPKI. bssl::UniquePtr<EVP_PKEY> public_key_; // SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6 - std::vector<quiche::QuicheStringPiece> subject_alt_name_domains_; + std::vector<absl::string_view> subject_alt_name_domains_; std::vector<QuicIpAddress> subject_alt_name_ips_; // Called from ParseSingleCertificate(). @@ -93,7 +97,7 @@ class QUIC_EXPORT_PRIVATE CertificatePrivateKey { // Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key. static std::unique_ptr<CertificatePrivateKey> LoadFromDer( - quiche::QuicheStringPiece private_key); + absl::string_view private_key); // Loads a private key from a PEM file formatted according to RFC 7468. Also // supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY"). @@ -101,8 +105,7 @@ class QUIC_EXPORT_PRIVATE CertificatePrivateKey { std::istream* input); // |signature_algorithm| is a TLS signature algorithm ID. - std::string Sign(quiche::QuicheStringPiece input, - uint16_t signature_algorithm); + std::string Sign(absl::string_view input, uint16_t signature_algorithm); // Verifies that the private key in question matches the public key of the // certificate |view|. @@ -120,11 +123,15 @@ class QUIC_EXPORT_PRIVATE CertificatePrivateKey { bssl::UniquePtr<EVP_PKEY> private_key_; }; +// Parses a DER-encoded X.509 NameAttribute. Exposed primarily for testing. +QUIC_EXPORT_PRIVATE absl::optional<std::string> X509NameAttributeToString( + CBS input); + // Parses a DER time based on the specified ASN.1 tag. Exposed primarily for // testing. -QUIC_EXPORT_PRIVATE quiche::QuicheOptional<quic::QuicWallTime> ParseDerTime( +QUIC_EXPORT_PRIVATE absl::optional<quic::QuicWallTime> ParseDerTime( unsigned tag, - quiche::QuicheStringPiece payload); + absl::string_view payload); } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc index e2de1ba7efe..e66f4f917bc 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_der_fuzzer.cc @@ -9,7 +9,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string input(reinterpret_cast<const char*>(data), size); - quic::CertificateView::ParseSingleCertificate(input); + std::unique_ptr<quic::CertificateView> view = + quic::CertificateView::ParseSingleCertificate(input); + if (view != nullptr) { + view->GetHumanReadableSubject(); + } quic::CertificatePrivateKey::LoadFromDer(input); return 0; } 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 e7ce0cea5a0..46e30f1285f 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 @@ -7,15 +7,17 @@ #include <memory> #include <sstream> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/ssl.h" +#include "net/third_party/quiche/src/quic/core/crypto/boring_utils.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/test_certificates.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_time_utils.h" namespace quic { @@ -43,9 +45,9 @@ TEST(CertificateViewTest, Parse) { ASSERT_TRUE(view != nullptr); EXPECT_THAT(view->subject_alt_name_domains(), - ElementsAre(quiche::QuicheStringPiece("www.example.org"), - quiche::QuicheStringPiece("mail.example.org"), - quiche::QuicheStringPiece("mail.example.com"))); + ElementsAre(absl::string_view("www.example.org"), + absl::string_view("mail.example.org"), + absl::string_view("mail.example.com"))); EXPECT_THAT(view->subject_alt_name_ips(), ElementsAre(QuicIpAddress::Loopback4())); EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA); @@ -56,6 +58,9 @@ 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("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1", + view->GetHumanReadableSubject()); } TEST(CertificateViewTest, ParseCertWithUnknownSanType) { @@ -148,27 +153,27 @@ TEST(CertificateViewTest, DerTime) { Optional(QuicWallTime::FromUNIXSeconds(24))); EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "200101000024Z").has_value()); - EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), QUICHE_NULLOPT); + EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.001Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"), - QUICHE_NULLOPT); + absl::nullopt); EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value()); // This should parse as 1950, which predates UNIX epoch. @@ -177,7 +182,29 @@ TEST(CertificateViewTest, DerTime) { EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"), Optional(QuicWallTime::FromUNIXSeconds(23 * 3600))); EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"), - QUICHE_NULLOPT); + absl::nullopt); +} + +TEST(CertificateViewTest, NameAttribute) { + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.112411 } + // UTF8String { "Test" } + std::string unknown_oid = + absl::HexStringToBytes("060b2a864886f712040186ee1b0c0454657374"); + EXPECT_EQ("1.2.840.113554.4.1.112411=Test", + X509NameAttributeToString(StringPieceToCbs(unknown_oid))); + + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "Bell: \x07" } + std::string non_printable = + absl::HexStringToBytes("06035504030c0742656c6c3a2007"); + EXPECT_EQ(R"(CN=Bell: \x07)", + X509NameAttributeToString(StringPieceToCbs(non_printable))); + + // OBJECT_IDENTIFIER { "\x55\x80" } + // UTF8String { "Test" } + std::string invalid_oid = absl::HexStringToBytes("060255800c0454657374"); + EXPECT_EQ("(5580)=Test", + X509NameAttributeToString(StringPieceToCbs(invalid_oid))); } } // namespace diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc index e2f55aa32ab..b860348b13f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.cc @@ -32,4 +32,12 @@ uint32_t ChaCha20Poly1305Decrypter::cipher_id() const { return TLS1_CK_CHACHA20_POLY1305_SHA256; } +QuicPacketCount ChaCha20Poly1305Decrypter::GetIntegrityLimit() const { + // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage + static_assert(kMaxIncomingPacketSize < 16384, + "This key limit requires limits on decryption payload sizes"); + return 68719476736U; +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h index 50bb348e98c..2e4b32b36f4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h @@ -33,6 +33,7 @@ class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter ~ChaCha20Poly1305Decrypter() override; uint32_t cipher_id() const override; + QuicPacketCount GetIntegrityLimit() const override; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc index 83e52b10e2c..3711104fc4f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc @@ -7,10 +7,11 @@ #include <memory> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -115,12 +116,12 @@ namespace test { // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing // in an nonce and also to allocate the buffer needed for the plaintext. QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view ciphertext) { uint64_t packet_number; - quiche::QuicheStringPiece nonce_prefix(nonce.data(), - nonce.size() - sizeof(packet_number)); + absl::string_view nonce_prefix(nonce.data(), + nonce.size() - sizeof(packet_number)); decrypter->SetNoncePrefix(nonce_prefix); memcpy(&packet_number, nonce.data() + nonce_prefix.size(), sizeof(packet_number)); @@ -143,15 +144,14 @@ TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) { bool has_pt = test_vectors[i].pt; // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv); - std::string fixed = - quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct); + std::string key = absl::HexStringToBytes(test_vectors[i].key); + std::string iv = absl::HexStringToBytes(test_vectors[i].iv); + std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed); + std::string aad = absl::HexStringToBytes(test_vectors[i].aad); + std::string ct = absl::HexStringToBytes(test_vectors[i].ct); std::string pt; if (has_pt) { - pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt); + pt = absl::HexStringToBytes(test_vectors[i].pt); } ChaCha20Poly1305Decrypter decrypter; @@ -160,8 +160,7 @@ TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) { &decrypter, fixed + iv, // This deliberately tests that the decrypter can handle an AAD that // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. - quiche::QuicheStringPiece(aad.length() ? aad.data() : nullptr, - aad.length()), + absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()), ct)); if (!decrypted) { EXPECT_FALSE(has_pt); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc index 37b899f90f6..f66f31c46b5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.cc @@ -27,4 +27,11 @@ ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter() ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {} +QuicPacketCount ChaCha20Poly1305Encrypter::GetConfidentialityLimit() const { + // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the + // number of possible packets (2^62) and so can be disregarded. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage + return std::numeric_limits<QuicPacketCount>::max(); +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h index 72007883ffd..98f6ff042bd 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h @@ -29,6 +29,8 @@ class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) = delete; ~ChaCha20Poly1305Encrypter() override; + + QuicPacketCount GetConfidentialityLimit() const override; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc index 47ee3d03a06..91b32ef5c3c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter_test.cc @@ -7,12 +7,12 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -72,9 +72,9 @@ namespace test { // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing // in an nonce and also to allocate the buffer needed for the ciphertext. QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext) { size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]); @@ -92,7 +92,7 @@ TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) { ChaCha20Poly1305Encrypter encrypter; ChaCha20Poly1305Decrypter decrypter; - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[0].key); + std::string key = absl::HexStringToBytes(test_vectors[0].key); ASSERT_TRUE(encrypter.SetKey(key)); ASSERT_TRUE(decrypter.SetKey(key)); ASSERT_TRUE(encrypter.SetNoncePrefix("abcd")); @@ -105,24 +105,23 @@ TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) { size_t len; ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext, encrypted, &len, - QUICHE_ARRAYSIZE(encrypted))); - quiche::QuicheStringPiece ciphertext(encrypted, len); + ABSL_ARRAYSIZE(encrypted))); + absl::string_view ciphertext(encrypted, len); char decrypted[1024]; ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data, ciphertext, decrypted, &len, - QUICHE_ARRAYSIZE(decrypted))); + ABSL_ARRAYSIZE(decrypted))); } TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) { for (size_t i = 0; test_vectors[i].key != nullptr; i++) { // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key); - std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv); - std::string fixed = - quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct); + std::string key = absl::HexStringToBytes(test_vectors[i].key); + std::string pt = absl::HexStringToBytes(test_vectors[i].pt); + std::string iv = absl::HexStringToBytes(test_vectors[i].iv); + std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed); + std::string aad = absl::HexStringToBytes(test_vectors[i].aad); + std::string ct = absl::HexStringToBytes(test_vectors[i].ct); ChaCha20Poly1305Encrypter encrypter; ASSERT_TRUE(encrypter.SetKey(key)); @@ -130,8 +129,7 @@ TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) { &encrypter, fixed + iv, // This deliberately tests that the encrypter can handle an AAD that // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. - quiche::QuicheStringPiece(aad.length() ? aad.data() : nullptr, - aad.length()), + absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()), pt)); ASSERT_TRUE(encrypted.get()); EXPECT_EQ(12u, ct.size() - pt.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc index 8d98da89bf1..7bf84785127 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc @@ -34,4 +34,12 @@ uint32_t ChaCha20Poly1305TlsDecrypter::cipher_id() const { return TLS1_CK_CHACHA20_POLY1305_SHA256; } +QuicPacketCount ChaCha20Poly1305TlsDecrypter::GetIntegrityLimit() const { + // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage + static_assert(kMaxIncomingPacketSize < 16384, + "This key limit requires limits on decryption payload sizes"); + return 68719476736U; +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h index 702fb8c7bcf..04ee5b8b865 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h @@ -31,6 +31,7 @@ class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsDecrypter ~ChaCha20Poly1305TlsDecrypter() override; uint32_t cipher_id() const override; + QuicPacketCount GetIntegrityLimit() const override; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc index 9127cd4634a..431f0121c7d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc @@ -7,10 +7,11 @@ #include <memory> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -115,9 +116,9 @@ namespace test { // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing // in an nonce and also to allocate the buffer needed for the plaintext. QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view ciphertext) { decrypter->SetIV(nonce); std::unique_ptr<char[]> output(new char[ciphertext.length()]); size_t output_length = 0; @@ -138,15 +139,14 @@ TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) { bool has_pt = test_vectors[i].pt; // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv); - std::string fixed = - quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct); + std::string key = absl::HexStringToBytes(test_vectors[i].key); + std::string iv = absl::HexStringToBytes(test_vectors[i].iv); + std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed); + std::string aad = absl::HexStringToBytes(test_vectors[i].aad); + std::string ct = absl::HexStringToBytes(test_vectors[i].ct); std::string pt; if (has_pt) { - pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt); + pt = absl::HexStringToBytes(test_vectors[i].pt); } ChaCha20Poly1305TlsDecrypter decrypter; @@ -155,8 +155,7 @@ TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) { &decrypter, fixed + iv, // This deliberately tests that the decrypter can handle an AAD that // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. - quiche::QuicheStringPiece(aad.length() ? aad.data() : nullptr, - aad.length()), + absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()), ct)); if (!decrypted) { EXPECT_FALSE(has_pt); @@ -173,14 +172,14 @@ TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) { TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) { ChaCha20Poly1305TlsDecrypter decrypter; - std::string key = quiche::QuicheTextUtils::HexDecode( + std::string key = absl::HexStringToBytes( "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7"); std::string sample = - quiche::QuicheTextUtils::HexDecode("1210d91cceb45c716b023f492c29e612"); + absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612"); QuicDataReader sample_reader(sample.data(), sample.size()); ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key)); std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader); - std::string expected_mask = quiche::QuicheTextUtils::HexDecode("1cc2cd98dc"); + std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc index c650b27f40e..a03a14c065e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc @@ -27,4 +27,11 @@ ChaCha20Poly1305TlsEncrypter::ChaCha20Poly1305TlsEncrypter() ChaCha20Poly1305TlsEncrypter::~ChaCha20Poly1305TlsEncrypter() {} +QuicPacketCount ChaCha20Poly1305TlsEncrypter::GetConfidentialityLimit() const { + // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the + // number of possible packets (2^62) and so can be disregarded. + // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage + return std::numeric_limits<QuicPacketCount>::max(); +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h index 0ef7ae8e21a..f83141fd626 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter.h @@ -27,6 +27,8 @@ class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsEncrypter ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) = delete; ~ChaCha20Poly1305TlsEncrypter() override; + + QuicPacketCount GetConfidentialityLimit() const override; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc index dd642a323a8..1918d2ab878 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc @@ -7,12 +7,13 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -72,9 +73,9 @@ namespace test { // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing // in an nonce and also to allocate the buffer needed for the ciphertext. QuicData* EncryptWithNonce(ChaCha20Poly1305TlsEncrypter* encrypter, - quiche::QuicheStringPiece nonce, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext) { + absl::string_view nonce, + absl::string_view associated_data, + absl::string_view plaintext) { size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]); @@ -92,7 +93,7 @@ TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) { ChaCha20Poly1305TlsEncrypter encrypter; ChaCha20Poly1305TlsDecrypter decrypter; - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[0].key); + std::string key = absl::HexStringToBytes(test_vectors[0].key); ASSERT_TRUE(encrypter.SetKey(key)); ASSERT_TRUE(decrypter.SetKey(key)); ASSERT_TRUE(encrypter.SetIV("abcdefghijkl")); @@ -105,24 +106,23 @@ TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) { size_t len; ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext, encrypted, &len, - QUICHE_ARRAYSIZE(encrypted))); - quiche::QuicheStringPiece ciphertext(encrypted, len); + ABSL_ARRAYSIZE(encrypted))); + absl::string_view ciphertext(encrypted, len); char decrypted[1024]; ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data, ciphertext, decrypted, &len, - QUICHE_ARRAYSIZE(decrypted))); + ABSL_ARRAYSIZE(decrypted))); } TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) { for (size_t i = 0; test_vectors[i].key != nullptr; i++) { // Decode the test vector. - std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key); - std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt); - std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv); - std::string fixed = - quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed); - std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad); - std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct); + std::string key = absl::HexStringToBytes(test_vectors[i].key); + std::string pt = absl::HexStringToBytes(test_vectors[i].pt); + std::string iv = absl::HexStringToBytes(test_vectors[i].iv); + std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed); + std::string aad = absl::HexStringToBytes(test_vectors[i].aad); + std::string ct = absl::HexStringToBytes(test_vectors[i].ct); ChaCha20Poly1305TlsEncrypter encrypter; ASSERT_TRUE(encrypter.SetKey(key)); @@ -130,8 +130,7 @@ TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) { &encrypter, fixed + iv, // This deliberately tests that the encrypter can handle an AAD that // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. - quiche::QuicheStringPiece(aad.length() ? aad.data() : nullptr, - aad.length()), + absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()), pt)); ASSERT_TRUE(encrypted.get()); EXPECT_EQ(16u, ct.size() - pt.size()); @@ -159,13 +158,13 @@ TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetCiphertextSize) { TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) { ChaCha20Poly1305TlsEncrypter encrypter; - std::string key = quiche::QuicheTextUtils::HexDecode( + std::string key = absl::HexStringToBytes( "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7"); std::string sample = - quiche::QuicheTextUtils::HexDecode("1210d91cceb45c716b023f492c29e612"); + absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612"); ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key)); std::string mask = encrypter.GenerateHeaderProtectionMask(sample); - std::string expected_mask = quiche::QuicheTextUtils::HexDecode("1cc2cd98dc"); + std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc"); quiche::test::CompareCharArraysWithHexError( "header protection mask", mask.data(), mask.size(), expected_mask.data(), expected_mask.size()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc index bc09b667d5e..1fccc5d1b9d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc @@ -6,17 +6,16 @@ #include <cstdint> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/chacha.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { -bool ChaChaBaseDecrypter::SetHeaderProtectionKey( - quiche::QuicheStringPiece key) { +bool ChaChaBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) { if (key.size() != GetKeySize()) { QUIC_BUG << "Invalid key size for header protection"; return false; @@ -27,7 +26,7 @@ bool ChaChaBaseDecrypter::SetHeaderProtectionKey( std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask( QuicDataReader* sample_reader) { - quiche::QuicheStringPiece sample; + absl::string_view sample; if (!sample_reader->ReadStringPiece(&sample, 16)) { return std::string(); } @@ -36,9 +35,9 @@ std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask( QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER) .ReadUInt32(&counter); const uint8_t zeroes[] = {0, 0, 0, 0, 0}; - std::string out(QUICHE_ARRAYSIZE(zeroes), 0); + std::string out(ABSL_ARRAYSIZE(zeroes), 0); CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())), - zeroes, QUICHE_ARRAYSIZE(zeroes), pne_key_, nonce, counter); + zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter); return out; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h index 24ca820a9ec..610bc594b77 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.h @@ -7,9 +7,9 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/aead_base_decrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -17,7 +17,7 @@ class QUIC_EXPORT_PRIVATE ChaChaBaseDecrypter : public AeadBaseDecrypter { public: using AeadBaseDecrypter::AeadBaseDecrypter; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; + bool SetHeaderProtectionKey(absl::string_view key) override; std::string GenerateHeaderProtectionMask( QuicDataReader* sample_reader) override; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc index 7fdc019e70c..0b9d3444d2b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc @@ -4,17 +4,16 @@ #include "net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/chacha.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { -bool ChaChaBaseEncrypter::SetHeaderProtectionKey( - quiche::QuicheStringPiece key) { +bool ChaChaBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) { if (key.size() != GetKeySize()) { QUIC_BUG << "Invalid key size for header protection"; return false; @@ -24,7 +23,7 @@ bool ChaChaBaseEncrypter::SetHeaderProtectionKey( } std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) { + absl::string_view sample) { if (sample.size() != 16) { return std::string(); } @@ -33,9 +32,9 @@ std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask( QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER) .ReadUInt32(&counter); const uint8_t zeroes[] = {0, 0, 0, 0, 0}; - std::string out(QUICHE_ARRAYSIZE(zeroes), 0); + std::string out(ABSL_ARRAYSIZE(zeroes), 0); CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())), - zeroes, QUICHE_ARRAYSIZE(zeroes), pne_key_, nonce, counter); + zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter); return out; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h index 16d1df1020b..97385c31364 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.h @@ -7,9 +7,9 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -17,9 +17,8 @@ class QUIC_EXPORT_PRIVATE ChaChaBaseEncrypter : public AeadBaseEncrypter { public: using AeadBaseEncrypter::AeadBaseEncrypter; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; - std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) override; + bool SetHeaderProtectionKey(absl::string_view key) override; + std::string GenerateHeaderProtectionMask(absl::string_view sample) override; private: // The key used for packet number encryption. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc index facd552772b..2d30147ef82 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.cc @@ -6,12 +6,12 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/ec.h" #include "third_party/boringssl/src/include/openssl/ecdsa.h" #include "third_party/boringssl/src/include/openssl/nid.h" #include "third_party/boringssl/src/include/openssl/sha.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -21,16 +21,16 @@ const char ChannelIDVerifier::kContextStr[] = "QUIC ChannelID"; const char ChannelIDVerifier::kClientToServerStr[] = "client -> server"; // static -bool ChannelIDVerifier::Verify(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece signed_data, - quiche::QuicheStringPiece signature) { +bool ChannelIDVerifier::Verify(absl::string_view key, + absl::string_view signed_data, + absl::string_view signature) { return VerifyRaw(key, signed_data, signature, true); } // static -bool ChannelIDVerifier::VerifyRaw(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece signed_data, - quiche::QuicheStringPiece signature, +bool ChannelIDVerifier::VerifyRaw(absl::string_view key, + absl::string_view signed_data, + absl::string_view signature, bool is_channel_id_signature) { if (key.size() != 32 * 2 || signature.size() != 32 * 2) { return false; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h index c04aac33c06..e176cdb0676 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id.h @@ -8,9 +8,9 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -30,17 +30,17 @@ class QUIC_EXPORT_PRIVATE ChannelIDVerifier { // Verify returns true iff |signature| is a valid signature of |signed_data| // by |key|. - static bool Verify(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece signed_data, - quiche::QuicheStringPiece signature); + static bool Verify(absl::string_view key, + absl::string_view signed_data, + absl::string_view signature); // FOR TESTING ONLY: VerifyRaw returns true iff |signature| is a valid // signature of |signed_data| by |key|. |is_channel_id_signature| indicates // whether |signature| is a ChannelID signature (with kContextStr prepended // to the data to be signed). - static bool VerifyRaw(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece signed_data, - quiche::QuicheStringPiece signature, + static bool VerifyRaw(absl::string_view key, + absl::string_view signed_data, + absl::string_view signature, bool is_channel_id_signature); }; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc index d4a14cd88a4..cd95539d541 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/channel_id_test.cc @@ -7,9 +7,9 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -275,12 +275,11 @@ TEST_F(ChannelIDTest, VerifyKnownAnswerTest) { EXPECT_EQ(sizeof(signature) / 2, r_len); EXPECT_EQ(sizeof(signature) / 2, s_len); - EXPECT_EQ( - test_vector[i].result, - ChannelIDVerifier::VerifyRaw( - quiche::QuicheStringPiece(key, sizeof(key)), - quiche::QuicheStringPiece(msg, msg_len), - quiche::QuicheStringPiece(signature, sizeof(signature)), false)); + EXPECT_EQ(test_vector[i].result, + ChannelIDVerifier::VerifyRaw( + absl::string_view(key, sizeof(key)), + absl::string_view(msg, msg_len), + absl::string_view(signature, sizeof(signature)), false)); } } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc index 0ccbf2d3d0c..fa66c7292cb 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.cc @@ -6,9 +6,9 @@ #include <cstddef> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -56,7 +56,7 @@ const uint64_t kSetHashes[] = { // Compare returns a value less than, equal to or greater than zero if |a| is // lexicographically less than, equal to or greater than |b|, respectively. -int Compare(quiche::QuicheStringPiece a, const unsigned char* b, size_t b_len) { +int Compare(absl::string_view a, const unsigned char* b, size_t b_len) { size_t len = a.size(); if (len > b_len) { len = b_len; @@ -79,18 +79,16 @@ int Compare(quiche::QuicheStringPiece a, const unsigned char* b, size_t b_len) { class CommonCertSetsQUIC : public CommonCertSets { public: // CommonCertSets interface. - quiche::QuicheStringPiece GetCommonHashes() const override { - return quiche::QuicheStringPiece( - reinterpret_cast<const char*>(kSetHashes), - sizeof(uint64_t) * QUICHE_ARRAYSIZE(kSetHashes)); + absl::string_view GetCommonHashes() const override { + return absl::string_view(reinterpret_cast<const char*>(kSetHashes), + sizeof(uint64_t) * ABSL_ARRAYSIZE(kSetHashes)); } - quiche::QuicheStringPiece GetCert(uint64_t hash, - uint32_t index) const override { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kSets); i++) { + absl::string_view GetCert(uint64_t hash, uint32_t index) const override { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kSets); i++) { if (kSets[i].hash == hash) { if (index < kSets[i].num_certs) { - return quiche::QuicheStringPiece( + return absl::string_view( reinterpret_cast<const char*>(kSets[i].certs[index]), kSets[i].lens[index]); } @@ -98,11 +96,11 @@ class CommonCertSetsQUIC : public CommonCertSets { } } - return quiche::QuicheStringPiece(); + return absl::string_view(); } - bool MatchCert(quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece common_set_hashes, + bool MatchCert(absl::string_view cert, + absl::string_view common_set_hashes, uint64_t* out_hash, uint32_t* out_index) const override { if (common_set_hashes.size() % sizeof(uint64_t) != 0) { @@ -114,7 +112,7 @@ class CommonCertSetsQUIC : public CommonCertSets { memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t), sizeof(uint64_t)); - for (size_t j = 0; j < QUICHE_ARRAYSIZE(kSets); j++) { + for (size_t j = 0; j < ABSL_ARRAYSIZE(kSets); j++) { if (kSets[j].hash != hash) { continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h index af211ad79ff..ae83e1ddbf5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set.h @@ -7,9 +7,9 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -22,23 +22,22 @@ class QUIC_EXPORT_PRIVATE CommonCertSets { // GetInstanceQUIC returns the standard QUIC common certificate sets. static const CommonCertSets* GetInstanceQUIC(); - // GetCommonHashes returns a quiche::QuicheStringPiece containing the hashes + // GetCommonHashes returns a absl::string_view containing the hashes // of common sets supported by this object. The 64-bit hashes are concatenated - // in the quiche::QuicheStringPiece. - virtual quiche::QuicheStringPiece GetCommonHashes() const = 0; + // in the absl::string_view. + virtual absl::string_view GetCommonHashes() const = 0; // GetCert returns a specific certificate (at index |index|) in the common // set identified by |hash|. If no such certificate is known, an empty - // quiche::QuicheStringPiece is returned. - virtual quiche::QuicheStringPiece GetCert(uint64_t hash, - uint32_t index) const = 0; + // absl::string_view is returned. + virtual absl::string_view GetCert(uint64_t hash, uint32_t index) const = 0; // MatchCert tries to find |cert| in one of the common certificate sets // identified by |common_set_hashes|. On success it puts the hash of the // set in |out_hash|, the index of |cert| in the set in |out_index| and // returns true. Otherwise it returns false. - virtual bool MatchCert(quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece common_set_hashes, + virtual bool MatchCert(absl::string_view cert, + absl::string_view common_set_hashes, uint64_t* out_hash, uint32_t* out_index) const = 0; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc index 537bab970a6..8c9a67bafe8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_empty.cc @@ -6,9 +6,9 @@ #include <cstddef> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -17,17 +17,17 @@ namespace { class CommonCertSetsEmpty : public CommonCertSets { public: // CommonCertSets interface. - quiche::QuicheStringPiece GetCommonHashes() const override { - return quiche::QuicheStringPiece(); + absl::string_view GetCommonHashes() const override { + return absl::string_view(); } - quiche::QuicheStringPiece GetCert(uint64_t /* hash */, - uint32_t /* index */) const override { - return quiche::QuicheStringPiece(); + absl::string_view GetCert(uint64_t /* hash */, + uint32_t /* index */) const override { + return absl::string_view(); } - bool MatchCert(quiche::QuicheStringPiece /* cert */, - quiche::QuicheStringPiece /* common_set_hashes */, + bool MatchCert(absl::string_view /* cert */, + absl::string_view /* common_set_hashes */, uint64_t* /* out_hash */, uint32_t* /* out_index */) const override { return false; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc index 148914d02e0..01996c33e15 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/common_cert_set_test.cc @@ -6,8 +6,8 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -193,44 +193,44 @@ static const unsigned char kGIACertificate3[] = { class CommonCertSetsTest : public QuicTest {}; TEST_F(CommonCertSetsTest, FindGIA_2) { - quiche::QuicheStringPiece gia(reinterpret_cast<const char*>(kGIACertificate2), - sizeof(kGIACertificate2)); + absl::string_view gia(reinterpret_cast<const char*>(kGIACertificate2), + sizeof(kGIACertificate2)); const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); // Common Cert Set 2's hash. const uint64_t in_hash = UINT64_C(0xe81a92926081e801); uint64_t hash; uint32_t index; - ASSERT_TRUE(sets->MatchCert( - gia, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(&in_hash), - sizeof(in_hash)), - &hash, &index)); + ASSERT_TRUE( + sets->MatchCert(gia, + absl::string_view(reinterpret_cast<const char*>(&in_hash), + sizeof(in_hash)), + &hash, &index)); EXPECT_EQ(in_hash, hash); - quiche::QuicheStringPiece gia_copy = sets->GetCert(hash, index); + absl::string_view gia_copy = sets->GetCert(hash, index); EXPECT_FALSE(gia_copy.empty()); ASSERT_EQ(gia.size(), gia_copy.size()); EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size())); } TEST_F(CommonCertSetsTest, FindGIA_3) { - quiche::QuicheStringPiece gia(reinterpret_cast<const char*>(kGIACertificate3), - sizeof(kGIACertificate3)); + absl::string_view gia(reinterpret_cast<const char*>(kGIACertificate3), + sizeof(kGIACertificate3)); const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); // Common Cert Set 3's hash. const uint64_t in_hash = UINT64_C(0x918215a28680ed7e); uint64_t hash; uint32_t index; - ASSERT_TRUE(sets->MatchCert( - gia, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(&in_hash), - sizeof(in_hash)), - &hash, &index)); + ASSERT_TRUE( + sets->MatchCert(gia, + absl::string_view(reinterpret_cast<const char*>(&in_hash), + sizeof(in_hash)), + &hash, &index)); EXPECT_EQ(in_hash, hash); - quiche::QuicheStringPiece gia_copy = sets->GetCert(hash, index); + absl::string_view gia_copy = sets->GetCert(hash, index); EXPECT_FALSE(gia_copy.empty()); ASSERT_EQ(gia.size(), gia_copy.size()); EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size())); @@ -238,15 +238,15 @@ TEST_F(CommonCertSetsTest, FindGIA_3) { TEST_F(CommonCertSetsTest, NonMatch) { const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); - quiche::QuicheStringPiece not_a_cert("hello"); + absl::string_view not_a_cert("hello"); const uint64_t in_hash = UINT64_C(0xc9fef74053f99f39); uint64_t hash; uint32_t index; - EXPECT_FALSE(sets->MatchCert( - not_a_cert, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(&in_hash), - sizeof(in_hash)), - &hash, &index)); + EXPECT_FALSE( + sets->MatchCert(not_a_cert, + absl::string_view(reinterpret_cast<const char*>(&in_hash), + sizeof(in_hash)), + &hash, &index)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc index 6a18884f6bd..2a3f7958034 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc @@ -7,15 +7,15 @@ #include <string> #include <utility> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -60,7 +60,7 @@ CryptoFramer::~CryptoFramer() {} // static std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage( - quiche::QuicheStringPiece in) { + absl::string_view in) { OneShotVisitor visitor; CryptoFramer framer; @@ -81,12 +81,12 @@ const std::string& CryptoFramer::error_detail() const { return error_detail_; } -bool CryptoFramer::ProcessInput(quiche::QuicheStringPiece input, +bool CryptoFramer::ProcessInput(absl::string_view input, EncryptionLevel /*level*/) { return ProcessInput(input); } -bool CryptoFramer::ProcessInput(quiche::QuicheStringPiece input) { +bool CryptoFramer::ProcessInput(absl::string_view input) { DCHECK_EQ(QUIC_NO_ERROR, error_); if (error_ != QUIC_NO_ERROR) { return false; @@ -121,7 +121,7 @@ void CryptoFramer::ForceHandshake() { QuicDataReader reader(buffer_.data(), buffer_.length(), quiche::HOST_BYTE_ORDER); for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) { - quiche::QuicheStringPiece value; + absl::string_view value; if (reader.BytesRemaining() < item.second) { break; } @@ -243,7 +243,7 @@ void CryptoFramer::Clear() { state_ = STATE_READING_TAG; } -QuicErrorCode CryptoFramer::Process(quiche::QuicheStringPiece input) { +QuicErrorCode CryptoFramer::Process(absl::string_view input) { // Add this data to the buffer. buffer_.append(input.data(), input.length()); QuicDataReader reader(buffer_.data(), buffer_.length(), @@ -258,7 +258,7 @@ QuicErrorCode CryptoFramer::Process(quiche::QuicheStringPiece input) { reader.ReadTag(&message_tag); message_.set_tag(message_tag); state_ = STATE_READING_NUM_ENTRIES; - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case STATE_READING_NUM_ENTRIES: if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) { break; @@ -274,7 +274,7 @@ QuicErrorCode CryptoFramer::Process(quiche::QuicheStringPiece input) { tags_and_lengths_.reserve(num_entries_); state_ = STATE_READING_TAGS_AND_LENGTHS; values_len_ = 0; - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case STATE_READING_TAGS_AND_LENGTHS: { if (reader.BytesRemaining() < num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) { @@ -308,7 +308,7 @@ QuicErrorCode CryptoFramer::Process(quiche::QuicheStringPiece input) { } values_len_ = last_end_offset; state_ = STATE_READING_VALUES; - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; } case STATE_READING_VALUES: if (reader.BytesRemaining() < values_len_) { @@ -319,7 +319,7 @@ QuicErrorCode CryptoFramer::Process(quiche::QuicheStringPiece input) { << values_len_ - reader.BytesRemaining() << " bytes."; } for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) { - quiche::QuicheStringPiece value; + absl::string_view value; if (!reader.ReadStringPiece(&value, item.second)) { DCHECK(process_truncated_messages_); // Store an empty value. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h index 8dc0d96eba1..e7289ebed2f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.h @@ -12,10 +12,10 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -43,10 +43,10 @@ class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser { ~CryptoFramer() override; // ParseMessage parses exactly one message from the given - // quiche::QuicheStringPiece. If there is an error, the message is truncated, + // absl::string_view. If there is an error, the message is truncated, // or the message has trailing garbage then nullptr will be returned. static std::unique_ptr<CryptoHandshakeMessage> ParseMessage( - quiche::QuicheStringPiece in); + absl::string_view in); // Set callbacks to be called from the framer. A visitor must be set, or // else the framer will crash. It is acceptable for the visitor to do @@ -63,9 +63,8 @@ class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser { // false if there was an error, and true otherwise. ProcessInput optionally // takes an EncryptionLevel, but it is ignored. The variant with the // EncryptionLevel is provided to match the CryptoMessageParser interface. - bool ProcessInput(quiche::QuicheStringPiece input, - EncryptionLevel level) override; - bool ProcessInput(quiche::QuicheStringPiece input); + bool ProcessInput(absl::string_view input, EncryptionLevel level) override; + bool ProcessInput(absl::string_view input); // Returns the number of bytes of buffered input data remaining to be // parsed. @@ -96,7 +95,7 @@ class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser { // Process does does the work of |ProcessInput|, but returns an error code, // doesn't set error_ and doesn't call |visitor_->OnError()|. - QuicErrorCode Process(quiche::QuicheStringPiece input); + QuicErrorCode Process(absl::string_view input); static bool WritePadTag(QuicDataWriter* writer, size_t pad_length, diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc index d598c4956d1..033e6248b90 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer_test.cc @@ -8,6 +8,8 @@ #include <memory> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" @@ -15,8 +17,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" namespace quic { @@ -85,7 +85,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessage) { ASSERT_TRUE(data != nullptr); quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { @@ -121,7 +121,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) { @@ -148,7 +148,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) { @@ -198,7 +198,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) { @@ -234,7 +234,7 @@ TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST(CryptoFramerTest, ProcessInput) { @@ -264,7 +264,7 @@ TEST(CryptoFramerTest, ProcessInput) { }; EXPECT_TRUE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_EQ(0u, framer.InputBytesRemaining()); EXPECT_EQ(0, visitor.error_count_); ASSERT_EQ(1u, visitor.messages_.size()); @@ -308,7 +308,7 @@ TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { }; EXPECT_TRUE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_EQ(0u, framer.InputBytesRemaining()); EXPECT_EQ(0, visitor.error_count_); ASSERT_EQ(1u, visitor.messages_.size()); @@ -346,9 +346,8 @@ TEST(CryptoFramerTest, ProcessInputIncrementally) { 'g', 'h', 'i', 'j', 'k', }; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(input); i++) { - EXPECT_TRUE( - framer.ProcessInput(quiche::QuicheStringPiece(AsChars(input) + i, 1))); + for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) { + EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1))); } EXPECT_EQ(0u, framer.InputBytesRemaining()); ASSERT_EQ(1u, visitor.messages_.size()); @@ -382,7 +381,7 @@ TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) { }; EXPECT_FALSE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER)); EXPECT_EQ(1, visitor.error_count_); } @@ -410,7 +409,7 @@ TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) { }; EXPECT_FALSE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER)); EXPECT_EQ(1, visitor.error_count_); } @@ -430,7 +429,7 @@ TEST(CryptoFramerTest, ProcessInputTooManyEntries) { }; EXPECT_FALSE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES)); EXPECT_EQ(1, visitor.error_count_); } @@ -458,7 +457,7 @@ TEST(CryptoFramerTest, ProcessInputZeroLength) { }; EXPECT_TRUE(framer.ProcessInput( - quiche::QuicheStringPiece(AsChars(input), QUICHE_ARRAYSIZE(input)))); + absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input)))); EXPECT_EQ(0, visitor.error_count_); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc index 3df9f12a033..75bd3feac4f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc @@ -7,16 +7,17 @@ #include <memory> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" #include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -97,7 +98,7 @@ void CryptoHandshakeMessage::SetVersion(QuicTag tag, } void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, - quiche::QuicheStringPiece value) { + absl::string_view value) { tag_value_map_[tag] = std::string(value); } @@ -159,9 +160,8 @@ QuicErrorCode CryptoHandshakeMessage::GetVersionLabel( return QUIC_NO_ERROR; } -bool CryptoHandshakeMessage::GetStringPiece( - QuicTag tag, - quiche::QuicheStringPiece* out) const { +bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag, + absl::string_view* out) const { auto it = tag_value_map_.find(tag); if (it == tag_value_map_.end()) { return false; @@ -177,8 +177,8 @@ bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const { QuicErrorCode CryptoHandshakeMessage::GetNthValue24( QuicTag tag, unsigned index, - quiche::QuicheStringPiece* out) const { - quiche::QuicheStringPiece value; + absl::string_view* out) const { + absl::string_view value; if (!GetStringPiece(tag, &value)) { return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; } @@ -203,7 +203,7 @@ QuicErrorCode CryptoHandshakeMessage::GetNthValue24( } if (i == index) { - *out = quiche::QuicheStringPiece(value.data(), size); + *out = absl::string_view(value.data(), size); return QUIC_NO_ERROR; } @@ -371,7 +371,7 @@ std::string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { if (!done) { // If there's no specific format for this tag, or the value is invalid, // then just use hex. - ret += "0x" + quiche::QuicheTextUtils::HexEncode(it->second); + ret += "0x" + absl::BytesToHexString(it->second); } ret += "\n"; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h index 95390507a6a..5c501277112 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h @@ -11,10 +11,10 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -78,7 +78,7 @@ class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage { const QuicTagValueMap& tag_value_map() const { return tag_value_map_; } - void SetStringPiece(QuicTag tag, quiche::QuicheStringPiece value); + void SetStringPiece(QuicTag tag, absl::string_view value); // Erase removes a tag/value, if present, from the message. void Erase(QuicTag tag); @@ -99,7 +99,7 @@ class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage { // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR. QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const; - bool GetStringPiece(QuicTag tag, quiche::QuicheStringPiece* out) const; + bool GetStringPiece(QuicTag tag, absl::string_view* out) const; bool HasStringPiece(QuicTag tag) const; // GetNthValue24 interprets the value with the given tag to be a series of @@ -107,7 +107,7 @@ class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage { // index. QuicErrorCode GetNthValue24(QuicTag tag, unsigned index, - quiche::QuicheStringPiece* out) const; + absl::string_view* out) const; QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const; QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const; QuicErrorCode GetUint128(QuicTag tag, QuicUint128* out) const; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc index b6dfdd4cdaa..b006572238b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc @@ -7,7 +7,7 @@ #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace test { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h index 80386646368..b5e6a9d4764 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h @@ -7,9 +7,9 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -23,8 +23,7 @@ class QUIC_EXPORT_PRIVATE CryptoMessageParser { // Processes input data, which must be delivered in order. The input data // being processed was received at encryption level |level|. Returns // false if there was an error, and true otherwise. - virtual bool ProcessInput(quiche::QuicheStringPiece input, - EncryptionLevel level) = 0; + virtual bool ProcessInput(absl::string_view input, EncryptionLevel level) = 0; // Returns the number of bytes of buffered input data remaining to be // parsed. 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 f5584adad55..9a4e223fae9 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 @@ -10,6 +10,7 @@ #include <iostream> #include <string> +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -47,7 +48,7 @@ int main(int argc, char* argv[]) { quic::CryptoFramer framer; framer.set_visitor(&printer); framer.set_process_truncated_messages(true); - std::string input = quiche::QuicheTextUtils::HexDecode(messages[0]); + std::string input = absl::HexStringToBytes(messages[0]); if (!framer.ProcessInput(input)) { return 1; } 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 bf3a97ca891..5372f3fdb50 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 @@ -24,10 +24,11 @@ namespace quic { -typedef std::string ServerConfigID; +using ServerConfigID = std::string; // The following tags have been deprecated and should not be reused: -// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL" +// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL", +// "QNZR", "B2HI" // clang-format off const QuicTag kCHLO = TAG('C', 'H', 'L', 'O'); // Client hello @@ -100,8 +101,8 @@ const QuicTag kBBR9 = TAG('B', 'B', 'R', '9'); // DEPRECATED const QuicTag kBBRS = TAG('B', 'B', 'R', 'S'); // DEPRECATED const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1'); // BBR with lower 2.77 STARTUP // pacing and CWND gain. -const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2'); // BBR with lower 2.0 STARTUP - // CWND gain. +const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2'); // BBRv2 with 2.885 STARTUP and + // DRAIN CWND gain. const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3'); // BBR with ack aggregation // compensation in STARTUP. const QuicTag kBBQ5 = TAG('B', 'B', 'Q', '5'); // Expire ack aggregation upon @@ -118,15 +119,24 @@ const QuicTag kIW50 = TAG('I', 'W', '5', '0'); // Force ICWND to 50 const QuicTag kB2ON = TAG('B', '2', 'O', 'N'); // Enable BBRv2 const QuicTag kB2NA = TAG('B', '2', 'N', 'A'); // For BBRv2, do not add ack // height to queueing threshold +const QuicTag kB2NE = TAG('B', '2', 'N', 'E'); // For BBRv2, do not exit + // STARTUP if there's enough + // bandwidth growth const QuicTag kB2RP = TAG('B', '2', 'R', 'P'); // For BBRv2, run PROBE_RTT on // the regular schedule const QuicTag kB2CL = TAG('B', '2', 'C', 'L'); // For BBRv2, allow PROBE_BW // cwnd to be below BDP + ack // height. const QuicTag kB2LO = TAG('B', '2', 'L', 'O'); // Ignore inflight_lo in BBR2 -const QuicTag kB2HI = TAG('B', '2', 'H', 'I'); // Limit inflight_hi reduction - // based on CWND. const QuicTag kB2HR = TAG('B', '2', 'H', 'R'); // 15% inflight_hi headroom. +const QuicTag kB2SL = TAG('B', '2', 'S', 'L'); // When exiting STARTUP due to + // loss, set inflight_hi to the + // max of bdp and max bytes + // delivered in round. +const QuicTag kB2H2 = TAG('B', '2', 'H', '2'); // When exiting PROBE_UP due to + // loss, set inflight_hi to the + // max of inflight@send and max + // bytes delivered in round. const QuicTag kBSAO = TAG('B', 'S', 'A', 'O'); // Avoid Overestimation in // Bandwidth Sampler with ack // aggregation @@ -160,7 +170,12 @@ const QuicTag kAKDU = TAG('A', 'K', 'D', 'U'); // Unlimited number of packets // received before acking const QuicTag kACKQ = TAG('A', 'C', 'K', 'Q'); // Send an immediate ack after // 1 RTT of not receiving. -const QuicTag kAFFE = TAG('A', 'F', 'F', 'E'); // AckFrequencyFrame Enabled. +const QuicTag kAFFE = TAG('A', 'F', 'F', 'E'); // Enable client receiving + // AckFrequencyFrame. +const QuicTag kAFF1 = TAG('A', 'F', 'F', '1'); // Use SRTT in building + // AckFrequencyFrame. +const QuicTag kAFF2 = TAG('A', 'F', 'F', '2'); // Send AckFrequencyFrame upon + // handshake completion. const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction. const QuicTag kNPRR = TAG('N', 'P', 'R', 'R'); // Pace at unity instead of PRR const QuicTag k2RTO = TAG('2', 'R', 'T', 'O'); // Close connection on 2 RTOs @@ -361,7 +376,8 @@ const QuicTag kUAID = TAG('U', 'A', 'I', 'D'); // Client's User Agent ID. const QuicTag kXLCT = TAG('X', 'L', 'C', 'T'); // Expected leaf certificate. const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E'); // Legacy Version // Encapsulation. -const QuicTag kQNZR = TAG('Q', 'N', 'Z', 'R'); // Turn off QUIC crypto 0-RTT. + +const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2'); // Turn off QUIC crypto 0-RTT. const QuicTag kQNSP = TAG('Q', 'N', 'S', 'P'); // Turn off server push in // gQUIC. 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 78cf768dcc6..1f75e0c7157 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 @@ -7,11 +7,11 @@ #include "net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/aead.h" #include "third_party/boringssl/src/include/openssl/err.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -68,7 +68,7 @@ void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) { } std::string CryptoSecretBoxer::Box(QuicRandom* rand, - quiche::QuicheStringPiece plaintext) const { + absl::string_view plaintext) const { // The box is formatted as: // 12 bytes of random nonce // n bytes of ciphertext @@ -104,9 +104,9 @@ std::string CryptoSecretBoxer::Box(QuicRandom* rand, return ret; } -bool CryptoSecretBoxer::Unbox(quiche::QuicheStringPiece in_ciphertext, +bool CryptoSecretBoxer::Unbox(absl::string_view in_ciphertext, std::string* out_storage, - quiche::QuicheStringPiece* out) const { + absl::string_view* out) const { if (in_ciphertext.size() < kSIVNonceSize) { return false; } @@ -130,7 +130,7 @@ bool CryptoSecretBoxer::Unbox(quiche::QuicheStringPiece in_ciphertext, kSIVNonceSize, ciphertext, ciphertext_len, nullptr, 0)) { ok = true; - *out = quiche::QuicheStringPiece(out_storage->data(), bytes_written); + *out = absl::string_view(out_storage->data(), bytes_written); break; } 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 dc4e0b14cb8..6cf61b41c8d 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 @@ -10,9 +10,9 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -41,16 +41,16 @@ class QUIC_EXPORT_PRIVATE CryptoSecretBoxer { // 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. - std::string Box(QuicRandom* rand, quiche::QuicheStringPiece plaintext) const; + std::string Box(QuicRandom* rand, absl::string_view plaintext) const; // Unbox takes the result of a previous call to |Box| in |ciphertext| and // authenticates+decrypts it. If |ciphertext| cannot be decrypted with any of // the supplied keys, the function returns false. Otherwise, |out_storage| is // used to store the result and |out| is set to point into |out_storage| and // contains the original plaintext. - bool Unbox(quiche::QuicheStringPiece ciphertext, + bool Unbox(absl::string_view ciphertext, std::string* out_storage, - quiche::QuicheStringPiece* out) const; + absl::string_view* out) const; private: struct State; 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 57a5712f07b..b63d081031f 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 @@ -6,9 +6,9 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -16,7 +16,7 @@ namespace test { class CryptoSecretBoxerTest : public QuicTest {}; TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) { - quiche::QuicheStringPiece message("hello world"); + absl::string_view message("hello world"); CryptoSecretBoxer boxer; boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)}); @@ -24,7 +24,7 @@ TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) { const std::string box = boxer.Box(QuicRandom::GetInstance(), message); std::string storage; - quiche::QuicheStringPiece result; + absl::string_view result; EXPECT_TRUE(boxer.Unbox(box, &storage, &result)); EXPECT_EQ(result, message); @@ -40,10 +40,10 @@ TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) { // Helper function to test whether one boxer can decode the output of another. static bool CanDecode(const CryptoSecretBoxer& decoder, const CryptoSecretBoxer& encoder) { - quiche::QuicheStringPiece message("hello world"); + absl::string_view message("hello world"); const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message); std::string storage; - quiche::QuicheStringPiece result; + absl::string_view result; bool ok = decoder.Unbox(boxed, &storage, &result); if (ok) { EXPECT_EQ(result, message); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc index 17ab10b0717..51dc4181002 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc @@ -10,6 +10,9 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "net/third_party/quiche/src/quic/core/crypto/cert_compressor.h" #include "net/third_party/quiche/src/quic/core/crypto/common_cert_set.h" @@ -29,10 +32,8 @@ #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace test { @@ -127,7 +128,7 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { std::unique_ptr<CryptoHandshakeMessage> msg( config_.AddConfig(primary_config, clock_.WallNow())); - quiche::QuicheStringPiece orbit; + absl::string_view orbit; CHECK(msg->GetStringPiece(kORBT, &orbit)); CHECK_EQ(sizeof(orbit_), orbit.size()); memcpy(orbit_, orbit.data(), orbit.size()); @@ -135,9 +136,9 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { char public_value[32]; memset(public_value, 42, sizeof(public_value)); - nonce_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(GenerateNonce()); - pub_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(public_value, - sizeof(public_value)); + nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce()); + pub_hex_ = "#" + absl::BytesToHexString( + absl::string_view(public_value, sizeof(public_value))); CryptoHandshakeMessage client_hello = crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, @@ -154,19 +155,19 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); - quiche::QuicheStringPiece srct; + absl::string_view srct; ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); - srct_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(srct); + srct_hex_ = "#" + absl::BytesToHexString(srct); - quiche::QuicheStringPiece scfg; + absl::string_view scfg; ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); server_config_ = CryptoFramer::ParseMessage(scfg); - quiche::QuicheStringPiece scid; + absl::string_view scid; ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid)); - scid_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(scid); + scid_hex_ = "#" + absl::BytesToHexString(scid); signed_config_ = QuicReferenceCountedPointer<QuicSignedServerConfig>( new QuicSignedServerConfig()); @@ -211,7 +212,7 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]); } - quiche::QuicheStringPiece address; + absl::string_view address; ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address)); QuicSocketAddressCoder decoder; ASSERT_TRUE(decoder.Decode(address.data(), address.size())); @@ -313,8 +314,8 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { std::string nonce; CryptoUtils::GenerateNonce( clock_.WallNow(), rand_, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(orbit_), - sizeof(orbit_)), + absl::string_view(reinterpret_cast<const char*>(orbit_), + sizeof(orbit_)), &nonce); return nonce; } @@ -340,8 +341,8 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { std::string XlctHexString() { uint64_t xlct = crypto_test_utils::LeafCertHashForTesting(); - return "#" + quiche::QuicheTextUtils::HexEncode( - reinterpret_cast<char*>(&xlct), sizeof(xlct)); + return "#" + absl::BytesToHexString(absl::string_view( + reinterpret_cast<char*>(&xlct), sizeof(xlct))); } protected: @@ -386,7 +387,7 @@ TEST_P(CryptoServerTest, BadSNI) { }; // clang-format on - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kBadSNIs); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSNIs); i++) { CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, {"SNI", kBadSNIs[i]}, @@ -395,7 +396,7 @@ TEST_P(CryptoServerTest, BadSNI) { ShouldFailMentioning("SNI", msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } } @@ -413,7 +414,7 @@ TEST_P(CryptoServerTest, DefaultCert) { kClientHelloMinimumSize); ShouldSucceed(msg); - quiche::QuicheStringPiece cert, proof, cert_sct; + absl::string_view cert, proof, cert_sct; EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct)); @@ -421,7 +422,7 @@ TEST_P(CryptoServerTest, DefaultCert) { EXPECT_NE(0u, proof.size()); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); EXPECT_LT(0u, cert_sct.size()); } @@ -442,13 +443,13 @@ TEST_P(CryptoServerTest, RejectTooLarge) { config_.set_chlo_multiplier(1); ShouldSucceed(msg); - quiche::QuicheStringPiece cert, proof, cert_sct; + absl::string_view cert, proof, cert_sct; EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert)); EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof)); EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct)); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, RejectNotTooLarge) { @@ -469,13 +470,13 @@ TEST_P(CryptoServerTest, RejectNotTooLarge) { config_.set_chlo_multiplier(1); ShouldSucceed(msg); - quiche::QuicheStringPiece cert, proof, cert_sct; + absl::string_view cert, proof, cert_sct; EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct)); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { @@ -496,7 +497,7 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { config_.set_chlo_multiplier(1); ShouldSucceed(msg); - quiche::QuicheStringPiece cert, proof, cert_sct; + absl::string_view cert, proof, cert_sct; EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct)); @@ -504,7 +505,7 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { EXPECT_NE(0u, proof.size()); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, BadSourceAddressToken) { @@ -518,7 +519,7 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) { }; // clang-format on - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kBadSourceAddressTokens); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) { CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, {"STK", kBadSourceAddressTokens[i]}, @@ -527,7 +528,7 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) { ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } } @@ -540,7 +541,7 @@ TEST_P(CryptoServerTest, BadClientNonce) { }; // clang-format on - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kBadNonces); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) { // Invalid nonces should be ignored, in an inchoate CHLO. CryptoHandshakeMessage msg = @@ -552,7 +553,7 @@ TEST_P(CryptoServerTest, BadClientNonce) { ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE. CryptoHandshakeMessage msg1 = @@ -573,7 +574,7 @@ TEST_P(CryptoServerTest, BadClientNonce) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons1[] = { CLIENT_NONCE_INVALID_FAILURE}; - CheckRejectReasons(kRejectReasons1, QUICHE_ARRAYSIZE(kRejectReasons1)); + CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1)); } } @@ -587,7 +588,7 @@ TEST_P(CryptoServerTest, NoClientNonce) { ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); CryptoHandshakeMessage msg1 = crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, @@ -604,7 +605,7 @@ TEST_P(CryptoServerTest, NoClientNonce) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons1[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons1, QUICHE_ARRAYSIZE(kRejectReasons1)); + CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1)); } TEST_P(CryptoServerTest, DowngradeAttack) { @@ -623,7 +624,7 @@ TEST_P(CryptoServerTest, DowngradeAttack) { ShouldFailMentioning("Downgrade", msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, CorruptServerConfig) { @@ -643,7 +644,7 @@ TEST_P(CryptoServerTest, CorruptServerConfig) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, CorruptSourceAddressToken) { @@ -664,7 +665,7 @@ TEST_P(CryptoServerTest, CorruptSourceAddressToken) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) { @@ -705,7 +706,7 @@ TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, CorruptMultipleTags) { @@ -729,7 +730,7 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) { const HandshakeFailureReason kRejectReasons[] = { SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, NoServerNonce) { @@ -778,15 +779,15 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); - quiche::QuicheStringPiece cert, proof, scfg_str; + absl::string_view cert, proof, scfg_str; EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str)); std::unique_ptr<CryptoHandshakeMessage> scfg( CryptoFramer::ParseMessage(scfg_str)); - quiche::QuicheStringPiece scid; + absl::string_view scid; EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid)); EXPECT_NE(scid, kOldConfigId); @@ -840,7 +841,7 @@ TEST_P(CryptoServerTest, RejectInvalidXlct) { const HandshakeFailureReason kRejectReasons[] = { INVALID_EXPECTED_LEAF_CERTIFICATE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } TEST_P(CryptoServerTest, ValidXlct) { @@ -886,7 +887,7 @@ TEST_P(CryptoServerTest, NonceInSHLO) { ShouldSucceed(msg); EXPECT_EQ(kSHLO, out_.tag()); - quiche::QuicheStringPiece nonce; + absl::string_view nonce; EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce)); } @@ -922,7 +923,7 @@ TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) { ShouldSucceed(msg); // Decompress cert chain from server to individual certs. - quiche::QuicheStringPiece certs_compressed; + absl::string_view certs_compressed; ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed)); ASSERT_NE(0u, certs_compressed.size()); std::vector<std::string> certs; @@ -942,7 +943,7 @@ TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) { ShouldSucceed(msg); // Server responds with inchoate REJ containing valid source-address token. - quiche::QuicheStringPiece srct; + absl::string_view srct; ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); // Client now drops cached certs; sends CHLO with updated source-address @@ -1003,7 +1004,7 @@ TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) { std::unique_ptr<CryptoHandshakeMessage> scfg_b( b.AddDefaultConfig(&rand_b, &clock, options)); - quiche::QuicheStringPiece scid_a, scid_b; + absl::string_view scid_a, scid_b; EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a)); EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b)); @@ -1021,7 +1022,7 @@ TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) { std::unique_ptr<CryptoHandshakeMessage> scfg( a.AddDefaultConfig(&rand_a, &clock, options)); - quiche::QuicheStringPiece scid; + absl::string_view scid; EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid)); // Need to take a copy of |scid| has we're about to call |Erase|. const std::string scid_str(scid); @@ -1064,7 +1065,7 @@ TEST_P(CryptoServerTestNoConfig, DontCrash) { const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; - CheckRejectReasons(kRejectReasons, QUICHE_ARRAYSIZE(kRejectReasons)); + CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons)); } class CryptoServerTestOldVersion : public CryptoServerTest { 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 365fb120d19..efb7b665744 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 @@ -8,6 +8,8 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/hkdf.h" #include "third_party/boringssl/src/include/openssl/mem.h" @@ -32,10 +34,8 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -74,7 +74,7 @@ std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf, !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) || !CBB_add_bytes(&inner_label, reinterpret_cast<const uint8_t*>(label_prefix), - QUICHE_ARRAYSIZE(label_prefix) - 1) || + ABSL_ARRAYSIZE(label_prefix) - 1) || !CBB_add_bytes(&inner_label, reinterpret_cast<const uint8_t*>(label.data()), label.size()) || @@ -96,6 +96,18 @@ std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf, } // namespace +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()); + crypter->SetHeaderProtectionKey( + absl::string_view(reinterpret_cast<char*>(header_protection_key.data()), + header_protection_key.size())); +} + void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, QuicCrypter* crypter) { @@ -103,14 +115,23 @@ void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, HkdfExpandLabel(prf, pp_secret, "quic key", crypter->GetKeySize()); std::vector<uint8_t> iv = HkdfExpandLabel(prf, pp_secret, "quic iv", crypter->GetIVSize()); - std::vector<uint8_t> pn = - HkdfExpandLabel(prf, pp_secret, "quic hp", crypter->GetKeySize()); - crypter->SetKey(quiche::QuicheStringPiece(reinterpret_cast<char*>(key.data()), - key.size())); + crypter->SetKey( + absl::string_view(reinterpret_cast<char*>(key.data()), key.size())); crypter->SetIV( - quiche::QuicheStringPiece(reinterpret_cast<char*>(iv.data()), iv.size())); - crypter->SetHeaderProtectionKey( - quiche::QuicheStringPiece(reinterpret_cast<char*>(pn.data()), pn.size())); + absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size())); +} + +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); +} + +std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret( + const EVP_MD* prf, + const std::vector<uint8_t>& current_secret) { + return HkdfExpandLabel(prf, current_secret, "quic ku", current_secret.size()); } namespace { @@ -140,30 +161,37 @@ const uint8_t kT050Salt[] = {0x7f, 0xf5, 0x79, 0xe5, 0xac, 0xd0, 0x72, const uint8_t kT051Salt[] = {0x7a, 0x4e, 0xde, 0xf4, 0xe7, 0xcc, 0xee, 0x5f, 0xa4, 0x50, 0x6c, 0x19, 0x12, 0x4f, 0xc8, 0xcc, 0xda, 0x6e, 0x03, 0x3d}; +// Salt to use for initial obfuscators in +// ParsedQuicVersion::ReservedForNegotiation(). +const uint8_t kReservedForNegotiationSalt[] = { + 0xf9, 0x64, 0xbf, 0x45, 0x3a, 0x1f, 0x1b, 0x80, 0xa5, 0xf8, + 0x82, 0x03, 0x77, 0xd4, 0xaf, 0xca, 0x58, 0x0e, 0xe7, 0x43}; const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version, size_t* out_len) { static_assert(SupportedVersions().size() == 7u, "Supported versions out of sync with initial encryption salts"); if (version == ParsedQuicVersion::Draft29()) { - *out_len = QUICHE_ARRAYSIZE(kDraft29InitialSalt); + *out_len = ABSL_ARRAYSIZE(kDraft29InitialSalt); return kDraft29InitialSalt; - } else if (version == ParsedQuicVersion::Draft27() || - version == ParsedQuicVersion::ReservedForNegotiation()) { - *out_len = QUICHE_ARRAYSIZE(kDraft27InitialSalt); + } else if (version == ParsedQuicVersion::Draft27()) { + *out_len = ABSL_ARRAYSIZE(kDraft27InitialSalt); return kDraft27InitialSalt; } else if (version == ParsedQuicVersion::T051()) { - *out_len = QUICHE_ARRAYSIZE(kT051Salt); + *out_len = ABSL_ARRAYSIZE(kT051Salt); return kT051Salt; } else if (version == ParsedQuicVersion::T050()) { - *out_len = QUICHE_ARRAYSIZE(kT050Salt); + *out_len = ABSL_ARRAYSIZE(kT050Salt); return kT050Salt; } else if (version == ParsedQuicVersion::Q050()) { - *out_len = QUICHE_ARRAYSIZE(kQ050Salt); + *out_len = ABSL_ARRAYSIZE(kQ050Salt); return kQ050Salt; + } else if (version == ParsedQuicVersion::ReservedForNegotiation()) { + *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt); + return kReservedForNegotiationSalt; } QUIC_BUG << "No initial obfuscation salt for version " << version; - *out_len = QUICHE_ARRAYSIZE(kDraft27InitialSalt); + *out_len = ABSL_ARRAYSIZE(kDraft27InitialSalt); return kDraft27InitialSalt; } @@ -192,16 +220,23 @@ const uint8_t kT050RetryIntegrityKey[] = {0xc9, 0x2d, 0x32, 0x3d, 0x9c, 0xe3, const uint8_t kT051RetryIntegrityKey[] = {0x2e, 0xb9, 0x61, 0xa6, 0x79, 0x56, 0xf8, 0x79, 0x53, 0x14, 0xda, 0xfb, 0x2e, 0xbc, 0x83, 0xd7}; +// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation(). +const uint8_t kReservedForNegotiationRetryIntegrityKey[] = { + 0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35, + 0x03, 0xe6, 0x7c, 0x7b, 0xd2, 0x44, 0xca, 0xd9}; // Nonces used by Google versions of QUIC. When introducing a new version, // generate a new nonce by running `openssl rand -hex 12`. const uint8_t kT050RetryIntegrityNonce[] = {0x26, 0xe4, 0xd6, 0x23, 0x83, 0xd5, 0xc7, 0x60, 0xea, 0x02, 0xb4, 0x1f}; const uint8_t kT051RetryIntegrityNonce[] = {0xb5, 0x0e, 0x4e, 0x53, 0x4c, 0xfc, 0x0b, 0xbb, 0x85, 0xf2, 0xf9, 0xca}; +// Retry integrity nonce used by ParsedQuicVersion::ReservedForNegotiation(). +const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = { + 0x35, 0x9f, 0x16, 0xd1, 0xed, 0x80, 0x90, 0x8e, 0xec, 0x85, 0xc4, 0xd6}; bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version, - quiche::QuicheStringPiece* key, - quiche::QuicheStringPiece* nonce) { + absl::string_view* key, + absl::string_view* nonce) { static_assert(SupportedVersions().size() == 7u, "Supported versions out of sync with retry integrity keys"); if (!version.HasRetryIntegrityTag()) { @@ -209,36 +244,45 @@ bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version, << version; return false; } else if (version == ParsedQuicVersion::Draft29()) { - *key = quiche::QuicheStringPiece( + *key = absl::string_view( reinterpret_cast<const char*>(kDraft29RetryIntegrityKey), - QUICHE_ARRAYSIZE(kDraft29RetryIntegrityKey)); - *nonce = quiche::QuicheStringPiece( + ABSL_ARRAYSIZE(kDraft29RetryIntegrityKey)); + *nonce = absl::string_view( reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce), - QUICHE_ARRAYSIZE(kDraft29RetryIntegrityNonce)); + ABSL_ARRAYSIZE(kDraft29RetryIntegrityNonce)); return true; } else if (version == ParsedQuicVersion::Draft27()) { - *key = quiche::QuicheStringPiece( + *key = absl::string_view( reinterpret_cast<const char*>(kDraft27RetryIntegrityKey), - QUICHE_ARRAYSIZE(kDraft27RetryIntegrityKey)); - *nonce = quiche::QuicheStringPiece( + ABSL_ARRAYSIZE(kDraft27RetryIntegrityKey)); + *nonce = absl::string_view( reinterpret_cast<const char*>(kDraft27RetryIntegrityNonce), - QUICHE_ARRAYSIZE(kDraft27RetryIntegrityNonce)); + ABSL_ARRAYSIZE(kDraft27RetryIntegrityNonce)); return true; } else if (version == ParsedQuicVersion::T051()) { - *key = quiche::QuicheStringPiece( - reinterpret_cast<const char*>(kT051RetryIntegrityKey), - QUICHE_ARRAYSIZE(kT051RetryIntegrityKey)); - *nonce = quiche::QuicheStringPiece( + *key = + absl::string_view(reinterpret_cast<const char*>(kT051RetryIntegrityKey), + ABSL_ARRAYSIZE(kT051RetryIntegrityKey)); + *nonce = absl::string_view( reinterpret_cast<const char*>(kT051RetryIntegrityNonce), - QUICHE_ARRAYSIZE(kT051RetryIntegrityNonce)); + ABSL_ARRAYSIZE(kT051RetryIntegrityNonce)); return true; } else if (version == ParsedQuicVersion::T050()) { - *key = quiche::QuicheStringPiece( - reinterpret_cast<const char*>(kT050RetryIntegrityKey), - QUICHE_ARRAYSIZE(kT050RetryIntegrityKey)); - *nonce = quiche::QuicheStringPiece( + *key = + absl::string_view(reinterpret_cast<const char*>(kT050RetryIntegrityKey), + ABSL_ARRAYSIZE(kT050RetryIntegrityKey)); + *nonce = absl::string_view( reinterpret_cast<const char*>(kT050RetryIntegrityNonce), - QUICHE_ARRAYSIZE(kT050RetryIntegrityNonce)); + ABSL_ARRAYSIZE(kT050RetryIntegrityNonce)); + return true; + } else if (version == ParsedQuicVersion::ReservedForNegotiation()) { + *key = absl::string_view( + reinterpret_cast<const char*>(kReservedForNegotiationRetryIntegrityKey), + ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityKey)); + *nonce = absl::string_view( + reinterpret_cast<const char*>( + kReservedForNegotiationRetryIntegrityNonce), + ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityNonce)); return true; } QUIC_BUG << "Attempted to get retry integrity keys for version " << version; @@ -294,27 +338,27 @@ 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>(); - SetKeyAndIV(hash, encryption_secret, crypters->encrypter.get()); + InitializeCrypterSecrets(hash, encryption_secret, 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>(); - SetKeyAndIV(hash, decryption_secret, crypters->decrypter.get()); + InitializeCrypterSecrets(hash, decryption_secret, crypters->decrypter.get()); } // static bool CryptoUtils::ValidateRetryIntegrityTag( ParsedQuicVersion version, QuicConnectionId original_connection_id, - quiche::QuicheStringPiece retry_without_tag, - quiche::QuicheStringPiece integrity_tag) { + absl::string_view retry_without_tag, + absl::string_view integrity_tag) { unsigned char computed_integrity_tag[kRetryIntegrityTagLength]; - if (integrity_tag.length() != QUICHE_ARRAYSIZE(computed_integrity_tag)) { + if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) { QUIC_BUG << "Invalid retry integrity tag length " << integrity_tag.length(); return false; } char retry_pseudo_packet[kMaxIncomingPacketSize + 256]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(retry_pseudo_packet), + QuicDataWriter writer(ABSL_ARRAYSIZE(retry_pseudo_packet), retry_pseudo_packet); if (!writer.WriteLengthPrefixedConnectionId(original_connection_id)) { QUIC_BUG << "Failed to write original connection ID in retry pseudo packet"; @@ -324,23 +368,23 @@ bool CryptoUtils::ValidateRetryIntegrityTag( QUIC_BUG << "Failed to write retry without tag in retry pseudo packet"; return false; } - quiche::QuicheStringPiece key; - quiche::QuicheStringPiece nonce; + absl::string_view key; + absl::string_view nonce; if (!RetryIntegrityKeysForVersion(version, &key, &nonce)) { // RetryIntegrityKeysForVersion already logs failures. return false; } Aes128GcmEncrypter crypter; crypter.SetKey(key); - quiche::QuicheStringPiece associated_data(writer.data(), writer.length()); - quiche::QuicheStringPiece plaintext; // Plaintext is empty. + absl::string_view associated_data(writer.data(), writer.length()); + absl::string_view plaintext; // Plaintext is empty. if (!crypter.Encrypt(nonce, associated_data, plaintext, computed_integrity_tag)) { QUIC_BUG << "Failed to compute retry integrity tag"; return false; } if (CRYPTO_memcmp(computed_integrity_tag, integrity_tag.data(), - QUICHE_ARRAYSIZE(computed_integrity_tag)) != 0) { + ABSL_ARRAYSIZE(computed_integrity_tag)) != 0) { QUIC_DLOG(ERROR) << "Failed to validate retry integrity tag"; return false; } @@ -350,7 +394,7 @@ bool CryptoUtils::ValidateRetryIntegrityTag( // static void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator, - quiche::QuicheStringPiece orbit, + absl::string_view orbit, std::string* nonce) { // a 4-byte timestamp + 28 random bytes. nonce->reserve(kNonceSize); @@ -376,11 +420,11 @@ void CryptoUtils::GenerateNonce(QuicWallTime now, // static bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, - quiche::QuicheStringPiece premaster_secret, + absl::string_view premaster_secret, QuicTag aead, - quiche::QuicheStringPiece client_nonce, - quiche::QuicheStringPiece server_nonce, - quiche::QuicheStringPiece pre_shared_key, + 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, @@ -389,7 +433,7 @@ bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, // 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()) { - const quiche::QuicheStringPiece label(kPreSharedKeyLabel); + const absl::string_view label(kPreSharedKeyLabel); const size_t psk_premaster_secret_size = label.size() + 1 + pre_shared_key.size() + 8 + premaster_secret.size() + 8; @@ -407,8 +451,8 @@ bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, return false; } - premaster_secret = quiche::QuicheStringPiece(psk_premaster_secret.get(), - psk_premaster_secret_size); + premaster_secret = absl::string_view(psk_premaster_secret.get(), + psk_premaster_secret_size); } crypters->encrypter = QuicEncrypter::Create(version, aead); @@ -422,7 +466,7 @@ bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, size_t subkey_secret_bytes = subkey_secret == nullptr ? 0 : premaster_secret.length(); - quiche::QuicheStringPiece nonce = client_nonce; + absl::string_view nonce = client_nonce; std::string nonce_storage; if (!server_nonce.empty()) { nonce_storage = std::string(client_nonce) + std::string(server_nonce); @@ -519,9 +563,9 @@ bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, } // static -bool CryptoUtils::ExportKeyingMaterial(quiche::QuicheStringPiece subkey_secret, - quiche::QuicheStringPiece label, - quiche::QuicheStringPiece context, +bool CryptoUtils::ExportKeyingMaterial(absl::string_view subkey_secret, + absl::string_view label, + absl::string_view context, size_t result_len, std::string* result) { for (size_t i = 0; i < label.length(); i++) { @@ -541,14 +585,14 @@ bool CryptoUtils::ExportKeyingMaterial(quiche::QuicheStringPiece subkey_secret, info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length)); info.append(context.data(), context.length()); - QuicHKDF hkdf(subkey_secret, quiche::QuicheStringPiece() /* no salt */, info, + QuicHKDF hkdf(subkey_secret, absl::string_view() /* no salt */, info, result_len, 0 /* no fixed IV */, 0 /* no subkey secret */); *result = std::string(hkdf.client_write_key()); return true; } // static -uint64_t CryptoUtils::ComputeLeafCertHash(quiche::QuicheStringPiece cert) { +uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) { return QuicUtils::FNV1a_64_Hash(cert); } @@ -691,8 +735,17 @@ const char* CryptoUtils::HandshakeFailureReasonToString( } // static -const char* CryptoUtils::EarlyDataReasonToString( +std::string CryptoUtils::EarlyDataReasonToString( ssl_early_data_reason_t reason) { +#if BORINGSSL_API_VERSION >= 12 + const char* reason_string = SSL_early_data_reason_string(reason); + if (reason_string != nullptr) { + return std::string("ssl_early_data_") + reason_string; + } +#else + // TODO(davidben): Remove this logic once + // https://boringssl-review.googlesource.com/c/boringssl/+/43724 has landed in + // downstream repositories. switch (reason) { RETURN_STRING_LITERAL(ssl_early_data_unknown); RETURN_STRING_LITERAL(ssl_early_data_disabled); @@ -709,6 +762,7 @@ const char* CryptoUtils::EarlyDataReasonToString( RETURN_STRING_LITERAL(ssl_early_data_ticket_age_skew); RETURN_STRING_LITERAL(ssl_early_data_quic_parameter_mismatch); } +#endif QUIC_BUG_IF(reason < 0 || reason > ssl_early_data_reason_max_value) << "Unknown ssl_early_data_reason_t " << reason; return "unknown ssl_early_data_reason_t"; 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 964f81fdf69..9195e3add82 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 @@ -11,6 +11,7 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -74,15 +74,35 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { DiversificationNonce* nonce_; }; - // SetKeyAndIV derives the key and IV from the given packet protection secret - // |pp_secret| and sets those fields on the given QuicCrypter |*crypter|. + // InitializeCrypterSecrets derives the key and IV and header protection key + // from the given packet protection secret |pp_secret| and sets those fields + // 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. + static void InitializeCrypterSecrets(const EVP_MD* prf, + const std::vector<uint8_t>& pp_secret, + QuicCrypter* crypter); + + // Derives the key and IV from the packet protection secret and sets those + // fields on the given QuicCrypter |*crypter|, but does not set the header + // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be + // called before using |crypter|. static void SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, 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); + + // 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 std::vector<uint8_t>& current_secret); + // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key // (to prevent network observers that are not aware of that QUIC version from // making decisions based on the TLS handshake). This packet protection secret @@ -101,11 +121,10 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // IETF QUIC Retry packets carry a retry integrity tag to detect packet // corruption and make it harder for an attacker to spoof. This function // checks whether a given retry packet is valid. - static bool ValidateRetryIntegrityTag( - ParsedQuicVersion version, - QuicConnectionId original_connection_id, - quiche::QuicheStringPiece retry_without_tag, - quiche::QuicheStringPiece integrity_tag); + static bool ValidateRetryIntegrityTag(ParsedQuicVersion version, + QuicConnectionId original_connection_id, + absl::string_view retry_without_tag, + absl::string_view integrity_tag); // Generates the connection nonce. The nonce is formed as: // <4 bytes> current time @@ -113,7 +132,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // <20 bytes> random static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator, - quiche::QuicheStringPiece orbit, + absl::string_view orbit, std::string* nonce); // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and @@ -136,11 +155,11 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // |SetDiversificationNonce| with a diversification nonce will be needed to // complete keying. static bool DeriveKeys(const ParsedQuicVersion& version, - quiche::QuicheStringPiece premaster_secret, + absl::string_view premaster_secret, QuicTag aead, - quiche::QuicheStringPiece client_nonce, - quiche::QuicheStringPiece server_nonce, - quiche::QuicheStringPiece pre_shared_key, + 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, @@ -151,15 +170,15 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // dependent on |subkey_secret|, |label|, and |context|. Returns false if the // parameters are invalid (e.g. |label| contains null bytes); returns true on // success. - static bool ExportKeyingMaterial(quiche::QuicheStringPiece subkey_secret, - quiche::QuicheStringPiece label, - quiche::QuicheStringPiece context, + static bool ExportKeyingMaterial(absl::string_view subkey_secret, + absl::string_view label, + absl::string_view context, size_t result_len, std::string* result); // Computes the FNV-1a hash of the provided DER-encoded cert for use in the // XLCT tag. - static uint64_t ComputeLeafCertHash(quiche::QuicheStringPiece cert); + static uint64_t ComputeLeafCertHash(absl::string_view cert); // Validates that |server_hello| is actually an SHLO message and that it is // not part of a downgrade attack. @@ -213,7 +232,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { HandshakeFailureReason reason); // Returns the name of an ssl_early_data_reason_t as a char* - static const char* EarlyDataReasonToString(ssl_early_data_reason_t reason); + static std::string EarlyDataReasonToString(ssl_early_data_reason_t reason); // Returns a hash of the serialized |message|. static std::string HashHandshakeMessage(const CryptoHandshakeMessage& message, 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 edf80515a75..e0d1165ff5f 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 @@ -6,10 +6,11 @@ #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -50,19 +51,17 @@ TEST_F(CryptoUtilsTest, TestExportKeyingMaterial) { "c9a46ed0757bd1812f1f21b4d41e62125fec8364a21db7"}, }; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_vector); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_vector); i++) { // Decode the test vector. std::string subkey_secret = - quiche::QuicheTextUtils::HexDecode(test_vector[i].subkey_secret); - std::string label = - quiche::QuicheTextUtils::HexDecode(test_vector[i].label); - std::string context = - quiche::QuicheTextUtils::HexDecode(test_vector[i].context); + absl::HexStringToBytes(test_vector[i].subkey_secret); + std::string label = absl::HexStringToBytes(test_vector[i].label); + std::string context = absl::HexStringToBytes(test_vector[i].context); size_t result_len = test_vector[i].result_len; bool expect_ok = test_vector[i].expected != nullptr; std::string expected; if (expect_ok) { - expected = quiche::QuicheTextUtils::HexDecode(test_vector[i].expected); + expected = absl::HexStringToBytes(test_vector[i].expected); } std::string result; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc index 2f19e9d486c..acdf9a8394b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.cc @@ -8,11 +8,11 @@ #include <cstring> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/curve25519.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -31,7 +31,7 @@ std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New( // static std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New( - quiche::QuicheStringPiece private_key) { + absl::string_view private_key) { // We don't want to #include the BoringSSL headers in the public header file, // so we use literals for the sizes of private_key_ and public_key_. Here we // assert that those values are equal to the values from the BoringSSL @@ -61,7 +61,7 @@ std::string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) { } bool Curve25519KeyExchange::CalculateSharedKeySync( - quiche::QuicheStringPiece peer_public_value, + absl::string_view peer_public_value, std::string* shared_key) const { if (peer_public_value.size() != X25519_PUBLIC_VALUE_LEN) { return false; @@ -77,9 +77,9 @@ bool Curve25519KeyExchange::CalculateSharedKeySync( return true; } -quiche::QuicheStringPiece Curve25519KeyExchange::public_value() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(public_key_), - sizeof(public_key_)); +absl::string_view Curve25519KeyExchange::public_value() const { + return absl::string_view(reinterpret_cast<const char*>(public_key_), + sizeof(public_key_)); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h index 76fd23ff242..e6703ec2056 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h @@ -8,9 +8,9 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/key_exchange.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,16 +29,16 @@ class QUIC_EXPORT_PRIVATE Curve25519KeyExchange // New creates a new key-exchange object from a private key. If |private_key| // is invalid, nullptr is returned. static std::unique_ptr<Curve25519KeyExchange> New( - quiche::QuicheStringPiece private_key); + absl::string_view private_key); // NewPrivateKey returns a private key, generated from |rand|, suitable for // passing to |New|. static std::string NewPrivateKey(QuicRandom* rand); // SynchronousKeyExchange interface. - bool CalculateSharedKeySync(quiche::QuicheStringPiece peer_public_value, + bool CalculateSharedKeySync(absl::string_view peer_public_value, std::string* shared_key) const override; - quiche::QuicheStringPiece public_value() const override; + absl::string_view public_value() const override; QuicTag type() const override { return kC255; } private: diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc index 2e5dfb4edc1..f100df58ae4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange_test.cc @@ -8,9 +8,9 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -55,8 +55,8 @@ TEST_F(Curve25519KeyExchangeTest, SharedKey) { std::unique_ptr<Curve25519KeyExchange> bob( Curve25519KeyExchange::New(bob_key)); - const quiche::QuicheStringPiece alice_public(alice->public_value()); - const quiche::QuicheStringPiece bob_public(bob->public_value()); + const absl::string_view alice_public(alice->public_value()); + const absl::string_view bob_public(bob->public_value()); std::string alice_shared, bob_shared; ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared)); @@ -79,8 +79,8 @@ TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) { std::unique_ptr<Curve25519KeyExchange> bob( Curve25519KeyExchange::New(bob_key)); - const quiche::QuicheStringPiece alice_public(alice->public_value()); - const quiche::QuicheStringPiece bob_public(bob->public_value()); + const absl::string_view alice_public(alice->public_value()); + const absl::string_view bob_public(bob->public_value()); std::string alice_shared, bob_shared; TestCallbackResult alice_result; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc index 84f9c86802c..d7c01052f9c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.cc @@ -3,16 +3,16 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/crypto/key_exchange.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/curve25519_key_exchange.h" #include "net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange( QuicTag type, - quiche::QuicheStringPiece private_key) { + absl::string_view private_key) { switch (type) { case kC255: return Curve25519KeyExchange::New(private_key); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h index cb6fdbc8705..e4288d75ffb 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h @@ -8,9 +8,9 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -48,7 +48,7 @@ class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange { // that |callback| might be invoked synchronously. Results will be written // into |*shared_key|. virtual void CalculateSharedKeyAsync( - quiche::QuicheStringPiece peer_public_value, + absl::string_view peer_public_value, std::string* shared_key, std::unique_ptr<Callback> callback) const = 0; @@ -66,7 +66,7 @@ class QUIC_EXPORT_PRIVATE SynchronousKeyExchange // AyncKeyExchange API. Note that this method is marked 'final.' Subclasses // should implement CalculateSharedKeySync only. - void CalculateSharedKeyAsync(quiche::QuicheStringPiece peer_public_value, + void CalculateSharedKeyAsync(absl::string_view peer_public_value, std::string* shared_key, std::unique_ptr<Callback> callback) const final { const bool ok = CalculateSharedKeySync(peer_public_value, shared_key); @@ -75,15 +75,14 @@ class QUIC_EXPORT_PRIVATE SynchronousKeyExchange // CalculateSharedKey computes the shared key between a local private key and // a public value from the peer. Results will be written into |*shared_key|. - virtual bool CalculateSharedKeySync( - quiche::QuicheStringPiece peer_public_value, - std::string* shared_key) const = 0; + virtual bool CalculateSharedKeySync(absl::string_view peer_public_value, + std::string* shared_key) const = 0; // public_value returns the local public key which can be sent to a peer in - // order to complete a key exchange. The returned quiche::QuicheStringPiece is + // order to complete a key exchange. The returned absl::string_view is // a reference to a member of this object and is only valid for as long as it // exists. - virtual quiche::QuicheStringPiece public_value() const = 0; + virtual absl::string_view public_value() const = 0; }; // Create a SynchronousKeyExchange object which will use a keypair generated @@ -92,7 +91,7 @@ class QUIC_EXPORT_PRIVATE SynchronousKeyExchange // invalid. std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange( QuicTag type, - quiche::QuicheStringPiece private_key); + absl::string_view private_key); // Create a SynchronousKeyExchange object which will use a keypair generated // from |rand|, and a key-exchange algorithm specified by |type|, which must be diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc index d453a359ea6..2fc1acee1fc 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc @@ -6,35 +6,35 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { NullDecrypter::NullDecrypter(Perspective perspective) : perspective_(perspective) {} -bool NullDecrypter::SetKey(quiche::QuicheStringPiece key) { +bool NullDecrypter::SetKey(absl::string_view key) { return key.empty(); } -bool NullDecrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { +bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) { return nonce_prefix.empty(); } -bool NullDecrypter::SetIV(quiche::QuicheStringPiece iv) { +bool NullDecrypter::SetIV(absl::string_view iv) { return iv.empty(); } -bool NullDecrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { +bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) { return key.empty(); } -bool NullDecrypter::SetPreliminaryKey(quiche::QuicheStringPiece /*key*/) { +bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) { QUIC_BUG << "Should not be called"; return false; } @@ -46,8 +46,8 @@ bool NullDecrypter::SetDiversificationNonce( } bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) { @@ -59,7 +59,7 @@ bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/, return false; } - quiche::QuicheStringPiece plaintext = reader.ReadRemainingPayload(); + absl::string_view plaintext = reader.ReadRemainingPayload(); if (plaintext.length() > max_output_length) { QUIC_BUG << "Output buffer must be larger than the plaintext."; return false; @@ -90,18 +90,22 @@ size_t NullDecrypter::GetIVSize() const { return 0; } -quiche::QuicheStringPiece NullDecrypter::GetKey() const { - return quiche::QuicheStringPiece(); +absl::string_view NullDecrypter::GetKey() const { + return absl::string_view(); } -quiche::QuicheStringPiece NullDecrypter::GetNoncePrefix() const { - return quiche::QuicheStringPiece(); +absl::string_view NullDecrypter::GetNoncePrefix() const { + return absl::string_view(); } uint32_t NullDecrypter::cipher_id() const { return 0; } +QuicPacketCount NullDecrypter::GetIntegrityLimit() const { + return std::numeric_limits<QuicPacketCount>::max(); +} + bool NullDecrypter::ReadHash(QuicDataReader* reader, QuicUint128* hash) { uint64_t lo; uint32_t hi; @@ -112,9 +116,8 @@ bool NullDecrypter::ReadHash(QuicDataReader* reader, QuicUint128* hash) { return true; } -QuicUint128 NullDecrypter::ComputeHash( - const quiche::QuicheStringPiece data1, - const quiche::QuicheStringPiece data2) const { +QuicUint128 NullDecrypter::ComputeHash(const absl::string_view data1, + const absl::string_view data2) const { QuicUint128 correct_hash; if (perspective_ == Perspective::IS_CLIENT) { // Peer is a server. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h index c3bd203f5d5..3c856f44397 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.h @@ -8,11 +8,11 @@ #include <cstddef> #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,15 +29,15 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter { ~NullDecrypter() override {} // QuicDecrypter implementation - bool SetKey(quiche::QuicheStringPiece key) override; - bool SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) override; - bool SetIV(quiche::QuicheStringPiece iv) override; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; - bool SetPreliminaryKey(quiche::QuicheStringPiece key) override; + bool SetKey(absl::string_view key) override; + bool SetNoncePrefix(absl::string_view nonce_prefix) override; + bool SetIV(absl::string_view iv) override; + bool SetHeaderProtectionKey(absl::string_view key) override; + bool SetPreliminaryKey(absl::string_view key) override; bool SetDiversificationNonce(const DiversificationNonce& nonce) override; bool DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) override; @@ -46,15 +46,16 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter { size_t GetKeySize() const override; size_t GetNoncePrefixSize() const override; size_t GetIVSize() const override; - quiche::QuicheStringPiece GetKey() const override; - quiche::QuicheStringPiece GetNoncePrefix() const override; + absl::string_view GetKey() const override; + absl::string_view GetNoncePrefix() const override; uint32_t cipher_id() const override; + QuicPacketCount GetIntegrityLimit() const override; private: bool ReadHash(QuicDataReader* reader, QuicUint128* hash); - QuicUint128 ComputeHash(quiche::QuicheStringPiece data1, - quiche::QuicheStringPiece data2) const; + QuicUint128 ComputeHash(absl::string_view data1, + absl::string_view data2) const; Perspective perspective_; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc index 1baecad227e..b8b7268e3ea 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter_test.cc @@ -3,9 +3,9 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -38,15 +38,14 @@ TEST_F(NullDecrypterTest, DecryptClient) { '!', }; const char* data = reinterpret_cast<const char*>(expected); - size_t len = QUICHE_ARRAYSIZE(expected); + size_t len = ABSL_ARRAYSIZE(expected); NullDecrypter decrypter(Perspective::IS_SERVER); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(0, "hello world!", - quiche::QuicheStringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket( + 0, "hello world!", absl::string_view(data, len), buffer, &length, 256)); EXPECT_LT(0u, length); - EXPECT_EQ("goodbye!", quiche::QuicheStringPiece(buffer, length)); + EXPECT_EQ("goodbye!", absl::string_view(buffer, length)); } TEST_F(NullDecrypterTest, DecryptServer) { @@ -75,15 +74,14 @@ TEST_F(NullDecrypterTest, DecryptServer) { '!', }; const char* data = reinterpret_cast<const char*>(expected); - size_t len = QUICHE_ARRAYSIZE(expected); + size_t len = ABSL_ARRAYSIZE(expected); NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(0, "hello world!", - quiche::QuicheStringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket( + 0, "hello world!", absl::string_view(data, len), buffer, &length, 256)); EXPECT_LT(0u, length); - EXPECT_EQ("goodbye!", quiche::QuicheStringPiece(buffer, length)); + EXPECT_EQ("goodbye!", absl::string_view(buffer, length)); } TEST_F(NullDecrypterTest, BadHash) { @@ -112,13 +110,12 @@ TEST_F(NullDecrypterTest, BadHash) { '!', }; const char* data = reinterpret_cast<const char*>(expected); - size_t len = QUICHE_ARRAYSIZE(expected); + size_t len = ABSL_ARRAYSIZE(expected); NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_FALSE(decrypter.DecryptPacket(0, "hello world!", - quiche::QuicheStringPiece(data, len), - buffer, &length, 256)); + ASSERT_FALSE(decrypter.DecryptPacket( + 0, "hello world!", absl::string_view(data, len), buffer, &length, 256)); } TEST_F(NullDecrypterTest, ShortInput) { @@ -127,13 +124,12 @@ TEST_F(NullDecrypterTest, ShortInput) { 0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc, }; const char* data = reinterpret_cast<const char*>(expected); - size_t len = QUICHE_ARRAYSIZE(expected); + size_t len = ABSL_ARRAYSIZE(expected); NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_FALSE(decrypter.DecryptPacket(0, "hello world!", - quiche::QuicheStringPiece(data, len), - buffer, &length, 256)); + ASSERT_FALSE(decrypter.DecryptPacket( + 0, "hello world!", absl::string_view(data, len), buffer, &length, 256)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc index 4de151023af..f379ff23b69 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -15,25 +15,25 @@ const size_t kHashSizeShort = 12; // size of uint128 serialized short NullEncrypter::NullEncrypter(Perspective perspective) : perspective_(perspective) {} -bool NullEncrypter::SetKey(quiche::QuicheStringPiece key) { +bool NullEncrypter::SetKey(absl::string_view key) { return key.empty(); } -bool NullEncrypter::SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) { +bool NullEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) { return nonce_prefix.empty(); } -bool NullEncrypter::SetIV(quiche::QuicheStringPiece iv) { +bool NullEncrypter::SetIV(absl::string_view iv) { return iv.empty(); } -bool NullEncrypter::SetHeaderProtectionKey(quiche::QuicheStringPiece key) { +bool NullEncrypter::SetHeaderProtectionKey(absl::string_view key) { return key.empty(); } bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) { @@ -59,7 +59,7 @@ bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/, } std::string NullEncrypter::GenerateHeaderProtectionMask( - quiche::QuicheStringPiece /*sample*/) { + absl::string_view /*sample*/) { return std::string(5, 0); } @@ -83,12 +83,16 @@ size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const { return plaintext_size + GetHashLength(); } -quiche::QuicheStringPiece NullEncrypter::GetKey() const { - return quiche::QuicheStringPiece(); +QuicPacketCount NullEncrypter::GetConfidentialityLimit() const { + return std::numeric_limits<QuicPacketCount>::max(); } -quiche::QuicheStringPiece NullEncrypter::GetNoncePrefix() const { - return quiche::QuicheStringPiece(); +absl::string_view NullEncrypter::GetKey() const { + return absl::string_view(); +} + +absl::string_view NullEncrypter::GetNoncePrefix() const { + return absl::string_view(); } size_t NullEncrypter::GetHashLength() const { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h index bda73dc0ad8..82cb2c12f6e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.h @@ -7,10 +7,10 @@ #include <cstddef> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -25,25 +25,25 @@ class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter { ~NullEncrypter() override {} // QuicEncrypter implementation - bool SetKey(quiche::QuicheStringPiece key) override; - bool SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) override; - bool SetIV(quiche::QuicheStringPiece iv) override; - bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) override; + bool SetKey(absl::string_view key) override; + bool SetNoncePrefix(absl::string_view nonce_prefix) override; + bool SetIV(absl::string_view iv) override; + bool SetHeaderProtectionKey(absl::string_view key) override; bool EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) override; - std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) override; + std::string GenerateHeaderProtectionMask(absl::string_view sample) override; size_t GetKeySize() const override; size_t GetNoncePrefixSize() const override; size_t GetIVSize() const override; size_t GetMaxPlaintextSize(size_t ciphertext_size) const override; size_t GetCiphertextSize(size_t plaintext_size) const override; - quiche::QuicheStringPiece GetKey() const override; - quiche::QuicheStringPiece GetNoncePrefix() const override; + QuicPacketCount GetConfidentialityLimit() const override; + absl::string_view GetKey() const override; + absl::string_view GetNoncePrefix() const override; private: size_t GetHashLength() const; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc index c9b00d4c171..1bc5932ec4f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc @@ -3,9 +3,9 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" namespace quic { @@ -45,7 +45,7 @@ TEST_F(NullEncrypterTest, EncryptClient) { &encrypted_len, 256)); quiche::test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, - reinterpret_cast<const char*>(expected), QUICHE_ARRAYSIZE(expected)); + reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected)); } TEST_F(NullEncrypterTest, EncryptServer) { @@ -80,7 +80,7 @@ TEST_F(NullEncrypterTest, EncryptServer) { &encrypted_len, 256)); quiche::test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, - reinterpret_cast<const char*>(expected), QUICHE_ARRAYSIZE(expected)); + reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected)); } TEST_F(NullEncrypterTest, GetMaxPlaintextSize) { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc index 01f345de824..7a543b90e24 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.cc @@ -10,13 +10,13 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ec.h" #include "third_party/boringssl/src/include/openssl/ecdh.h" #include "third_party/boringssl/src/include/openssl/err.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -34,8 +34,7 @@ std::unique_ptr<P256KeyExchange> P256KeyExchange::New() { } // static -std::unique_ptr<P256KeyExchange> P256KeyExchange::New( - quiche::QuicheStringPiece key) { +std::unique_ptr<P256KeyExchange> P256KeyExchange::New(absl::string_view key) { if (key.empty()) { QUIC_DLOG(INFO) << "Private key is empty"; return nullptr; @@ -85,7 +84,7 @@ std::string P256KeyExchange::NewPrivateKey() { } bool P256KeyExchange::CalculateSharedKeySync( - quiche::QuicheStringPiece peer_public_value, + absl::string_view peer_public_value, std::string* shared_key) const { if (peer_public_value.size() != kUncompressedP256PointBytes) { QUIC_DLOG(INFO) << "Peer public value is invalid"; @@ -115,9 +114,9 @@ bool P256KeyExchange::CalculateSharedKeySync( return true; } -quiche::QuicheStringPiece P256KeyExchange::public_value() const { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(public_key_), - sizeof(public_key_)); +absl::string_view P256KeyExchange::public_value() const { + return absl::string_view(reinterpret_cast<const char*>(public_key_), + sizeof(public_key_)); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h index 10cc542597e..2b6f9b87b47 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange.h @@ -8,10 +8,10 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "net/third_party/quiche/src/quic/core/crypto/key_exchange.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -26,8 +26,7 @@ class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange { // New creates a new key-exchange object from a private key. If |private_key| // is invalid, nullptr is returned. - static std::unique_ptr<P256KeyExchange> New( - quiche::QuicheStringPiece private_key); + static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key); // NewPrivateKey returns a private key, suitable for passing to |New|. // If |NewPrivateKey| can't generate a private key, it returns an empty @@ -35,9 +34,9 @@ class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange { static std::string NewPrivateKey(); // SynchronousKeyExchange interface. - bool CalculateSharedKeySync(quiche::QuicheStringPiece peer_public_value, + bool CalculateSharedKeySync(absl::string_view peer_public_value, std::string* shared_key) const override; - quiche::QuicheStringPiece public_value() const override; + absl::string_view public_value() const override; QuicTag type() const override { return kP256; } private: diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc index 7e7dcd77a60..9419dcb5783 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/p256_key_exchange_test.cc @@ -8,8 +8,8 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -57,8 +57,8 @@ TEST_F(P256KeyExchangeTest, SharedKey) { ASSERT_TRUE(alice != nullptr); ASSERT_TRUE(bob != nullptr); - const quiche::QuicheStringPiece alice_public(alice->public_value()); - const quiche::QuicheStringPiece bob_public(bob->public_value()); + const absl::string_view alice_public(alice->public_value()); + const absl::string_view bob_public(bob->public_value()); std::string alice_shared, bob_shared; ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared)); @@ -84,8 +84,8 @@ TEST_F(P256KeyExchangeTest, AsyncSharedKey) { ASSERT_TRUE(alice != nullptr); ASSERT_TRUE(bob != nullptr); - const quiche::QuicheStringPiece alice_public(alice->public_value()); - const quiche::QuicheStringPiece bob_public(bob->public_value()); + const absl::string_view alice_public(alice->public_value()); + const absl::string_view bob_public(bob->public_value()); std::string alice_shared, bob_shared; TestCallbackResult alice_result; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h index 637dd0c33c5..e9358d50b85 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h @@ -9,13 +9,13 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -137,7 +137,7 @@ class QUIC_EXPORT_PRIVATE ProofSource { const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<Callback> callback) = 0; // Returns the certificate chain for |hostname| in leaf-first order. @@ -159,7 +159,7 @@ class QUIC_EXPORT_PRIVATE ProofSource { const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<SignatureCallback> callback) = 0; class QUIC_EXPORT_PRIVATE DecryptCallback { @@ -193,13 +193,13 @@ class QUIC_EXPORT_PRIVATE ProofSource { // returns the encrypted ticket. The resulting value must not be larger than // MaxOverhead bytes larger than |in|. If encryption fails, this method // returns an empty vector. - virtual std::vector<uint8_t> Encrypt(quiche::QuicheStringPiece in) = 0; + virtual std::vector<uint8_t> Encrypt(absl::string_view in) = 0; // Decrypt takes an encrypted ticket |in|, decrypts it, and calls // |callback->Run| with the decrypted ticket, which must not be larger than // |in|. If decryption fails, the callback is invoked with an empty // vector. - virtual void Decrypt(quiche::QuicheStringPiece in, + virtual void Decrypt(absl::string_view in, std::unique_ptr<DecryptCallback> callback) = 0; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc index e432682bddd..530f9d52ae1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc @@ -6,14 +6,14 @@ #include <memory> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -34,7 +34,7 @@ void ProofSourceX509::GetProof( const std::string& hostname, const std::string& server_config, QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<ProofSource::Callback> callback) { QuicCryptoProof proof; @@ -54,9 +54,9 @@ void ProofSourceX509::GetProof( } Certificate* certificate = GetCertificate(hostname); - proof.signature = certificate->key.Sign( - quiche::QuicheStringPiece(payload.get(), payload_size), - SSL_SIGN_RSA_PSS_RSAE_SHA256); + proof.signature = + certificate->key.Sign(absl::string_view(payload.get(), payload_size), + SSL_SIGN_RSA_PSS_RSAE_SHA256); callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof, nullptr); } @@ -73,7 +73,7 @@ void ProofSourceX509::ComputeTlsSignature( const QuicSocketAddress& /*client_address*/, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::SignatureCallback> callback) { std::string signature = GetCertificate(hostname)->key.Sign(in, signature_algorithm); @@ -109,7 +109,7 @@ bool ProofSourceX509::AddCertificateChain( }); Certificate* certificate = &certificates_.front(); - for (quiche::QuicheStringPiece host : leaf->subject_alt_name_domains()) { + for (absl::string_view host : leaf->subject_alt_name_domains()) { certificate_map_[std::string(host)] = certificate; } return true; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h index 8632d4bfe95..bc6baaad77b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.h @@ -8,11 +8,11 @@ #include <forward_list> #include <memory> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -32,7 +32,7 @@ class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource { const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<Callback> callback) override; QuicReferenceCountedPointer<Chain> GetCertChain( const QuicSocketAddress& server_address, @@ -43,14 +43,14 @@ class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource { const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<SignatureCallback> callback) override; TicketCrypter* GetTicketCrypter() override; // Adds a certificate chain to the verifier. Returns false if the chain is // not valid. Newer certificates will override older certificates with the // same SubjectAltName value. - QUIC_MUST_USE_RESULT bool AddCertificateChain( + ABSL_MUST_USE_RESULT bool AddCertificateChain( QuicReferenceCountedPointer<Chain> chain, CertificatePrivateKey key); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc index 23311d08232..e0b45c6bd5d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509_test.cc @@ -6,6 +6,7 @@ #include <memory> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" @@ -15,14 +16,13 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/test_certificates.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { namespace { QuicReferenceCountedPointer<ProofSource::Chain> MakeChain( - quiche::QuicheStringPiece cert) { + absl::string_view cert) { return QuicReferenceCountedPointer<ProofSource::Chain>( new ProofSource::Chain(std::vector<std::string>{std::string(cert)})); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h index 0380b8a87d8..ab09811c1c8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_verifier.h @@ -9,10 +9,10 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -79,7 +79,7 @@ class QUIC_EXPORT_PRIVATE ProofVerifier { const uint16_t port, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& certs, const std::string& cert_sct, const std::string& signature, @@ -97,6 +97,11 @@ class QUIC_EXPORT_PRIVATE ProofVerifier { // for some implementations) that provides useful information for the // verifier, e.g. logging handles. // + // If certificate verification fails, a TLS alert will be sent when closing + // the connection. This alert defaults to certificate_unknown. By setting + // |*out_alert|, a different alert can be sent to provide a more specific + // reason why verification failed. + // // This function may also return QUIC_PENDING, in which case the ProofVerifier // will call back, on the original thread, via |callback| when complete. // In this case, the ProofVerifier will take ownership of |callback|. @@ -109,6 +114,7 @@ class QUIC_EXPORT_PRIVATE ProofVerifier { const ProofVerifyContext* context, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, std::unique_ptr<ProofVerifierCallback> callback) = 0; // Returns a ProofVerifyContext instance which can be use for subsequent diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc index d8e7f2d1c92..036f694699b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.cc @@ -3,13 +3,12 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/crypto/quic_crypter.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { -bool QuicCrypter::SetNoncePrefixOrIV( - const ParsedQuicVersion& version, - quiche::QuicheStringPiece nonce_prefix_or_iv) { +bool QuicCrypter::SetNoncePrefixOrIV(const ParsedQuicVersion& version, + absl::string_view nonce_prefix_or_iv) { if (version.UsesInitialObfuscators()) { return SetIV(nonce_prefix_or_iv); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h index a12cd6f9eb2..348a3fbe56e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypter.h @@ -5,9 +5,9 @@ #ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_ #define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -24,7 +24,7 @@ class QUIC_EXPORT_PRIVATE QuicCrypter { // // NOTE: The key is the client_write_key or server_write_key derived from // the master secret. - virtual bool SetKey(quiche::QuicheStringPiece key) = 0; + virtual bool SetKey(absl::string_view key) = 0; // Sets the fixed initial bytes of the nonce. Returns true on success, // false on failure. This method must only be used with Google QUIC crypters. @@ -41,7 +41,7 @@ class QUIC_EXPORT_PRIVATE QuicCrypter { // // The security of the nonce format requires that QUIC never reuse a // packet number, even when retransmitting a lost packet. - virtual bool SetNoncePrefix(quiche::QuicheStringPiece nonce_prefix) = 0; + virtual bool SetNoncePrefix(absl::string_view nonce_prefix) = 0; // Sets |iv| as the initialization vector to use when constructing the nonce. // Returns true on success, false on failure. This method must only be used @@ -68,15 +68,15 @@ class QUIC_EXPORT_PRIVATE QuicCrypter { // // The security of the nonce format requires that QUIC never reuse a // packet number, even when retransmitting a lost packet. - virtual bool SetIV(quiche::QuicheStringPiece iv) = 0; + virtual bool SetIV(absl::string_view iv) = 0; // Calls SetNoncePrefix or SetIV depending on whether |version| uses the // Google QUIC crypto or IETF QUIC nonce construction. virtual bool SetNoncePrefixOrIV(const ParsedQuicVersion& version, - quiche::QuicheStringPiece nonce_prefix_or_iv); + absl::string_view nonce_prefix_or_iv); // Sets the key to use for header protection. - virtual bool SetHeaderProtectionKey(quiche::QuicheStringPiece key) = 0; + virtual bool SetHeaderProtectionKey(absl::string_view key) = 0; // GetKeySize, GetIVSize, and GetNoncePrefixSize are used to know how many // bytes of key material needs to be derived from the master secret. 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 c110f8ec1c3..102678105dd 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 @@ -8,6 +8,9 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/cert_compressor.h" #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h" @@ -31,8 +34,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -68,7 +69,7 @@ QuicCryptoClientConfig::QuicCryptoClientConfig( : proof_verifier_(std::move(proof_verifier)), session_cache_(std::move(session_cache)), ssl_ctx_(TlsClientConnection::CreateSslCtx( - GetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2))) { + !GetQuicFlag(FLAGS_quic_disable_client_tls_zero_rtt))) { DCHECK(proof_verifier_.get()); SetDefaults(); } @@ -144,7 +145,7 @@ bool QuicCryptoClientConfig::CachedState::has_server_nonce() const { QuicCryptoClientConfig::CachedState::ServerConfigState QuicCryptoClientConfig::CachedState::SetServerConfig( - quiche::QuicheStringPiece server_config, + absl::string_view server_config, QuicWallTime now, QuicWallTime expiry_time, std::string* error_details) { @@ -199,9 +200,9 @@ void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { void QuicCryptoClientConfig::CachedState::SetProof( const std::vector<std::string>& certs, - quiche::QuicheStringPiece cert_sct, - quiche::QuicheStringPiece chlo_hash, - quiche::QuicheStringPiece signature) { + absl::string_view cert_sct, + absl::string_view chlo_hash, + absl::string_view signature) { bool has_changed = signature != server_config_sig_ || chlo_hash != chlo_hash_ || certs_.size() != certs.size(); @@ -257,12 +258,12 @@ void QuicCryptoClientConfig::CachedState::SetProofInvalid() { } bool QuicCryptoClientConfig::CachedState::Initialize( - quiche::QuicheStringPiece server_config, - quiche::QuicheStringPiece source_address_token, + absl::string_view server_config, + absl::string_view source_address_token, const std::vector<std::string>& certs, const std::string& cert_sct, - quiche::QuicheStringPiece chlo_hash, - quiche::QuicheStringPiece signature, + absl::string_view chlo_hash, + absl::string_view signature, QuicWallTime now, QuicWallTime expiration_time) { DCHECK(server_config_.empty()); @@ -330,12 +331,12 @@ QuicCryptoClientConfig::CachedState::proof_verify_details() const { } void QuicCryptoClientConfig::CachedState::set_source_address_token( - quiche::QuicheStringPiece token) { + absl::string_view token) { source_address_token_ = std::string(token); } void QuicCryptoClientConfig::CachedState::set_cert_sct( - quiche::QuicheStringPiece cert_sct) { + absl::string_view cert_sct) { cert_sct_ = std::string(cert_sct); } @@ -439,7 +440,7 @@ void QuicCryptoClientConfig::FillInchoateClientHello( // the STK can be validated by the server. const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); if (scfg != nullptr) { - quiche::QuicheStringPiece scid; + absl::string_view scid; if (scfg->GetStringPiece(kSCID, &scid)) { out->SetStringPiece(kSCID, scid); } @@ -454,9 +455,9 @@ void QuicCryptoClientConfig::FillInchoateClientHello( } char proof_nonce[32]; - rand->RandBytes(proof_nonce, QUICHE_ARRAYSIZE(proof_nonce)); - out->SetStringPiece(kNONP, quiche::QuicheStringPiece( - proof_nonce, QUICHE_ARRAYSIZE(proof_nonce))); + rand->RandBytes(proof_nonce, ABSL_ARRAYSIZE(proof_nonce)); + out->SetStringPiece( + kNONP, absl::string_view(proof_nonce, ABSL_ARRAYSIZE(proof_nonce))); out->SetVector(kPDMD, QuicTagVector{kX509}); @@ -513,7 +514,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( return QUIC_CRYPTO_INTERNAL_ERROR; } - quiche::QuicheStringPiece scid; + absl::string_view scid; if (!scfg->GetStringPiece(kSCID, &scid)) { *error_details = "SCFG missing SCID"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; @@ -545,14 +546,14 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( out->SetVector(kAEAD, QuicTagVector{out_params->aead}); out->SetVector(kKEXS, QuicTagVector{out_params->key_exchange}); - quiche::QuicheStringPiece public_value; + absl::string_view public_value; if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != QUIC_NO_ERROR) { *error_details = "Missing public value"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; } - quiche::QuicheStringPiece orbit; + absl::string_view orbit; if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) { *error_details = "SCFG missing OBIT"; return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; @@ -635,13 +636,13 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( const CryptoHandshakeMessage& message, QuicWallTime now, QuicTransportVersion /*version*/, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& cached_certs, CachedState* cached, std::string* error_details) { DCHECK(error_details != nullptr); - quiche::QuicheStringPiece scfg; + absl::string_view scfg; if (!message.GetStringPiece(kSCFG, &scfg)) { *error_details = "Missing SCFG"; return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; @@ -666,12 +667,12 @@ QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; } - quiche::QuicheStringPiece token; + absl::string_view token; if (message.GetStringPiece(kSourceAddressTokenTag, &token)) { cached->set_source_address_token(token); } - quiche::QuicheStringPiece proof, cert_bytes, cert_sct; + absl::string_view proof, cert_bytes, cert_sct; bool has_proof = message.GetStringPiece(kPROF, &proof); bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes); if (has_proof && has_cert) { @@ -707,7 +708,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection( const CryptoHandshakeMessage& rej, QuicWallTime now, const QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, CachedState* cached, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details) { @@ -725,7 +726,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection( return error; } - quiche::QuicheStringPiece nonce; + absl::string_view nonce; if (rej.GetStringPiece(kServerNonceTag, &nonce)) { out_params->server_nonce = std::string(nonce); } @@ -750,12 +751,12 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( } // Learn about updated source address tokens. - quiche::QuicheStringPiece token; + absl::string_view token; if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) { cached->set_source_address_token(token); } - quiche::QuicheStringPiece shlo_nonce; + absl::string_view shlo_nonce; if (!server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) { *error_details = "server hello missing server nonce"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; @@ -764,7 +765,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( // TODO(agl): // learn about updated SCFGs. - quiche::QuicheStringPiece public_value; + absl::string_view public_value; if (!server_hello.GetStringPiece(kPUBS, &public_value)) { *error_details = "server hello missing forward secure public value"; return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; @@ -800,7 +801,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate( const CryptoHandshakeMessage& server_config_update, QuicWallTime now, const QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, CachedState* cached, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details) { @@ -858,8 +859,7 @@ bool QuicCryptoClientConfig::PopulateFromCanonicalConfig( DCHECK(server_state->IsEmpty()); size_t i = 0; for (; i < canonical_suffixes_.size(); ++i) { - if (quiche::QuicheTextUtils::EndsWithIgnoreCase(server_id.host(), - canonical_suffixes_[i])) { + if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) { break; } } 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 701b7ffef66..913ddf94d23 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 @@ -11,6 +11,7 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" @@ -21,7 +22,6 @@ #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -131,7 +131,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // SetServerConfig checks that |server_config| parses correctly and stores // it in |server_config_|. |now| is used to judge whether |server_config| // has expired. - ServerConfigState SetServerConfig(quiche::QuicheStringPiece server_config, + ServerConfigState SetServerConfig(absl::string_view server_config, QuicWallTime now, QuicWallTime expiry_time, std::string* error_details); @@ -141,9 +141,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // SetProof stores a cert chain, cert signed timestamp and signature. void SetProof(const std::vector<std::string>& certs, - quiche::QuicheStringPiece cert_sct, - quiche::QuicheStringPiece chlo_hash, - quiche::QuicheStringPiece signature); + absl::string_view cert_sct, + absl::string_view chlo_hash, + absl::string_view signature); // Clears all the data. void Clear(); @@ -171,9 +171,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { uint64_t generation_counter() const; const ProofVerifyDetails* proof_verify_details() const; - void set_source_address_token(quiche::QuicheStringPiece token); + void set_source_address_token(absl::string_view token); - void set_cert_sct(quiche::QuicheStringPiece cert_sct); + void set_cert_sct(absl::string_view cert_sct); // Adds the servernonce to the queue of server nonces. void add_server_nonce(const std::string& server_nonce); @@ -198,12 +198,12 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // Initializes this cached state based on the arguments provided. // Returns false if there is a problem parsing the server config. - bool Initialize(quiche::QuicheStringPiece server_config, - quiche::QuicheStringPiece source_address_token, + bool Initialize(absl::string_view server_config, + absl::string_view source_address_token, const std::vector<std::string>& certs, const std::string& cert_sct, - quiche::QuicheStringPiece chlo_hash, - quiche::QuicheStringPiece signature, + absl::string_view chlo_hash, + absl::string_view signature, QuicWallTime now, QuicWallTime expiration_time); @@ -311,7 +311,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { const CryptoHandshakeMessage& rej, QuicWallTime now, QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, CachedState* cached, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details); @@ -343,7 +343,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { const CryptoHandshakeMessage& server_update, QuicWallTime now, const QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, CachedState* cached, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details); @@ -380,7 +380,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { void set_alpn(const std::string& alpn) { alpn_ = alpn; } // Saves the pre-shared key used during the handshake. - void set_pre_shared_key(quiche::QuicheStringPiece psk) { + void set_pre_shared_key(absl::string_view psk) { pre_shared_key_ = std::string(psk); } @@ -407,7 +407,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { const CryptoHandshakeMessage& message, QuicWallTime now, QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& cached_certs, CachedState* cached, std::string* error_details); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc index 88b3eb68f14..d7625cd4e09 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc @@ -6,6 +6,7 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -15,7 +16,6 @@ #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::StartsWith; @@ -149,13 +149,13 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChlo) { QuicVersionLabel cver; EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError()); EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver); - quiche::QuicheStringPiece proof_nonce; + absl::string_view proof_nonce; EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce)); EXPECT_EQ(std::string(32, 'r'), proof_nonce); - quiche::QuicheStringPiece user_agent_id; + absl::string_view user_agent_id; EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id)); EXPECT_EQ("quic-tester", user_agent_id); - quiche::QuicheStringPiece alpn; + absl::string_view alpn; EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn)); EXPECT_EQ("hq", alpn); EXPECT_EQ(msg.minimum_size(), 1u); @@ -203,7 +203,7 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) { QuicTag pdmd; EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError()); EXPECT_EQ(kX509, pdmd); - quiche::QuicheStringPiece scid; + absl::string_view scid; EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid)); } @@ -229,7 +229,7 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) { config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand, /* demand_x509_proof= */ true, params, &msg); - quiche::QuicheStringPiece scid; + absl::string_view scid; EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid)); EXPECT_EQ("12345678", scid); } @@ -255,7 +255,7 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) { config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand, /* demand_x509_proof= */ true, params, &msg); - quiche::QuicheStringPiece scid; + absl::string_view scid; EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid)); EXPECT_EQ("12345678", scid); } 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 ec535cfa7c6..b929dcc11b9 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 @@ -10,11 +10,16 @@ #include <string> #include <utility> +#include "absl/base/attributes.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/cert_compressor.h" +#include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/channel_id.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" @@ -40,7 +45,6 @@ #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h" @@ -48,7 +52,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_testvalue.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -64,11 +67,11 @@ const size_t kMultiplier = 3; const int kMaxTokenAddresses = 4; std::string DeriveSourceAddressTokenKey( - quiche::QuicheStringPiece source_address_token_secret) { - QuicHKDF hkdf( - source_address_token_secret, quiche::QuicheStringPiece() /* no salt */, - "QUIC source address token key", CryptoSecretBoxer::GetKeySize(), - 0 /* no fixed IV needed */, 0 /* no subkey secret */); + absl::string_view source_address_token_secret) { + QuicHKDF hkdf(source_address_token_secret, absl::string_view() /* no salt */, + "QUIC source address token key", + CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */, + 0 /* no subkey secret */); return std::string(hkdf.server_write_key()); } @@ -82,7 +85,7 @@ class DefaultKeyExchangeSource : public KeyExchangeSource { std::string /*server_config_id*/, bool /* is_fallback */, QuicTag type, - quiche::QuicheStringPiece private_key) override { + absl::string_view private_key) override { if (private_key.empty()) { QUIC_LOG(WARNING) << "Server config contains key exchange method without " "corresponding private key of type " @@ -232,7 +235,7 @@ void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed( } QuicCryptoServerConfig::QuicCryptoServerConfig( - quiche::QuicheStringPiece source_address_token_secret, + absl::string_view source_address_token_secret, QuicRandom* server_nonce_entropy, std::unique_ptr<ProofSource> proof_source, std::unique_ptr<KeyExchangeSource> key_exchange_source) @@ -281,8 +284,7 @@ QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig( Curve25519KeyExchange::NewPrivateKey(rand); std::unique_ptr<Curve25519KeyExchange> curve25519 = Curve25519KeyExchange::New(curve25519_private_key); - quiche::QuicheStringPiece curve25519_public_value = - curve25519->public_value(); + absl::string_view curve25519_public_value = curve25519->public_value(); std::string encoded_public_values; // First three bytes encode the length of the public value. @@ -301,7 +303,7 @@ QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig( p256_private_key = P256KeyExchange::NewPrivateKey(); std::unique_ptr<P256KeyExchange> p256( P256KeyExchange::New(p256_private_key)); - quiche::QuicheStringPiece p256_public_value = p256->public_value(); + absl::string_view p256_public_value = p256->public_value(); DCHECK_LT(p256_public_value.size(), (1U << 24)); encoded_public_values.push_back( @@ -340,8 +342,8 @@ QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig( DCHECK(options.orbit.empty()); rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); } - msg.SetStringPiece( - kORBT, quiche::QuicheStringPiece(orbit_bytes, sizeof(orbit_bytes))); + msg.SetStringPiece(kORBT, + absl::string_view(orbit_bytes, sizeof(orbit_bytes))); if (options.channel_id_enabled) { msg.SetVector(kPDMD, QuicTagVector{kCHID}); @@ -358,9 +360,9 @@ QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig( serialized->length(), scid_bytes); // The SCID is a truncated SHA-256 digest. static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high."); - msg.SetStringPiece(kSCID, - quiche::QuicheStringPiece( - reinterpret_cast<const char*>(scid_bytes), 16)); + msg.SetStringPiece( + kSCID, + absl::string_view(reinterpret_cast<const char*>(scid_bytes), 16)); } else { msg.SetStringPiece(kSCID, options.id); } @@ -409,7 +411,7 @@ std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig( if (configs_.find(config->id) != configs_.end()) { QUIC_LOG(WARNING) << "Failed to add config because another with the same " "server config id already exists: " - << quiche::QuicheTextUtils::HexEncode(config->id); + << absl::BytesToHexString(config->id); return nullptr; } @@ -455,7 +457,7 @@ bool QuicCryptoServerConfig::SetConfigs( return false; } QUIC_LOG(INFO) << "Fallback config has scid " - << quiche::QuicheTextUtils::HexEncode(fallback_config->id); + << absl::BytesToHexString(fallback_config->id); parsed_configs.push_back(fallback_config); } else { QUIC_LOG(INFO) << "No fallback config provided"; @@ -475,26 +477,27 @@ bool QuicCryptoServerConfig::SetConfigs( for (const QuicReferenceCountedPointer<Config>& config : parsed_configs) { auto it = configs_.find(config->id); if (it != configs_.end()) { - QUIC_LOG(INFO) - << "Keeping scid: " << quiche::QuicheTextUtils::HexEncode(config->id) - << " orbit: " - << quiche::QuicheTextUtils::HexEncode( - reinterpret_cast<const char*>(config->orbit), kOrbitSize) - << " new primary_time " << config->primary_time.ToUNIXSeconds() - << " old primary_time " << it->second->primary_time.ToUNIXSeconds() - << " new priority " << config->priority << " old priority " - << it->second->priority; + QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id) + << " orbit: " + << absl::BytesToHexString(absl::string_view( + reinterpret_cast<const char*>(config->orbit), + kOrbitSize)) + << " new primary_time " + << config->primary_time.ToUNIXSeconds() + << " old primary_time " + << it->second->primary_time.ToUNIXSeconds() + << " new priority " << config->priority << " old priority " + << it->second->priority; // Update primary_time and priority. it->second->primary_time = config->primary_time; it->second->priority = config->priority; new_configs.insert(*it); } else { - QUIC_LOG(INFO) << "Adding scid: " - << quiche::QuicheTextUtils::HexEncode(config->id) + QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id) << " orbit: " - << quiche::QuicheTextUtils::HexEncode( + << absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(config->orbit), - kOrbitSize) + kOrbitSize)) << " primary_time " << config->primary_time.ToUNIXSeconds() << " priority " << config->priority; new_configs.emplace(config->id, config); @@ -538,7 +541,7 @@ void QuicCryptoServerConfig::ValidateClientHello( new ValidateClientHelloResultCallback::Result( client_hello, client_address.host(), now)); - quiche::QuicheStringPiece requested_scid; + absl::string_view requested_scid; client_hello.GetStringPiece(kSCID, &requested_scid); Configs configs; if (!GetCurrentConfigs(now, requested_scid, @@ -594,7 +597,7 @@ class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback std::unique_ptr<ProofSource::Details> proof_source_details, QuicTag key_exchange_type, std::unique_ptr<CryptoHandshakeMessage> out, - quiche::QuicheStringPiece public_value, + absl::string_view public_value, std::unique_ptr<ProcessClientHelloContext> context, const Configs& configs) : config_(config), @@ -687,7 +690,7 @@ void QuicCryptoServerConfig::ProcessClientHello( return; } - quiche::QuicheStringPiece requested_scid; + absl::string_view requested_scid; context->client_hello().GetStringPiece(kSCID, &requested_scid); Configs configs; if (!GetCurrentConfigs(context->clock()->WallNow(), requested_scid, @@ -748,7 +751,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( auto out_diversification_nonce = std::make_unique<DiversificationNonce>(); - quiche::QuicheStringPiece cert_sct; + absl::string_view cert_sct; if (context->client_hello().GetStringPiece(kCertificateSCTTag, &cert_sct) && cert_sct.empty()) { context->params()->sct_supported_by_client = true; @@ -791,7 +794,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( return; } - quiche::QuicheStringPiece public_value; + absl::string_view public_value; if (!context->client_hello().GetStringPiece(kPUBS, &public_value)) { context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); @@ -819,7 +822,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys( std::unique_ptr<ProofSource::Details> proof_source_details, QuicTag key_exchange_type, std::unique_ptr<CryptoHandshakeMessage> out, - quiche::QuicheStringPiece public_value, + absl::string_view public_value, std::unique_ptr<ProcessClientHelloContext> context, const Configs& configs) const { QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion( @@ -832,8 +835,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys( if (found_error) { // If we are already using the fallback config, or there is no fallback // config to use, just bail out of the handshake. - if ((GetQuicReloadableFlag(quic_check_fallback_null) && - configs.fallback == nullptr) || + if (configs.fallback == nullptr || context->signed_config()->config == configs.fallback || !GetQuicReloadableFlag( send_quic_fallback_server_config_on_leto_error)) { @@ -868,7 +870,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys( } hkdf_suffix.append(context->signed_config()->chain->certs.at(0)); - quiche::QuicheStringPiece cetv_ciphertext; + absl::string_view cetv_ciphertext; if (configs.requested->channel_id_enabled && context->client_hello().GetStringPiece(kCETV, &cetv_ciphertext)) { CryptoHandshakeMessage client_hello_copy(context->client_hello()); @@ -901,22 +903,21 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys( char plaintext[kMaxOutgoingPacketSize]; size_t plaintext_length = 0; const bool success = crypters.decrypter->DecryptPacket( - 0 /* packet number */, - quiche::QuicheStringPiece() /* associated data */, cetv_ciphertext, - plaintext, &plaintext_length, kMaxOutgoingPacketSize); + 0 /* packet number */, absl::string_view() /* associated data */, + cetv_ciphertext, plaintext, &plaintext_length, kMaxOutgoingPacketSize); if (!success) { context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV decryption failure"); return; } std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( - quiche::QuicheStringPiece(plaintext, plaintext_length))); + absl::string_view(plaintext, plaintext_length))); if (!cetv) { context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error"); return; } - quiche::QuicheStringPiece key, signature; + absl::string_view key, signature; if (cetv->GetStringPiece(kCIDK, &key) && cetv->GetStringPiece(kCIDS, &signature)) { if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { @@ -1055,7 +1056,7 @@ void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof( QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> QuicCryptoServerConfig::GetConfigWithScid( - quiche::QuicheStringPiece requested_scid) const { + absl::string_view requested_scid) const { configs_lock_.AssertReaderHeld(); if (!requested_scid.empty()) { @@ -1072,7 +1073,7 @@ QuicCryptoServerConfig::GetConfigWithScid( bool QuicCryptoServerConfig::GetCurrentConfigs( const QuicWallTime& now, - quiche::QuicheStringPiece requested_scid, + absl::string_view requested_scid, QuicReferenceCountedPointer<Config> old_primary_config, Configs* configs) const { QuicReaderMutexLock locked(&configs_lock_); @@ -1175,10 +1176,10 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig( primary_config_ = new_primary; new_primary->is_primary = true; QUIC_DLOG(INFO) << "New primary config. orbit: " - << quiche::QuicheTextUtils::HexEncode( - reinterpret_cast<const char*>( - primary_config_->orbit), - kOrbitSize); + << absl::BytesToHexString( + absl::string_view(reinterpret_cast<const char*>( + primary_config_->orbit), + kOrbitSize)); if (primary_config_changed_cb_ != nullptr) { primary_config_changed_cb_->Run(primary_config_->id); } @@ -1195,11 +1196,10 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig( primary_config_ = new_primary; new_primary->is_primary = true; QUIC_DLOG(INFO) << "New primary config. orbit: " - << quiche::QuicheTextUtils::HexEncode( + << absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(primary_config_->orbit), - kOrbitSize) - << " scid: " - << quiche::QuicheTextUtils::HexEncode(primary_config_->id); + kOrbitSize)) + << " scid: " << absl::BytesToHexString(primary_config_->id); next_config_promotion_time_ = QuicWallTime::Zero(); if (primary_config_changed_cb_ != nullptr) { primary_config_changed_cb_->Run(primary_config_->id); @@ -1230,7 +1230,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON; if (validate_source_address_token_) { - quiche::QuicheStringPiece srct; + absl::string_view srct; if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { Config& config = configs.requested != nullptr ? *configs.requested : *configs.primary; @@ -1253,7 +1253,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( } if (!configs.requested) { - quiche::QuicheStringPiece requested_scid; + absl::string_view requested_scid; if (client_hello.GetStringPiece(kSCID, &requested_scid)) { info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); } else { @@ -1308,7 +1308,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const SourceAddressTokens& previous_source_address_tokens, const QuicSocketAddress& server_address, const QuicSocketAddress& client_address, @@ -1457,13 +1457,13 @@ void QuicCryptoServerConfig::BuildRejection( return; } - quiche::QuicheStringPiece client_common_set_hashes; + absl::string_view client_common_set_hashes; if (context.client_hello().GetStringPiece(kCCS, &client_common_set_hashes)) { context.params()->client_common_set_hashes = std::string(client_common_set_hashes); } - quiche::QuicheStringPiece client_cached_cert_hashes; + absl::string_view client_cached_cert_hashes; if (context.client_hello().GetStringPiece(kCCRT, &client_cached_cert_hashes)) { context.params()->client_cached_cert_hashes = @@ -1511,9 +1511,29 @@ void QuicCryptoServerConfig::BuildRejection( // This is for debugging b/28342827. const std::vector<std::string>& certs = context.signed_config()->chain->certs; - quiche::QuicheStringPiece ca_subject; + std::string ca_subject; if (!certs.empty()) { - QuicCertUtils::ExtractSubjectNameFromDERCert(certs[0], &ca_subject); + if (GetQuicReloadableFlag( + quic_extract_x509_subject_using_certificate_view)) { + QUIC_RELOADABLE_FLAG_COUNT_N( + quic_extract_x509_subject_using_certificate_view, 1, 2); + std::unique_ptr<CertificateView> view = + CertificateView::ParseSingleCertificate(certs[0]); + if (view != nullptr) { + absl::optional<std::string> maybe_ca_subject = + view->GetHumanReadableSubject(); + if (maybe_ca_subject.has_value()) { + QUIC_RELOADABLE_FLAG_COUNT_N( + quic_extract_x509_subject_using_certificate_view, 2, 2); + ca_subject = *maybe_ca_subject; + } + } + } else { + absl::string_view ca_subject_view; + QuicCertUtils::ExtractSubjectNameFromDERCert(certs[0], + &ca_subject_view); + ca_subject = std::string(ca_subject_view); + } } QUIC_LOG_EVERY_N_SEC(WARNING, 60) << "SCT is expected but it is empty. sni: '" @@ -1578,7 +1598,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf( config->priority = protobuf.priority(); - quiche::QuicheStringPiece scid; + absl::string_view scid; if (!msg->GetStringPiece(kSCID, &scid)) { QUIC_LOG(WARNING) << "Server config message is missing SCID"; return nullptr; @@ -1596,7 +1616,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf( return nullptr; } - quiche::QuicheStringPiece orbit; + absl::string_view orbit; if (!msg->GetStringPiece(kORBT, &orbit)) { QUIC_LOG(WARNING) << "Server config message is missing ORBT"; return nullptr; @@ -1767,10 +1787,10 @@ SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const { HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( const Config& config, - quiche::QuicheStringPiece token, + absl::string_view token, SourceAddressTokens* tokens) const { std::string storage; - quiche::QuicheStringPiece plaintext; + absl::string_view plaintext; if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; } @@ -1860,8 +1880,8 @@ std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, sizeof(server_nonce) - sizeof(timestamp)); return server_nonce_boxer_.Box( - rand, quiche::QuicheStringPiece(reinterpret_cast<char*>(server_nonce), - sizeof(server_nonce))); + rand, absl::string_view(reinterpret_cast<char*>(server_nonce), + sizeof(server_nonce))); } bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( 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 9f2db603416..7fae412bce2 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 @@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" @@ -30,7 +31,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -54,10 +54,10 @@ struct QUIC_EXPORT_PRIVATE ClientHelloInfo { // Outputs from EvaluateClientHello. bool valid_source_address_token; - quiche::QuicheStringPiece sni; - quiche::QuicheStringPiece client_nonce; - quiche::QuicheStringPiece server_nonce; - quiche::QuicheStringPiece user_agent_id; + absl::string_view sni; + absl::string_view client_nonce; + absl::string_view server_nonce; + absl::string_view user_agent_id; SourceAddressTokens source_address_tokens; // Errors from EvaluateClientHello. @@ -171,7 +171,7 @@ class QUIC_EXPORT_PRIVATE KeyExchangeSource { std::string server_config_id, bool is_fallback, QuicTag type, - quiche::QuicheStringPiece private_key) = 0; + absl::string_view private_key) = 0; }; // QuicCryptoServerConfig contains the crypto configuration of a QUIC server. @@ -215,7 +215,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // |proof_source|: provides certificate chains and signatures. // |key_exchange_source|: provides key-exchange functionality. QuicCryptoServerConfig( - quiche::QuicheStringPiece source_address_token_secret, + absl::string_view source_address_token_secret, QuicRandom* server_nonce_entropy, std::unique_ptr<ProofSource> proof_source, std::unique_ptr<KeyExchangeSource> key_exchange_source); @@ -357,7 +357,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // |cached_network_params| is optional, and can be nullptr. void BuildServerConfigUpdateMessage( QuicTransportVersion version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const SourceAddressTokens& previous_source_address_tokens, const QuicSocketAddress& server_address, const QuicSocketAddress& client_address, @@ -434,7 +434,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // Pre-shared key used during the handshake. const std::string& pre_shared_key() const { return pre_shared_key_; } - void set_pre_shared_key(quiche::QuicheStringPiece psk) { + void set_pre_shared_key(absl::string_view psk) { pre_shared_key_ = std::string(psk); } @@ -511,12 +511,12 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { ~Config() override; }; - typedef std::map<ServerConfigID, QuicReferenceCountedPointer<Config>> - ConfigMap; + using ConfigMap = + std::map<ServerConfigID, QuicReferenceCountedPointer<Config>>; // Get a ref to the config with a given server config id. QuicReferenceCountedPointer<Config> GetConfigWithScid( - quiche::QuicheStringPiece requested_scid) const + absl::string_view requested_scid) const QUIC_SHARED_LOCKS_REQUIRED(configs_lock_); // A snapshot of the configs associated with an in-progress handshake. @@ -533,7 +533,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // Returns true if any configs are loaded. If false is returned, |configs| is // not modified. bool GetCurrentConfigs(const QuicWallTime& now, - quiche::QuicheStringPiece requested_scid, + absl::string_view requested_scid, QuicReferenceCountedPointer<Config> old_primary_config, Configs* configs) const; @@ -687,7 +687,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { std::unique_ptr<ProofSource::Details> proof_source_details, QuicTag key_exchange_type, std::unique_ptr<CryptoHandshakeMessage> out, - quiche::QuicheStringPiece public_value, + absl::string_view public_value, std::unique_ptr<ProcessClientHelloContext> context, const Configs& configs) const; @@ -761,7 +761,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // failure. HandshakeFailureReason ParseSourceAddressToken( const Config& config, - quiche::QuicheStringPiece token, + absl::string_view token, SourceAddressTokens* tokens) const; // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc index 6f0c047b95b..e612a33b6d5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc @@ -9,6 +9,8 @@ #include <memory> #include <string> +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/cert_compressor.h" #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" @@ -23,7 +25,6 @@ #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -142,7 +143,7 @@ TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) { static const uint64_t set_hash = 42; std::unique_ptr<CommonCertSets> common_sets( crypto_test_utils::MockCommonCertSets(certs[0], set_hash, 1)); - quiche::QuicheStringPiece different_common_certs( + absl::string_view different_common_certs( reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)); std::string compressed3 = QuicCryptoServerConfigPeer::CompressChain( &compressed_certs_cache, chain, std::string(different_common_certs), @@ -193,16 +194,15 @@ class SourceAddressTokenTest : public QuicTest { clock_.WallNow(), cached_network_params); } - HandshakeFailureReason ValidateSourceAddressTokens( - std::string config_id, - quiche::QuicheStringPiece srct, - const QuicIpAddress& ip) { + HandshakeFailureReason ValidateSourceAddressTokens(std::string config_id, + absl::string_view srct, + const QuicIpAddress& ip) { return ValidateSourceAddressTokens(config_id, srct, ip, nullptr); } HandshakeFailureReason ValidateSourceAddressTokens( std::string config_id, - quiche::QuicheStringPiece srct, + absl::string_view srct, const QuicIpAddress& ip, CachedNetworkParameters* cached_network_params) { return peer_.ValidateSourceAddressTokens( @@ -356,8 +356,7 @@ class CryptoServerConfigsTest : public QuicTest { QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options); protobuf.set_primary_time(primary_time); protobuf.set_priority(priority); - if (quiche::QuicheTextUtils::StartsWith(std::string(server_config_id), - "INVALID")) { + if (absl::StartsWith(std::string(server_config_id), "INVALID")) { protobuf.clear_key(); has_invalid = true; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc index c4249017cae..29e1e18c967 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.cc @@ -7,6 +7,7 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/tls1.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter.h" @@ -18,7 +19,6 @@ #include "net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -62,16 +62,15 @@ std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite( } // static -void QuicDecrypter::DiversifyPreliminaryKey( - quiche::QuicheStringPiece preliminary_key, - quiche::QuicheStringPiece nonce_prefix, - const DiversificationNonce& nonce, - size_t key_size, - size_t nonce_prefix_size, - std::string* out_key, - std::string* out_nonce_prefix) { +void QuicDecrypter::DiversifyPreliminaryKey(absl::string_view preliminary_key, + absl::string_view nonce_prefix, + const DiversificationNonce& nonce, + size_t key_size, + size_t nonce_prefix_size, + std::string* out_key, + std::string* out_nonce_prefix) { QuicHKDF hkdf((std::string(preliminary_key)) + (std::string(nonce_prefix)), - quiche::QuicheStringPiece(nonce.data(), nonce.size()), + absl::string_view(nonce.data(), nonce.size()), "QUIC key diversification", 0, key_size, 0, nonce_prefix_size, 0); *out_key = std::string(hkdf.server_write_key()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h index 7f4d93d323a..4a6cc59d0ab 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h @@ -10,11 +10,11 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypter.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -38,7 +38,7 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter { // // If this function is called, neither |SetKey| nor |SetNoncePrefix| may be // called. - virtual bool SetPreliminaryKey(quiche::QuicheStringPiece key) = 0; + virtual bool SetPreliminaryKey(absl::string_view key) = 0; // SetDiversificationNonce uses |nonce| to derive final keys based on the // input keying material given by calling |SetPreliminaryKey|. @@ -56,8 +56,8 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter { // TODO(wtc): add a way for DecryptPacket to report decryption failure due // to non-authentic inputs, as opposed to other reasons for failure. virtual bool DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) = 0; @@ -73,12 +73,16 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter { // selector'. virtual uint32_t cipher_id() const = 0; + // Returns the maximum number of packets that can safely fail decryption with + // this decrypter. + virtual QuicPacketCount GetIntegrityLimit() const = 0; + // For use by unit tests only. - virtual quiche::QuicheStringPiece GetKey() const = 0; - virtual quiche::QuicheStringPiece GetNoncePrefix() const = 0; + virtual absl::string_view GetKey() const = 0; + virtual absl::string_view GetNoncePrefix() const = 0; - static void DiversifyPreliminaryKey(quiche::QuicheStringPiece preliminary_key, - quiche::QuicheStringPiece nonce_prefix, + static void DiversifyPreliminaryKey(absl::string_view preliminary_key, + absl::string_view nonce_prefix, const DiversificationNonce& nonce, size_t key_size, size_t nonce_prefix_size, diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h index 6fe552d1778..b454997f397 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h @@ -8,10 +8,10 @@ #include <cstddef> #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypter.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,8 +36,8 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter { // |associated_data|. If |output| overlaps with |plaintext| then // |plaintext| must be <= |output|. virtual bool EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) = 0; @@ -47,7 +47,7 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter { // success, the mask will be at least 5 bytes long; on failure the string will // be empty. virtual std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece sample) = 0; + absl::string_view sample) = 0; // Returns the maximum length of plaintext that can be encrypted // to ciphertext no larger than |ciphertext_size|. @@ -57,9 +57,13 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter { // to plaintext of size |plaintext_size|. virtual size_t GetCiphertextSize(size_t plaintext_size) const = 0; + // Returns the maximum number of packets that can be safely encrypted with + // this encrypter. + virtual QuicPacketCount GetConfidentialityLimit() const = 0; + // For use by unit tests only. - virtual quiche::QuicheStringPiece GetKey() const = 0; - virtual quiche::QuicheStringPiece GetNoncePrefix() const = 0; + virtual absl::string_view GetKey() const = 0; + virtual absl::string_view GetNoncePrefix() const = 0; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc index 28cf4a93a18..59c3eb0fb9d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.cc @@ -6,19 +6,19 @@ #include <memory> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/digest.h" #include "third_party/boringssl/src/include/openssl/hkdf.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { const size_t kSHA256HashLength = 32; const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256; -QuicHKDF::QuicHKDF(quiche::QuicheStringPiece secret, - quiche::QuicheStringPiece salt, - quiche::QuicheStringPiece info, +QuicHKDF::QuicHKDF(absl::string_view secret, + absl::string_view salt, + absl::string_view info, size_t key_bytes_to_generate, size_t iv_bytes_to_generate, size_t subkey_secret_bytes_to_generate) @@ -31,9 +31,9 @@ QuicHKDF::QuicHKDF(quiche::QuicheStringPiece secret, iv_bytes_to_generate, subkey_secret_bytes_to_generate) {} -QuicHKDF::QuicHKDF(quiche::QuicheStringPiece secret, - quiche::QuicheStringPiece salt, - quiche::QuicheStringPiece info, +QuicHKDF::QuicHKDF(absl::string_view secret, + absl::string_view salt, + absl::string_view info, size_t client_key_bytes_to_generate, size_t server_key_bytes_to_generate, size_t client_iv_bytes_to_generate, @@ -60,44 +60,44 @@ QuicHKDF::QuicHKDF(quiche::QuicheStringPiece secret, size_t j = 0; if (client_key_bytes_to_generate) { - client_write_key_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), client_key_bytes_to_generate); + client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + client_key_bytes_to_generate); j += client_key_bytes_to_generate; } if (server_key_bytes_to_generate) { - server_write_key_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), server_key_bytes_to_generate); + server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + server_key_bytes_to_generate); j += server_key_bytes_to_generate; } if (client_iv_bytes_to_generate) { - client_write_iv_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), client_iv_bytes_to_generate); + client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + client_iv_bytes_to_generate); j += client_iv_bytes_to_generate; } if (server_iv_bytes_to_generate) { - server_write_iv_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), server_iv_bytes_to_generate); + server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + server_iv_bytes_to_generate); j += server_iv_bytes_to_generate; } if (subkey_secret_bytes_to_generate) { - subkey_secret_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), subkey_secret_bytes_to_generate); + subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + subkey_secret_bytes_to_generate); j += subkey_secret_bytes_to_generate; } // Repeat client and server key bytes for header protection keys. if (client_key_bytes_to_generate) { - client_hp_key_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), client_key_bytes_to_generate); + client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + client_key_bytes_to_generate); j += client_key_bytes_to_generate; } if (server_key_bytes_to_generate) { - server_hp_key_ = quiche::QuicheStringPiece( - reinterpret_cast<char*>(&output_[j]), server_key_bytes_to_generate); + server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]), + server_key_bytes_to_generate); j += server_key_bytes_to_generate; } } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h index 2945173f421..63018b4443a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h @@ -7,8 +7,8 @@ #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -31,18 +31,18 @@ class QUIC_EXPORT_PRIVATE QuicHKDF { // client and server. // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to // generate, shared between client and server. - QuicHKDF(quiche::QuicheStringPiece secret, - quiche::QuicheStringPiece salt, - quiche::QuicheStringPiece info, + QuicHKDF(absl::string_view secret, + absl::string_view salt, + absl::string_view info, size_t key_bytes_to_generate, size_t iv_bytes_to_generate, size_t subkey_secret_bytes_to_generate); // An alternative constructor that allows the client and server key/IV // lengths to be different. - QuicHKDF(quiche::QuicheStringPiece secret, - quiche::QuicheStringPiece salt, - quiche::QuicheStringPiece info, + QuicHKDF(absl::string_view secret, + absl::string_view salt, + absl::string_view info, size_t client_key_bytes_to_generate, size_t server_key_bytes_to_generate, size_t client_iv_bytes_to_generate, @@ -51,28 +51,24 @@ class QUIC_EXPORT_PRIVATE QuicHKDF { ~QuicHKDF(); - quiche::QuicheStringPiece client_write_key() const { - return client_write_key_; - } - quiche::QuicheStringPiece client_write_iv() const { return client_write_iv_; } - quiche::QuicheStringPiece server_write_key() const { - return server_write_key_; - } - quiche::QuicheStringPiece server_write_iv() const { return server_write_iv_; } - quiche::QuicheStringPiece subkey_secret() const { return subkey_secret_; } - quiche::QuicheStringPiece client_hp_key() const { return client_hp_key_; } - quiche::QuicheStringPiece server_hp_key() const { return server_hp_key_; } + absl::string_view client_write_key() const { return client_write_key_; } + absl::string_view client_write_iv() const { return client_write_iv_; } + absl::string_view server_write_key() const { return server_write_key_; } + absl::string_view server_write_iv() const { return server_write_iv_; } + absl::string_view subkey_secret() const { return subkey_secret_; } + absl::string_view client_hp_key() const { return client_hp_key_; } + absl::string_view server_hp_key() const { return server_hp_key_; } private: std::vector<uint8_t> output_; - quiche::QuicheStringPiece client_write_key_; - quiche::QuicheStringPiece server_write_key_; - quiche::QuicheStringPiece client_write_iv_; - quiche::QuicheStringPiece server_write_iv_; - quiche::QuicheStringPiece subkey_secret_; - quiche::QuicheStringPiece client_hp_key_; - quiche::QuicheStringPiece server_hp_key_; + absl::string_view client_write_key_; + absl::string_view server_write_key_; + absl::string_view client_write_iv_; + absl::string_view server_write_iv_; + absl::string_view subkey_secret_; + absl::string_view client_hp_key_; + absl::string_view server_hp_key_; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc index 8b74f633d02..48e089f7bc4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf_test.cc @@ -6,8 +6,9 @@ #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -67,15 +68,14 @@ static const HKDFInput kHKDFInputs[] = { class QuicHKDFTest : public QuicTest {}; TEST_F(QuicHKDFTest, HKDF) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kHKDFInputs); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kHKDFInputs); i++) { const HKDFInput& test(kHKDFInputs[i]); SCOPED_TRACE(i); - const std::string key = quiche::QuicheTextUtils::HexDecode(test.key_hex); - const std::string salt = quiche::QuicheTextUtils::HexDecode(test.salt_hex); - const std::string info = quiche::QuicheTextUtils::HexDecode(test.info_hex); - const std::string expected = - quiche::QuicheTextUtils::HexDecode(test.output_hex); + const std::string key = absl::HexStringToBytes(test.key_hex); + const std::string salt = absl::HexStringToBytes(test.salt_hex); + const std::string info = absl::HexStringToBytes(test.info_hex); + const std::string expected = absl::HexStringToBytes(test.output_hex); // We set the key_length to the length of the expected output and then take // the result from the first key, which is the client write key. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc index 79088473bbc..0591571ae39 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc @@ -13,9 +13,9 @@ TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx, Delegate* delegate) // static bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx( bool enable_early_data) { - bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx(); + bssl::UniquePtr<SSL_CTX> ssl_ctx = + TlsConnection::CreateSslCtx(SSL_VERIFY_PEER); // Configure certificate verification. - SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback); int reverify_on_resume_enabled = 1; SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled); @@ -29,14 +29,6 @@ bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx( } // static -enum ssl_verify_result_t TlsClientConnection::VerifyCallback( - SSL* ssl, - uint8_t* out_alert) { - return static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) - ->delegate_->VerifyCert(out_alert); -} - -// static int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) { static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session)); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h index a7ef209792f..6bea641be84 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h @@ -20,12 +20,6 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection { virtual ~Delegate() {} protected: - // Verifies the peer's certificate chain. It may use - // SSL_get0_peer_certificates to get the cert chain. This method returns - // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid, - // or ssl_verify_retry if verification is happening asynchronously. - virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; - // Called when a NewSessionTicket is received from the server. virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0; @@ -42,10 +36,6 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection { static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data); private: - // Registered as the callback for SSL_CTX_set_custom_verify. The - // implementation is delegated to Delegate::VerifyCert. - static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); - // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls // Delegate::InsertSession. static int NewSessionCallback(SSL* ssl, SSL_SESSION* session); 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 8e4d391db4b..be274e2cb2a 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 @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/crypto/tls_connection.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -93,12 +93,15 @@ TlsConnection::TlsConnection(SSL_CTX* ssl_ctx, this); } // static -bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() { +bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx(int cert_verify_mode) { CRYPTO_library_init(); bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method())); SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION); SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION); SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod); + if (cert_verify_mode != SSL_VERIFY_NONE) { + SSL_CTX_set_custom_verify(ssl_ctx.get(), cert_verify_mode, &VerifyCallback); + } return ssl_ctx; } @@ -108,6 +111,12 @@ TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) { ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection())); } +// static +enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl, + uint8_t* out_alert) { + return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert); +} + const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{ TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback, TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback, @@ -151,7 +160,7 @@ int TlsConnection::WriteMessageCallback(SSL* ssl, size_t len) { ConnectionFromSsl(ssl)->delegate_->WriteMessage( QuicEncryptionLevel(level), - quiche::QuicheStringPiece(reinterpret_cast<const char*>(data), len)); + absl::string_view(reinterpret_cast<const char*>(data), len)); return 1; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h index 15a4f4f9a3a..037e4b03f1e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h @@ -7,9 +7,9 @@ #include <vector> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -31,6 +31,16 @@ class QUIC_EXPORT_PRIVATE TlsConnection { virtual ~Delegate() {} protected: + // Certificate management functions: + + // Verifies the peer's certificate chain. It may use + // SSL_get0_peer_certificates to get the cert chain. This method returns + // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid, + // or ssl_verify_retry if verification is happening asynchronously. + virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; + + // QUIC-TLS interface functions: + // SetWriteSecret provides the encryption secret used to encrypt messages at // encryption level |level|. The secret provided here is the one from the // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake @@ -53,7 +63,7 @@ class QUIC_EXPORT_PRIVATE TlsConnection { // the QUIC stack to write in a crypto frame. The data must be transmitted // at encryption level |level|. virtual void WriteMessage(EncryptionLevel level, - quiche::QuicheStringPiece data) = 0; + absl::string_view data) = 0; // FlushFlight is called to signal that the current flight of messages have // all been written (via calls to WriteMessage) and can be flushed to the @@ -87,7 +97,12 @@ class QUIC_EXPORT_PRIVATE TlsConnection { // Creates an SSL_CTX and configures it with the options that are appropriate // for both client and server. The caller is responsible for ownership of the // newly created struct. - static bssl::UniquePtr<SSL_CTX> CreateSslCtx(); + // + // The provided |cert_verify_mode| is passed in as the |mode| argument for + // |SSL_CTX_set_verify|. See + // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_VERIFY_NONE + // for a description of possible values. + static bssl::UniquePtr<SSL_CTX> CreateSslCtx(int cert_verify_mode); // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it // belongs to. This helper method allows the callbacks set in BoringSSL to be @@ -96,6 +111,10 @@ class QUIC_EXPORT_PRIVATE TlsConnection { static TlsConnection* ConnectionFromSsl(const SSL* ssl); private: + // Registered as the callback for SSL_CTX_set_custom_verify. The + // implementation is delegated to Delegate::VerifyCert. + static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); + // TlsConnection implements SSL_QUIC_METHOD, which provides the interface // between BoringSSL's TLS stack and a QUIC implementation. static const SSL_QUIC_METHOD kSslQuicMethod; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc index c821a388748..f47e5ad7258 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,20 +18,27 @@ TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate) // static bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx( ProofSource* proof_source) { - bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx(); + bssl::UniquePtr<SSL_CTX> ssl_ctx = + TlsConnection::CreateSslCtx(SSL_VERIFY_NONE); SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), &SelectCertificateCallback); SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr); // We don't actually need the TicketCrypter here, but we need to know // whether it's set. if (proof_source->GetTicketCrypter()) { + QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 1, 3); SSL_CTX_set_ticket_aead_method(ssl_ctx.get(), &TlsServerConnection::kSessionTicketMethod); - if (GetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2)) { - SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1); - } - } else { + } else if (!GetQuicRestartFlag(quic_session_tickets_always_enabled)) { + QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 2, 3); SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_TICKET); + } else { + QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 3, 3); + } + if (GetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2) && + (proof_source->GetTicketCrypter() || + GetQuicRestartFlag(quic_session_tickets_always_enabled))) { + SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1); } return ssl_ctx; } @@ -82,7 +89,7 @@ ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl, size_t in_len) { return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign( out, out_len, max_out, sig_alg, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(in), in_len)); + absl::string_view(reinterpret_cast<const char*>(in), in_len)); } // static @@ -116,7 +123,7 @@ int TlsServerConnection::SessionTicketSeal(SSL* ssl, size_t in_len) { return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal( out, out_len, max_out_len, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(in), in_len)); + absl::string_view(reinterpret_cast<const char*>(in), in_len)); } // static @@ -129,7 +136,7 @@ enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen( size_t in_len) { return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen( out, out_len, max_out_len, - quiche::QuicheStringPiece(reinterpret_cast<const char*>(in), in_len)); + absl::string_view(reinterpret_cast<const char*>(in), in_len)); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h index 6da81141335..954f8303163 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h @@ -5,9 +5,9 @@ #ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_ #define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" #include "net/third_party/quiche/src/quic/core/crypto/tls_connection.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -43,12 +43,11 @@ class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection { // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success // is returned with the signature put in |*out| and the length in // |*out_len|. - virtual ssl_private_key_result_t PrivateKeySign( - uint8_t* out, - size_t* out_len, - size_t max_out, - uint16_t sig_alg, - quiche::QuicheStringPiece in) = 0; + virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out, + size_t* out_len, + size_t max_out, + uint16_t sig_alg, + absl::string_view in) = 0; // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete // will be called after the async sign operation has completed. @@ -76,7 +75,7 @@ class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection { virtual int SessionTicketSeal(uint8_t* out, size_t* out_len, size_t max_out_len, - quiche::QuicheStringPiece in) = 0; + absl::string_view in) = 0; // SessionTicketOpen is called when BoringSSL has an encrypted session // ticket |in| and wants the ticket decrypted. This decryption operation can @@ -102,7 +101,7 @@ class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection { uint8_t* out, size_t* out_len, size_t max_out_len, - quiche::QuicheStringPiece in) = 0; + absl::string_view in) = 0; // Provides the delegate for callbacks that are shared between client and // server. 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 71a9dfb8bad..c047e0ff143 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 @@ -10,6 +10,8 @@ #include <memory> #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/digest.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" @@ -20,7 +22,6 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -210,7 +211,7 @@ bool WriteTransportParameterLength(QuicDataWriter* writer, } bool WriteTransportParameterStringPiece(QuicDataWriter* writer, - quiche::QuicheStringPiece value, + absl::string_view value, ParsedQuicVersion version) { if (version.HasVarIntTransportParams()) { return writer->WriteStringPieceVarInt62(value); @@ -240,10 +241,9 @@ bool ReadTransportParameterId( return true; } -bool ReadTransportParameterLengthAndValue( - QuicDataReader* reader, - ParsedQuicVersion version, - quiche::QuicheStringPiece* out_value) { +bool ReadTransportParameterLengthAndValue(QuicDataReader* reader, + ParsedQuicVersion version, + absl::string_view* out_value) { if (version.HasVarIntTransportParams()) { return reader->ReadStringPieceVarInt62(out_value); } @@ -395,9 +395,9 @@ std::string TransportParameters::PreferredAddress::ToString() const { return "[" + ipv4_socket_address.ToString() + " " + ipv6_socket_address.ToString() + " connection_id " + connection_id.ToString() + " stateless_reset_token " + - quiche::QuicheTextUtils::HexEncode( + absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(stateless_reset_token.data()), - stateless_reset_token.size()) + + stateless_reset_token.size())) + "]"; } @@ -427,9 +427,9 @@ std::string TransportParameters::ToString() const { rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true); if (!stateless_reset_token.empty()) { rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " + - quiche::QuicheTextUtils::HexEncode( + absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(stateless_reset_token.data()), - stateless_reset_token.size()); + stateless_reset_token.size())); } rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true); rv += initial_max_data.ToString(/*for_use_in_list=*/true); @@ -486,11 +486,10 @@ std::string TransportParameters::ToString() const { rv += "="; static constexpr size_t kMaxPrintableLength = 32; if (kv.second.length() <= kMaxPrintableLength) { - rv += quiche::QuicheTextUtils::HexEncode(kv.second); + rv += absl::BytesToHexString(kv.second); } else { - quiche::QuicheStringPiece truncated(kv.second.data(), - kMaxPrintableLength); - rv += quiche::QuicheStrCat(quiche::QuicheTextUtils::HexEncode(truncated), + absl::string_view truncated(kv.second.data(), kMaxPrintableLength); + rv += quiche::QuicheStrCat(absl::BytesToHexString(truncated), "...(length ", kv.second.length(), ")"); } } @@ -813,9 +812,8 @@ bool SerializeTransportParameters(ParsedQuicVersion version, version) || !WriteTransportParameterStringPiece( &writer, - quiche::QuicheStringPiece( - original_destination_connection_id.data(), - original_destination_connection_id.length()), + absl::string_view(original_destination_connection_id.data(), + original_destination_connection_id.length()), version)) { QUIC_BUG << "Failed to write original_destination_connection_id " << original_destination_connection_id << " for " << in; @@ -836,7 +834,7 @@ bool SerializeTransportParameters(ParsedQuicVersion version, &writer, TransportParameters::kStatelessResetToken, version) || !WriteTransportParameterStringPiece( &writer, - quiche::QuicheStringPiece( + absl::string_view( reinterpret_cast<const char*>(in.stateless_reset_token.data()), in.stateless_reset_token.size()), version)) { @@ -919,8 +917,8 @@ bool SerializeTransportParameters(ParsedQuicVersion version, version) || !WriteTransportParameterStringPiece( &writer, - quiche::QuicheStringPiece(initial_source_connection_id.data(), - initial_source_connection_id.length()), + absl::string_view(initial_source_connection_id.data(), + initial_source_connection_id.length()), version)) { QUIC_BUG << "Failed to write initial_source_connection_id " << initial_source_connection_id << " for " << in; @@ -937,8 +935,8 @@ bool SerializeTransportParameters(ParsedQuicVersion version, &writer, TransportParameters::kRetrySourceConnectionId, version) || !WriteTransportParameterStringPiece( &writer, - quiche::QuicheStringPiece(retry_source_connection_id.data(), - retry_source_connection_id.length()), + absl::string_view(retry_source_connection_id.data(), + retry_source_connection_id.length()), version)) { QUIC_BUG << "Failed to write retry_source_connection_id " << retry_source_connection_id << " for " << in; @@ -1079,7 +1077,7 @@ bool SerializeTransportParameters(ParsedQuicVersion version, random->RandBytes(grease_contents, grease_length); if (!WriteTransportParameterId(&writer, grease_id, version) || !WriteTransportParameterStringPiece( - &writer, quiche::QuicheStringPiece(grease_contents, grease_length), + &writer, absl::string_view(grease_contents, grease_length), version)) { QUIC_BUG << "Failed to write GREASE parameter " << TransportParameterIdToString(grease_id); @@ -1141,7 +1139,7 @@ bool ParseTransportParameters(ParsedQuicVersion version, *error_details = "Failed to parse transport parameter ID"; return false; } - quiche::QuicheStringPiece value; + absl::string_view value; if (!ReadTransportParameterLengthAndValue(&reader, version, &value)) { *error_details = "Failed to read length and value of transport parameter " + @@ -1183,7 +1181,7 @@ bool ParseTransportParameters(ParsedQuicVersion version, *error_details = "Received a second stateless_reset_token"; return false; } - quiche::QuicheStringPiece stateless_reset_token = + absl::string_view stateless_reset_token = value_reader.ReadRemainingPayload(); if (stateless_reset_token.length() != kStatelessResetTokenLength) { *error_details = quiche::QuicheStrCat( 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 bf8c6076b81..8c7970c29d5 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 @@ -8,6 +8,8 @@ #include <memory> #include <vector> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" @@ -16,8 +18,6 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -133,7 +133,7 @@ struct QUIC_EXPORT_PRIVATE TransportParameters { // The value of the Destination Connection ID field from the first // Initial packet sent by the client. - quiche::QuicheOptional<QuicConnectionId> original_destination_connection_id; + absl::optional<QuicConnectionId> original_destination_connection_id; // Maximum idle timeout expressed in milliseconds. IntegerParameter max_idle_timeout_ms; @@ -187,11 +187,11 @@ struct QUIC_EXPORT_PRIVATE TransportParameters { // The value that the endpoint included in the Source Connection ID field of // the first Initial packet it sent. - quiche::QuicheOptional<QuicConnectionId> initial_source_connection_id; + absl::optional<QuicConnectionId> initial_source_connection_id; // The value that the server included in the Source Connection ID field of a // Retry packet it sent. - quiche::QuicheOptional<QuicConnectionId> retry_source_connection_id; + absl::optional<QuicConnectionId> retry_source_connection_id; // Indicates support for the DATAGRAM frame and the maximum frame size that // the sender accepts. See draft-ietf-quic-datagram. @@ -202,10 +202,10 @@ struct QUIC_EXPORT_PRIVATE TransportParameters { IntegerParameter initial_round_trip_time_us; // Google-specific connection options. - quiche::QuicheOptional<QuicTagVector> google_connection_options; + absl::optional<QuicTagVector> google_connection_options; // Google-specific user agent identifier. - quiche::QuicheOptional<std::string> user_agent_id; + absl::optional<std::string> user_agent_id; // Google-specific handshake done support. This is only used for T050. bool support_handshake_done; 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 0578e290de1..ab8360eabca 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 @@ -7,6 +7,8 @@ #include <cstring> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_tag.h" @@ -16,8 +18,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -202,7 +202,7 @@ TEST_P(TransportParametersTest, Comparator) { // Test comparison on connection IDs. orig_params.initial_source_connection_id = CreateFakeInitialSourceConnectionId(); - new_params.initial_source_connection_id = QUICHE_NULLOPT; + new_params.initial_source_connection_id = absl::nullopt; EXPECT_NE(orig_params, new_params); EXPECT_FALSE(orig_params == new_params); EXPECT_TRUE(orig_params != new_params); @@ -627,10 +627,10 @@ TEST_P(TransportParametersTest, ParseClientParams) { // clang-format on const uint8_t* client_params = reinterpret_cast<const uint8_t*>(kClientParams); - size_t client_params_length = QUICHE_ARRAYSIZE(kClientParams); + size_t client_params_length = ABSL_ARRAYSIZE(kClientParams); if (!version_.HasVarIntTransportParams()) { client_params = reinterpret_cast<const uint8_t*>(kClientParamsOld); - client_params_length = QUICHE_ARRAYSIZE(kClientParamsOld); + client_params_length = ABSL_ARRAYSIZE(kClientParamsOld); } TransportParameters new_params; std::string error_details; @@ -724,11 +724,11 @@ TEST_P(TransportParametersTest, // clang-format on const uint8_t* client_params = reinterpret_cast<const uint8_t*>(kClientParamsWithFullToken); - size_t client_params_length = QUICHE_ARRAYSIZE(kClientParamsWithFullToken); + size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullToken); if (!version_.HasVarIntTransportParams()) { client_params = reinterpret_cast<const uint8_t*>(kClientParamsWithFullTokenOld); - client_params_length = QUICHE_ARRAYSIZE(kClientParamsWithFullTokenOld); + client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullTokenOld); } TransportParameters out_params; std::string error_details; @@ -779,11 +779,11 @@ TEST_P(TransportParametersTest, // clang-format on const uint8_t* client_params = reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyToken); - size_t client_params_length = QUICHE_ARRAYSIZE(kClientParamsWithEmptyToken); + size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyToken); if (!version_.HasVarIntTransportParams()) { client_params = reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyTokenOld); - client_params_length = QUICHE_ARRAYSIZE(kClientParamsWithEmptyTokenOld); + client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyTokenOld); } TransportParameters out_params; std::string error_details; @@ -828,10 +828,10 @@ TEST_P(TransportParametersTest, ParseClientParametersRepeated) { // clang-format on const uint8_t* client_params = reinterpret_cast<const uint8_t*>(kClientParamsRepeated); - size_t client_params_length = QUICHE_ARRAYSIZE(kClientParamsRepeated); + size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeated); if (!version_.HasVarIntTransportParams()) { client_params = reinterpret_cast<const uint8_t*>(kClientParamsRepeatedOld); - client_params_length = QUICHE_ARRAYSIZE(kClientParamsRepeatedOld); + client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeatedOld); } TransportParameters out_params; std::string error_details; @@ -1049,10 +1049,10 @@ TEST_P(TransportParametersTest, ParseServerParams) { // clang-format on const uint8_t* server_params = reinterpret_cast<const uint8_t*>(kServerParams); - size_t server_params_length = QUICHE_ARRAYSIZE(kServerParams); + size_t server_params_length = ABSL_ARRAYSIZE(kServerParams); if (!version_.HasVarIntTransportParams()) { server_params = reinterpret_cast<const uint8_t*>(kServerParamsOld); - server_params_length = QUICHE_ARRAYSIZE(kServerParamsOld); + server_params_length = ABSL_ARRAYSIZE(kServerParamsOld); } TransportParameters new_params; std::string error_details; @@ -1158,10 +1158,10 @@ TEST_P(TransportParametersTest, ParseServerParametersRepeated) { // clang-format on const uint8_t* server_params = reinterpret_cast<const uint8_t*>(kServerParamsRepeated); - size_t server_params_length = QUICHE_ARRAYSIZE(kServerParamsRepeated); + size_t server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeated); if (!version_.HasVarIntTransportParams()) { server_params = reinterpret_cast<const uint8_t*>(kServerParamsRepeatedOld); - server_params_length = QUICHE_ARRAYSIZE(kServerParamsRepeatedOld); + server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeatedOld); } TransportParameters out_params; std::string error_details; @@ -1207,12 +1207,12 @@ TEST_P(TransportParametersTest, const uint8_t* server_params = reinterpret_cast<const uint8_t*>(kServerParamsEmptyOriginalConnectionId); size_t server_params_length = - QUICHE_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId); + ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId); if (!version_.HasVarIntTransportParams()) { server_params = reinterpret_cast<const uint8_t*>( kServerParamsEmptyOriginalConnectionIdOld); server_params_length = - QUICHE_ARRAYSIZE(kServerParamsEmptyOriginalConnectionIdOld); + ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionIdOld); } TransportParameters out_params; std::string error_details; 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 69023404db3..e69cbbed9a0 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 @@ -29,9 +29,9 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue { PacketNumberQueue& operator=(const PacketNumberQueue& other); PacketNumberQueue& operator=(PacketNumberQueue&& other); - typedef QuicIntervalSet<QuicPacketNumber>::const_iterator const_iterator; - typedef QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator - const_reverse_iterator; + using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator; + using const_reverse_iterator = + QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator; // Adds |packet_number| to the set of packets in the queue. void Add(QuicPacketNumber packet_number); diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc index bef5f286d23..e804f273521 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -16,7 +16,7 @@ QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level, QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level, QuicStreamOffset offset, - quiche::QuicheStringPiece data) + absl::string_view data) : QuicCryptoFrame(level, offset, data.data(), data.length()) {} QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level, diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h index 2bb7a08d68a..a8f0fe3733f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h @@ -8,10 +8,10 @@ #include <memory> #include <ostream> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -22,7 +22,7 @@ struct QUIC_EXPORT_PRIVATE QuicCryptoFrame { QuicPacketLength data_length); QuicCryptoFrame(EncryptionLevel level, QuicStreamOffset offset, - quiche::QuicheStringPiece data); + absl::string_view data); ~QuicCryptoFrame(); friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h index 6e096e3d91c..505f562b7c8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h @@ -133,7 +133,7 @@ static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type), // A inline size of 1 is chosen to optimize the typical use case of // 1-stream-frame in QuicTransmissionInfo.retransmittable_frames. -typedef QuicInlinedVector<QuicFrame, 1> QuicFrames; +using QuicFrames = QuicInlinedVector<QuicFrame, 1>; // Deletes all the sub-frames contained in |frames|. QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames); diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h index 7f0179c95a9..68fbf2201ad 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_message_frame.h @@ -13,7 +13,7 @@ namespace quic { -typedef QuicInlinedVector<QuicMemSlice, 1> QuicMessageData; +using QuicMessageData = QuicInlinedVector<QuicMemSlice, 1>; struct QUIC_EXPORT_PRIVATE QuicMessageFrame { QuicMessageFrame() = default; diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc index 0178422526c..6806cda221f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -15,7 +16,7 @@ QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id, std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) { os << "{ control_frame_id: " << s.control_frame_id - << ", token: " << quiche::QuicheTextUtils::HexEncode(s.token) << " }\n"; + << ", token: " << absl::BytesToHexString(s.token) << " }\n"; return os; } diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc index 4a8d1207b73..eb841b26ddc 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -21,9 +22,9 @@ QuicPathChallengeFrame::~QuicPathChallengeFrame() {} std::ostream& operator<<(std::ostream& os, const QuicPathChallengeFrame& frame) { os << "{ control_frame_id: " << frame.control_frame_id << ", data: " - << quiche::QuicheTextUtils::HexEncode( + << absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(frame.data_buffer.data()), - frame.data_buffer.size()) + frame.data_buffer.size())) << " }\n"; return os; } diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc index 4779c6ad25f..1623777b0e6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -20,9 +21,9 @@ QuicPathResponseFrame::~QuicPathResponseFrame() {} std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) { os << "{ control_frame_id: " << frame.control_frame_id << ", data: " - << quiche::QuicheTextUtils::HexEncode( + << absl::BytesToHexString(absl::string_view( reinterpret_cast<const char*>(frame.data_buffer.data()), - frame.data_buffer.size()) + frame.data_buffer.size())) << " }\n"; return os; } diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc index db199998860..728d320e3ac 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -14,7 +14,7 @@ QuicStreamFrame::QuicStreamFrame() : QuicInlinedFrame(STREAM_FRAME) {} QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id, bool fin, QuicStreamOffset offset, - quiche::QuicheStringPiece data) + absl::string_view data) : QuicStreamFrame(stream_id, fin, offset, data.data(), data.length()) {} QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id, diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h index 10ad7db1025..32b2c7404bf 100644 --- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h +++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h @@ -8,11 +8,11 @@ #include <memory> #include <ostream> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/frames/quic_inlined_frame.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -22,7 +22,7 @@ struct QUIC_EXPORT_PRIVATE QuicStreamFrame QuicStreamFrame(QuicStreamId stream_id, bool fin, QuicStreamOffset offset, - quiche::QuicheStringPiece data); + absl::string_view data); QuicStreamFrame(QuicStreamId stream_id, bool fin, QuicStreamOffset offset, 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 5103509d06e..a8e5e968ab3 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 @@ -71,6 +71,9 @@ class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface { const TransportParameters& params, bool is_resumption, std::string* error_details) = 0; + + // Called at the end of an handshake operation callback. + virtual void OnHandshakeCallbackDone() = 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 7a0bd9a7823..6b188fcf38d 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 @@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h" @@ -65,7 +66,6 @@ #include "net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using spdy::kV3LowestPriority; @@ -465,9 +465,9 @@ class EndToEndTest : public QuicTestWithParam<TestParams> { } } - void AddToCache(quiche::QuicheStringPiece path, + void AddToCache(absl::string_view path, int response_code, - quiche::QuicheStringPiece body) { + absl::string_view body) { memory_cache_backend_.AddSimpleResponse(server_hostname_, path, response_code, body); } @@ -1498,6 +1498,48 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) { VerifyCleanConnection(false); } +// Regression test for b/168020146. +// TODO(renjietang): Reenable this test in Chrome once the BoringSSL fix is +// rolled in. +TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleZeroRtt)) { + ASSERT_TRUE(Initialize()); + + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + QuicSpdyClientSession* client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + EXPECT_FALSE(client_session->ReceivedInchoateReject()); + EXPECT_FALSE(client_->client()->EarlyDataAccepted()); + EXPECT_FALSE(client_->client()->ReceivedInchoateReject()); + + client_->Disconnect(); + + // The 0-RTT handshake should succeed. + client_->Connect(); + EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable()); + ASSERT_TRUE(client_->client()->connected()); + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_TRUE(client_session->EarlyDataAccepted()); + EXPECT_TRUE(client_->client()->EarlyDataAccepted()); + + client_->Disconnect(); + + client_->Connect(); + EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable()); + ASSERT_TRUE(client_->client()->connected()); + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_TRUE(client_session->EarlyDataAccepted()); + EXPECT_TRUE(client_->client()->EarlyDataAccepted()); + + client_->Disconnect(); +} + TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) { // Send a request and then disconnect. This prepares the client to attempt // a 0-RTT handshake for the next request. @@ -1998,13 +2040,13 @@ TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) { // count. size_t client_max_open_outgoing_bidirectional_streams = version_.HasIetfQuicFrames() - ? QuicSessionPeer::v99_streamid_manager(client_session) + ? QuicSessionPeer::ietf_streamid_manager(client_session) ->max_outgoing_bidirectional_streams() : QuicSessionPeer::GetStreamIdManager(client_session) ->max_open_outgoing_streams(); size_t client_max_open_outgoing_unidirectional_streams = version_.HasIetfQuicFrames() - ? QuicSessionPeer::v99_streamid_manager(client_session) + ? QuicSessionPeer::ietf_streamid_manager(client_session) ->max_outgoing_unidirectional_streams() - kHttp3StaticUnidirectionalStreamCount : QuicSessionPeer::GetStreamIdManager(client_session) @@ -2018,13 +2060,13 @@ TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) { if (server_session != nullptr) { size_t server_max_open_outgoing_bidirectional_streams = version_.HasIetfQuicFrames() - ? QuicSessionPeer::v99_streamid_manager(server_session) + ? QuicSessionPeer::ietf_streamid_manager(server_session) ->max_outgoing_bidirectional_streams() : QuicSessionPeer::GetStreamIdManager(server_session) ->max_open_outgoing_streams(); size_t server_max_open_outgoing_unidirectional_streams = version_.HasIetfQuicFrames() - ? QuicSessionPeer::v99_streamid_manager(server_session) + ? QuicSessionPeer::ietf_streamid_manager(server_session) ->max_outgoing_unidirectional_streams() - kHttp3StaticUnidirectionalStreamCount : QuicSessionPeer::GetStreamIdManager(server_session) @@ -2135,6 +2177,41 @@ TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) { server_thread_->Resume(); } +// Regression test for b/171378845 +TEST_P(EndToEndTest, ClientDisablesGQuicZeroRtt) { + if (version_.UsesTls()) { + // This feature is gQUIC only. + ASSERT_TRUE(Initialize()); + return; + } + QuicTagVector options; + options.push_back(kQNZ2); + client_config_.SetClientConnectionOptions(options); + + ASSERT_TRUE(Initialize()); + + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + QuicSpdyClientSession* client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + EXPECT_FALSE(client_session->ReceivedInchoateReject()); + EXPECT_FALSE(client_->client()->EarlyDataAccepted()); + EXPECT_FALSE(client_->client()->ReceivedInchoateReject()); + + client_->Disconnect(); + + // Make sure that the request succeeds but 0-RTT was not used. + client_->Connect(); + EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable()); + ASSERT_TRUE(client_->client()->connected()); + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo")); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + EXPECT_FALSE(client_->client()->EarlyDataAccepted()); +} + TEST_P(EndToEndTest, MaxInitialRTT) { // Client tries to suggest twice the server's max initial rtt and the server // uses the max. @@ -2160,17 +2237,10 @@ TEST_P(EndToEndTest, MaxInitialRTT) { client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite()); const RttStats* server_rtt_stats = server_sent_packet_manager->GetRttStats(); - if (GetQuicReloadableFlag(quic_cap_large_client_initial_rtt)) { - EXPECT_EQ(static_cast<int64_t>(1 * kNumMicrosPerSecond), - server_rtt_stats->initial_rtt().ToMicroseconds()); - EXPECT_GE(static_cast<int64_t>(1 * kNumMicrosPerSecond), - server_rtt_stats->smoothed_rtt().ToMicroseconds()); - } else { - EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), - server_rtt_stats->initial_rtt().ToMicroseconds()); - EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), - server_rtt_stats->smoothed_rtt().ToMicroseconds()); - } + EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), + server_rtt_stats->initial_rtt().ToMicroseconds()); + EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs), + server_rtt_stats->smoothed_rtt().ToMicroseconds()); } else { ADD_FAILURE() << "Missing sent packet manager"; } @@ -2311,7 +2381,19 @@ TEST_P(EndToEndTest, StreamCancelErrorTest) { // Transmit the cancel, and ensure the connection is torn down properly. SetPacketLossPercentage(0); QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0); + QuicConnection* client_connection = GetClientConnection(); + ASSERT_TRUE(client_connection); + const QuicPacketCount packets_sent_before = + client_connection->GetStats().packets_sent; session->ResetStream(stream_id, QUIC_STREAM_CANCELLED); + const QuicPacketCount packets_sent_now = + client_connection->GetStats().packets_sent; + + if (version_.UsesHttp3() && GetQuicReloadableFlag(quic_split_up_send_rst_2)) { + // Make sure 2 packets were sent, one for QPACK instructions, another for + // RESET_STREAM and STOP_SENDING. + EXPECT_EQ(packets_sent_before + 2, packets_sent_now); + } // WaitForEvents waits 50ms and returns true if there are outstanding // requests. @@ -3878,21 +3960,17 @@ TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) { EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); } +// A single large header value causes a different error than the total size of +// headers exceeding a smaller limit, tested at EndToEndTest.LargeHeaders. TEST_P(EndToEndTest, WayTooLongRequestHeaders) { ASSERT_TRUE(Initialize()); - if (version_.UsesTls() && !version_.UsesHttp3()) { - // In T050, it took relatively long time for HPACK to compress the header - // while server will detect blackhole on NST message. - // TODO(b/157248143): remove this when the HPACK compression issue is - // understood. - return; - } + SpdyHeaderBlock headers; headers[":method"] = "GET"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; headers[":authority"] = server_hostname_; - headers["key"] = std::string(64 * 1024 * 1024, 'a'); + headers["key"] = std::string(2 * 1024 * 1024, 'a'); client_->SendMessage(headers, ""); client_->WaitForResponse(); @@ -4248,7 +4326,7 @@ TEST_P(EndToEndTest, SendMessages) { ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload()); std::string message_string(kMaxOutgoingPacketSize, 'a'); - quiche::QuicheStringPiece message_buffer(message_string); + absl::string_view message_buffer(message_string); QuicRandom* random = QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator(); QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); @@ -4258,7 +4336,7 @@ TEST_P(EndToEndTest, SendMessages) { EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1), client_session->SendMessage(MakeSpan( client_connection->helper()->GetStreamSendBufferAllocator(), - quiche::QuicheStringPiece( + absl::string_view( message_buffer.data(), client_session->GetCurrentLargestMessagePayload()), &storage))); @@ -4272,8 +4350,7 @@ TEST_P(EndToEndTest, SendMessages) { 1; MessageResult result = client_session->SendMessage(MakeSpan( client_connection->helper()->GetStreamSendBufferAllocator(), - quiche::QuicheStringPiece(message_buffer.data(), message_length), - &storage)); + absl::string_view(message_buffer.data(), message_length), &storage)); if (result.status == MESSAGE_STATUS_BLOCKED) { // Connection is write blocked. break; @@ -4287,7 +4364,7 @@ TEST_P(EndToEndTest, SendMessages) { client_session ->SendMessage(MakeSpan( client_connection->helper()->GetStreamSendBufferAllocator(), - quiche::QuicheStringPiece( + absl::string_view( message_buffer.data(), client_session->GetCurrentLargestMessagePayload() + 1), &storage)) @@ -4602,7 +4679,7 @@ TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) { QuicSpdySession* client_session = GetClientSession(); ASSERT_TRUE(client_session); QuicStreamIdManager* stream_id_manager = - QuicSessionPeer::v99_bidirectional_stream_id_manager(client_session); + QuicSessionPeer::ietf_bidirectional_stream_id_manager(client_session); ASSERT_TRUE(stream_id_manager); QuicStreamCount max_number_of_streams = stream_id_manager->outgoing_max_streams(); @@ -4780,6 +4857,349 @@ TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) { 0u); } +TEST_P(EndToEndTest, KeyUpdateInitiatedByClient) { + SetQuicReloadableFlag(quic_key_update_supported, true); + + if (!version_.UsesTls()) { + // Key Update is only supported in TLS handshake. + ASSERT_TRUE(Initialize()); + return; + } + + ASSERT_TRUE(Initialize()); + + SendSynchronousFooRequestAndCheckResponse(); + QuicConnection* client_connection = GetClientConnection(); + ASSERT_TRUE(client_connection); + EXPECT_EQ(0u, client_connection->GetStats().key_update_count); + + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(2u, client_connection->GetStats().key_update_count); + + server_thread_->Pause(); + QuicConnection* server_connection = GetServerConnection(); + if (server_connection) { + QuicConnectionStats server_stats = server_connection->GetStats(); + EXPECT_EQ(2u, server_stats.key_update_count); + } else { + ADD_FAILURE() << "Missing server connection"; + } + server_thread_->Resume(); +} + +TEST_P(EndToEndTest, KeyUpdateInitiatedByServer) { + SetQuicReloadableFlag(quic_key_update_supported, true); + + if (!version_.UsesTls()) { + // Key Update is only supported in TLS handshake. + ASSERT_TRUE(Initialize()); + return; + } + + ASSERT_TRUE(Initialize()); + + SendSynchronousFooRequestAndCheckResponse(); + QuicConnection* client_connection = GetClientConnection(); + ASSERT_TRUE(client_connection); + EXPECT_EQ(0u, client_connection->GetStats().key_update_count); + + // Use WaitUntil to ensure the server had executed the key update predicate + // before sending the Foo request, otherwise the test can be flaky if it + // receives the Foo request before executing the key update. + server_thread_->WaitUntil( + [this]() { + QuicConnection* server_connection = GetServerConnection(); + if (server_connection != nullptr) { + if (!server_connection->IsKeyUpdateAllowed()) { + // Server may not have received ack from client yet for the current + // key phase, wait a bit and try again. + return false; + } + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); + } else { + ADD_FAILURE() << "Missing server connection"; + } + return true; + }, + QuicTime::Delta::FromSeconds(5)); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + server_thread_->WaitUntil( + [this]() { + QuicConnection* server_connection = GetServerConnection(); + if (server_connection != nullptr) { + if (!server_connection->IsKeyUpdateAllowed()) { + return false; + } + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); + } else { + ADD_FAILURE() << "Missing server connection"; + } + return true; + }, + QuicTime::Delta::FromSeconds(5)); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(2u, client_connection->GetStats().key_update_count); + + server_thread_->Pause(); + QuicConnection* server_connection = GetServerConnection(); + if (server_connection) { + QuicConnectionStats server_stats = server_connection->GetStats(); + EXPECT_EQ(2u, server_stats.key_update_count); + } else { + ADD_FAILURE() << "Missing server connection"; + } + server_thread_->Resume(); +} + +TEST_P(EndToEndTest, KeyUpdateInitiatedByBoth) { + SetQuicReloadableFlag(quic_key_update_supported, true); + + if (!version_.UsesTls()) { + // Key Update is only supported in TLS handshake. + ASSERT_TRUE(Initialize()); + return; + } + + ASSERT_TRUE(Initialize()); + + SendSynchronousFooRequestAndCheckResponse(); + + // Use WaitUntil to ensure the server had executed the key update predicate + // before the client sends the Foo request, otherwise the Foo request from + // the client could trigger the server key update before the server can + // initiate the key update locally. That would mean the test is no longer + // hitting the intended test state of both sides locally initiating a key + // update before receiving a packet in the new key phase from the other side. + // Additionally the test would fail since InitiateKeyUpdate() would not allow + // to do another key update yet and return false. + server_thread_->WaitUntil( + [this]() { + QuicConnection* server_connection = GetServerConnection(); + if (server_connection != nullptr) { + if (!server_connection->IsKeyUpdateAllowed()) { + // Server may not have received ack from client yet for the current + // key phase, wait a bit and try again. + return false; + } + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); + } else { + ADD_FAILURE() << "Missing server connection"; + } + return true; + }, + QuicTime::Delta::FromSeconds(5)); + QuicConnection* client_connection = GetClientConnection(); + ASSERT_TRUE(client_connection); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(1u, client_connection->GetStats().key_update_count); + + server_thread_->WaitUntil( + [this]() { + QuicConnection* server_connection = GetServerConnection(); + if (server_connection != nullptr) { + if (!server_connection->IsKeyUpdateAllowed()) { + return false; + } + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); + } else { + ADD_FAILURE() << "Missing server connection"; + } + return true; + }, + QuicTime::Delta::FromSeconds(5)); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + + SendSynchronousFooRequestAndCheckResponse(); + EXPECT_EQ(2u, client_connection->GetStats().key_update_count); + + server_thread_->Pause(); + QuicConnection* server_connection = GetServerConnection(); + if (server_connection) { + QuicConnectionStats server_stats = server_connection->GetStats(); + EXPECT_EQ(2u, server_stats.key_update_count); + } else { + ADD_FAILURE() << "Missing server connection"; + } + server_thread_->Resume(); +} + +TEST_P(EndToEndTest, KeyUpdateInitiatedByConfidentialityLimit) { + SetQuicReloadableFlag(quic_enable_aead_limits, true); + SetQuicReloadableFlag(quic_key_update_supported, true); + SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 4U); + + if (!version_.UsesTls()) { + // Key Update is only supported in TLS handshake. + ASSERT_TRUE(Initialize()); + return; + } + + ASSERT_TRUE(Initialize()); + + QuicConnection* client_connection = GetClientConnection(); + ASSERT_TRUE(client_connection); + EXPECT_EQ(0u, client_connection->GetStats().key_update_count); + + server_thread_->WaitUntil( + [this]() { + QuicConnection* server_connection = GetServerConnection(); + if (server_connection != nullptr) { + EXPECT_EQ(0u, server_connection->GetStats().key_update_count); + } else { + ADD_FAILURE() << "Missing server connection"; + } + return true; + }, + QuicTime::Delta::FromSeconds(5)); + + SendSynchronousFooRequestAndCheckResponse(); + SendSynchronousFooRequestAndCheckResponse(); + SendSynchronousFooRequestAndCheckResponse(); + // Don't know exactly how many packets will be sent in each request/response, + // so just test that at least one key update occurred. + EXPECT_LE(1u, client_connection->GetStats().key_update_count); + + server_thread_->Pause(); + QuicConnection* server_connection = GetServerConnection(); + if (server_connection) { + QuicConnectionStats server_stats = server_connection->GetStats(); + EXPECT_LE(1u, server_stats.key_update_count); + } else { + ADD_FAILURE() << "Missing server connection"; + } + server_thread_->Resume(); +} + +TEST_P(EndToEndTest, TlsResumptionEnabledOnTheFly) { + SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true); + ASSERT_TRUE(Initialize()); + + if (!version_.UsesTls()) { + // This test is TLS specific. + return; + } + + // Send the first request. Client should not have a resumption ticket. + SendSynchronousFooRequestAndCheckResponse(); + QuicSpdyClientSession* client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(), + ssl_early_data_no_session_offered); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + client_->Disconnect(); + + SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false); + + // Send the second request. Client should still have no resumption ticket, but + // it will receive one which can be used by the next request. + client_->Connect(); + SendSynchronousFooRequestAndCheckResponse(); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(), + ssl_early_data_no_session_offered); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + client_->Disconnect(); + + // Send the third request in 0RTT. + client_->Connect(); + SendSynchronousFooRequestAndCheckResponse(); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_TRUE(client_session->EarlyDataAccepted()); + client_->Disconnect(); +} + +TEST_P(EndToEndTest, TlsResumptionDisabledOnTheFly) { + SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false); + ASSERT_TRUE(Initialize()); + + if (!version_.UsesTls()) { + // This test is TLS specific. + return; + } + + // Send the first request and then disconnect. + SendSynchronousFooRequestAndCheckResponse(); + QuicSpdyClientSession* client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + client_->Disconnect(); + + // Send the second request in 0RTT. + client_->Connect(); + SendSynchronousFooRequestAndCheckResponse(); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_TRUE(client_session->EarlyDataAccepted()); + client_->Disconnect(); + + SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true); + + // Send the third request. The client should try resumption but server should + // decline it. + client_->Connect(); + SendSynchronousFooRequestAndCheckResponse(); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(), + ssl_early_data_session_not_resumed); + client_->Disconnect(); + + // Keep sending until the client runs out of resumption tickets. + for (int i = 0; i < 10; ++i) { + client_->Connect(); + SendSynchronousFooRequestAndCheckResponse(); + + client_session = GetClientSession(); + ASSERT_TRUE(client_session); + EXPECT_FALSE(client_session->EarlyDataAccepted()); + const auto early_data_reason = + client_session->GetCryptoStream()->EarlyDataReason(); + client_->Disconnect(); + + if (early_data_reason != ssl_early_data_session_not_resumed) { + EXPECT_EQ(early_data_reason, ssl_early_data_no_session_offered); + return; + } + } + + ADD_FAILURE() << "Client should not have 10 resumption tickets."; +} + } // namespace } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc index 3e067036e8d..1a160e9d5f6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.cc @@ -6,13 +6,16 @@ #include <cstdint> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/quic/core/http/http_frames.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -51,7 +54,7 @@ bool HttpDecoder::DecodeSettings(const char* data, return false; } - quiche::QuicheStringPiece frame_contents; + absl::string_view frame_contents; if (!reader.ReadStringPieceVarInt62(&frame_contents)) { QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents"; return false; @@ -93,7 +96,7 @@ QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) { switch (state_) { case STATE_READING_FRAME_TYPE: - ReadFrameType(&reader); + continue_processing = ReadFrameType(&reader); break; case STATE_READING_FRAME_LENGTH: continue_processing = ReadFrameLength(&reader); @@ -114,7 +117,7 @@ QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) { return len - reader.BytesRemaining(); } -void HttpDecoder::ReadFrameType(QuicDataReader* reader) { +bool HttpDecoder::ReadFrameType(QuicDataReader* reader) { DCHECK_NE(0u, reader->BytesRemaining()); if (current_type_field_length_ == 0) { // A new frame is coming. @@ -124,7 +127,7 @@ void HttpDecoder::ReadFrameType(QuicDataReader* reader) { // Buffer a new type field. remaining_type_field_length_ = current_type_field_length_; BufferFrameType(reader); - return; + return true; } // The reader has all type data needed, so no need to buffer. bool success = reader->ReadVarInt62(¤t_frame_type_); @@ -134,14 +137,34 @@ void HttpDecoder::ReadFrameType(QuicDataReader* reader) { BufferFrameType(reader); // The frame is still not buffered completely. if (remaining_type_field_length_ != 0) { - return; + return true; } QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_); bool success = type_reader.ReadVarInt62(¤t_frame_type_); DCHECK(success); } + if (GetQuicReloadableFlag(quic_reject_spdy_frames)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_reject_spdy_frames); + // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8 + // specifies that the following frames are treated as errors. + if (current_frame_type_ == + static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) || + current_frame_type_ == + static_cast<uint64_t>(http2::Http2FrameType::PING) || + current_frame_type_ == + static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) || + current_frame_type_ == + static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) { + RaiseError( + QUIC_HTTP_RECEIVE_SPDY_FRAME, + quiche::QuicheStrCat("HTTP/2 frame received in a HTTP/3 connection: ", + current_frame_type_)); + return false; + } + } state_ = STATE_READING_FRAME_LENGTH; + return true; } bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) { @@ -214,6 +237,14 @@ bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) { case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length); break; + case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): + if (GetQuicReloadableFlag(quic_new_priority_update_frame)) { + QUIC_CODE_COUNT_N(quic_new_priority_update_frame, 2, 2); + continue_processing = + visitor_->OnPriorityUpdateFrameStart(header_length); + break; + } + ABSL_FALLTHROUGH_INTENDED; default: continue_processing = visitor_->OnUnknownFrameStart( current_frame_type_, header_length, current_frame_length_); @@ -236,7 +267,7 @@ bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) { case static_cast<uint64_t>(HttpFrameType::DATA): { QuicByteCount bytes_to_read = std::min<QuicByteCount>( remaining_frame_length_, reader->BytesRemaining()); - quiche::QuicheStringPiece payload; + absl::string_view payload; bool success = reader->ReadStringPiece(&payload, bytes_to_read); DCHECK(success); DCHECK(!payload.empty()); @@ -247,7 +278,7 @@ bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) { case static_cast<uint64_t>(HttpFrameType::HEADERS): { QuicByteCount bytes_to_read = std::min<QuicByteCount>( remaining_frame_length_, reader->BytesRemaining()); - quiche::QuicheStringPiece payload; + absl::string_view payload; bool success = reader->ReadStringPiece(&payload, bytes_to_read); DCHECK(success); DCHECK(!payload.empty()); @@ -320,7 +351,7 @@ bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) { if (bytes_to_read == 0) { break; } - quiche::QuicheStringPiece payload; + absl::string_view payload; bool success = reader->ReadStringPiece(&payload, bytes_to_read); DCHECK(success); DCHECK(!payload.empty()); @@ -342,10 +373,19 @@ bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) { BufferFramePayload(reader); break; } + case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): { + if (GetQuicReloadableFlag(quic_new_priority_update_frame)) { + // TODO(bnc): Avoid buffering if the entire frame is present, and + // instead parse directly out of |reader|. + BufferFramePayload(reader); + break; + } + ABSL_FALLTHROUGH_INTENDED; + } default: { QuicByteCount bytes_to_read = std::min<QuicByteCount>( remaining_frame_length_, reader->BytesRemaining()); - quiche::QuicheStringPiece payload; + absl::string_view payload; bool success = reader->ReadStringPiece(&payload, bytes_to_read); DCHECK(success); DCHECK(!payload.empty()); @@ -446,6 +486,20 @@ bool HttpDecoder::FinishParsing() { continue_processing = visitor_->OnPriorityUpdateFrame(frame); break; } + case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): { + if (GetQuicReloadableFlag(quic_new_priority_update_frame)) { + // TODO(bnc): Avoid buffering if the entire frame is present, and + // instead parse directly out of |reader|. + PriorityUpdateFrame frame; + QuicDataReader reader(buffer_.data(), current_frame_length_); + if (!ParseNewPriorityUpdateFrame(&reader, &frame)) { + return false; + } + continue_processing = visitor_->OnPriorityUpdateFrame(frame); + break; + } + ABSL_FALLTHROUGH_INTENDED; + } default: { continue_processing = visitor_->OnUnknownFrameEnd(); break; @@ -461,7 +515,7 @@ bool HttpDecoder::FinishParsing() { void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) { QuicByteCount bytes_to_read = std::min<QuicByteCount>( remaining_frame_length_, reader->BytesRemaining()); - quiche::QuicheStringPiece payload; + absl::string_view payload; bool success = reader->ReadStringPiece(&payload, bytes_to_read); DCHECK(success); remaining_frame_length_ -= payload.length(); @@ -574,8 +628,23 @@ bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader, return false; } - quiche::QuicheStringPiece priority_field_value = - reader->ReadRemainingPayload(); + absl::string_view priority_field_value = reader->ReadRemainingPayload(); + frame->priority_field_value = + std::string(priority_field_value.data(), priority_field_value.size()); + + return true; +} + +bool HttpDecoder::ParseNewPriorityUpdateFrame(QuicDataReader* reader, + PriorityUpdateFrame* frame) { + frame->prioritized_element_type = REQUEST_STREAM; + + if (!reader->ReadVarInt62(&frame->prioritized_element_id)) { + RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id."); + return false; + } + + absl::string_view priority_field_value = reader->ReadRemainingPayload(); frame->priority_field_value = std::string(priority_field_value.data(), priority_field_value.size()); @@ -596,6 +665,9 @@ QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) { case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): // This limit is arbitrary. return 1024 * 1024; + case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): + // This limit is arbitrary. + return 1024 * 1024; default: // Other frames require no data buffering, so it's safe to have no limit. return std::numeric_limits<QuicByteCount>::max(); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h index 1551aa7d275..479f4448866 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder.h @@ -7,11 +7,11 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_frames.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -62,7 +62,7 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Called when part of the payload of a DATA frame has been read. May be // called multiple times for a single frame. |payload| is guaranteed to be // non-empty. - virtual bool OnDataFramePayload(quiche::QuicheStringPiece payload) = 0; + virtual bool OnDataFramePayload(absl::string_view payload) = 0; // Called when a DATA frame has been completely processed. virtual bool OnDataFrameEnd() = 0; @@ -74,7 +74,7 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Called when part of the payload of a HEADERS frame has been read. May be // called multiple times for a single frame. |payload| is guaranteed to be // non-empty. - virtual bool OnHeadersFramePayload(quiche::QuicheStringPiece payload) = 0; + virtual bool OnHeadersFramePayload(absl::string_view payload) = 0; // Called when a HEADERS frame has been completely processed. virtual bool OnHeadersFrameEnd() = 0; @@ -91,8 +91,7 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Called when part of the header block of a PUSH_PROMISE frame has been // read. May be called multiple times for a single frame. |payload| is // guaranteed to be non-empty. - virtual bool OnPushPromiseFramePayload( - quiche::QuicheStringPiece payload) = 0; + virtual bool OnPushPromiseFramePayload(absl::string_view payload) = 0; // Called when a PUSH_PROMISE frame has been completely processed. virtual bool OnPushPromiseFrameEnd() = 0; @@ -113,7 +112,7 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Called when part of the payload of the unknown frame has been read. May // be called multiple times for a single frame. |payload| is guaranteed to // be non-empty. - virtual bool OnUnknownFramePayload(quiche::QuicheStringPiece payload) = 0; + virtual bool OnUnknownFramePayload(absl::string_view payload) = 0; // Called when the unknown frame has been completely processed. virtual bool OnUnknownFrameEnd() = 0; }; @@ -158,8 +157,9 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Reads the type of a frame from |reader|. Sets error_ and error_detail_ // if there are any errors. Also calls OnDataFrameStart() or - // OnHeadersFrameStart() for appropriate frame types. - void ReadFrameType(QuicDataReader* reader); + // OnHeadersFrameStart() for appropriate frame types. Returns whether the + // processing should continue. + bool ReadFrameType(QuicDataReader* reader); // Reads the length of a frame from |reader|. Sets error_ and error_detail_ // if there are any errors. Returns whether processing should continue. @@ -197,10 +197,16 @@ class QUIC_EXPORT_PRIVATE HttpDecoder { // Parses the payload of a SETTINGS frame from |reader| into |frame|. bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame); - // Parses the payload of a PRIORITY_UPDATE frame from |reader| into |frame|. + // Parses the payload of a PRIORITY_UPDATE frame (draft-01, type 0x0f) + // from |reader| into |frame|. bool ParsePriorityUpdateFrame(QuicDataReader* reader, PriorityUpdateFrame* frame); + // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700) + // from |reader| into |frame|. + bool ParseNewPriorityUpdateFrame(QuicDataReader* reader, + PriorityUpdateFrame* frame); + // Returns the max frame size of a given |frame_type|. QuicByteCount MaxFrameLength(uint64_t frame_type); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc index 01f0a5fbfa9..d56626ffa21 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_decoder_test.cc @@ -7,15 +7,17 @@ #include <memory> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" #include "net/third_party/quiche/src/quic/core/http/http_frames.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using ::testing::_; @@ -62,7 +64,7 @@ class MockVisitor : public HttpDecoder::Visitor { (override)); MOCK_METHOD(bool, OnDataFramePayload, - (quiche::QuicheStringPiece payload), + (absl::string_view payload), (override)); MOCK_METHOD(bool, OnDataFrameEnd, (), (override)); @@ -72,7 +74,7 @@ class MockVisitor : public HttpDecoder::Visitor { (override)); MOCK_METHOD(bool, OnHeadersFramePayload, - (quiche::QuicheStringPiece payload), + (absl::string_view payload), (override)); MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override)); @@ -88,7 +90,7 @@ class MockVisitor : public HttpDecoder::Visitor { (override)); MOCK_METHOD(bool, OnPushPromiseFramePayload, - (quiche::QuicheStringPiece payload), + (absl::string_view payload), (override)); MOCK_METHOD(bool, OnPushPromiseFrameEnd, (), (override)); @@ -109,7 +111,7 @@ class MockVisitor : public HttpDecoder::Visitor { (override)); MOCK_METHOD(bool, OnUnknownFramePayload, - (quiche::QuicheStringPiece payload), + (absl::string_view payload), (override)); MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override)); }; @@ -147,13 +149,13 @@ class HttpDecoderTest : public QuicTest { } // Process |input| in a single call to HttpDecoder::ProcessInput(). - QuicByteCount ProcessInput(quiche::QuicheStringPiece input) { + QuicByteCount ProcessInput(absl::string_view input) { return decoder_.ProcessInput(input.data(), input.size()); } // Feed |input| to |decoder_| one character at a time, // verifying that each character gets processed. - void ProcessInputCharByChar(quiche::QuicheStringPiece input) { + void ProcessInputCharByChar(absl::string_view input) { for (char c : input) { EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1)); } @@ -161,8 +163,7 @@ class HttpDecoderTest : public QuicTest { // Append garbage to |input|, then process it in a single call to // HttpDecoder::ProcessInput(). Verify that garbage is not read. - QuicByteCount ProcessInputWithGarbageAppended( - quiche::QuicheStringPiece input) { + QuicByteCount ProcessInputWithGarbageAppended(absl::string_view input) { std::string input_with_garbage_appended = quiche::QuicheStrCat(input, "blahblah"); QuicByteCount processed_bytes = ProcessInput(input_with_garbage_appended); @@ -192,7 +193,7 @@ TEST_F(HttpDecoderTest, UnknownFrame) { const QuicByteCount payload_lengths[] = {0, 14, 100}; const uint64_t frame_types[] = { 0x21, 0x40, 0x5f, 0x7e, 0x9d, // some reserved frame types - 0x06, 0x6f, 0x14 // some unknown, not reserved frame types + 0x6f, 0x14 // some unknown, not reserved frame types }; for (auto payload_length : payload_lengths) { @@ -230,7 +231,7 @@ TEST_F(HttpDecoderTest, UnknownFrame) { TEST_F(HttpDecoderTest, CancelPush) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "03" // type (CANCEL_PUSH) "01" // length "01"); // Push Id @@ -258,16 +259,16 @@ TEST_F(HttpDecoderTest, CancelPush) { TEST_F(HttpDecoderTest, PushPromiseFrame) { InSequence s; std::string input = quiche::QuicheStrCat( - quiche::QuicheTextUtils::HexDecode("05" // type (PUSH PROMISE) - "0f" // length - "C000000000000101"), // push id 257 - "Headers"); // headers + absl::HexStringToBytes("05" // type (PUSH PROMISE) + "0f" // length + "C000000000000101"), // push id 257 + "Headers"); // headers // Visitor pauses processing. EXPECT_CALL(visitor_, OnPushPromiseFrameStart(2)).WillOnce(Return(false)); EXPECT_CALL(visitor_, OnPushPromiseFramePushId(257, 8, 7)) .WillOnce(Return(false)); - quiche::QuicheStringPiece remaining_input(input); + absl::string_view remaining_input(input); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(2u, processed_bytes); @@ -276,8 +277,7 @@ TEST_F(HttpDecoderTest, PushPromiseFrame) { EXPECT_EQ(8u, processed_bytes); remaining_input = remaining_input.substr(processed_bytes); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("Headers"))) + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("Headers"))) .WillOnce(Return(false)); processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(remaining_input.size(), processed_bytes); @@ -291,7 +291,7 @@ TEST_F(HttpDecoderTest, PushPromiseFrame) { EXPECT_CALL(visitor_, OnPushPromiseFrameStart(2)); EXPECT_CALL(visitor_, OnPushPromiseFramePushId(257, 8, 7)); EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("Headers"))); + OnPushPromiseFramePayload(absl::string_view("Headers"))); EXPECT_CALL(visitor_, OnPushPromiseFrameEnd()); EXPECT_EQ(input.size(), ProcessInput(input)); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -300,20 +300,13 @@ TEST_F(HttpDecoderTest, PushPromiseFrame) { // Process the frame incrementally. EXPECT_CALL(visitor_, OnPushPromiseFrameStart(2)); EXPECT_CALL(visitor_, OnPushPromiseFramePushId(257, 8, 7)); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("H"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("e"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("a"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("d"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("e"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("r"))); - EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("s"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("H"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("e"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("a"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("d"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("e"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("r"))); + EXPECT_CALL(visitor_, OnPushPromiseFramePayload(absl::string_view("s"))); EXPECT_CALL(visitor_, OnPushPromiseFrameEnd()); ProcessInputCharByChar(input); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -323,7 +316,7 @@ TEST_F(HttpDecoderTest, PushPromiseFrame) { EXPECT_CALL(visitor_, OnPushPromiseFrameStart(2)); EXPECT_CALL(visitor_, OnPushPromiseFramePushId(257, 8, 7)); EXPECT_CALL(visitor_, - OnPushPromiseFramePayload(quiche::QuicheStringPiece("Headers"))); + OnPushPromiseFramePayload(absl::string_view("Headers"))); EXPECT_CALL(visitor_, OnPushPromiseFrameEnd()); ProcessInputCharByChar(input.substr(0, 9)); EXPECT_EQ(8u, ProcessInput(input.substr(9))); @@ -334,7 +327,7 @@ TEST_F(HttpDecoderTest, PushPromiseFrame) { TEST_F(HttpDecoderTest, CorruptPushPromiseFrame) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "05" // type (PUSH_PROMISE) "01" // length "40"); // first byte of two-byte varint push id @@ -365,7 +358,7 @@ TEST_F(HttpDecoderTest, CorruptPushPromiseFrame) { TEST_F(HttpDecoderTest, MaxPushId) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "0D" // type (MAX_PUSH_ID) "01" // length "01"); // Push Id @@ -392,7 +385,7 @@ TEST_F(HttpDecoderTest, MaxPushId) { TEST_F(HttpDecoderTest, SettingsFrame) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "04" // type (SETTINGS) "07" // length "01" // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY) @@ -408,7 +401,7 @@ TEST_F(HttpDecoderTest, SettingsFrame) { frame.values[256] = 4; // Visitor pauses processing. - quiche::QuicheStringPiece remaining_input(input); + absl::string_view remaining_input(input); EXPECT_CALL(visitor_, OnSettingsFrameStart(2)).WillOnce(Return(false)); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); @@ -472,7 +465,7 @@ TEST_F(HttpDecoderTest, CorruptSettingsFrame) { } TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "04" // type (SETTINGS) "04" // length "01" // identifier @@ -492,20 +485,20 @@ TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) { TEST_F(HttpDecoderTest, DataFrame) { InSequence s; - std::string input = quiche::QuicheStrCat( - quiche::QuicheTextUtils::HexDecode("00" // type (DATA) - "05"), // length - "Data!"); // data + std::string input = + quiche::QuicheStrCat(absl::HexStringToBytes("00" // type (DATA) + "05"), // length + "Data!"); // data // Visitor pauses processing. EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false)); - quiche::QuicheStringPiece remaining_input(input); + absl::string_view remaining_input(input); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(2u, processed_bytes); remaining_input = remaining_input.substr(processed_bytes); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("Data!"))) + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!"))) .WillOnce(Return(false)); processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(remaining_input.size(), processed_bytes); @@ -517,7 +510,7 @@ TEST_F(HttpDecoderTest, DataFrame) { // Process the full frame. EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("Data!"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!"))); EXPECT_CALL(visitor_, OnDataFrameEnd()); EXPECT_EQ(input.size(), ProcessInput(input)); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -525,11 +518,11 @@ TEST_F(HttpDecoderTest, DataFrame) { // Process the frame incrementally. EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("D"))); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("a"))); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("t"))); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("a"))); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("!"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("D"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("t"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("!"))); EXPECT_CALL(visitor_, OnDataFrameEnd()); ProcessInputCharByChar(input); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -557,7 +550,7 @@ TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) { EXPECT_EQ("", decoder_.error_detail()); // Send data. - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece(input))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view(input))); EXPECT_CALL(visitor_, OnDataFrameEnd()); EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048)); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -594,7 +587,7 @@ TEST_F(HttpDecoderTest, PartialDeliveryOfLargeFrameType) { TEST_F(HttpDecoderTest, GoAway) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "07" // type (GOAWAY) "01" // length "01"); // ID @@ -621,21 +614,20 @@ TEST_F(HttpDecoderTest, GoAway) { TEST_F(HttpDecoderTest, HeadersFrame) { InSequence s; - std::string input = quiche::QuicheStrCat( - quiche::QuicheTextUtils::HexDecode("01" // type (HEADERS) - "07"), // length - "Headers"); // headers + std::string input = + quiche::QuicheStrCat(absl::HexStringToBytes("01" // type (HEADERS) + "07"), // length + "Headers"); // headers // Visitor pauses processing. EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false)); - quiche::QuicheStringPiece remaining_input(input); + absl::string_view remaining_input(input); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(2u, processed_bytes); remaining_input = remaining_input.substr(processed_bytes); - EXPECT_CALL(visitor_, - OnHeadersFramePayload(quiche::QuicheStringPiece("Headers"))) + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers"))) .WillOnce(Return(false)); processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(remaining_input.size(), processed_bytes); @@ -647,8 +639,7 @@ TEST_F(HttpDecoderTest, HeadersFrame) { // Process the full frame. EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)); - EXPECT_CALL(visitor_, - OnHeadersFramePayload(quiche::QuicheStringPiece("Headers"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers"))); EXPECT_CALL(visitor_, OnHeadersFrameEnd()); EXPECT_EQ(input.size(), ProcessInput(input)); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -656,13 +647,13 @@ TEST_F(HttpDecoderTest, HeadersFrame) { // Process the frame incrementally. EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("H"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("e"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("a"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("d"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("e"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("r"))); - EXPECT_CALL(visitor_, OnHeadersFramePayload(quiche::QuicheStringPiece("s"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("H"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("a"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("d"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("r"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("s"))); EXPECT_CALL(visitor_, OnHeadersFrameEnd()); ProcessInputCharByChar(input); EXPECT_THAT(decoder_.error(), IsQuicNoError()); @@ -671,7 +662,7 @@ TEST_F(HttpDecoderTest, HeadersFrame) { TEST_F(HttpDecoderTest, EmptyDataFrame) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "00" // type (DATA) "00"); // length @@ -701,7 +692,7 @@ TEST_F(HttpDecoderTest, EmptyDataFrame) { TEST_F(HttpDecoderTest, EmptyHeadersFrame) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "01" // type (HEADERS) "00"); // length @@ -731,7 +722,7 @@ TEST_F(HttpDecoderTest, EmptyHeadersFrame) { TEST_F(HttpDecoderTest, PushPromiseFrameNoHeaders) { InSequence s; - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "05" // type (PUSH_PROMISE) "01" // length "01"); // Push Id @@ -765,7 +756,7 @@ TEST_F(HttpDecoderTest, PushPromiseFrameNoHeaders) { } TEST_F(HttpDecoderTest, MalformedFrameWithOverlyLargePayload) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "03" // type (CANCEL_PUSH) "10" // length "15"); // malformed payload @@ -786,27 +777,41 @@ TEST_F(HttpDecoderTest, MalformedSettingsFrame) { writer.WriteStringPiece("Malformed payload"); EXPECT_CALL(visitor_, OnError(&decoder_)); - EXPECT_EQ(5u, decoder_.ProcessInput(input, QUICHE_ARRAYSIZE(input))); + EXPECT_EQ(5u, decoder_.ProcessInput(input, ABSL_ARRAYSIZE(input))); EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE)); EXPECT_EQ("Frame is too large.", decoder_.error_detail()); } +TEST_F(HttpDecoderTest, Http2Frame) { + SetQuicReloadableFlag(quic_reject_spdy_frames, true); + std::string input = absl::HexStringToBytes( + "06" // PING in HTTP/2 but not supported in HTTP/3. + "05" // length + "15"); // random payload + + // Process the full frame. + EXPECT_CALL(visitor_, OnError(&decoder_)); + EXPECT_EQ(1u, ProcessInput(input)); + EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_RECEIVE_SPDY_FRAME)); + EXPECT_EQ("HTTP/2 frame received in a HTTP/3 connection: 6", + decoder_.error_detail()); +} + TEST_F(HttpDecoderTest, HeadersPausedThenData) { InSequence s; - std::string input = quiche::QuicheStrCat( - quiche::QuicheTextUtils::HexDecode("01" // type (HEADERS) - "07"), // length - "Headers", // headers - quiche::QuicheTextUtils::HexDecode("00" // type (DATA) - "05"), // length - "Data!"); // data + std::string input = + quiche::QuicheStrCat(absl::HexStringToBytes("01" // type (HEADERS) + "07"), // length + "Headers", // headers + absl::HexStringToBytes("00" // type (DATA) + "05"), // length + "Data!"); // data // Visitor pauses processing, maybe because header decompression is blocked. EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)); - EXPECT_CALL(visitor_, - OnHeadersFramePayload(quiche::QuicheStringPiece("Headers"))); + EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers"))); EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false)); - quiche::QuicheStringPiece remaining_input(input); + absl::string_view remaining_input(input); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(9u, processed_bytes); @@ -814,7 +819,7 @@ TEST_F(HttpDecoderTest, HeadersPausedThenData) { // Process DATA frame. EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)); - EXPECT_CALL(visitor_, OnDataFramePayload(quiche::QuicheStringPiece("Data!"))); + EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!"))); EXPECT_CALL(visitor_, OnDataFrameEnd()); processed_bytes = ProcessInput(remaining_input); @@ -863,7 +868,7 @@ TEST_F(HttpDecoderTest, CorruptFrame) { HttpDecoder decoder(&visitor_); EXPECT_CALL(visitor_, OnError(&decoder)); - quiche::QuicheStringPiece input(test_data.input); + absl::string_view input(test_data.input); decoder.ProcessInput(input.data(), input.size()); EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR)); EXPECT_EQ(test_data.error_message, decoder.error_detail()); @@ -872,7 +877,7 @@ TEST_F(HttpDecoderTest, CorruptFrame) { HttpDecoder decoder(&visitor_); EXPECT_CALL(visitor_, OnError(&decoder)); - quiche::QuicheStringPiece input(test_data.input); + absl::string_view input(test_data.input); for (auto c : input) { decoder.ProcessInput(&c, 1); } @@ -883,7 +888,7 @@ TEST_F(HttpDecoderTest, CorruptFrame) { } TEST_F(HttpDecoderTest, EmptyCancelPushFrame) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "03" // type (CANCEL_PUSH) "00"); // frame length @@ -894,7 +899,7 @@ TEST_F(HttpDecoderTest, EmptyCancelPushFrame) { } TEST_F(HttpDecoderTest, EmptySettingsFrame) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "04" // type (SETTINGS) "00"); // frame length @@ -910,7 +915,7 @@ TEST_F(HttpDecoderTest, EmptySettingsFrame) { // Regression test for https://crbug.com/1001823. TEST_F(HttpDecoderTest, EmptyPushPromiseFrame) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "05" // type (PUSH_PROMISE) "00"); // frame length @@ -921,7 +926,7 @@ TEST_F(HttpDecoderTest, EmptyPushPromiseFrame) { } TEST_F(HttpDecoderTest, EmptyGoAwayFrame) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "07" // type (GOAWAY) "00"); // frame length @@ -932,7 +937,7 @@ TEST_F(HttpDecoderTest, EmptyGoAwayFrame) { } TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "0d" // type (MAX_PUSH_ID) "00"); // frame length @@ -956,7 +961,7 @@ TEST_F(HttpDecoderTest, LargeStreamIdInGoAway) { TEST_F(HttpDecoderTest, PriorityUpdateFrame) { InSequence s; - std::string input1 = quiche::QuicheTextUtils::HexDecode( + std::string input1 = absl::HexStringToBytes( "0f" // type (PRIORITY_UPDATE) "02" // length "00" // prioritized element type: REQUEST_STREAM @@ -968,7 +973,7 @@ TEST_F(HttpDecoderTest, PriorityUpdateFrame) { // Visitor pauses processing. EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(2)).WillOnce(Return(false)); - quiche::QuicheStringPiece remaining_input(input1); + absl::string_view remaining_input(input1); QuicByteCount processed_bytes = ProcessInputWithGarbageAppended(remaining_input); EXPECT_EQ(2u, processed_bytes); @@ -995,8 +1000,8 @@ TEST_F(HttpDecoderTest, PriorityUpdateFrame) { EXPECT_THAT(decoder_.error(), IsQuicNoError()); EXPECT_EQ("", decoder_.error_detail()); - std::string input2 = quiche::QuicheTextUtils::HexDecode( - "0f" // type (PRIORIRTY) + std::string input2 = absl::HexStringToBytes( + "0f" // type (PRIORITY_UPDATE) "05" // length "80" // prioritized element type: PUSH_STREAM "05" // prioritized element id @@ -1036,12 +1041,96 @@ TEST_F(HttpDecoderTest, PriorityUpdateFrame) { EXPECT_EQ("", decoder_.error_detail()); } +TEST_F(HttpDecoderTest, NewPriorityUpdateFrame) { + if (!GetQuicReloadableFlag(quic_new_priority_update_frame)) { + return; + } + + InSequence s; + std::string input1 = absl::HexStringToBytes( + "800f0700" // type (PRIORITY_UPDATE) + "01" // length + "03"); // prioritized element id + + PriorityUpdateFrame priority_update1; + priority_update1.prioritized_element_type = REQUEST_STREAM; + priority_update1.prioritized_element_id = 0x03; + + // Visitor pauses processing. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false)); + absl::string_view remaining_input(input1); + QuicByteCount processed_bytes = + ProcessInputWithGarbageAppended(remaining_input); + EXPECT_EQ(5u, processed_bytes); + remaining_input = remaining_input.substr(processed_bytes); + + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1)) + .WillOnce(Return(false)); + processed_bytes = ProcessInputWithGarbageAppended(remaining_input); + EXPECT_EQ(remaining_input.size(), processed_bytes); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); + + // Process the full frame. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)); + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1)); + EXPECT_EQ(input1.size(), ProcessInput(input1)); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); + + // Process the frame incrementally. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)); + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1)); + ProcessInputCharByChar(input1); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); + + std::string input2 = absl::HexStringToBytes( + "800f0700" // type (PRIORITY_UPDATE) + "04" // length + "05" // prioritized element id + "666f6f"); // priority field value: "foo" + + PriorityUpdateFrame priority_update2; + priority_update2.prioritized_element_type = REQUEST_STREAM; + priority_update2.prioritized_element_id = 0x05; + priority_update2.priority_field_value = "foo"; + + // Visitor pauses processing. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false)); + remaining_input = input2; + processed_bytes = ProcessInputWithGarbageAppended(remaining_input); + EXPECT_EQ(5u, processed_bytes); + remaining_input = remaining_input.substr(processed_bytes); + + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2)) + .WillOnce(Return(false)); + processed_bytes = ProcessInputWithGarbageAppended(remaining_input); + EXPECT_EQ(remaining_input.size(), processed_bytes); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); + + // Process the full frame. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)); + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2)); + EXPECT_EQ(input2.size(), ProcessInput(input2)); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); + + // Process the frame incrementally. + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)); + EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2)); + ProcessInputCharByChar(input2); + EXPECT_THAT(decoder_.error(), IsQuicNoError()); + EXPECT_EQ("", decoder_.error_detail()); +} + TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) { - std::string payload1 = quiche::QuicheTextUtils::HexDecode( + std::string payload1 = absl::HexStringToBytes( "80" // prioritized element type: PUSH_STREAM "4005"); // prioritized element id - std::string payload2 = quiche::QuicheTextUtils::HexDecode( - "42"); // invalid prioritized element type + std::string payload2 = + absl::HexStringToBytes("42"); // invalid prioritized element type struct { const char* const payload; size_t payload_length; @@ -1072,8 +1161,42 @@ TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) { } } +TEST_F(HttpDecoderTest, CorruptNewPriorityUpdateFrame) { + if (!GetQuicReloadableFlag(quic_new_priority_update_frame)) { + return; + } + + std::string payload = + absl::HexStringToBytes("4005"); // prioritized element id + struct { + size_t payload_length; + const char* const error_message; + } kTestData[] = { + {0, "Unable to read prioritized element id."}, + {1, "Unable to read prioritized element id."}, + }; + + for (const auto& test_data : kTestData) { + std::string input = + absl::HexStringToBytes("800f0700"); // type PRIORITY_UPDATE + input.push_back(test_data.payload_length); + size_t header_length = input.size(); + input.append(payload.data(), test_data.payload_length); + + HttpDecoder decoder(&visitor_); + EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(header_length)); + EXPECT_CALL(visitor_, OnError(&decoder)); + + QuicByteCount processed_bytes = + decoder.ProcessInput(input.data(), input.size()); + EXPECT_EQ(input.size(), processed_bytes); + EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR)); + EXPECT_EQ(test_data.error_message, decoder.error_detail()); + } +} + TEST_F(HttpDecoderTest, DecodeSettings) { - std::string input = quiche::QuicheTextUtils::HexDecode( + std::string input = absl::HexStringToBytes( "04" // type (SETTINGS) "07" // length "01" // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY) @@ -1093,7 +1216,7 @@ TEST_F(HttpDecoderTest, DecodeSettings) { EXPECT_EQ(frame, out); // non-settings frame. - input = quiche::QuicheTextUtils::HexDecode( + input = absl::HexStringToBytes( "0D" // type (MAX_PUSH_ID) "01" // length "01"); // Push Id @@ -1101,7 +1224,7 @@ TEST_F(HttpDecoderTest, DecodeSettings) { EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out)); // Corrupt SETTINGS. - input = quiche::QuicheTextUtils::HexDecode( + input = absl::HexStringToBytes( "04" // type (SETTINGS) "01" // length "42"); // First byte of setting identifier, indicating a 2-byte varint62. diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc index 770770561f7..4f86d45b7b7 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder.cc @@ -202,6 +202,37 @@ QuicByteCount HttpEncoder::SerializeMaxPushIdFrame( QuicByteCount HttpEncoder::SerializePriorityUpdateFrame( const PriorityUpdateFrame& priority_update, std::unique_ptr<char[]>* output) { + if (GetQuicReloadableFlag(quic_new_priority_update_frame)) { + QUIC_CODE_COUNT_N(quic_new_priority_update_frame, 1, 2); + + if (priority_update.prioritized_element_type != REQUEST_STREAM) { + QUIC_BUG << "PRIORITY_UPDATE for push streams not implemented"; + return 0; + } + + QuicByteCount payload_length = + QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) + + priority_update.priority_field_value.size(); + QuicByteCount total_length = GetTotalLength( + payload_length, HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM); + + output->reset(new char[total_length]); + QuicDataWriter writer(total_length, output->get()); + + if (WriteFrameHeader(payload_length, + HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM, + &writer) && + writer.WriteVarInt62(priority_update.prioritized_element_id) && + writer.WriteBytes(priority_update.priority_field_value.data(), + priority_update.priority_field_value.size())) { + return total_length; + } + + QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize " + "PRIORITY_UPDATE frame."; + return 0; + } + QuicByteCount payload_length = kPriorityFirstByteLength + QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) + diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc index f6c04449a39..2466326586c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_encoder_test.cc @@ -4,9 +4,10 @@ #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" +#include "absl/base/macros.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" namespace quic { @@ -20,9 +21,9 @@ TEST(HttpEncoderTest, SerializeDataFrameHeader) { 0x00, // length 0x05}; - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError("DATA", buffer.get(), length, - output, QUICHE_ARRAYSIZE(output)); + output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializeHeadersFrameHeader) { @@ -33,9 +34,9 @@ TEST(HttpEncoderTest, SerializeHeadersFrameHeader) { 0x01, // length 0x07}; - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError("HEADERS", buffer.get(), length, - output, QUICHE_ARRAYSIZE(output)); + output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializeCancelPushFrame) { @@ -49,9 +50,9 @@ TEST(HttpEncoderTest, SerializeCancelPushFrame) { 0x01}; std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializeCancelPushFrame(cancel_push, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError( - "CANCEL_PUSH", buffer.get(), length, output, QUICHE_ARRAYSIZE(output)); + "CANCEL_PUSH", buffer.get(), length, output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializeSettingsFrame) { @@ -77,9 +78,9 @@ TEST(HttpEncoderTest, SerializeSettingsFrame) { 0x04}; std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializeSettingsFrame(settings, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError("SETTINGS", buffer.get(), length, - output, QUICHE_ARRAYSIZE(output)); + output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializePushPromiseFrameWithOnlyPushId) { @@ -95,9 +96,9 @@ TEST(HttpEncoderTest, SerializePushPromiseFrameWithOnlyPushId) { std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializePushPromiseFrameWithOnlyPushId( push_promise, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError( - "PUSH_PROMISE", buffer.get(), length, output, QUICHE_ARRAYSIZE(output)); + "PUSH_PROMISE", buffer.get(), length, output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializeGoAwayFrame) { @@ -111,9 +112,9 @@ TEST(HttpEncoderTest, SerializeGoAwayFrame) { 0x01}; std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializeGoAwayFrame(goaway, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError("GOAWAY", buffer.get(), length, - output, QUICHE_ARRAYSIZE(output)); + output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializeMaxPushIdFrame) { @@ -127,12 +128,30 @@ TEST(HttpEncoderTest, SerializeMaxPushIdFrame) { 0x01}; std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializeMaxPushIdFrame(max_push_id, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output), length); quiche::test::CompareCharArraysWithHexError( - "MAX_PUSH_ID", buffer.get(), length, output, QUICHE_ARRAYSIZE(output)); + "MAX_PUSH_ID", buffer.get(), length, output, ABSL_ARRAYSIZE(output)); } TEST(HttpEncoderTest, SerializePriorityUpdateFrame) { + if (GetQuicReloadableFlag(quic_new_priority_update_frame)) { + PriorityUpdateFrame priority_update1; + priority_update1.prioritized_element_type = REQUEST_STREAM; + priority_update1.prioritized_element_id = 0x03; + char output1[] = {0x80, 0x0f, 0x07, 0x00, // type (PRIORITY_UPDATE) + 0x01, // length + 0x03}; // prioritized element id + + std::unique_ptr<char[]> buffer; + uint64_t length = + HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer); + EXPECT_EQ(ABSL_ARRAYSIZE(output1), length); + quiche::test::CompareCharArraysWithHexError("PRIORITY_UPDATE", buffer.get(), + length, output1, + ABSL_ARRAYSIZE(output1)); + return; + } + PriorityUpdateFrame priority_update1; priority_update1.prioritized_element_type = REQUEST_STREAM; priority_update1.prioritized_element_id = 0x03; @@ -144,10 +163,10 @@ TEST(HttpEncoderTest, SerializePriorityUpdateFrame) { std::unique_ptr<char[]> buffer; uint64_t length = HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output1), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output1), length); quiche::test::CompareCharArraysWithHexError("PRIORITY_UPDATE", buffer.get(), length, output1, - QUICHE_ARRAYSIZE(output1)); + ABSL_ARRAYSIZE(output1)); PriorityUpdateFrame priority_update2; priority_update2.prioritized_element_type = PUSH_STREAM; @@ -159,10 +178,10 @@ TEST(HttpEncoderTest, SerializePriorityUpdateFrame) { 0x05, // prioritized element id 'f', 'o', 'o'}; // priority field value length = HttpEncoder::SerializePriorityUpdateFrame(priority_update2, &buffer); - EXPECT_EQ(QUICHE_ARRAYSIZE(output2), length); + EXPECT_EQ(ABSL_ARRAYSIZE(output2), length); quiche::test::CompareCharArraysWithHexError("PRIORITY_UPDATE", buffer.get(), length, output2, - QUICHE_ARRAYSIZE(output2)); + ABSL_ARRAYSIZE(output2)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h b/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h index 159b250088e..ed7ad2c2d24 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/http_frames.h @@ -9,16 +9,16 @@ #include <map> #include <ostream> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" namespace quic { -enum class HttpFrameType : uint8_t { +enum class HttpFrameType { DATA = 0x0, HEADERS = 0x1, CANCEL_PUSH = 0X3, @@ -26,7 +26,10 @@ enum class HttpFrameType : uint8_t { PUSH_PROMISE = 0x5, GOAWAY = 0x7, MAX_PUSH_ID = 0xD, + // https://tools.ietf.org/html/draft-ietf-httpbis-priority-01 PRIORITY_UPDATE = 0XF, + // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02 + PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700, }; // 7.2.1. DATA @@ -34,7 +37,7 @@ enum class HttpFrameType : uint8_t { // DATA frames (type=0x0) convey arbitrary, variable-length sequences of // octets associated with an HTTP request or response payload. struct QUIC_EXPORT_PRIVATE DataFrame { - quiche::QuicheStringPiece data; + absl::string_view data; }; // 7.2.2. HEADERS @@ -42,7 +45,7 @@ struct QUIC_EXPORT_PRIVATE DataFrame { // The HEADERS frame (type=0x1) is used to carry a header block, // compressed using QPACK. struct QUIC_EXPORT_PRIVATE HeadersFrame { - quiche::QuicheStringPiece headers; + absl::string_view headers; }; // 7.2.3. CANCEL_PUSH @@ -98,7 +101,7 @@ struct QUIC_EXPORT_PRIVATE SettingsFrame { // set from server to client, as in HTTP/2. struct QUIC_EXPORT_PRIVATE PushPromiseFrame { PushId push_id; - quiche::QuicheStringPiece headers; + absl::string_view headers; bool operator==(const PushPromiseFrame& rhs) const { return push_id == rhs.push_id && headers == rhs.headers; @@ -132,8 +135,11 @@ struct QUIC_EXPORT_PRIVATE MaxPushIdFrame { // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html // -// The PRIORITY_UPDATE (type=0x0f) frame specifies the sender-advised priority -// of a stream +// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream. +// https://tools.ietf.org/html/draft-ietf-httpbis-priority-01 uses frame type +// 0x0f, both for request streams and push streams. +// https://tools.ietf.org/html/draft-ietf-httpbis-priority-02 uses frame types +// 0xf0700 for request streams and 0xf0701 for push streams (not implemented). // Length of a priority frame's first byte. const QuicByteCount kPriorityFirstByteLength = 1; diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc index 1a1ec691251..9e21f41c50c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc @@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -52,6 +53,11 @@ class MockQuicSpdyClientSession : public QuicSpdyClientSession { void set_authorized(bool authorized) { authorized_ = authorized; } + MOCK_METHOD(bool, + WriteControlFrame, + (const QuicFrame& frame, TransmissionType type), + (override)); + private: QuicCryptoClientConfig crypto_config_; @@ -73,6 +79,9 @@ class QuicClientPromisedInfoTest : public QuicTest { promise_id_( QuicUtils::GetInvalidStreamId(connection_->transport_version())) { connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_.Initialize(); headers_[":status"] = "200"; @@ -142,7 +151,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) { ASSERT_NE(promised, nullptr); // Fire the alarm that will cancel the promised stream. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT)); alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised)); @@ -156,7 +165,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) { // Promise with an unsafe method push_promise_[":method"] = "PUT"; - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD)); ReceivePromise(promise_id_); @@ -170,7 +179,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) { // Promise with a missing method push_promise_.erase(":method"); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD)); ReceivePromise(promise_id_); @@ -184,7 +193,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) { // Remove required header field to make URL invalid push_promise_.erase(":authority"); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL)); ReceivePromise(promise_id_); @@ -197,7 +206,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) { TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) { session_.set_authorized(false); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL)); @@ -222,7 +231,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) { headers); TestPushPromiseDelegate delegate(/*match=*/false); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH)); @@ -300,7 +309,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) { session_.GetOrCreateStream(promise_id_); // Cancel the promised stream. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED)); promised->Cancel(); @@ -323,7 +332,7 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) { promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), headers); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY)); session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc index cbfc2e9f73b..5282f2d852e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.cc @@ -7,10 +7,10 @@ #include <limits> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,8 +36,7 @@ void QuicHeaderList::OnHeaderBlockStart() { << "OnHeaderBlockStart called more than once!"; } -void QuicHeaderList::OnHeader(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +void QuicHeaderList::OnHeader(absl::string_view name, absl::string_view value) { // Avoid infinite buffering of headers. No longer store headers // once the current headers are over the limit. if (current_header_list_size_ < max_header_list_size_) { diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h index 0ed8ae8c4a9..bc3a73bcf41 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_header_list.h @@ -10,10 +10,10 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" #include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" @@ -36,8 +36,7 @@ class QUIC_EXPORT_PRIVATE QuicHeaderList // From SpdyHeadersHandlerInteface. void OnHeaderBlockStart() override; - void OnHeader(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) override; + void OnHeader(absl::string_view name, absl::string_view value) override; void OnHeaderBlockEnd(size_t uncompressed_header_bytes, size_t compressed_header_bytes) override; diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc index 8157daec788..1cce85f7271 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_headers_stream.cc @@ -4,11 +4,11 @@ #include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { 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 9e1b08a486b..8f604b37dd4 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 @@ -11,6 +11,8 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -23,15 +25,16 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" +#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h" using spdy::ERROR_CODE_PROTOCOL_ERROR; +using spdy::RecordingHeadersHandler; using spdy::SETTINGS_ENABLE_PUSH; using spdy::SETTINGS_HEADER_TABLE_SIZE; using spdy::SETTINGS_INITIAL_WINDOW_SIZE; @@ -59,7 +62,6 @@ using spdy::SpdySettingsId; using spdy::SpdySettingsIR; using spdy::SpdyStreamId; using spdy::SpdyWindowUpdateIR; -using spdy::test::TestHeadersHandler; using testing::_; using testing::AnyNumber; using testing::AtLeast; @@ -150,7 +152,7 @@ class MockVisitor : public SpdyFramerVisitorInterface { void, OnAltSvc, (SpdyStreamId stream_id, - quiche::QuicheStringPiece origin, + absl::string_view origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector), (override)); MOCK_METHOD(void, @@ -226,6 +228,9 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> { QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024); EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber()); session_.Initialize(); + connection_->SetEncrypter( + quic::ENCRYPTION_FORWARD_SECURE, + std::make_unique<quic::NullEncrypter>(connection_->perspective())); headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_); headers_[":status"] = "200 Ok"; headers_["content-length"] = "11"; @@ -271,7 +276,7 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> { return true; } - void SaveHeaderDataStringPiece(quiche::QuicheStringPiece data) { + void SaveHeaderDataStringPiece(absl::string_view data) { saved_header_data_.append(data.data(), data.length()); } @@ -290,7 +295,7 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> { } void SaveToHandler(size_t size, const QuicHeaderList& header_list) { - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); headers_handler_->OnHeaderBlockStart(); for (const auto& p : header_list) { headers_handler_->OnHeader(p.first, p.second); @@ -335,7 +340,7 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> { /*parent_stream_id=*/0, /*exclusive=*/false, fin, kFrameComplete)); } - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) .WillOnce(Return(headers_handler_.get())); EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1); @@ -386,7 +391,7 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> { StrictMock<MockQuicSpdySession> session_; QuicHeadersStream* headers_stream_; SpdyHeaderBlock headers_; - std::unique_ptr<TestHeadersHandler> headers_handler_; + std::unique_ptr<RecordingHeadersHandler> headers_handler_; std::string body_; std::string saved_data_; std::string saved_header_data_; @@ -445,7 +450,7 @@ TEST_P(QuicHeadersStreamTest, WritePushPromises) { // Parse the outgoing data and check that it matches was was written. EXPECT_CALL(visitor_, OnPushPromise(stream_id, promised_stream_id, kFrameComplete)); - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id)) .WillOnce(Return(headers_handler_.get())); EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc index 1367a953272..4f5f1cf186c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc @@ -6,13 +6,15 @@ #include <utility> +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/http_decoder.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -142,7 +144,7 @@ bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/, } bool QuicReceiveControlStream::OnDataFramePayload( - quiche::QuicheStringPiece /*payload*/) { + absl::string_view /*payload*/) { OnWrongFrame("Data"); return false; } @@ -161,7 +163,7 @@ bool QuicReceiveControlStream::OnHeadersFrameStart( } bool QuicReceiveControlStream::OnHeadersFramePayload( - quiche::QuicheStringPiece /*payload*/) { + absl::string_view /*payload*/) { OnWrongFrame("Headers"); return false; } @@ -186,7 +188,7 @@ bool QuicReceiveControlStream::OnPushPromiseFramePushId( } bool QuicReceiveControlStream::OnPushPromiseFramePayload( - quiche::QuicheStringPiece /*payload*/) { + absl::string_view /*payload*/) { OnWrongFrame("Push Promise"); return false; } @@ -214,23 +216,23 @@ bool QuicReceiveControlStream::OnPriorityUpdateFrame( } // TODO(b/147306124): Use a proper structured headers parser instead. - for (auto key_value : - quiche::QuicheTextUtils::Split(frame.priority_field_value, ',')) { - auto key_and_value = quiche::QuicheTextUtils::Split(key_value, '='); + for (absl::string_view key_value : + absl::StrSplit(frame.priority_field_value, ',')) { + std::vector<absl::string_view> key_and_value = + absl::StrSplit(key_value, '='); if (key_and_value.size() != 2) { continue; } - quiche::QuicheStringPiece key = key_and_value[0]; + absl::string_view key = key_and_value[0]; quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&key); if (key != "u") { continue; } - quiche::QuicheStringPiece value = key_and_value[1]; + absl::string_view value = key_and_value[1]; int urgency; - if (!quiche::QuicheTextUtils::StringToInt(value, &urgency) || urgency < 0 || - urgency > 7) { + if (!absl::SimpleAtoi(value, &urgency) || urgency < 0 || urgency > 7) { stream_delegate()->OnStreamError( QUIC_INVALID_STREAM_ID, "Invalid value for PRIORITY_UPDATE urgency parameter."); @@ -269,7 +271,7 @@ bool QuicReceiveControlStream::OnUnknownFrameStart( } bool QuicReceiveControlStream::OnUnknownFramePayload( - quiche::QuicheStringPiece /*payload*/) { + absl::string_view /*payload*/) { // Ignore unknown frame types. return true; } @@ -279,8 +281,7 @@ bool QuicReceiveControlStream::OnUnknownFrameEnd() { return true; } -void QuicReceiveControlStream::OnWrongFrame( - quiche::QuicheStringPiece frame_type) { +void QuicReceiveControlStream::OnWrongFrame(absl::string_view frame_type) { OnUnrecoverableError( QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM, quiche::QuicheStrCat(frame_type, " frame received on control stream")); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h index 7fd02b495f6..2654bb8e549 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h @@ -42,24 +42,24 @@ class QUIC_EXPORT_PRIVATE QuicReceiveControlStream bool OnSettingsFrame(const SettingsFrame& frame) override; bool OnDataFrameStart(QuicByteCount header_length, QuicByteCount payload_length) override; - bool OnDataFramePayload(quiche::QuicheStringPiece payload) override; + bool OnDataFramePayload(absl::string_view payload) override; bool OnDataFrameEnd() override; bool OnHeadersFrameStart(QuicByteCount header_length, QuicByteCount payload_length) override; - bool OnHeadersFramePayload(quiche::QuicheStringPiece payload) override; + bool OnHeadersFramePayload(absl::string_view payload) override; bool OnHeadersFrameEnd() override; bool OnPushPromiseFrameStart(QuicByteCount header_length) override; bool OnPushPromiseFramePushId(PushId push_id, QuicByteCount push_id_length, QuicByteCount header_block_length) override; - bool OnPushPromiseFramePayload(quiche::QuicheStringPiece payload) override; + bool OnPushPromiseFramePayload(absl::string_view payload) override; bool OnPushPromiseFrameEnd() override; bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override; bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override; bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length, QuicByteCount payload_length) override; - bool OnUnknownFramePayload(quiche::QuicheStringPiece payload) override; + bool OnUnknownFramePayload(absl::string_view payload) override; bool OnUnknownFrameEnd() override; void SetUnblocked() { sequencer()->SetUnblocked(); } @@ -67,7 +67,7 @@ class QUIC_EXPORT_PRIVATE QuicReceiveControlStream QuicSpdySession* spdy_session() { return spdy_session_; } private: - void OnWrongFrame(quiche::QuicheStringPiece frame_type); + void OnWrongFrame(absl::string_view frame_type); // False until a SETTINGS frame is received. bool settings_frame_received_; diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc index 5ee5f50e785..5a401b68019 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream_test.cc @@ -4,6 +4,8 @@ #include "net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -13,7 +15,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -96,7 +97,7 @@ class QuicReceiveControlStreamTest : public QuicTestWithParam<TestParams> { session_.transport_version(), 3); char type[] = {kControlStream}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_.OnStreamFrame(data1); receive_control_stream_ = @@ -336,7 +337,7 @@ TEST_P(QuicReceiveControlStreamTest, ConsumeUnknownFrame) { EXPECT_EQ(offset, NumBytesConsumed()); // Receive unknown frame. - std::string unknown_frame = quiche::QuicheTextUtils::HexDecode( + std::string unknown_frame = absl::HexStringToBytes( "21" // reserved frame type "03" // payload length "666f6f"); // payload "foo" @@ -365,7 +366,7 @@ TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) { offset += settings_frame.length(); // Receive unknown frame. - std::string unknown_frame = quiche::QuicheTextUtils::HexDecode( + std::string unknown_frame = absl::HexStringToBytes( "21" // reserved frame type "03" // payload length "666f6f"); // payload "foo" @@ -377,7 +378,7 @@ TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) { } TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) { - std::string cancel_push_frame = quiche::QuicheTextUtils::HexDecode( + std::string cancel_push_frame = absl::HexStringToBytes( "03" // type CANCEL_PUSH "01" // payload length "01"); // push ID @@ -396,7 +397,7 @@ TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) { } TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) { - std::string unknown_frame = quiche::QuicheTextUtils::HexDecode( + std::string unknown_frame = absl::HexStringToBytes( "21" // reserved frame type "03" // payload length "666f6f"); // payload "foo" diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc index c7f1b381799..939c32724db 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc @@ -6,6 +6,8 @@ #include <cstdint> #include <memory> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h" @@ -13,8 +15,6 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -45,10 +45,10 @@ void QuicSendControlStream::MaybeSendSettingsFrame() { QuicConnection::ScopedPacketFlusher flusher(session()->connection()); // Send the stream type on so the peer knows about this stream. char data[sizeof(kControlStream)]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(data), data); + QuicDataWriter writer(ABSL_ARRAYSIZE(data), data); writer.WriteVarInt62(kControlStream); - WriteOrBufferData(quiche::QuicheStringPiece(writer.data(), writer.length()), - false, nullptr); + WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false, + nullptr); SettingsFrame settings = settings_; // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1 @@ -72,7 +72,7 @@ void QuicSendControlStream::MaybeSendSettingsFrame() { if (spdy_session_->debug_visitor()) { spdy_session_->debug_visitor()->OnSettingsFrameSent(settings); } - WriteOrBufferData(quiche::QuicheStringPiece(buffer.get(), frame_length), + WriteOrBufferData(absl::string_view(buffer.get(), frame_length), /*fin = */ false, nullptr); settings_sent_ = true; @@ -81,7 +81,7 @@ void QuicSendControlStream::MaybeSendSettingsFrame() { // discarded. A greasing frame is added here. std::unique_ptr<char[]> grease; QuicByteCount grease_length = HttpEncoder::SerializeGreasingFrame(&grease); - WriteOrBufferData(quiche::QuicheStringPiece(grease.get(), grease_length), + WriteOrBufferData(absl::string_view(grease.get(), grease_length), /*fin = */ false, nullptr); } @@ -99,8 +99,8 @@ void QuicSendControlStream::WritePriorityUpdate( HttpEncoder::SerializePriorityUpdateFrame(priority_update, &buffer); QUIC_DVLOG(1) << "Control Stream " << id() << " is writing " << priority_update; - WriteOrBufferData(quiche::QuicheStringPiece(buffer.get(), frame_length), - false, nullptr); + WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false, + nullptr); } void QuicSendControlStream::SendMaxPushIdFrame(PushId max_push_id) { @@ -117,7 +117,7 @@ void QuicSendControlStream::SendMaxPushIdFrame(PushId max_push_id) { std::unique_ptr<char[]> buffer; QuicByteCount frame_length = HttpEncoder::SerializeMaxPushIdFrame(frame, &buffer); - WriteOrBufferData(quiche::QuicheStringPiece(buffer.get(), frame_length), + WriteOrBufferData(absl::string_view(buffer.get(), frame_length), /*fin = */ false, nullptr); } @@ -140,8 +140,8 @@ void QuicSendControlStream::SendGoAway(QuicStreamId id) { std::unique_ptr<char[]> buffer; QuicByteCount frame_length = HttpEncoder::SerializeGoAwayFrame(frame, &buffer); - WriteOrBufferData(quiche::QuicheStringPiece(buffer.get(), frame_length), - false, nullptr); + WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false, + nullptr); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc index 284708de0a0..4f1b461d0f5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream_test.cc @@ -6,11 +6,13 @@ #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -81,6 +83,9 @@ class QuicSendControlStreamTest : public QuicTestWithParam<TestParams> { void Initialize() { EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber()); session_.Initialize(); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_); QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow( session_.config(), kMinimumFlowControlSendWindow); @@ -113,7 +118,7 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) { Initialize(); testing::InSequence s; - std::string expected_write_data = quiche::QuicheTextUtils::HexDecode( + std::string expected_write_data = absl::HexStringToBytes( "00" // stream type: control stream "04" // frame type: SETTINGS frame "0b" // frame length @@ -138,7 +143,7 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) { [&writer, this](QuicStreamId /*id*/, size_t write_length, QuicStreamOffset offset, StreamSendingState /*state*/, TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) { + absl::optional<EncryptionLevel> /*level*/) { send_control_stream_->WriteStreamData(offset, write_length, &writer); return QuicConsumedData(/* bytes_consumed = */ write_length, /* fin_consumed = */ false); @@ -154,7 +159,7 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) { send_control_stream_->MaybeSendSettingsFrame(); EXPECT_EQ(expected_write_data, - quiche::QuicheStringPiece(writer.data(), writer.length())); + absl::string_view(writer.data(), writer.length())); } TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) { 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 61303de9fce..4abde4262ac 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 @@ -9,6 +9,7 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" @@ -39,7 +40,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::StrictMock; @@ -71,6 +71,11 @@ class TestServerSession : public QuicServerSessionBase { ~TestServerSession() override { DeleteConnection(); } + MOCK_METHOD(bool, + WriteControlFrame, + (const QuicFrame& frame, TransmissionType type), + (override)); + protected: QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override { if (!ShouldCreateIncomingStream(id)) { @@ -147,6 +152,9 @@ class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> { connection_ = new StrictMock<MockQuicConnection>( &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions); connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_ = std::make_unique<TestServerSession>( config_, connection_, &owner_, &stream_helper_, &crypto_config_, &compressed_certs_cache_, &memory_cache_backend_); @@ -193,7 +201,7 @@ class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> { EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1); // Expect the RESET_STREAM that is generated in response to receiving a // STOP_SENDING. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM)); session_->OnStopSendingFrame(stop_sending); @@ -237,7 +245,7 @@ TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) { // Open a stream, then reset it. // Send two bytes of payload to open it. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -249,7 +257,7 @@ TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) { if (!VersionHasIetfQuicFrames(transport_version())) { // For non-version 99, the RESET_STREAM will do the full close. // Set up expects accordingly. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedBidirectionalId(0), QUIC_RST_ACKNOWLEDGEMENT)); @@ -278,7 +286,7 @@ TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) { if (!VersionHasIetfQuicFrames(transport_version())) { // For non-version 99, the RESET_STREAM will do the full close. // Set up expects accordingly. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedBidirectionalId(0), QUIC_RST_ACKNOWLEDGEMENT)); @@ -292,7 +300,7 @@ TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) { EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); // Send two bytes of payload. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data1); // The stream should never be opened, now that the reset is received. @@ -303,9 +311,9 @@ TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) { TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) { // Send (empty) compressed headers followed by two bytes of data. QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("\1\0\0\0\0\0\0\0HT")); + absl::string_view("\1\0\0\0\0\0\0\0HT")); QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0, - quiche::QuicheStringPiece("\2\0\0\0\0\0\0\0HT")); + absl::string_view("\3\0\0\0\0\0\0\0HT")); session_->OnStreamFrame(frame1); session_->OnStreamFrame(frame2); EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -318,7 +326,7 @@ TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) { if (!VersionHasIetfQuicFrames(transport_version())) { // For non-version 99, the RESET_STREAM will do the full close. // Set up expects accordingly. - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedBidirectionalId(0), QUIC_RST_ACKNOWLEDGEMENT)); @@ -333,9 +341,9 @@ TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) { // past the reset point of stream 3. As it's a closed stream we just drop the // data on the floor, but accept the packet because it has data for stream 5. QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2, - quiche::QuicheStringPiece("TP")); + absl::string_view("TP")); QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2, - quiche::QuicheStringPiece("TP")); + absl::string_view("TP")); session_->OnStreamFrame(frame3); session_->OnStreamFrame(frame4); // The stream should never be opened, now that the reset is received. @@ -348,9 +356,6 @@ TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) { // streams. For versions other than version 99, the server accepts slightly // more than the negotiated stream limit to deal with rare cases where a // client FIN/RST is lost. - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); if (!VersionHasIetfQuicFrames(transport_version())) { @@ -387,7 +392,7 @@ TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) { // For non-version 99, QUIC responds to an attempt to exceed the stream // limit by resetting the stream. EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM)); } else { // In version 99 QUIC responds to an attempt to exceed the stream limit by @@ -403,9 +408,6 @@ TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) { // Test that the server closes the connection if a client makes too many data // streams available. The server accepts slightly more than the negotiated // stream limit to deal with rare cases where a client FIN/RST is lost. - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); const size_t kAvailableStreamLimit = @@ -512,9 +514,6 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) { QuicTagVector copt; copt.push_back(kBWRE); QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); EXPECT_TRUE( @@ -706,9 +705,6 @@ TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) { QuicTagVector copt; copt.push_back(kBWMX); QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); EXPECT_TRUE( @@ -718,9 +714,6 @@ TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) { TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) { EXPECT_FALSE( QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get())); - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); EXPECT_FALSE( @@ -736,9 +729,6 @@ TEST_P(QuicServerSessionBaseTest, TurnOffServerPush) { QuicTagVector copt; copt.push_back(kQNSP); QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); - connection_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(session_->perspective())); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_->OnConfigNegotiated(); EXPECT_FALSE(session_->server_push_enabled()); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc index c3fc0e0ff76..5444c9d9d55 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc @@ -9,6 +9,8 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" @@ -36,9 +38,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using spdy::SpdyHeaderBlock; using ::testing::_; @@ -121,6 +121,9 @@ class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> { QuicServerId(kServerHostname, kPort, false), client_crypto_config_.get(), &push_promise_index_); session_->Initialize(); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); crypto_stream_ = static_cast<QuicCryptoClientStream*>( session_->GetMutableCryptoStream()); push_promise_[":path"] = "/bar"; @@ -280,8 +283,8 @@ TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) { // Verify that no data may be send on existing streams. char data[] = "hello world"; EXPECT_QUIC_BUG( - session_->WritevData(stream->id(), QUICHE_ARRAYSIZE(data), 0, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT), + session_->WritevData(stream->id(), ABSL_ARRAYSIZE(data), 0, NO_FIN, + NOT_RETRANSMISSION, ENCRYPTION_INITIAL), "Client: Try to send data of stream"); } @@ -294,7 +297,7 @@ TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) { EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream()); // Close the stream, but without having received a FIN or a RST_STREAM - // or MAX_STREAMS (V99) and check that a new one can not be created. + // or MAX_STREAMS (IETF QUIC) and check that a new one can not be created. session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -317,7 +320,7 @@ TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) { // Check that a new one can be created. EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); if (VersionHasIetfQuicFrames(GetParam().transport_version)) { - // In V99 the stream limit increases only if we get a MAX_STREAMS + // In IETF QUIC the stream limit increases only if we get a MAX_STREAMS // frame; pretend we got one. QuicMaxStreamsFrame frame(0, 2, @@ -330,7 +333,7 @@ TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) { // Ensure that we have 2 total streams, 1 open and 1 closed. QuicStreamCount expected_stream_count = 2; EXPECT_EQ(expected_stream_count, - QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) + QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_) ->outgoing_stream_count()); } } @@ -347,7 +350,7 @@ TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) { ASSERT_NE(nullptr, stream); if (VersionHasIetfQuicFrames(GetParam().transport_version)) { - // For v99, trying to open a stream and failing due to lack + // For IETF QUIC, trying to open a stream and failing due to lack // of stream ids will result in a STREAMS_BLOCKED. Make // sure we get one. Also clear out the frame because if it's // left sitting, the later SendRstStream will not actually @@ -399,7 +402,7 @@ TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) { // Ensure that we have 2 open streams. QuicStreamCount expected_stream_count = 2; EXPECT_EQ(expected_stream_count, - QuicSessionPeer::v99_bidirectional_stream_id_manager(&*session_) + QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_) ->outgoing_stream_count()); } } @@ -448,7 +451,7 @@ TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) { connection_->transport_version(), 3); char type[] = {0x00}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_->OnStreamFrame(data1); } else { id = QuicUtils::GetHeadersStreamId(connection_->transport_version()); @@ -478,7 +481,7 @@ TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) { connection_->transport_version(), 3); char type[] = {0x00}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_->OnStreamFrame(data1); } else { id = QuicUtils::GetHeadersStreamId(connection_->transport_version()); @@ -766,6 +769,7 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) { } TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) { + CompleteCryptoHandshake(); for (size_t i = 0u; i < session_->get_max_promises(); i++) { push_promise_[":path"] = quiche::QuicheStringPrintf("/bar%zu", i); @@ -1022,7 +1026,7 @@ TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) { EXPECT_EQ(kInitialSessionFlowControlWindowForTest, session_->flow_controller()->send_window_offset()); if (session_->version().UsesHttp3()) { - auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get()); + auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get()); EXPECT_EQ(kDefaultMaxStreamsPerConnection, id_manager->max_outgoing_bidirectional_streams()); EXPECT_EQ( @@ -1055,7 +1059,7 @@ TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) { EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1, session_->flow_controller()->send_window_offset()); if (session_->version().UsesHttp3()) { - auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get()); + auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get()); auto* control_stream = QuicSpdySessionPeer::GetSendControlStream(session_.get()); EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1, diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc index f50e756d1b3..f4bbca55850 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc @@ -6,12 +6,12 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_alarm.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" using spdy::SpdyHeaderBlock; @@ -158,7 +158,7 @@ void QuicSpdyClientStream::OnBodyAvailable() { } size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin) { QuicConnection::ScopedPacketFlusher flusher(session_->connection()); bool send_fin_with_headers = fin && body.empty(); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h index dfb9270ae78..e426db7baf4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h @@ -8,9 +8,9 @@ #include <cstddef> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" namespace quic { @@ -52,7 +52,7 @@ class QUIC_NO_EXPORT QuicSpdyClientStream : public QuicSpdyStream { // Serializes the headers and body, sends it to the server, and // returns the number of bytes sent. size_t SendRequest(spdy::SpdyHeaderBlock headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin); // Returns the response data. diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc index c8653ed3129..90d4ee13e9c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc @@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -46,6 +47,11 @@ class MockQuicSpdyClientSession : public QuicSpdyClientSession { delete; ~MockQuicSpdyClientSession() override = default; + MOCK_METHOD(bool, + WriteControlFrame, + (const QuicFrame& frame, TransmissionType type), + (override)); + using QuicSession::ActivateStream; private: @@ -68,7 +74,9 @@ class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> { body_("hello world") { session_.Initialize(); connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); - + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); headers_[":status"] = "200"; headers_["content-length"] = "11"; @@ -109,7 +117,7 @@ INSTANTIATE_TEST_SUITE_P(Tests, TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) { headers_[":status"] = "200 ok"; - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD)); auto headers = AsHeaderList(headers_); @@ -200,7 +208,7 @@ TEST_P(QuicSpdyClientStreamTest, TestReceiving101) { // 101 "Switching Protocols" is forbidden in HTTP/3 as per the // "HTTP Upgrade" section of draft-ietf-quic-http. headers_[":status"] = "101"; - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD)); auto headers = AsHeaderList(headers_); @@ -246,7 +254,7 @@ TEST_P(QuicSpdyClientStreamTest, std::string data = VersionUsesHttp3(connection_->transport_version()) ? header + large_body : large_body; - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(session_, WriteControlFrame(_, _)); EXPECT_CALL(*connection_, OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD)); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc index 2e2e2ec4cda..aee50456d05 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.cc @@ -28,7 +28,11 @@ void QuicSpdyServerStreamBase::CloseWriteSide() { DCHECK(fin_sent() || !session()->connection()->connected()); // Tell the peer to stop sending further data. QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id(); - Reset(QUIC_STREAM_NO_ERROR); + if (session()->split_up_send_rst()) { + MaybeSendStopSending(QUIC_STREAM_NO_ERROR); + } else { + Reset(QUIC_STREAM_NO_ERROR); + } } QuicSpdyStream::CloseWriteSide(); @@ -40,7 +44,11 @@ void QuicSpdyServerStreamBase::StopReading() { DCHECK(fin_sent()); // Tell the peer to stop sending further data. QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id(); - Reset(QUIC_STREAM_NO_ERROR); + if (session()->split_up_send_rst()) { + MaybeSendStopSending(QUIC_STREAM_NO_ERROR); + } else { + Reset(QUIC_STREAM_NO_ERROR); + } } QuicSpdyStream::StopReading(); } diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc index 1d08da3d568..4505cd0ce50 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" @@ -33,6 +34,9 @@ class QuicSpdyServerStreamBaseTest : public QuicTest { &alarm_factory_, Perspective::IS_SERVER)) { session_.Initialize(); + session_.connection()->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(session_.perspective())); stream_ = new TestQuicSpdyServerStream(GetNthClientInitiatedBidirectionalStreamId( session_.transport_version(), 0), @@ -50,7 +54,19 @@ class QuicSpdyServerStreamBaseTest : public QuicTest { TEST_F(QuicSpdyServerStreamBaseTest, SendQuicRstStreamNoErrorWithEarlyResponse) { stream_->StopReading(); - EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(1); + + if (!session_.split_up_send_rst()) { + EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)) + .Times(1); + } else { + if (session_.version().UsesHttp3()) { + EXPECT_CALL(session_, MaybeSendStopSendingFrame(_, QUIC_STREAM_NO_ERROR)) + .Times(1); + } else { + EXPECT_CALL(session_, MaybeSendRstStreamFrame(_, QUIC_STREAM_NO_ERROR, _)) + .Times(1); + } + } QuicStreamPeer::SetFinSent(stream_); stream_->CloseWriteSide(); } @@ -61,14 +77,25 @@ TEST_F(QuicSpdyServerStreamBaseTest, EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(0); - EXPECT_CALL( - session_, - SendRstStream(_, + if (!session_.split_up_send_rst()) { + EXPECT_CALL( + session_, + SendRstStream(_, + VersionHasIetfQuicFrames(session_.transport_version()) + ? QUIC_STREAM_CANCELLED + : QUIC_RST_ACKNOWLEDGEMENT, + _, _)) + .Times(1); + } else { + EXPECT_CALL(session_, + MaybeSendRstStreamFrame( + _, VersionHasIetfQuicFrames(session_.transport_version()) ? QUIC_STREAM_CANCELLED : QUIC_RST_ACKNOWLEDGEMENT, - _, _)) - .Times(1); + _)) + .Times(1); + } QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 1234); stream_->OnStreamReset(rst_frame); 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 0f806f70bae..581a4fa79ae 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 @@ -10,6 +10,9 @@ #include <string> #include <utility> +#include "absl/base/attributes.h" +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" @@ -18,13 +21,11 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" @@ -405,7 +406,12 @@ QuicSpdySession::QuicSpdySession( ietf_server_push_enabled_( GetQuicFlag(FLAGS_quic_enable_http3_server_push)), http3_max_push_id_sent_(false), - reject_spdy_settings_(GetQuicReloadableFlag(quic_reject_spdy_settings)) { + reject_spdy_settings_(GetQuicReloadableFlag(quic_reject_spdy_settings)), + goaway_with_max_stream_id_( + GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + if (goaway_with_max_stream_id_) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_goaway_with_max_stream_id, 1, 2); + } h2_deframer_.set_visitor(spdy_framer_visitor_.get()); h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get()); spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); @@ -476,21 +482,21 @@ void QuicSpdySession::FillSettingsFrame() { max_inbound_header_list_size_; } -void QuicSpdySession::OnDecoderStreamError( - quiche::QuicheStringPiece error_message) { +void QuicSpdySession::OnDecoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) { DCHECK(VersionUsesHttp3(transport_version())); CloseConnectionWithDetails( - QUIC_QPACK_DECODER_STREAM_ERROR, + error_code, quiche::QuicheStrCat("Decoder stream error: ", error_message)); } -void QuicSpdySession::OnEncoderStreamError( - quiche::QuicheStringPiece error_message) { +void QuicSpdySession::OnEncoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) { DCHECK(VersionUsesHttp3(transport_version())); CloseConnectionWithDetails( - QUIC_QPACK_ENCODER_STREAM_ERROR, + error_code, quiche::QuicheStrCat("Encoder stream error: ", error_message)); } @@ -524,8 +530,7 @@ void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, const std::string& header_key = header.first; const std::string& header_value = header.second; if (header_key == kFinalOffsetHeaderKey) { - if (!quiche::QuicheTextUtils::StringToSizeT(header_value, - &final_byte_offset)) { + if (!absl::SimpleAtoi(header_value, &final_byte_offset)) { connection()->CloseConnection( QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed (no final offset)", @@ -646,7 +651,7 @@ size_t QuicSpdySession::WritePriority(QuicStreamId id, SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive); SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame)); headers_stream()->WriteOrBufferData( - quiche::QuicheStringPiece(frame.data(), frame.size()), false, nullptr); + absl::string_view(frame.data(), frame.size()), false, nullptr); return frame.size(); } @@ -714,26 +719,46 @@ void QuicSpdySession::SendHttp3GoAway() { DCHECK_EQ(perspective(), Perspective::IS_SERVER); DCHECK(VersionUsesHttp3(transport_version())); - QuicStreamId stream_id = - GetLargestPeerCreatedStreamId(/*unidirectional = */ false); + QuicStreamId stream_id; - if (GetQuicReloadableFlag(quic_fix_http3_goaway_stream_id)) { - QUIC_RELOADABLE_FLAG_COUNT(quic_fix_http3_goaway_stream_id); - if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) { - // No client-initiated bidirectional streams received yet. - // Send 0 to let client know that all requests can be retried. - stream_id = 0; - } else { - // Tell client that streams starting with the next after the largest - // received one can be retried. - stream_id += QuicUtils::StreamIdDelta(transport_version()); + if (goaway_with_max_stream_id_) { + stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId( + transport_version()); + if (last_sent_http3_goaway_id_.has_value()) { + if (last_sent_http3_goaway_id_.value() == stream_id) { + // Do not send GOAWAY twice. + return; + } + if (last_sent_http3_goaway_id_.value() < stream_id) { + // A previous GOAWAY frame was sent with smaller stream ID. This is not + // possible, because the only time a GOAWAY frame with non-maximal + // stream ID is sent is right before closing connection. + QUIC_BUG << "GOAWAY frame with smaller ID already sent."; + return; + } } - if (last_sent_http3_goaway_id_.has_value() && - last_sent_http3_goaway_id_.value() <= stream_id) { - // MUST not send GOAWAY with identifier larger than previously sent. - // Do not bother sending one with same identifier as before, since GOAWAY - // frames on the control stream are guaranteed to be processed in order. - return; + } else { + stream_id = GetLargestPeerCreatedStreamId(/*unidirectional = */ false); + + if (GetQuicReloadableFlag(quic_fix_http3_goaway_stream_id)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_http3_goaway_stream_id); + if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) { + // No client-initiated bidirectional streams received yet. + // Send 0 to let client know that all requests can be retried. + stream_id = 0; + } else { + // Tell client that streams starting with the next after the largest + // received one can be retried. + stream_id += QuicUtils::StreamIdDelta(transport_version()); + } + if (last_sent_http3_goaway_id_.has_value() && + last_sent_http3_goaway_id_.value() <= stream_id) { + // MUST not send GOAWAY with identifier larger than previously sent. + // Do not bother sending one with same identifier as before, since + // GOAWAY frames on the control stream are guaranteed to be processed in + // order. + return; + } } } @@ -742,6 +767,11 @@ void QuicSpdySession::SendHttp3GoAway() { } void QuicSpdySession::SendHttp3Shutdown() { + if (goaway_with_max_stream_id_) { + SendHttp3GoAway(); + return; + } + DCHECK_EQ(perspective(), Perspective::IS_SERVER); DCHECK(VersionUsesHttp3(transport_version())); QuicStreamCount advertised_max_incoming_bidirectional_streams = @@ -777,7 +807,7 @@ void QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id, SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); headers_stream()->WriteOrBufferData( - quiche::QuicheStringPiece(frame.data(), frame.size()), false, nullptr); + absl::string_view(frame.data(), frame.size()), false, nullptr); return; } @@ -903,7 +933,7 @@ size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl( } SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); headers_stream()->WriteOrBufferData( - quiche::QuicheStringPiece(frame.data(), frame.size()), false, + absl::string_view(frame.data(), frame.size()), false, std::move(ack_listener)); // Calculate compressed header block size without framing overhead. @@ -1046,11 +1076,11 @@ bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) { break; } case spdy::SETTINGS_ENABLE_PUSH: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case spdy::SETTINGS_INITIAL_WINDOW_SIZE: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case spdy::SETTINGS_MAX_FRAME_SIZE: if (reject_spdy_settings_) { CloseConnectionWithDetails( @@ -1224,9 +1254,7 @@ void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error, } bool QuicSpdySession::HasActiveRequestStreams() const { - DCHECK_GE(static_cast<size_t>(stream_map_size()), - num_static_streams() + num_zombie_streams()); - return stream_map_size() - num_static_streams() - num_zombie_streams() > 0; + return GetNumActiveStreams() + num_draining_streams() > 0; } bool QuicSpdySession::ProcessPendingStream(PendingStream* pending) { @@ -1363,6 +1391,50 @@ void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() { } } +void QuicSpdySession::BeforeConnectionCloseSent() { + if (!GetQuicReloadableFlag(quic_send_goaway_with_connection_close) || + !VersionUsesHttp3(transport_version()) || !IsEncryptionEstablished()) { + return; + } + + DCHECK_EQ(perspective(), Perspective::IS_SERVER); + + QUIC_CODE_COUNT(quic_send_goaway_with_connection_close); + + QuicStreamId stream_id = + GetLargestPeerCreatedStreamId(/*unidirectional = */ false); + + if (GetQuicReloadableFlag(quic_fix_http3_goaway_stream_id)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_http3_goaway_stream_id); + if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) { + // No client-initiated bidirectional streams received yet. + // Send 0 to let client know that all requests can be retried. + stream_id = 0; + } else { + // Tell client that streams starting with the next after the largest + // received one can be retried. + stream_id += QuicUtils::StreamIdDelta(transport_version()); + } + if (last_sent_http3_goaway_id_.has_value() && + last_sent_http3_goaway_id_.value() <= stream_id) { + if (goaway_with_max_stream_id_) { + // A previous GOAWAY frame was sent with smaller stream ID. This is not + // possible, because this is the only method sending a GOAWAY frame with + // non-maximal stream ID, and this must only be called once, right + // before closing connection. + QUIC_BUG << "GOAWAY frame with smaller ID already sent."; + } + // MUST not send GOAWAY with identifier larger than previously sent. + // Do not bother sending one with same identifier as before, since GOAWAY + // frames on the control stream are guaranteed to be processed in order. + return; + } + } + + send_control_stream_->SendGoAway(stream_id); + last_sent_http3_goaway_id_ = stream_id; +} + void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) { if (unidirectional && VersionUsesHttp3(transport_version())) { MaybeInitializeHttp3UnidirectionalStreams(); @@ -1412,7 +1484,7 @@ bool QuicSpdySession::OnMaxPushIdFrame(PushId max_push_id) { QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id << " from unset"; } - quiche::QuicheOptional<PushId> old_max_push_id = max_push_id_; + absl::optional<PushId> old_max_push_id = max_push_id_; max_push_id_ = max_push_id; if (!old_max_push_id.has_value() || max_push_id > old_max_push_id.value()) { @@ -1469,7 +1541,7 @@ bool QuicSpdySession::CanCreatePushStreamWithId(PushId push_id) { } void QuicSpdySession::CloseConnectionOnDuplicateHttp3UnidirectionalStreams( - quiche::QuicheStringPiece type) { + absl::string_view type) { QUIC_PEER_BUG << quiche::QuicheStrCat("Received a duplicate ", type, " stream: Closing connection."); CloseConnectionWithDetails( diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h index db8fc6b2df2..56719016053 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h @@ -9,6 +9,8 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/http/http_frames.h" #include "net/third_party/quiche/src/quic/core/http/quic_header_list.h" #include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h" @@ -26,8 +28,6 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" namespace quic { @@ -154,10 +154,12 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession void Initialize() override; // QpackEncoder::DecoderStreamErrorDelegate implementation. - void OnDecoderStreamError(quiche::QuicheStringPiece error_message) override; + void OnDecoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) override; // QpackDecoder::EncoderStreamErrorDelegate implementation. - void OnEncoderStreamError(quiche::QuicheStringPiece error_message) override; + void OnEncoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) override; // Called by |headers_stream_| when headers with a priority have been // received for a stream. This method will only be called for server streams. @@ -225,15 +227,14 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession // Send GOAWAY if the peer is blocked on the implementation max. bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override; - // Write GOAWAY frame on the control stream to notify the client that every - // stream that has not reached the server yet can be retried. Do not send a - // GOAWAY frame if it could not convey new information to the client with - // respect to the previous GOAWAY frame. + // Write GOAWAY frame with maximum stream ID on the control stream. Called to + // initite graceful connection shutdown. Do not use smaller stream ID, in + // case client does not implement retry on GOAWAY. Do not send GOAWAY if one + // has already been sent. void SendHttp3GoAway(); - // Write advisory GOAWAY frame on the control stream with the max stream ID - // that the client could send. If GOAWAY has already been sent, the lesser of - // its max stream ID and the one advertised via MAX_STREAMS is used. + // Same as SendHttp3GoAway(). TODO(bnc): remove when + // gfe2_reloadable_flag_quic_goaway_with_max_stream_id flag is deprecated. void SendHttp3Shutdown(); // Write |headers| for |promised_stream_id| on |original_stream_id| in a @@ -467,6 +468,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession // Initializes HTTP/3 unidirectional streams if not yet initialzed. virtual void MaybeInitializeHttp3UnidirectionalStreams(); + // QuicConnectionVisitorInterface method. + void BeforeConnectionCloseSent() override; + private: friend class test::QuicSpdySessionPeer; @@ -485,7 +489,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession const spdy::SpdyStreamPrecedence& precedence); void CloseConnectionOnDuplicateHttp3UnidirectionalStreams( - quiche::QuicheStringPiece type); + absl::string_view type); // Sends any data which should be sent at the start of a connection, including // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID @@ -564,7 +568,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession // after encryption is established, the push ID in the most recently sent // MAX_PUSH_ID frame. // Once set, never goes back to unset. - quiche::QuicheOptional<PushId> max_push_id_; + absl::optional<PushId> max_push_id_; // Not owned by the session. Http3DebugVisitor* debug_visitor_; @@ -589,10 +593,10 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession // The identifier in the most recently received GOAWAY frame. Unset if no // GOAWAY frame has been received yet. - quiche::QuicheOptional<uint64_t> last_received_http3_goaway_id_; + absl::optional<uint64_t> last_received_http3_goaway_id_; // The identifier in the most recently sent GOAWAY frame. Unset if no GOAWAY // frame has been sent yet. - quiche::QuicheOptional<uint64_t> last_sent_http3_goaway_id_; + absl::optional<uint64_t> last_sent_http3_goaway_id_; // Only used by a client, only with IETF QUIC. True if a MAX_PUSH_ID frame // has been sent, in which case |max_push_id_| has the value sent in the most @@ -601,6 +605,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession // Latched value of reloadable flag quic_reject_spdy_settings. const bool reject_spdy_settings_; + + // Latched value of reloadable flag quic_goaway_with_max_stream_id. + const bool goaway_with_max_stream_id_; }; } // namespace quic 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 6f7d85f68d2..6d93b44db60 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 @@ -10,6 +10,9 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" @@ -22,6 +25,7 @@ #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_stream.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" @@ -40,11 +44,9 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" using spdy::kV3HighestPriority; @@ -83,6 +85,13 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker { params_->cipher_suite = 1; } + void EstablishZeroRttEncryption() { + encryption_established_ = true; + session()->connection()->SetEncrypter( + ENCRYPTION_ZERO_RTT, + std::make_unique<NullEncrypter>(session()->perspective())); + } + void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override { encryption_established_ = true; one_rtt_keys_available_ = true; @@ -145,6 +154,14 @@ 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; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } const QuicCryptoNegotiatedParameters& crypto_negotiated_params() const override { return *params_; @@ -287,13 +304,12 @@ class TestSession : public QuicSpdySession { return QuicSpdySession::GetOrCreateStream(stream_id); } - QuicConsumedData WritevData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) override { + QuicConsumedData WritevData(QuicStreamId id, + size_t write_length, + QuicStreamOffset offset, + StreamSendingState state, + TransmissionType type, + absl::optional<EncryptionLevel> level) override { bool fin = state != NO_FIN; QuicConsumedData consumed(write_length, fin); if (!writev_consumes_all_data_) { @@ -319,7 +335,8 @@ class TestSession : public QuicSpdySession { MakeIOVector("not empty", &iov); QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9); QuicConsumedData consumed = - WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, QUICHE_NULLOPT); + WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, + GetEncryptionLevelToSendApplicationData()); QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed( consumed.bytes_consumed); return consumed; @@ -328,7 +345,7 @@ class TestSession : public QuicSpdySession { QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) { DCHECK(writev_consumes_all_data_); return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION, - QUICHE_NULLOPT); + GetEncryptionLevelToSendApplicationData()); } using QuicSession::closed_streams; @@ -405,7 +422,7 @@ class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> { EXPECT_CALL(*connection_, SendControlFrame(_)) .WillOnce(Invoke(&ClearControlFrame)); } else { - // V99 has two frames, RST_STREAM and STOP_SENDING + // IETF QUIC has two frames, RST_STREAM and STOP_SENDING EXPECT_CALL(*connection_, SendControlFrame(_)) .Times(2) .WillRepeatedly(Invoke(&ClearControlFrame)); @@ -564,6 +581,7 @@ TEST_P(QuicSpdySessionTestServer, AvailableStreams) { } TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id()); QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -577,6 +595,7 @@ TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) { } TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) { + CompleteHandshake(); QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0); QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1); session_.GetOrCreateStream(stream_id1); @@ -601,27 +620,29 @@ TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) { // is not the number of open streams, we allocate the max and the max+2. // Get the max allowed stream ID, this should succeed. QuicStreamId stream_id = StreamCountToId( - QuicSessionPeer::v99_streamid_manager(&session_) + QuicSessionPeer::ietf_streamid_manager(&session_) ->max_incoming_bidirectional_streams(), Perspective::IS_CLIENT, // Client initates stream, allocs stream id. /*bidirectional=*/true); EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id)); - stream_id = StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_) - ->max_incoming_unidirectional_streams(), - Perspective::IS_CLIENT, - /*bidirectional=*/false); + stream_id = + StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_) + ->max_incoming_unidirectional_streams(), + Perspective::IS_CLIENT, + /*bidirectional=*/false); EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id)); EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2); // Get the (max allowed stream ID)++. These should all fail. - stream_id = StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_) - ->max_incoming_bidirectional_streams() + - 1, - Perspective::IS_CLIENT, - /*bidirectional=*/true); + stream_id = + StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_) + ->max_incoming_bidirectional_streams() + + 1, + Perspective::IS_CLIENT, + /*bidirectional=*/true); EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id)); stream_id = - StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_) + StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_) ->max_incoming_unidirectional_streams() + 1, Perspective::IS_CLIENT, @@ -694,6 +715,7 @@ TEST_P(QuicSpdySessionTestServer, } TEST_P(QuicSpdySessionTestServer, OnCanWrite) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -851,6 +873,7 @@ TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) { } TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); InSequence s; @@ -898,6 +921,7 @@ TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) { } TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) { + CompleteHandshake(); // Drive congestion control manually in order to ensure that // application-limited signaling is handled correctly. MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; @@ -974,6 +998,7 @@ TEST_P(QuicSpdySessionTestServer, BufferedHandshake) { } TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -999,6 +1024,7 @@ TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) { TEST_P(QuicSpdySessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { + CompleteHandshake(); // Drive congestion control manually in order to ensure that // application-limited signaling is handled correctly. MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; @@ -1050,6 +1076,7 @@ TEST_P(QuicSpdySessionTestServer, } TEST_P(QuicSpdySessionTestServer, SendGoAway) { + CompleteHandshake(); if (VersionHasIetfQuicFrames(transport_version())) { // HTTP/3 GOAWAY has different semantic and thus has its own test. return; @@ -1083,17 +1110,35 @@ TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) { EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - // No client-initiated stream has been received, therefore a GOAWAY frame with - // stream ID = 0 is sent to notify the client that all requests can be retried - // on a different connection. - EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0)); + if (GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + // Send max stream id (currently 32 bits). + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc)); + } else { + // No client-initiated stream has been received, therefore a GOAWAY frame + // with stream ID = 0 is sent to notify the client that all requests can be + // retried on a different connection. + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0)); + } session_.SendHttp3GoAway(); EXPECT_TRUE(session_.goaway_sent()); + // New incoming stream is not reset. const QuicStreamId kTestStreamId = GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0); EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0); EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId)); + + // No more GOAWAY frames are sent because they could not convey new + // information to the client. + if (!GetQuicReloadableFlag(quic_fix_http3_goaway_stream_id) && + !GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + // Except when both these flags are false, in which case a second GOAWAY + // frame is sent. + EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) + .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0)); + } + session_.SendHttp3GoAway(); } TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) { @@ -1115,10 +1160,15 @@ TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) { EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - // The first stream, of kTestStreamId = 0, could already have been processed. - // A GOAWAY frame is sent to notify the client that requests starting with - // stream ID = 4 can be retried on a different connection. - EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 4)); + if (GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + // Send max stream id (currently 32 bits). + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc)); + } else { + // The first stream, of kTestStreamId = 0, could already have been + // processed. A GOAWAY frame is sent to notify the client that requests + // starting with stream ID = 4 can be retried on a different connection. + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 4)); + } session_.SendHttp3GoAway(); EXPECT_TRUE(session_.goaway_sent()); @@ -1128,6 +1178,10 @@ TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) { } TEST_P(QuicSpdySessionTestServer, SendHttp3Shutdown) { + if (GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + return; + } + if (!VersionUsesHttp3(transport_version())) { return; } @@ -1149,6 +1203,10 @@ TEST_P(QuicSpdySessionTestServer, SendHttp3Shutdown) { } TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterShutdownNotice) { + if (GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + return; + } + if (!VersionUsesHttp3(transport_version())) { return; } @@ -1173,6 +1231,7 @@ TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterShutdownNotice) { } TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) { + CompleteHandshake(); if (VersionHasIetfQuicFrames(transport_version())) { // HTTP/3 GOAWAY doesn't have such restriction. return; @@ -1256,7 +1315,7 @@ TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) { CompleteHandshake(); // Send two bytes of payload. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); @@ -1307,14 +1366,14 @@ TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) { id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_.OnStreamFrame(data1); } else { id = QuicUtils::GetHeadersStreamId(transport_version()); } // Send two bytes of payload. - QuicStreamFrame data1(id, true, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(id, true, 0, absl::string_view("HT")); EXPECT_CALL(*connection_, CloseConnection( QUIC_INVALID_STREAM_ID, "Attempt to close a static stream", @@ -1331,7 +1390,7 @@ TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) { id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_.OnStreamFrame(data1); expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM; error_message = "RESET_STREAM received for receive control stream"; @@ -1354,7 +1413,7 @@ TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) { TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) { // Send two bytes of payload. QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()), - true, 0, quiche::QuicheStringPiece("HT")); + true, 0, absl::string_view("HT")); EXPECT_CALL(*connection_, CloseConnection( QUIC_INVALID_STREAM_ID, "Received data for an invalid stream", @@ -1385,6 +1444,7 @@ TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { // Ensure that Writev consumes all the data it is given (simulate no socket // blocking). + session_.GetMutableCryptoStream()->EstablishZeroRttEncryption(); session_.set_writev_consumes_all_data(true); // Create a stream, and send enough data to make it flow control blocked. @@ -1411,9 +1471,12 @@ TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { - if (QuicVersionUsesCryptoFrames(transport_version())) { + if (QuicVersionUsesCryptoFrames(transport_version()) || + connection_->encrypted_control_frames()) { // QUIC version 47 onwards uses CRYPTO frames for the handshake, so this - // test doesn't make sense for those versions. + // test doesn't make sense for those versions. With + // use_encryption_level_context, control frames can only be sent when + // encryption gets established, do not send BLOCKED for crypto streams. return; } // Test that if the crypto stream is flow control blocked, then if the SHLO @@ -1438,7 +1501,7 @@ TEST_P(QuicSpdySessionTestServer, QuicConfig config; CryptoHandshakeMessage crypto_message; config.ToHandshakeMessage(&crypto_message, transport_version()); - crypto_stream->SendHandshakeMessage(crypto_message); + crypto_stream->SendHandshakeMessage(crypto_message, ENCRYPTION_INITIAL); char buf[1000]; QuicDataWriter writer(1000, buf, quiche::NETWORK_BYTE_ORDER); crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer); @@ -1483,6 +1546,7 @@ TEST_P(QuicSpdySessionTestServer, // Test that if the header stream is flow control blocked, then if the SHLO // contains a larger send window offset, the stream becomes unblocked. + session_.GetMutableCryptoStream()->EstablishZeroRttEncryption(); session_.set_writev_consumes_all_data(true); TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream(); EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); @@ -1599,6 +1663,7 @@ TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) { if (!VersionUsesHttp3(transport_version())) { return; } + session_.GetMutableCryptoStream()->EstablishZeroRttEncryption(); QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); @@ -1614,7 +1679,6 @@ TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) { QuicTagVector copt; copt.push_back(kIFW7); QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt); - connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); session_.OnConfigNegotiated(); EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize( @@ -1653,6 +1717,7 @@ TEST_P(QuicSpdySessionTestServer, // If a buggy/malicious peer creates too many streams that are not ended // with a FIN or RST then we send an RST to refuse streams for versions other // than version 99. In version 99 the connection gets closed. + CompleteHandshake(); const QuicStreamId kMaxStreams = 5; if (VersionHasIetfQuicFrames(transport_version())) { QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, @@ -1669,7 +1734,7 @@ TEST_P(QuicSpdySessionTestServer, // However, the stream ID manager does not assume stream 4 is for headers. // The ID manager would assume that stream#5 is streamid 24. // In order to make this all work out properly, kFinalStreamId will - // be set to GetNth...(kMaxStreams-1)... but only for V99 + // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0); const QuicStreamId kFinalStreamId = GetNthClientInitiatedBidirectionalId(kMaxStreams); @@ -1677,7 +1742,7 @@ TEST_P(QuicSpdySessionTestServer, // FIN or a RST_STREAM from the client. const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version()); for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) { - QuicStreamFrame data1(i, false, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(i, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); CloseStream(i); } @@ -1699,8 +1764,7 @@ TEST_P(QuicSpdySessionTestServer, _)); } // Create one more data streams to exceed limit of open stream. - QuicStreamFrame data1(kFinalStreamId, false, 0, - quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); } @@ -1708,6 +1772,7 @@ TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) { // Verify that a draining stream (which has received a FIN but not consumed // it) does not count against the open quota (because it is closed from the // protocol point of view). + CompleteHandshake(); if (VersionHasIetfQuicFrames(transport_version())) { // Simulate receiving a config. so that MAX_STREAMS/etc frames may // be transmitted @@ -1735,7 +1800,7 @@ TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) { const QuicStreamId kFinalStreamId = GetNthClientInitiatedBidirectionalId(kMaxStreams + 1); for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) { - QuicStreamFrame data1(i, true, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(i, true, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); session_.StreamDraining(i, /*unidirectional=*/false); @@ -1755,7 +1820,7 @@ TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) { QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - quiche::QuicheStringPiece stream_type(type, 1); + absl::string_view stream_type(type, 1); QuicStreamOffset offset = 0; QuicStreamFrame data1(stream_id, false, offset, stream_type); @@ -1893,6 +1958,7 @@ TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) { // Verify that an incoming FIN is recorded in a stream object even if the read // side has been closed. This prevents an entry from being made in // locally_closed_streams_highest_offset_ (which will never be deleted). + CompleteHandshake(); TestStream* stream = session_.CreateOutgoingBidirectionalStream(); QuicStreamId stream_id = stream->id(); @@ -1900,7 +1966,7 @@ TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) { QuicStreamPeer::CloseReadSide(stream); // Receive a stream data frame with FIN. - QuicStreamFrame frame(stream_id, true, 0, quiche::QuicheStringPiece()); + QuicStreamFrame frame(stream_id, true, 0, absl::string_view()); session_.OnStreamFrame(frame); EXPECT_TRUE(stream->fin_received()); @@ -1954,8 +2020,8 @@ TEST_P(QuicSpdySessionTestClient, WritePriority) { const QuicMemSlice& slice = QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice; - EXPECT_EQ(quiche::QuicheStringPiece(frame.data(), frame.size()), - quiche::QuicheStringPiece(slice.data(), slice.length())); + EXPECT_EQ(absl::string_view(frame.data(), frame.size()), + absl::string_view(slice.data(), slice.length())); } TEST_P(QuicSpdySessionTestClient, Http3ServerPush) { @@ -1966,7 +2032,7 @@ TEST_P(QuicSpdySessionTestClient, Http3ServerPush) { EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); // Push unidirectional stream is type 0x01. - std::string frame_type1 = quiche::QuicheTextUtils::HexDecode("01"); + std::string frame_type1 = absl::HexStringToBytes("01"); QuicStreamId stream_id1 = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0); session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false, @@ -1978,7 +2044,7 @@ TEST_P(QuicSpdySessionTestClient, Http3ServerPush) { EXPECT_EQ(1u, session_.flow_controller()->bytes_consumed()); // The same stream type can be encoded differently. - std::string frame_type2 = quiche::QuicheTextUtils::HexDecode("80000001"); + std::string frame_type2 = absl::HexStringToBytes("80000001"); QuicStreamId stream_id2 = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1); session_.OnStreamFrame(QuicStreamFrame(stream_id2, /* fin = */ false, @@ -1998,9 +2064,9 @@ TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) { EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); // Push unidirectional stream is type 0x01. - std::string frame_type = quiche::QuicheTextUtils::HexDecode("01"); + std::string frame_type = absl::HexStringToBytes("01"); // The first field of a push stream is the Push ID. - std::string push_id = quiche::QuicheTextUtils::HexDecode("4000"); + std::string push_id = absl::HexStringToBytes("4000"); QuicStreamId stream_id = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0); @@ -2022,6 +2088,7 @@ TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) { } TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) { + CompleteHandshake(); InSequence s; // Drive congestion control manually. @@ -2096,6 +2163,7 @@ TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) { TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) { // Resetting a stream will send a QPACK Stream Cancellation instruction on the // decoder stream. For simplicity, ignore writes on this stream. + CompleteHandshake(); NoopQpackStreamSenderDelegate qpack_stream_sender_delegate; if (VersionUsesHttp3(transport_version())) { session_.qpack_decoder()->set_qpack_stream_sender_delegate( @@ -2141,6 +2209,7 @@ TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) { } TEST_P(QuicSpdySessionTestServer, RetransmitFrames) { + CompleteHandshake(); MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); InSequence s; @@ -2196,7 +2265,7 @@ TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) { QuicStreamId receive_control_stream_id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - quiche::QuicheStringPiece stream_type(type, 1); + absl::string_view stream_type(type, 1); QuicStreamOffset offset = 0; QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type); offset += stream_type.length(); @@ -2228,7 +2297,7 @@ TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) { // PRIORITY_UPDATE frame arrives after stream creation. TestStream* stream1 = session_.CreateIncomingStream(stream_id1); - EXPECT_EQ(QuicStream::DefaultUrgency(), + EXPECT_EQ(QuicStream::kDefaultUrgency, stream1->precedence().spdy3_priority()); EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1)); session_.OnStreamFrame(data3); @@ -2259,10 +2328,10 @@ TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) { if (!VersionUsesHttp3(transport_version())) { return; } - + CompleteHandshake(); char input[] = {0x04, // type 'a', 'b', 'c'}; // data - quiche::QuicheStringPiece payload(input, QUICHE_ARRAYSIZE(input)); + absl::string_view payload(input, ABSL_ARRAYSIZE(input)); // This is a server test with a client-initiated unidirectional stream. QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( @@ -2311,10 +2380,10 @@ TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) { if (!VersionUsesHttp3(transport_version())) { return; } - + CompleteHandshake(); char input[] = {0x04, // type 'a', 'b', 'c'}; // data - quiche::QuicheStringPiece payload(input, QUICHE_ARRAYSIZE(input)); + absl::string_view payload(input, ABSL_ARRAYSIZE(input)); // This is a server test with a client-initiated unidirectional stream. QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( @@ -2352,10 +2421,10 @@ TEST_P(QuicSpdySessionTestServer, if (!VersionUsesHttp3(transport_version())) { return; } - + CompleteHandshake(); char input[] = {0x41, 0x00, // type (256) 'a', 'b', 'c'}; // data - quiche::QuicheStringPiece payload(input, QUICHE_ARRAYSIZE(input)); + absl::string_view payload(input, ABSL_ARRAYSIZE(input)); // This is a server test with a client-initiated unidirectional stream. QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( @@ -2406,8 +2475,7 @@ TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) { GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - QuicStreamFrame data1(stream_id, false, 0, - quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1)); EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id)); session_.OnStreamFrame(data1); EXPECT_EQ(stream_id, @@ -2418,7 +2486,7 @@ TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) { settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5; settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42; std::string data = EncodeSettings(settings); - QuicStreamFrame frame(stream_id, false, 1, quiche::QuicheStringPiece(data)); + QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data)); QpackEncoder* qpack_encoder = session_.qpack_encoder(); QpackHeaderTable* header_table = @@ -2451,9 +2519,8 @@ TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) { settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5; std::string data = EncodeSettings(settings); - QuicStreamFrame data1(stream_id, false, 1, quiche::QuicheStringPiece(data)); - QuicStreamFrame data2(stream_id, false, 0, - quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(stream_id, false, 1, absl::string_view(data)); + QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1)); session_.OnStreamFrame(data1); EXPECT_NE(5u, session_.max_outbound_header_list_size()); @@ -2466,20 +2533,20 @@ TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) { if (!VersionUsesHttp3(transport_version())) { return; } - + CompleteHandshake(); session_.qpack_decoder()->OnSetDynamicTableCapacity(1024); QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0); TestStream* stream = session_.CreateIncomingStream(stream_id); // HEADERS frame referencing first dynamic table entry. - std::string headers_payload = quiche::QuicheTextUtils::HexDecode("020080"); + std::string headers_payload = absl::HexStringToBytes("020080"); std::unique_ptr<char[]> headers_buffer; QuicByteCount headers_frame_header_length = HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(), &headers_buffer); - quiche::QuicheStringPiece headers_frame_header(headers_buffer.get(), - headers_frame_header_length); + absl::string_view headers_frame_header(headers_buffer.get(), + headers_frame_header_length); std::string headers = quiche::QuicheStrCat(headers_frame_header, headers_payload); stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers)); @@ -2508,13 +2575,13 @@ TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) { TestStream* stream = session_.CreateIncomingStream(stream_id); // HEADERS frame referencing first dynamic table entry. - std::string headers_payload = quiche::QuicheTextUtils::HexDecode("020080"); + std::string headers_payload = absl::HexStringToBytes("020080"); std::unique_ptr<char[]> headers_buffer; QuicByteCount headers_frame_header_length = HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(), &headers_buffer); - quiche::QuicheStringPiece headers_frame_header(headers_buffer.get(), - headers_frame_header_length); + absl::string_view headers_frame_header(headers_buffer.get(), + headers_frame_header_length); std::string headers = quiche::QuicheStrCat(headers_frame_header, headers_payload); stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers)); @@ -2533,6 +2600,7 @@ TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) { if (!VersionUsesHttp3(transport_version())) { return; } + CompleteHandshake(); ASSERT_TRUE(session_.UsesPendingStreams()); const QuicStreamId stream_id = @@ -2541,7 +2609,7 @@ TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) { // Payload consists of two bytes. The first byte is an unknown unidirectional // stream type. The second one would be the type of a push stream, but it // must not be interpreted as stream type. - std::string payload = quiche::QuicheTextUtils::HexDecode("3f01"); + std::string payload = absl::HexStringToBytes("3f01"); QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, payload); @@ -2579,6 +2647,7 @@ TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) { if (!VersionUsesHttp3(transport_version())) { return; } + CompleteHandshake(); ASSERT_TRUE(session_.UsesPendingStreams()); const QuicStreamId stream_id = @@ -2587,7 +2656,7 @@ TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) { // Payload consists of two bytes. The first byte is an unknown unidirectional // stream type. The second one would be the type of a push stream, but it // must not be interpreted as stream type. - std::string payload = quiche::QuicheTextUtils::HexDecode("3f01"); + std::string payload = absl::HexStringToBytes("3f01"); QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, payload); @@ -2624,7 +2693,7 @@ TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) { GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0); // Payload is the first byte of a two byte varint encoding. - std::string payload = quiche::QuicheTextUtils::HexDecode("40"); + std::string payload = absl::HexStringToBytes("40"); QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, payload); @@ -2652,7 +2721,7 @@ TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) { GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0); // Payload is the first byte of a two byte varint encoding with a FIN. - std::string payload = quiche::QuicheTextUtils::HexDecode("40"); + std::string payload = absl::HexStringToBytes("40"); QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload); session_.OnStreamFrame(frame); @@ -2671,12 +2740,12 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) { GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0); char type1[] = {kControlStream}; - QuicStreamFrame data1(id1, false, 0, quiche::QuicheStringPiece(type1, 1)); + QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1)); EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1)); session_.OnStreamFrame(data1); QuicStreamId id2 = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1); - QuicStreamFrame data2(id2, false, 0, quiche::QuicheStringPiece(type1, 1)); + QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1)); EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0); EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM, @@ -2689,13 +2758,13 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) { GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2); char type2[]{kQpackEncoderStream}; - QuicStreamFrame data3(id3, false, 0, quiche::QuicheStringPiece(type2, 1)); + QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1)); EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3)); session_.OnStreamFrame(data3); QuicStreamId id4 = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3); - QuicStreamFrame data4(id4, false, 0, quiche::QuicheStringPiece(type2, 1)); + QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1)); EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0); EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM, @@ -2708,13 +2777,13 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) { GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4); char type3[]{kQpackDecoderStream}; - QuicStreamFrame data5(id5, false, 0, quiche::QuicheStringPiece(type3, 1)); + QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1)); EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5)); session_.OnStreamFrame(data5); QuicStreamId id6 = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5); - QuicStreamFrame data6(id6, false, 0, quiche::QuicheStringPiece(type3, 1)); + QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1)); EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0); EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM, @@ -2729,7 +2798,7 @@ TEST_P(QuicSpdySessionTestClient, EncoderStreamError) { return; } - std::string data = quiche::QuicheTextUtils::HexDecode( + std::string data = absl::HexStringToBytes( "02" // Encoder stream. "00"); // Duplicate entry 0, but no entries exist. @@ -2740,8 +2809,11 @@ TEST_P(QuicSpdySessionTestClient, EncoderStreamError) { EXPECT_CALL( *connection_, - CloseConnection(QUIC_QPACK_ENCODER_STREAM_ERROR, - "Encoder stream error: Invalid relative index.", _)); + CloseConnection( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX + : QUIC_QPACK_ENCODER_STREAM_ERROR, + "Encoder stream error: Invalid relative index.", _)); session_.OnStreamFrame(frame); } @@ -2750,7 +2822,7 @@ TEST_P(QuicSpdySessionTestClient, DecoderStreamError) { return; } - std::string data = quiche::QuicheTextUtils::HexDecode( + std::string data = absl::HexStringToBytes( "03" // Decoder stream. "00"); // Insert Count Increment with forbidden increment value of zero. @@ -2761,7 +2833,9 @@ TEST_P(QuicSpdySessionTestClient, DecoderStreamError) { EXPECT_CALL( *connection_, - CloseConnection(QUIC_QPACK_DECODER_STREAM_ERROR, + CloseConnection(GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT + : QUIC_QPACK_DECODER_STREAM_ERROR, "Decoder stream error: Invalid increment value 0.", _)); session_.OnStreamFrame(frame); } @@ -2815,7 +2889,7 @@ TEST_P(QuicSpdySessionTestClient, IgnoreCancelPush) { QuicStreamId receive_control_stream_id = GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - quiche::QuicheStringPiece stream_type(type, 1); + absl::string_view stream_type(type, 1); QuicStreamOffset offset = 0; QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset, stream_type); @@ -2839,7 +2913,7 @@ TEST_P(QuicSpdySessionTestClient, IgnoreCancelPush) { auto frame_length = HttpEncoder::SerializeCancelPushFrame(cancel_push, &buffer); QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset, - quiche::QuicheStringPiece(buffer.get(), frame_length)); + absl::string_view(buffer.get(), frame_length)); EXPECT_CALL(debug_visitor, OnCancelPushFrameReceived(_)); session_.OnStreamFrame(data3); } @@ -2903,7 +2977,7 @@ TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) { // Index 126 does not exist (static table has 61 entries and dynamic table is // empty). - std::string headers_frame = quiche::QuicheTextUtils::HexDecode( + std::string headers_frame = absl::HexStringToBytes( "000006" // length "01" // type "24" // flags: PRIORITY | END_HEADERS @@ -2936,13 +3010,12 @@ TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) { {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"}, {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"}, }; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) { QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1); const QuicByteCount data_length = 1; - QuicStreamFrame data( - stream_id, false, 0, - quiche::QuicheStringPiece(&kTestData[i].type, data_length)); + QuicStreamFrame data(stream_id, false, 0, + absl::string_view(&kTestData[i].type, data_length)); session_.OnStreamFrame(data); EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, @@ -3027,7 +3100,7 @@ TEST_P(QuicSpdySessionTestServer, IgnoreCancelPush) { QuicStreamId receive_control_stream_id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); char type[] = {kControlStream}; - quiche::QuicheStringPiece stream_type(type, 1); + absl::string_view stream_type(type, 1); QuicStreamOffset offset = 0; QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset, stream_type); @@ -3051,11 +3124,68 @@ TEST_P(QuicSpdySessionTestServer, IgnoreCancelPush) { auto frame_length = HttpEncoder::SerializeCancelPushFrame(cancel_push, &buffer); QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset, - quiche::QuicheStringPiece(buffer.get(), frame_length)); + absl::string_view(buffer.get(), frame_length)); EXPECT_CALL(debug_visitor, OnCancelPushFrameReceived(_)); session_.OnStreamFrame(data3); } +TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) { + if (!VersionUsesHttp3(transport_version())) { + return; + } + + StrictMock<MockHttp3DebugVisitor> debug_visitor; + session_.set_debug_visitor(&debug_visitor); + + EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_)); + CompleteHandshake(); + + QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0); + + // Create stream by receiving some data (CreateIncomingStream() would not + // update the session's largest peer created stream ID). + const size_t headers_payload_length = 10; + std::unique_ptr<char[]> headers_buffer; + QuicByteCount headers_frame_header_length = + HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length, + &headers_buffer); + absl::string_view headers_frame_header(headers_buffer.get(), + headers_frame_header_length); + EXPECT_CALL(debug_visitor, + OnHeadersFrameReceived(stream_id, headers_payload_length)); + session_.OnStreamFrame( + QuicStreamFrame(stream_id, false, 0, headers_frame_header)); + + EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId( + &session_, /*unidirectional = */ false)); + + if (GetQuicReloadableFlag(quic_send_goaway_with_connection_close)) { + if (GetQuicReloadableFlag(quic_fix_http3_goaway_stream_id)) { + // Stream with stream_id is already received and potentially processed, + // therefore a GOAWAY frame is sent with the next stream ID. + EXPECT_CALL(debug_visitor, + OnGoAwayFrameSent(stream_id + QuicUtils::StreamIdDelta( + transport_version()))); + } else { + // GOAWAY frame stream id is incorrect, ignore. + EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_)); + } + } + + // Close connection. + EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) + .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0))); + EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _)) + .WillOnce( + Invoke(connection_, &MockQuicConnection::ReallyCloseConnection)); + EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _)) + .WillOnce(Invoke(connection_, + &MockQuicConnection::ReallySendConnectionClosePacket)); + connection_->CloseConnection( + QUIC_NO_ERROR, "closing connection", + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); +} + TEST_P(QuicSpdySessionTestClient, SendInitialMaxPushIdIfSet) { if (!VersionUsesHttp3(transport_version())) { return; 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 1c5f9645822..7059fc0dee7 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 @@ -8,6 +8,9 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/http/http_decoder.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h" @@ -22,8 +25,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" @@ -74,7 +75,7 @@ class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor { return stream_->OnDataFrameStart(header_length, payload_length); } - bool OnDataFramePayload(quiche::QuicheStringPiece payload) override { + bool OnDataFramePayload(absl::string_view payload) override { DCHECK(!payload.empty()); return stream_->OnDataFramePayload(payload); } @@ -90,7 +91,7 @@ class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor { return stream_->OnHeadersFrameStart(header_length, payload_length); } - bool OnHeadersFramePayload(quiche::QuicheStringPiece payload) override { + bool OnHeadersFramePayload(absl::string_view payload) override { DCHECK(!payload.empty()); if (!VersionUsesHttp3(stream_->transport_version())) { CloseConnectionOnWrongFrame("Headers"); @@ -126,7 +127,7 @@ class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor { header_block_length); } - bool OnPushPromiseFramePayload(quiche::QuicheStringPiece payload) override { + bool OnPushPromiseFramePayload(absl::string_view payload) override { DCHECK(!payload.empty()); if (!VersionUsesHttp3(stream_->transport_version())) { CloseConnectionOnWrongFrame("Push Promise"); @@ -160,14 +161,14 @@ class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor { payload_length); } - bool OnUnknownFramePayload(quiche::QuicheStringPiece payload) override { + bool OnUnknownFramePayload(absl::string_view payload) override { return stream_->OnUnknownFramePayload(payload); } bool OnUnknownFrameEnd() override { return stream_->OnUnknownFrameEnd(); } private: - void CloseConnectionOnWrongFrame(quiche::QuicheStringPiece frame_type) { + void CloseConnectionOnWrongFrame(absl::string_view frame_type) { stream_->OnUnrecoverableError( QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, quiche::QuicheStrCat(frame_type, " frame received on data stream")); @@ -199,7 +200,7 @@ QuicSpdyStream::QuicSpdyStream(QuicStreamId id, sequencer_offset_(0), is_decoder_processing_input_(false), ack_listener_(nullptr), - last_sent_urgency_(DefaultUrgency()) { + last_sent_urgency_(kDefaultUrgency) { DCHECK_EQ(session()->connection(), spdy_session->connection()); DCHECK_EQ(transport_version(), spdy_session->transport_version()); DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id)); @@ -235,7 +236,7 @@ QuicSpdyStream::QuicSpdyStream(PendingStream* pending, sequencer_offset_(sequencer()->NumBytesConsumed()), is_decoder_processing_input_(false), ack_listener_(nullptr), - last_sent_urgency_(DefaultUrgency()) { + last_sent_urgency_(kDefaultUrgency) { DCHECK_EQ(session()->connection(), spdy_session->connection()); DCHECK_EQ(transport_version(), spdy_session->transport_version()); DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id())); @@ -263,7 +264,7 @@ size_t QuicSpdyStream::WriteHeaders( if (VersionUsesHttp3(transport_version()) && type() == WRITE_UNIDIRECTIONAL && send_buffer().stream_offset() == 0) { char data[sizeof(kServerPushStream)]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(data), data); + QuicDataWriter writer(ABSL_ARRAYSIZE(data), data); writer.WriteVarInt62(kServerPushStream); // Similar to frame headers, stream type byte shouldn't be exposed to upper @@ -272,8 +273,8 @@ size_t QuicSpdyStream::WriteHeaders( QUIC_LOG(INFO) << ENDPOINT << "Stream " << id() << " is writing type as server push"; - WriteOrBufferData(quiche::QuicheStringPiece(writer.data(), writer.length()), - false, nullptr); + WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false, + nullptr); } size_t bytes_written = @@ -289,8 +290,7 @@ size_t QuicSpdyStream::WriteHeaders( return bytes_written; } -void QuicSpdyStream::WriteOrBufferBody(quiche::QuicheStringPiece data, - bool fin) { +void QuicSpdyStream::WriteOrBufferBody(absl::string_view data, bool fin) { if (!VersionUsesHttp3(transport_version()) || data.length() == 0) { WriteOrBufferData(data, fin, nullptr); return; @@ -311,8 +311,8 @@ void QuicSpdyStream::WriteOrBufferBody(quiche::QuicheStringPiece data, QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " is writing DATA frame header of length " << header_length; - WriteOrBufferData(quiche::QuicheStringPiece(buffer.get(), header_length), - false, nullptr); + WriteOrBufferData(absl::string_view(buffer.get(), header_length), false, + nullptr); // Write body. QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() @@ -379,8 +379,8 @@ void QuicSpdyStream::WritePushPromise(const PushPromiseFrame& frame) { << " is writing Push Promise frame header of length " << push_promise_frame_length << " , with promised id " << frame.push_id; - WriteOrBufferData(quiche::QuicheStringPiece(push_promise_frame_with_id.get(), - push_promise_frame_length), + WriteOrBufferData(absl::string_view(push_promise_frame_with_id.get(), + push_promise_frame_length), /* fin = */ false, /* ack_listener = */ nullptr); // Write response headers. @@ -594,8 +594,7 @@ void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers, } } -void QuicSpdyStream::OnHeaderDecodingError( - quiche::QuicheStringPiece error_message) { +void QuicSpdyStream::OnHeaderDecodingError(absl::string_view error_message) { qpack_decoded_headers_accumulator_.reset(); std::string connection_close_error_message = quiche::QuicheStrCat( @@ -641,14 +640,14 @@ void QuicSpdyStream::OnInitialHeadersComplete( if (fin) { OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true, highest_received_byte_offset(), - quiche::QuicheStringPiece())); + absl::string_view())); } return; } if (fin && !rst_sent()) { - OnStreamFrame(QuicStreamFrame(id(), fin, /* offset = */ 0, - quiche::QuicheStringPiece())); + OnStreamFrame( + QuicStreamFrame(id(), fin, /* offset = */ 0, absl::string_view())); } if (FinishedReadingHeaders()) { sequencer()->SetUnblocked(); @@ -703,8 +702,7 @@ void QuicSpdyStream::OnTrailingHeadersComplete( const QuicStreamOffset offset = VersionUsesHttp3(transport_version()) ? highest_received_byte_offset() : final_byte_offset; - OnStreamFrame( - QuicStreamFrame(id(), fin, offset, quiche::QuicheStringPiece())); + OnStreamFrame(QuicStreamFrame(id(), fin, offset, absl::string_view())); } } @@ -835,7 +833,7 @@ bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header, if (it == header.end()) { return false; } - const quiche::QuicheStringPiece status(it->second); + const absl::string_view status(it->second); if (status.size() != 3) { return false; } @@ -847,7 +845,7 @@ bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header, if (!isdigit(status[1]) || !isdigit(status[2])) { return false; } - return quiche::QuicheTextUtils::StringToInt(status, status_code); + return absl::SimpleAtoi(status, status_code); } bool QuicSpdyStream::FinishedReadingTrailers() const { @@ -886,7 +884,7 @@ bool QuicSpdyStream::OnDataFrameStart(QuicByteCount header_length, return true; } -bool QuicSpdyStream::OnDataFramePayload(quiche::QuicheStringPiece payload) { +bool QuicSpdyStream::OnDataFramePayload(absl::string_view payload) { DCHECK(VersionUsesHttp3(transport_version())); body_manager_.OnBody(payload); @@ -981,7 +979,7 @@ bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length, return true; } -bool QuicSpdyStream::OnHeadersFramePayload(quiche::QuicheStringPiece payload) { +bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) { DCHECK(VersionUsesHttp3(transport_version())); DCHECK(qpack_decoded_headers_accumulator_); @@ -1045,8 +1043,7 @@ bool QuicSpdyStream::OnPushPromiseFramePushId( return true; } -bool QuicSpdyStream::OnPushPromiseFramePayload( - quiche::QuicheStringPiece payload) { +bool QuicSpdyStream::OnPushPromiseFramePayload(absl::string_view payload) { spdy_session_->OnCompressedFrameSize(payload.length()); return OnHeadersFramePayload(payload); } @@ -1073,7 +1070,7 @@ bool QuicSpdyStream::OnUnknownFrameStart(uint64_t frame_type, return true; } -bool QuicSpdyStream::OnUnknownFramePayload(quiche::QuicheStringPiece payload) { +bool QuicSpdyStream::OnUnknownFramePayload(absl::string_view payload) { // Ignore unknown frames, but consume frame payload. QUIC_DVLOG(1) << ENDPOINT << "Discarding " << payload.size() << " bytes of payload of frame of unknown type."; @@ -1117,8 +1114,8 @@ size_t QuicSpdyStream::WriteHeadersImpl( QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " is writing HEADERS frame header of length " << headers_frame_header_length; - WriteOrBufferData(quiche::QuicheStringPiece(headers_frame_header.get(), - headers_frame_header_length), + WriteOrBufferData(absl::string_view(headers_frame_header.get(), + headers_frame_header_length), /* fin = */ false, /* ack_listener = */ nullptr); QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() 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 5a58842e1f8..c460b6e5512 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 @@ -15,6 +15,7 @@ #include <list> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/http_decoder.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" #include "net/third_party/quiche/src/quic/core/http/quic_header_list.h" @@ -26,7 +27,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" namespace quic { @@ -122,7 +122,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); // Sends |data| to the peer, or buffers if it can't be sent immediately. - void WriteOrBufferBody(quiche::QuicheStringPiece data, bool fin); + void WriteOrBufferBody(absl::string_view data, bool fin); // Writes the trailers contained in |trailer_block| on the dedicated headers // stream or on this stream, depending on VersionUsesHttp3(). Trailers will @@ -220,7 +220,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream // QpackDecodedHeadersAccumulator::Visitor implementation. void OnHeadersDecoded(QuicHeaderList headers, bool header_list_size_limit_exceeded) override; - void OnHeaderDecodingError(quiche::QuicheStringPiece error_message) override; + void OnHeaderDecodingError(absl::string_view error_message) override; QuicSpdySession* spdy_session() const { return spdy_session_; } @@ -262,22 +262,22 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream // Called by HttpDecoderVisitor. bool OnDataFrameStart(QuicByteCount header_length, QuicByteCount payload_length); - bool OnDataFramePayload(quiche::QuicheStringPiece payload); + bool OnDataFramePayload(absl::string_view payload); bool OnDataFrameEnd(); bool OnHeadersFrameStart(QuicByteCount header_length, QuicByteCount payload_length); - bool OnHeadersFramePayload(quiche::QuicheStringPiece payload); + bool OnHeadersFramePayload(absl::string_view payload); bool OnHeadersFrameEnd(); bool OnPushPromiseFrameStart(QuicByteCount header_length); bool OnPushPromiseFramePushId(PushId push_id, QuicByteCount push_id_length, QuicByteCount header_block_length); - bool OnPushPromiseFramePayload(quiche::QuicheStringPiece payload); + bool OnPushPromiseFramePayload(absl::string_view payload); bool OnPushPromiseFrameEnd(); bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length, QuicByteCount payload_length); - bool OnUnknownFramePayload(quiche::QuicheStringPiece payload); + bool OnUnknownFramePayload(absl::string_view payload); bool OnUnknownFrameEnd(); // Given the interval marked by [|offset|, |offset| + |data_length|), return diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc index 1e36aa70af9..83af51d0208 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.cc @@ -6,8 +6,8 @@ #include <algorithm> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -28,7 +28,7 @@ size_t QuicSpdyStreamBodyManager::OnNonBody(QuicByteCount length) { return 0; } -void QuicSpdyStreamBodyManager::OnBody(quiche::QuicheStringPiece body) { +void QuicSpdyStreamBodyManager::OnBody(absl::string_view body) { DCHECK(!body.empty()); fragments_.push_back({body, 0}); @@ -46,7 +46,7 @@ size_t QuicSpdyStreamBodyManager::OnBodyConsumed(size_t num_bytes) { } Fragment& fragment = fragments_.front(); - const quiche::QuicheStringPiece body = fragment.body; + const absl::string_view body = fragment.body; if (body.length() > remaining_bytes) { // Consume leading |remaining_bytes| bytes of body. @@ -78,7 +78,7 @@ int QuicSpdyStreamBodyManager::PeekBody(iovec* iov, size_t iov_len) const { size_t iov_filled = 0; while (iov_filled < fragments_.size() && iov_filled < iov_len) { - quiche::QuicheStringPiece body = fragments_[iov_filled].body; + absl::string_view body = fragments_[iov_filled].body; iov[iov_filled].iov_base = const_cast<char*>(body.data()); iov[iov_filled].iov_len = body.size(); iov_filled++; @@ -102,7 +102,7 @@ size_t QuicSpdyStreamBodyManager::ReadBody(const struct iovec* iov, while (!fragments_.empty()) { Fragment& fragment = fragments_.front(); - const quiche::QuicheStringPiece body = fragment.body; + const absl::string_view body = fragment.body; const size_t bytes_to_copy = std::min<size_t>(body.length(), dest_remaining); diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h index a5afecaa5e7..5e73ac7829c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h @@ -5,13 +5,13 @@ #ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ #define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_iovec.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -38,18 +38,18 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager { // sequencer (provided that all previous body fragments are consumed) is // received. |length| must be positive. Returns number of bytes the caller // must mark consumed, which might be zero. - QUIC_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length); + ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length); // Called when body is received. |body| is added to |fragments_|. The data // pointed to by |body| must be kept alive until an OnBodyConsumed() or // ReadBody() call consumes it. |body| must not be empty. - void OnBody(quiche::QuicheStringPiece body); + void OnBody(absl::string_view body); // Internally marks |num_bytes| of body consumed. |num_bytes| might be zero. // Returns the number of bytes that the caller should mark consumed with the // sequencer, which is the sum of |num_bytes| for body, and the number of any // interleaving or immediately trailing non-body bytes. - QUIC_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes); + ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes); // Set up to |iov_len| elements of iov[] to point to available bodies: each // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be @@ -63,7 +63,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager { // preassigned and will not be changed. Returns the total number of bytes the // caller shall mark consumed. Sets |*total_bytes_read| to the total number // of body bytes read. - QUIC_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov, + ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov, size_t iov_len, size_t* total_bytes_read); @@ -79,7 +79,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager { // consumed as soon as all of the body fragment is read. struct QUIC_EXPORT_PRIVATE Fragment { // |body| must not be empty. - quiche::QuicheStringPiece body; + absl::string_view body; // Might be zero. QuicByteCount trailing_non_body_byte_count; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc index 0cdc65af3b1..aaa8cce8007 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager_test.cc @@ -8,11 +8,11 @@ #include <numeric> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -75,7 +75,7 @@ TEST_F(QuicSpdyStreamBodyManagerTest, OnBodyConsumed) { }; for (size_t test_case_index = 0; - test_case_index < QUICHE_ARRAYSIZE(kOnBodyConsumedTestData); + test_case_index < ABSL_ARRAYSIZE(kOnBodyConsumedTestData); ++test_case_index) { const std::vector<QuicByteCount>& frame_header_lengths = kOnBodyConsumedTestData[test_case_index].frame_header_lengths; @@ -127,8 +127,7 @@ TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) { }; for (size_t test_case_index = 0; - test_case_index < QUICHE_ARRAYSIZE(kPeekBodyTestData); - ++test_case_index) { + test_case_index < ABSL_ARRAYSIZE(kPeekBodyTestData); ++test_case_index) { const std::vector<QuicByteCount>& frame_header_lengths = kPeekBodyTestData[test_case_index].frame_header_lengths; const std::vector<const char*>& frame_payloads = @@ -154,7 +153,7 @@ TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) { static_cast<size_t>(body_manager.PeekBody(&iovecs[0], iov_len))); for (size_t iovec_index = 0; iovec_index < iovs_filled; ++iovec_index) { EXPECT_EQ(frame_payloads[iovec_index], - quiche::QuicheStringPiece( + absl::string_view( static_cast<const char*>(iovecs[iovec_index].iov_base), iovecs[iovec_index].iov_len)); } @@ -221,8 +220,7 @@ TEST_F(QuicSpdyStreamBodyManagerTest, ReadBody) { }; for (size_t test_case_index = 0; - test_case_index < QUICHE_ARRAYSIZE(kReadBodyTestData); - ++test_case_index) { + test_case_index < ABSL_ARRAYSIZE(kReadBodyTestData); ++test_case_index) { const std::vector<QuicByteCount>& frame_header_lengths = kReadBodyTestData[test_case_index].frame_header_lengths; const std::vector<const char*>& frame_payloads = 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 1c55c96af0b..526b987b7ed 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 @@ -9,6 +9,9 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" @@ -30,8 +33,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using spdy::kV3HighestPriority; @@ -133,6 +134,14 @@ 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; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } const QuicCryptoNegotiatedParameters& crypto_negotiated_params() const override { return *params_; @@ -182,7 +191,7 @@ class TestStream : public QuicSpdyStream { char buffer[2048]; struct iovec vec; vec.iov_base = buffer; - vec.iov_len = QUICHE_ARRAYSIZE(buffer); + vec.iov_len = ABSL_ARRAYSIZE(buffer); size_t bytes_read = Readv(&vec, 1); data_ += std::string(buffer, bytes_read); } @@ -307,8 +316,7 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> { // Return QPACK-encoded header block without using the dynamic table. std::string EncodeQpackHeaders( - std::vector<std::pair<quiche::QuicheStringPiece, - quiche::QuicheStringPiece>> headers) { + std::vector<std::pair<absl::string_view, absl::string_view>> headers) { SpdyHeaderBlock header_block; for (const auto& header_field : headers) { header_block.AppendValueOrAddHeader(header_field.first, @@ -408,8 +416,7 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> { // Construct HEADERS frame with QPACK-encoded |headers| without using the // dynamic table. std::string HeadersFrame( - std::vector<std::pair<quiche::QuicheStringPiece, - quiche::QuicheStringPiece>> headers) { + std::vector<std::pair<absl::string_view, absl::string_view>> headers) { return HeadersFrame(EncodeQpackHeaders(headers)); } @@ -420,19 +427,19 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> { } // Construct HEADERS frame with given payload. - std::string HeadersFrame(quiche::QuicheStringPiece payload) { + std::string HeadersFrame(absl::string_view payload) { std::unique_ptr<char[]> headers_buffer; QuicByteCount headers_frame_header_length = HttpEncoder::SerializeHeadersFrameHeader(payload.length(), &headers_buffer); - quiche::QuicheStringPiece headers_frame_header(headers_buffer.get(), - headers_frame_header_length); + absl::string_view headers_frame_header(headers_buffer.get(), + headers_frame_header_length); return quiche::QuicheStrCat(headers_frame_header, payload); } // Construct PUSH_PROMISE frame with given payload. std::string SerializePushPromiseFrame(PushId push_id, - quiche::QuicheStringPiece payload) { + absl::string_view payload) { PushPromiseFrame frame; frame.push_id = push_id; frame.headers = payload; @@ -440,22 +447,21 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> { QuicByteCount push_promise_frame_header_length = HttpEncoder::SerializePushPromiseFrameWithOnlyPushId( frame, &push_promise_buffer); - quiche::QuicheStringPiece push_promise_frame_header( + absl::string_view push_promise_frame_header( push_promise_buffer.get(), push_promise_frame_header_length); return quiche::QuicheStrCat(push_promise_frame_header, payload); } - std::string DataFrame(quiche::QuicheStringPiece payload) { + std::string DataFrame(absl::string_view payload) { std::unique_ptr<char[]> data_buffer; QuicByteCount data_frame_header_length = HttpEncoder::SerializeDataFrameHeader(payload.length(), &data_buffer); - quiche::QuicheStringPiece data_frame_header(data_buffer.get(), - data_frame_header_length); + absl::string_view data_frame_header(data_buffer.get(), + data_frame_header_length); return quiche::QuicheStrCat(data_frame_header, payload); } - std::string UnknownFrame(uint64_t frame_type, - quiche::QuicheStringPiece payload) { + std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) { std::string frame; const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) + QuicDataWriter::GetVarInt62Len(payload.size()) + @@ -509,8 +515,13 @@ TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) { stream_->OnStreamHeadersPriority( spdy::SpdyStreamPrecedence(kV3HighestPriority)); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0, _)); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame( + stream_->id(), QUIC_HEADERS_TOO_LARGE, 0)); + } stream_->OnStreamHeaderList(false, 1 << 20, headers); EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE)); @@ -525,8 +536,15 @@ TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) { QuicStreamFrame frame(stream_->id(), false, 0, headers); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0, _)); + } else { + EXPECT_CALL(*session_, MaybeSendStopSendingFrame(stream_->id(), + QUIC_HEADERS_TOO_LARGE)); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), + QUIC_HEADERS_TOO_LARGE, 0)); + } auto qpack_decoder_stream = QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get()); @@ -646,7 +664,7 @@ TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) { EXPECT_EQ(headers, stream_->header_list()); stream_->ConsumeHeaderList(); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _)) @@ -662,8 +680,11 @@ TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) { ConnectionCloseSource source) { session_->ReallyOnConnectionClosed(frame, source); })); - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)); - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(_, _, _, _)).Times(2); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2); + } stream_->OnStreamFrame(frame); } @@ -676,7 +697,7 @@ TEST_P(QuicSpdyStreamTest, Http3FrameError) { Initialize(kShouldProcessData); // PUSH_PROMISE frame with empty payload is considered invalid. - std::string invalid_http3_frame = quiche::QuicheTextUtils::HexDecode("0500"); + std::string invalid_http3_frame = absl::HexStringToBytes("0500"); QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false, /* offset = */ 0, invalid_http3_frame); @@ -692,7 +713,7 @@ TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) { Initialize(kShouldProcessData); // SETTINGS frame with empty payload. - std::string settings = quiche::QuicheTextUtils::HexDecode("0400"); + std::string settings = absl::HexStringToBytes("0400"); QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false, /* offset = */ 0, settings); @@ -712,7 +733,7 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { EXPECT_EQ(headers, stream_->header_list()); stream_->ConsumeHeaderList(); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); EXPECT_EQ(QuicHeaderList(), stream_->header_list()); EXPECT_EQ(body, stream_->data()); @@ -729,10 +750,10 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { stream_->ConsumeHeaderList(); for (size_t offset = 0; offset < data.size(); offset += fragment_size) { size_t remaining_data = data.size() - offset; - quiche::QuicheStringPiece fragment( - data.data() + offset, std::min(fragment_size, remaining_data)); + absl::string_view fragment(data.data() + offset, + std::min(fragment_size, remaining_data)); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, - offset, quiche::QuicheStringPiece(fragment)); + offset, absl::string_view(fragment)); stream_->OnStreamFrame(frame); } ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; @@ -749,15 +770,15 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { ASSERT_EQ(headers, stream_->header_list()); stream_->ConsumeHeaderList(); - quiche::QuicheStringPiece fragment1(data.data(), split_point); + absl::string_view fragment1(data.data(), split_point); QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(fragment1)); + absl::string_view(fragment1)); stream_->OnStreamFrame(frame1); - quiche::QuicheStringPiece fragment2(data.data() + split_point, - data.size() - split_point); + absl::string_view fragment2(data.data() + split_point, + data.size() - split_point); QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false, - split_point, quiche::QuicheStringPiece(fragment2)); + split_point, absl::string_view(fragment2)); stream_->OnStreamFrame(frame2); ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; @@ -772,15 +793,15 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { ProcessHeaders(false, headers_); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); stream_->ConsumeHeaderList(); char buffer[2048]; - ASSERT_LT(data.length(), QUICHE_ARRAYSIZE(buffer)); + ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer)); struct iovec vec; vec.iov_base = buffer; - vec.iov_len = QUICHE_ARRAYSIZE(buffer); + vec.iov_len = ABSL_ARRAYSIZE(buffer); size_t bytes_read = stream_->Readv(&vec, 1); QuicStreamPeer::CloseReadSide(stream_); @@ -795,16 +816,16 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) { ProcessHeaders(false, headers_); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); stream_->ConsumeHeaderList(); char buffer[2048]; char buffer2[2048]; struct iovec vec[2]; vec[0].iov_base = buffer; - vec[0].iov_len = QUICHE_ARRAYSIZE(buffer); + vec[0].iov_len = ABSL_ARRAYSIZE(buffer); vec[1].iov_base = buffer2; - vec[1].iov_len = QUICHE_ARRAYSIZE(buffer2); + vec[1].iov_len = ABSL_ARRAYSIZE(buffer2); size_t bytes_read = stream_->Readv(vec, 2); EXPECT_EQ(2048u * 2, bytes_read); EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048)); @@ -819,7 +840,7 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { ProcessHeaders(false, headers_); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); stream_->ConsumeHeaderList(); @@ -842,9 +863,9 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) { ProcessHeaders(false, headers_); QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data1)); + absl::string_view(data1)); QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false, - data1.length(), quiche::QuicheStringPiece(data2)); + data1.length(), absl::string_view(data2)); stream_->OnStreamFrame(frame1); stream_->OnStreamFrame(frame2); stream_->ConsumeHeaderList(); @@ -862,14 +883,14 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { ProcessHeaders(false, headers_); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); stream_->ConsumeHeaderList(); char buffer[1]; struct iovec vec; vec.iov_base = buffer; - vec.iov_len = QUICHE_ARRAYSIZE(buffer); + vec.iov_len = ABSL_ARRAYSIZE(buffer); for (size_t i = 0; i < body.length(); ++i) { size_t bytes_read = stream_->Readv(&vec, 1); @@ -886,7 +907,7 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { ProcessHeaders(false, headers_); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame); stream_->ConsumeHeaderList(); @@ -894,9 +915,9 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { char buffer2[1]; struct iovec vec[2]; vec[0].iov_base = buffer1; - vec[0].iov_len = QUICHE_ARRAYSIZE(buffer1); + vec[0].iov_len = ABSL_ARRAYSIZE(buffer1); vec[1].iov_base = buffer2; - vec[1].iov_len = QUICHE_ARRAYSIZE(buffer2); + vec[1].iov_len = ABSL_ARRAYSIZE(buffer2); for (size_t i = 0; i < body.length(); i += 2) { size_t bytes_read = stream_->Readv(vec, 2); @@ -971,7 +992,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { ProcessHeaders(false, headers_); QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame1); EXPECT_EQ(kWindow - (kWindow / 3) - header_length, QuicStreamPeer::ReceiveWindowSize(stream_)); @@ -980,8 +1001,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { // half full. This should all be buffered, decreasing the receive window but // not sending WINDOW_UPDATE. QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false, - kWindow / 3 + header_length, - quiche::QuicheStringPiece(data)); + kWindow / 3 + header_length, absl::string_view(data)); stream_->OnStreamFrame(frame2); EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length, QuicStreamPeer::ReceiveWindowSize(stream_)); @@ -1017,7 +1037,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { stream_->ConsumeHeaderList(); QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame1); EXPECT_EQ(kWindow - (kWindow / 3) - header_length, QuicStreamPeer::ReceiveWindowSize(stream_)); @@ -1027,8 +1047,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { // offset and send a WINDOW_UPDATE. The result will be again an available // window of kWindow bytes. QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false, - kWindow / 3 + header_length, - quiche::QuicheStringPiece(data)); + kWindow / 3 + header_length, absl::string_view(data)); EXPECT_CALL(*session_, SendWindowUpdate(_, _)); EXPECT_CALL(*connection_, SendControlFrame(_)); stream_->OnStreamFrame(frame2); @@ -1088,10 +1107,10 @@ TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { } QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream_->OnStreamFrame(frame1); QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); stream2_->OnStreamFrame(frame2); // Now receive a further single byte on one stream - again this does not @@ -1101,7 +1120,7 @@ TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { EXPECT_CALL(*connection_, SendControlFrame(_)); QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, body.length() + header_length, - quiche::QuicheStringPiece(data2)); + absl::string_view(data2)); stream_->OnStreamFrame(frame3); } @@ -1122,7 +1141,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) { std::string body(kWindow + 1, 'a'); std::string data = UsesHttp3() ? DataFrame(body) : body; QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); EXPECT_CALL(*connection_, CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); stream_->OnStreamFrame(frame); @@ -1161,7 +1180,7 @@ TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) { EXPECT_LT(data.size(), kStreamWindow); QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece(data)); + absl::string_view(data)); EXPECT_CALL(*connection_, CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); @@ -2049,9 +2068,9 @@ TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) { char buffer[2048]; struct iovec vec; vec.iov_base = buffer; - vec.iov_len = QUICHE_ARRAYSIZE(buffer); + vec.iov_len = ABSL_ARRAYSIZE(buffer); size_t bytes_read = stream_->Readv(&vec, 1); - EXPECT_EQ(kDataFramePayload, quiche::QuicheStringPiece(buffer, bytes_read)); + EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read)); EXPECT_FALSE(stream_->HasBytesToRead()); } @@ -2070,7 +2089,7 @@ TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) { // Random bad headers. std::string headers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("00002a94e7036261")); + HeadersFrame(absl::HexStringToBytes("00002a94e7036261")); std::string data = DataFrame(kDataFramePayload); std::string stream_frame_payload = quiche::QuicheStrCat(headers, data); @@ -2094,8 +2113,11 @@ TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) { ConnectionCloseSource source) { session_->ReallyOnConnectionClosed(frame, source); })); - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)); - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(_, _, _, _)).Times(2); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2); + } stream_->OnStreamFrame(frame); } @@ -2133,13 +2155,17 @@ TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) { session_->ReallyOnConnectionClosed(frame, source); })); } - EXPECT_CALL(*session_, SendRstStream(stream_->id(), _, _, _)); - EXPECT_CALL(*session_, SendRstStream(stream2_->id(), _, _, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(stream_->id(), _, _, _)); + EXPECT_CALL(*session_, SendRstStream(stream2_->id(), _, _, _)); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _)); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _)); + } // Invalid headers: Required Insert Count is zero, but the header block // contains a dynamic table reference. - std::string headers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("000080")); + std::string headers = HeadersFrame(absl::HexStringToBytes("000080")); QuicStreamFrame frame(stream_->id(), false, 0, headers); stream_->OnStreamFrame(frame); } @@ -2162,7 +2188,7 @@ TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) { session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); // HEADERS frame referencing first dynamic table entry. - std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080"); + std::string encoded_headers = absl::HexStringToBytes("020080"); std::string headers = HeadersFrame(encoded_headers); EXPECT_CALL(debug_visitor, OnHeadersFrameReceived(stream_->id(), encoded_headers.length())); @@ -2196,7 +2222,7 @@ TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) { session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar"); // Trailing HEADERS frame referencing second dynamic table entry. - std::string encoded_trailers = quiche::QuicheTextUtils::HexDecode("030080"); + std::string encoded_trailers = absl::HexStringToBytes("030080"); std::string trailers = HeadersFrame(encoded_trailers); EXPECT_CALL(debug_visitor, OnHeadersFrameReceived(stream_->id(), encoded_trailers.length())); @@ -2228,7 +2254,7 @@ TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) { session_->set_debug_visitor(&debug_visitor); // HEADERS frame referencing first dynamic table entry. - std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080"); + std::string encoded_headers = absl::HexStringToBytes("020080"); std::string headers = HeadersFrame(encoded_headers); EXPECT_CALL(debug_visitor, OnHeadersFrameReceived(stream_->id(), encoded_headers.length())); @@ -2266,7 +2292,7 @@ TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) { EXPECT_EQ(kDataFramePayload, stream_->data()); // Trailing HEADERS frame referencing second dynamic table entry. - std::string encoded_trailers = quiche::QuicheTextUtils::HexDecode("030080"); + std::string encoded_trailers = absl::HexStringToBytes("030080"); std::string trailers = HeadersFrame(encoded_trailers); EXPECT_CALL(debug_visitor, OnHeadersFrameReceived(stream_->id(), encoded_trailers.length())); @@ -2300,8 +2326,7 @@ TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) { // HEADERS frame only referencing entry with absolute index 0 but with // Required Insert Count = 2, which is incorrect. - std::string headers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("030081")); + std::string headers = HeadersFrame(absl::HexStringToBytes("030081")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); // Even though entire header block is received and every referenced entry is @@ -2333,8 +2358,7 @@ TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) { session_->qpack_decoder()->OnSetDynamicTableCapacity(1024); // Relative index 2 is invalid because it is larger than or equal to the Base. - std::string headers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("020082")); + std::string headers = HeadersFrame(absl::HexStringToBytes("020082")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); // Decoding is blocked. @@ -2362,8 +2386,7 @@ TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) { session_->qpack_decoder()->OnSetDynamicTableCapacity(1024); // HEADERS frame referencing first dynamic table entry. - std::string headers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("020080")); + std::string headers = HeadersFrame(absl::HexStringToBytes("020080")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); // Decoding is blocked because dynamic table entry has not been received yet. @@ -2396,8 +2419,7 @@ TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) { // Trailing HEADERS frame only referencing entry with absolute index 0 but // with Required Insert Count = 2, which is incorrect. - std::string trailers = - HeadersFrame(quiche::QuicheTextUtils::HexDecode("030081")); + std::string trailers = HeadersFrame(absl::HexStringToBytes("030081")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */ headers.length() + data.length(), trailers)); @@ -2433,7 +2455,7 @@ TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) { session_->set_debug_visitor(&debug_visitor); // HEADERS frame referencing first dynamic table entry. - std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080"); + std::string encoded_headers = absl::HexStringToBytes("020080"); std::string headers = HeadersFrame(encoded_headers); EXPECT_CALL(debug_visitor, OnHeadersFrameReceived(stream_->id(), encoded_headers.length())); @@ -2453,8 +2475,15 @@ TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) { /* offset = */ 1, _, _, _)); // Reset stream. - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, _, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, _, _)); + } else { + EXPECT_CALL(*session_, MaybeSendStopSendingFrame(stream_->id(), + QUIC_STREAM_CANCELLED)); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), + QUIC_STREAM_CANCELLED, _)); + } stream_->Reset(QUIC_STREAM_CANCELLED); if (!GetQuicReloadableFlag(quic_abort_qpack_on_stream_close)) { @@ -2484,7 +2513,7 @@ class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest { // Create QuicStreamFrame with |payload| // and pass it to stream_->OnStreamFrame(). - void OnStreamFrame(quiche::QuicheStringPiece payload) { + void OnStreamFrame(absl::string_view payload) { QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload); stream_->OnStreamFrame(frame); offset_ += payload.size(); @@ -2536,12 +2565,11 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) { // All HEADERS frame bytes are consumed even if the frame is not received // completely. - OnStreamFrame( - quiche::QuicheStringPiece(headers).substr(0, headers.size() - 1)); + OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1)); EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes()); // The rest of the HEADERS frame is also consumed immediately. - OnStreamFrame(quiche::QuicheStringPiece(headers).substr(headers.size() - 1)); + OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1)); EXPECT_EQ(1u, NewlyConsumedBytes()); // Verify headers. @@ -2549,7 +2577,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) { stream_->ConsumeHeaderList(); // DATA frame. - quiche::QuicheStringPiece data_payload(kDataFramePayload); + absl::string_view data_payload(kDataFramePayload); std::string data_frame = DataFrame(data_payload); QuicByteCount data_frame_header_length = data_frame.size() - data_payload.size(); @@ -2568,8 +2596,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) { HeadersFrame({std::make_pair("custom-key", "custom-value")}); // No bytes are consumed, because last byte of DATA payload is still buffered. - OnStreamFrame( - quiche::QuicheStringPiece(trailers).substr(0, trailers.size() - 1)); + OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1)); EXPECT_EQ(0u, NewlyConsumedBytes()); // Reading last byte of DATA payload triggers consumption of all data received @@ -2578,8 +2605,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) { EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes()); // Last byte of trailers is immediately consumed. - OnStreamFrame( - quiche::QuicheStringPiece(trailers).substr(trailers.size() - 1)); + OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1)); EXPECT_EQ(1u, NewlyConsumedBytes()); // Verify trailers. @@ -2619,12 +2645,11 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) { // All HEADERS frame bytes are consumed even if the frame is not received // completely. - OnStreamFrame( - quiche::QuicheStringPiece(headers).substr(0, headers.size() - 1)); + OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1)); EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes()); // The rest of the HEADERS frame is also consumed immediately. - OnStreamFrame(quiche::QuicheStringPiece(headers).substr(headers.size() - 1)); + OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1)); EXPECT_EQ(1u, NewlyConsumedBytes()); // Verify headers. @@ -2638,7 +2663,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) { EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes()); // DATA frame. - quiche::QuicheStringPiece data_payload(kDataFramePayload); + absl::string_view data_payload(kDataFramePayload); std::string data_frame = DataFrame(data_payload); QuicByteCount data_frame_header_length = data_frame.size() - data_payload.size(); @@ -2663,8 +2688,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) { HeadersFrame({std::make_pair("custom-key", "custom-value")}); // No bytes are consumed, because last byte of DATA payload is still buffered. - OnStreamFrame( - quiche::QuicheStringPiece(trailers).substr(0, trailers.size() - 1)); + OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1)); EXPECT_EQ(0u, NewlyConsumedBytes()); // Reading last byte of DATA payload triggers consumption of all data received @@ -2674,8 +2698,7 @@ TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) { NewlyConsumedBytes()); // Last byte of trailers is immediately consumed. - OnStreamFrame( - quiche::QuicheStringPiece(trailers).substr(trailers.size() - 1)); + OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1)); EXPECT_EQ(1u, NewlyConsumedBytes()); // Verify trailers. @@ -2876,7 +2899,7 @@ TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) { Initialize(kShouldProcessData); // SETTINGS frame with empty payload. - std::string settings = quiche::QuicheTextUtils::HexDecode("0400"); + std::string settings = absl::HexStringToBytes("0400"); // HEADERS frame. // Since it arrives after a SETTINGS frame, it should never be read. @@ -2920,8 +2943,15 @@ TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) { EXPECT_CALL(*session_, WritevData(qpack_decoder_stream->id(), /* write_length = */ 1, /* offset = */ 1, _, _, _)); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 0, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, _, _)); + } else { + EXPECT_CALL(*session_, MaybeSendStopSendingFrame(stream_->id(), + QUIC_STREAM_CANCELLED)); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), + QUIC_STREAM_CANCELLED, _)); + } stream_->Reset(QUIC_STREAM_CANCELLED); } diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc index 4ba328943ff..3c89a545801 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h" +#include "absl/strings/string_view.h" #include "url/gurl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using spdy::SpdyHeaderBlock; @@ -40,7 +40,7 @@ std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders( if (it == headers.end() || it->second.empty()) { return std::string(); } - quiche::QuicheStringPiece scheme = it->second; + absl::string_view scheme = it->second; // RFC 7540, Section 8.2: The server MUST include a value in the // ":authority" pseudo-header field for which the server is authoritative @@ -49,7 +49,7 @@ std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders( if (it == headers.end() || it->second.empty()) { return std::string(); } - quiche::QuicheStringPiece authority = it->second; + absl::string_view authority = it->second; // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST // NOT be empty for "http" or "https" URIs; @@ -60,7 +60,7 @@ std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders( if (it == headers.end()) { return std::string(); } - quiche::QuicheStringPiece path = it->second; + absl::string_view path = it->second; return GetPushPromiseUrl(scheme, authority, path); } @@ -80,10 +80,9 @@ bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) { } // static -std::string SpdyServerPushUtils::GetPushPromiseUrl( - quiche::QuicheStringPiece scheme, - quiche::QuicheStringPiece authority, - quiche::QuicheStringPiece path) { +std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view scheme, + absl::string_view authority, + absl::string_view path) { // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the // path and query parts of the target URI (the "path-absolute" production // and optionally a '?' character followed by the "query" production (see diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h index 16e1ac6db64..99a834bd695 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h +++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_ #define QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -33,9 +33,9 @@ class QUIC_EXPORT_PRIVATE SpdyServerPushUtils { // Returns a canonical, valid URL for a PUSH_PROMISE with the specified // ":scheme", ":authority", and ":path" header fields, or an empty // string if the resulting URL is not valid or supported. - static std::string GetPushPromiseUrl(quiche::QuicheStringPiece scheme, - quiche::QuicheStringPiece authority, - quiche::QuicheStringPiece path); + static std::string GetPushPromiseUrl(absl::string_view scheme, + absl::string_view authority, + absl::string_view path); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc index ed7895e3b0a..fa98f077c6d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/http/spdy_server_push_utils_test.cc @@ -7,8 +7,8 @@ #include <memory> #include <string> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" using spdy::SpdyHeaderBlock; @@ -157,11 +157,11 @@ TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) { {"[::ffff:192.168", 0}, {"]/", 0}, {"//", 0}}; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(input_headers); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(input_headers); ++i) { bool should_accept = (input_headers[i].second & SCHEME); - for (size_t j = 0; j < QUICHE_ARRAYSIZE(input_headers); ++j) { + for (size_t j = 0; j < ABSL_ARRAYSIZE(input_headers); ++j) { bool should_accept_2 = should_accept && (input_headers[j].second & AUTH); - for (size_t k = 0; k < QUICHE_ARRAYSIZE(input_headers); ++k) { + for (size_t k = 0; k < ABSL_ARRAYSIZE(input_headers); ++k) { // |should_accept_3| indicates whether or not GetPushPromiseUrl() is // expected to accept this input combination. bool should_accept_3 = 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 847408d89cc..2a888fb1af0 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 @@ -8,12 +8,14 @@ #include <string> #include <vector> +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" @@ -29,12 +31,12 @@ bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length, return false; } else { // Check whether multiple values are consistent. - quiche::QuicheStringPiece content_length_header = it->second; - std::vector<quiche::QuicheStringPiece> values = - quiche::QuicheTextUtils::Split(content_length_header, '\0'); - for (const quiche::QuicheStringPiece& value : values) { + absl::string_view content_length_header = it->second; + std::vector<absl::string_view> values = + absl::StrSplit(content_length_header, '\0'); + for (const absl::string_view& value : values) { uint64_t new_value; - if (!quiche::QuicheTextUtils::StringToUint64(value, &new_value) || + if (!absl::SimpleAtoi(value, &new_value) || !quiche::QuicheTextUtils::IsAllDigits(value)) { QUIC_DLOG(ERROR) << "Content length was either unparseable or negative."; @@ -96,7 +98,7 @@ bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list, // response body bytes expected. if (expect_final_byte_offset && !found_final_byte_offset && name == kFinalOffsetHeaderKey && - quiche::QuicheTextUtils::StringToSizeT(p.second, final_byte_offset)) { + absl::SimpleAtoi(p.second, final_byte_offset)) { found_final_byte_offset = true; continue; } 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 dd8079e6320..9216a538b91 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 @@ -5,10 +5,10 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using spdy::SpdyHeaderBlock; @@ -66,14 +66,13 @@ TEST_F(CopyAndValidateHeaders, NormalUsage) { SpdyHeaderBlock block; ASSERT_TRUE( SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block)); - EXPECT_THAT( - block, - UnorderedElementsAre( - Pair("cookie", " part 1; part 2 ; part3; fin!"), - Pair("passed-through", quiche::QuicheStringPiece("foo\0baz", 7)), - Pair("joined", quiche::QuicheStringPiece("value 1\0value 2", 15)), - Pair("empty", ""), - Pair("empty-joined", quiche::QuicheStringPiece("\0foo\0\0", 6)))); + EXPECT_THAT(block, + UnorderedElementsAre( + Pair("cookie", " part 1; part 2 ; part3; fin!"), + Pair("passed-through", absl::string_view("foo\0baz", 7)), + Pair("joined", absl::string_view("value 1\0value 2", 15)), + Pair("empty", ""), + Pair("empty-joined", absl::string_view("\0foo\0\0", 6)))); EXPECT_EQ(-1, content_length); } @@ -104,11 +103,10 @@ TEST_F(CopyAndValidateHeaders, MultipleContentLengths) { SpdyHeaderBlock block; ASSERT_TRUE( SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block)); - EXPECT_THAT(block, - UnorderedElementsAre( - Pair("foo", "foovalue"), Pair("bar", "barvalue"), - Pair("content-length", quiche::QuicheStringPiece("9\09", 3)), - Pair("baz", ""))); + EXPECT_THAT(block, UnorderedElementsAre( + Pair("foo", "foovalue"), Pair("bar", "barvalue"), + Pair("content-length", absl::string_view("9\09", 3)), + Pair("baz", ""))); EXPECT_EQ(9, content_length); } @@ -133,11 +131,11 @@ TEST_F(CopyAndValidateHeaders, LargeContentLength) { SpdyHeaderBlock block; ASSERT_TRUE( SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block)); - EXPECT_THAT(block, UnorderedElementsAre( - Pair("foo", "foovalue"), Pair("bar", "barvalue"), - Pair("content-length", - quiche::QuicheStringPiece("9000000000")), - Pair("baz", ""))); + EXPECT_THAT(block, + UnorderedElementsAre( + Pair("foo", "foovalue"), Pair("bar", "barvalue"), + Pair("content-length", absl::string_view("9000000000")), + Pair("baz", ""))); EXPECT_EQ(9000000000, content_length); } @@ -165,11 +163,10 @@ TEST_F(CopyAndValidateHeaders, MultipleValues) { SpdyHeaderBlock block; ASSERT_TRUE( SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block)); - EXPECT_THAT(block, - UnorderedElementsAre( - Pair("foo", quiche::QuicheStringPiece("foovalue\0boo", 12)), - Pair("bar", "barvalue"), - Pair("baz", quiche::QuicheStringPiece("\0buzz", 5)))); + EXPECT_THAT(block, UnorderedElementsAre( + Pair("foo", absl::string_view("foovalue\0boo", 12)), + Pair("bar", "barvalue"), + Pair("baz", absl::string_view("\0buzz", 5)))); EXPECT_EQ(-1, content_length); } @@ -182,8 +179,8 @@ TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) { ASSERT_TRUE( SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block)); EXPECT_THAT(block, UnorderedElementsAre(Pair( - "set-cookie", quiche::QuicheStringPiece( - "value1\0value2\0value3", 20)))); + "set-cookie", + absl::string_view("value1\0value2\0value3", 20)))); EXPECT_EQ(-1, content_length); } @@ -325,7 +322,7 @@ TEST_F(CopyAndValidateTrailers, DuplicateTrailers) { block, UnorderedElementsAre( Pair("key", - quiche::QuicheStringPiece( + absl::string_view( "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate", 48)), Pair("other_key", "value"))); 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 6469dd266b5..1e66346cdb3 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 @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -27,9 +27,8 @@ QpackDecodedHeadersAccumulator::QpackDecodedHeadersAccumulator( quic_header_list_.OnHeaderBlockStart(); } -void QpackDecodedHeadersAccumulator::OnHeaderDecoded( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +void QpackDecodedHeadersAccumulator::OnHeaderDecoded(absl::string_view name, + absl::string_view value) { DCHECK(!error_detected_); uncompressed_header_bytes_without_overhead_ += name.size() + value.size(); @@ -64,7 +63,7 @@ void QpackDecodedHeadersAccumulator::OnDecodingCompleted() { } void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected( - quiche::QuicheStringPiece error_message) { + absl::string_view error_message) { DCHECK(!error_detected_); DCHECK(!headers_decoded_); @@ -73,7 +72,7 @@ void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected( visitor_->OnHeaderDecodingError(error_message); } -void QpackDecodedHeadersAccumulator::Decode(quiche::QuicheStringPiece data) { +void QpackDecodedHeadersAccumulator::Decode(absl::string_view data) { DCHECK(!error_detected_); compressed_header_bytes_ += data.size(); diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h index 334fcbda543..e194a98ebc5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator.h @@ -8,11 +8,11 @@ #include <cstddef> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_header_list.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -45,8 +45,7 @@ class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator bool header_list_size_limit_exceeded) = 0; // Called when an error has occurred. - virtual void OnHeaderDecodingError( - quiche::QuicheStringPiece error_message) = 0; + virtual void OnHeaderDecodingError(absl::string_view error_message) = 0; }; QpackDecodedHeadersAccumulator(QuicStreamId id, @@ -57,16 +56,15 @@ class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator // QpackProgressiveDecoder::HeadersHandlerInterface implementation. // These methods should only be called by |decoder_|. - void OnHeaderDecoded(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) override; + void OnHeaderDecoded(absl::string_view name, + absl::string_view value) override; void OnDecodingCompleted() override; - void OnDecodingErrorDetected( - quiche::QuicheStringPiece error_message) override; + void OnDecodingErrorDetected(absl::string_view error_message) override; // Decode payload data. // Must not be called if an error has been detected. // Must not be called after EndHeaderBlock(). - void Decode(quiche::QuicheStringPiece data); + void Decode(absl::string_view data); // Signal end of HEADERS frame. // Must not be called if an error has been detected. diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc index 93e2561f367..2a5b0da86bf 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc @@ -6,11 +6,12 @@ #include <cstring> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using ::testing::_; @@ -48,7 +49,7 @@ class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor { (override)); MOCK_METHOD(void, OnHeaderDecodingError, - (quiche::QuicheStringPiece error_message), + (absl::string_view error_message), (override)); }; @@ -84,7 +85,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyPayload) { // HEADERS frame payload must have a complete Header Block Prefix. TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) { - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("00")); + accumulator_.Decode(absl::HexStringToBytes("00")); EXPECT_CALL(visitor_, OnHeaderDecodingError(Eq("Incomplete header data prefix."))); @@ -92,7 +93,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) { } TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) { - std::string encoded_data(quiche::QuicheTextUtils::HexDecode("0000")); + std::string encoded_data(absl::HexStringToBytes("0000")); accumulator_.Decode(encoded_data); QuicHeaderList header_list; @@ -108,7 +109,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) { // This payload is the prefix of a valid payload, but EndHeaderBlock() is called // before it can be completely decoded. TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) { - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("00002366")); + accumulator_.Decode(absl::HexStringToBytes("00002366")); EXPECT_CALL(visitor_, OnHeaderDecodingError(Eq("Incomplete header block."))); accumulator_.EndHeaderBlock(); @@ -118,12 +119,11 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) { TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) { EXPECT_CALL(visitor_, OnHeaderDecodingError(Eq("Static table entry not found."))); - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("0000ff23ff24")); + accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24")); } TEST_F(QpackDecodedHeadersAccumulatorTest, Success) { - std::string encoded_data( - quiche::QuicheTextUtils::HexDecode("000023666f6f03626172")); + std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172")); accumulator_.Decode(encoded_data); QuicHeaderList header_list; @@ -141,7 +141,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, Success) { // otherwise decoding could fail with "incomplete header block" error. TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) { // Total length of header list exceeds kMaxHeaderListSize. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode( + accumulator_.Decode(absl::HexStringToBytes( "0000" // header block prefix "26666f6f626172" // header key: "foobar" "7d61616161616161616161616161616161616161" // header value: 'a' 125 times @@ -149,7 +149,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) { "616161616161616161616161616161616161616161616161616161616161616161616161" "61616161616161616161616161616161616161616161616161616161616161616161" "ff")); // first byte of a two-byte long Indexed Header Field instruction - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode( + accumulator_.Decode(absl::HexStringToBytes( "0f" // second byte of a two-byte long Indexed Header Field instruction )); @@ -160,7 +160,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) { // Test that header list limit enforcement works with blocked encoding. TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) { // Total length of header list exceeds kMaxHeaderListSize. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode( + accumulator_.Decode(absl::HexStringToBytes( "0200" // header block prefix "80" // reference to dynamic table entry not yet received "26666f6f626172" // header key: "foobar" @@ -182,7 +182,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) { TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) { // Reference to dynamic table entry not yet received. - std::string encoded_data(quiche::QuicheTextUtils::HexDecode("020080")); + std::string encoded_data(absl::HexStringToBytes("020080")); accumulator_.Decode(encoded_data); accumulator_.EndHeaderBlock(); @@ -206,7 +206,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) { TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { // Reference to dynamic table entry not yet received. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("020080")); + accumulator_.Decode(absl::HexStringToBytes("020080")); // Set dynamic table capacity. qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity); @@ -216,7 +216,7 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, // Rest of header block: same entry again. EXPECT_CALL(decoder_stream_sender_delegate_, WriteStreamData(Eq(kHeaderAcknowledgement))); - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("80")); + accumulator_.Decode(absl::HexStringToBytes("80")); QuicHeaderList header_list; EXPECT_CALL(visitor_, OnHeadersDecoded(_, false)) @@ -231,12 +231,12 @@ TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) { // Required Insert Count higher than number of entries causes decoding to be // blocked. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("0200")); + accumulator_.Decode(absl::HexStringToBytes("0200")); // Indexed Header Field instruction addressing dynamic table entry with // relative index 0, absolute index 0. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("80")); + accumulator_.Decode(absl::HexStringToBytes("80")); // Relative index larger than or equal to Base is invalid. - accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("81")); + accumulator_.Decode(absl::HexStringToBytes("81")); // Set dynamic table capacity. qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity); diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc index 17790defd5f..86383319c33 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.cc @@ -6,9 +6,10 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -70,19 +71,19 @@ void QpackDecoder::OnDecodingCompleted(QuicStreamId stream_id, void QpackDecoder::OnInsertWithNameReference(bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value) { + absl::string_view value) { if (is_static) { auto entry = header_table_.LookupEntry(/* is_static = */ true, name_index); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Invalid static table entry."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY, + "Invalid static table entry."); return; } entry = header_table_.InsertEntry(entry->name(), value); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Error inserting entry with name reference."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC, + "Error inserting entry with name reference."); } return; } @@ -90,32 +91,31 @@ void QpackDecoder::OnInsertWithNameReference(bool is_static, uint64_t absolute_index; if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex( name_index, header_table_.inserted_entry_count(), &absolute_index)) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Invalid relative index."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX, + "Invalid relative index."); return; } const QpackEntry* entry = header_table_.LookupEntry(/* is_static = */ false, absolute_index); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Dynamic table entry not found."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND, + "Dynamic table entry not found."); return; } entry = header_table_.InsertEntry(entry->name(), value); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Error inserting entry with name reference."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC, + "Error inserting entry with name reference."); } } -void QpackDecoder::OnInsertWithoutNameReference( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +void QpackDecoder::OnInsertWithoutNameReference(absl::string_view name, + absl::string_view value) { const QpackEntry* entry = header_table_.InsertEntry(name, value); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Error inserting literal entry."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL, + "Error inserting literal entry."); } } @@ -123,34 +123,44 @@ void QpackDecoder::OnDuplicate(uint64_t index) { uint64_t absolute_index; if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex( index, header_table_.inserted_entry_count(), &absolute_index)) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Invalid relative index."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX, + "Invalid relative index."); return; } const QpackEntry* entry = header_table_.LookupEntry(/* is_static = */ false, absolute_index); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Dynamic table entry not found."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND, + "Dynamic table entry not found."); return; } entry = header_table_.InsertEntry(entry->name(), entry->value()); if (!entry) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Error inserting duplicate entry."); + // InsertEntry() can only fail if entry is larger then dynamic table + // capacity, but that is impossible since entry was retrieved from the + // dynamic table. + OnErrorDetected(QUIC_INTERNAL_ERROR, "Error inserting duplicate entry."); } } void QpackDecoder::OnSetDynamicTableCapacity(uint64_t capacity) { if (!header_table_.SetDynamicTableCapacity(capacity)) { - encoder_stream_error_delegate_->OnEncoderStreamError( - "Error updating dynamic table capacity."); + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY, + "Error updating dynamic table capacity."); } } -void QpackDecoder::OnErrorDetected(quiche::QuicheStringPiece error_message) { - encoder_stream_error_delegate_->OnEncoderStreamError(error_message); +void QpackDecoder::OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) { + if (GetQuicReloadableFlag(quic_granular_qpack_error_codes)) { + QUIC_CODE_COUNT_N(quic_granular_qpack_error_codes, 2, 2); + encoder_stream_error_delegate_->OnEncoderStreamError(error_code, + error_message); + } else { + encoder_stream_error_delegate_->OnEncoderStreamError( + QUIC_QPACK_ENCODER_STREAM_ERROR, error_message); + } } std::unique_ptr<QpackProgressiveDecoder> QpackDecoder::CreateProgressiveDecoder( diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h index e09b14bef91..6e0c0ab92a1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h @@ -9,19 +9,24 @@ #include <memory> #include <set> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { // QPACK decoder class. Exactly one instance should exist per QUIC connection. // This class vends a new QpackProgressiveDecoder instance for each new header // list to be encoded. +// QpackProgressiveDecoder detects and signals errors with header blocks, which +// are stream errors. +// The only input of QpackDecoder is the encoder stream. Any error QpackDecoder +// signals is an encoder stream error, which is fatal to the connection. class QUIC_EXPORT_PRIVATE QpackDecoder : public QpackEncoderStreamReceiver::Delegate, public QpackProgressiveDecoder::BlockedStreamLimitEnforcer, @@ -34,8 +39,8 @@ class QUIC_EXPORT_PRIVATE QpackDecoder public: virtual ~EncoderStreamErrorDelegate() {} - virtual void OnEncoderStreamError( - quiche::QuicheStringPiece error_message) = 0; + virtual void OnEncoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) = 0; }; QpackDecoder(uint64_t maximum_dynamic_table_capacity, @@ -80,12 +85,13 @@ class QUIC_EXPORT_PRIVATE QpackDecoder // QpackEncoderStreamReceiver::Delegate implementation void OnInsertWithNameReference(bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value) override; - void OnInsertWithoutNameReference(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) override; + absl::string_view value) override; + void OnInsertWithoutNameReference(absl::string_view name, + absl::string_view value) override; void OnDuplicate(uint64_t index) override; void OnSetDynamicTableCapacity(uint64_t capacity) override; - void OnErrorDetected(quiche::QuicheStringPiece error_message) override; + void OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) override; // delegate must be set if dynamic table capacity is not zero. void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) { diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc index 5d6cf837621..e63d853da20 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,7 +18,7 @@ QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate) DCHECK(delegate_); } -void QpackDecoderStreamReceiver::Decode(quiche::QuicheStringPiece data) { +void QpackDecoderStreamReceiver::Decode(absl::string_view data) { if (data.empty() || error_detected_) { return; } @@ -43,12 +43,20 @@ bool QpackDecoderStreamReceiver::OnInstructionDecoded( return true; } -void QpackDecoderStreamReceiver::OnError( - quiche::QuicheStringPiece error_message) { +void QpackDecoderStreamReceiver::OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message) { DCHECK(!error_detected_); error_detected_ = true; - delegate_->OnErrorDetected(error_message); + + // There is no string literals on the decoder stream, + // the only possible error is INTEGER_TOO_LARGE. + QuicErrorCode quic_error_code = + (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE) + ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE + : QUIC_INTERNAL_ERROR; + delegate_->OnErrorDetected(quic_error_code, error_message); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h index 19f51f0d3b4..b3b3d692cbe 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h @@ -7,11 +7,12 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -34,7 +35,8 @@ class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver // 5.3.3 Stream Cancellation virtual void OnStreamCancellation(QuicStreamId stream_id) = 0; // Decoding error - virtual void OnErrorDetected(quiche::QuicheStringPiece error_message) = 0; + virtual void OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) = 0; }; explicit QpackDecoderStreamReceiver(Delegate* delegate); @@ -47,11 +49,12 @@ class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver // Decode data and call appropriate Delegate method after each decoded // instruction. Once an error occurs, Delegate::OnErrorDetected() is called, // and all further data is ignored. - void Decode(quiche::QuicheStringPiece data) override; + void Decode(absl::string_view data) override; // QpackInstructionDecoder::Delegate implementation. bool OnInstructionDecoded(const QpackInstruction* instruction) override; - void OnError(quiche::QuicheStringPiece error_message) override; + void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message) override; private: QpackInstructionDecoder instruction_decoder_; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc index 70d2450662a..fd7959512c8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver_test.cc @@ -4,8 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using testing::Eq; @@ -27,7 +28,7 @@ class MockDelegate : public QpackDecoderStreamReceiver::Delegate { MOCK_METHOD(void, OnStreamCancellation, (QuicStreamId stream_id), (override)); MOCK_METHOD(void, OnErrorDetected, - (quiche::QuicheStringPiece error_message), + (QuicErrorCode error_code, absl::string_view error_message), (override)); }; @@ -42,53 +43,59 @@ class QpackDecoderStreamReceiverTest : public QuicTest { TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) { EXPECT_CALL(delegate_, OnInsertCountIncrement(0)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("00")); + stream_.Decode(absl::HexStringToBytes("00")); EXPECT_CALL(delegate_, OnInsertCountIncrement(10)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("0a")); + stream_.Decode(absl::HexStringToBytes("0a")); EXPECT_CALL(delegate_, OnInsertCountIncrement(63)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("3f00")); + stream_.Decode(absl::HexStringToBytes("3f00")); EXPECT_CALL(delegate_, OnInsertCountIncrement(200)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("3f8901")); + stream_.Decode(absl::HexStringToBytes("3f8901")); - EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large."))); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff")); + EXPECT_CALL(delegate_, + OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); + stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff")); } TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) { EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("80")); + stream_.Decode(absl::HexStringToBytes("80")); EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("a5")); + stream_.Decode(absl::HexStringToBytes("a5")); EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("ff00")); + stream_.Decode(absl::HexStringToBytes("ff00")); EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("fff802")); + stream_.Decode(absl::HexStringToBytes("fff802")); - EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large."))); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff")); + EXPECT_CALL(delegate_, + OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); + stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff")); } TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) { EXPECT_CALL(delegate_, OnStreamCancellation(0)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("40")); + stream_.Decode(absl::HexStringToBytes("40")); EXPECT_CALL(delegate_, OnStreamCancellation(19)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("53")); + stream_.Decode(absl::HexStringToBytes("53")); EXPECT_CALL(delegate_, OnStreamCancellation(63)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("7f00")); + stream_.Decode(absl::HexStringToBytes("7f00")); EXPECT_CALL(delegate_, OnStreamCancellation(110)); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("7f2f")); + stream_.Decode(absl::HexStringToBytes("7f2f")); - EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large."))); - stream_.Decode(quiche::QuicheTextUtils::HexDecode("7fffffffffffffffffffff")); + EXPECT_CALL(delegate_, + OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); + stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff")); } } // namespace diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc index 34f4de8d2af..bfb19e10f59 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.cc @@ -8,9 +8,9 @@ #include <limits> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc index 1d18fa92e59..c412c9f78e3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender_test.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -27,67 +28,55 @@ class QpackDecoderStreamSenderTest : public QuicTest { }; TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) { - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("00")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00")))); stream_.SendInsertCountIncrement(0); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("0a")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a")))); stream_.SendInsertCountIncrement(10); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("3f00")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00")))); stream_.SendInsertCountIncrement(63); stream_.Flush(); - EXPECT_CALL(delegate_, WriteStreamData( - Eq(quiche::QuicheTextUtils::HexDecode("3f8901")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901")))); stream_.SendInsertCountIncrement(200); stream_.Flush(); } TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) { - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("80")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80")))); stream_.SendHeaderAcknowledgement(0); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("a5")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5")))); stream_.SendHeaderAcknowledgement(37); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("ff00")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00")))); stream_.SendHeaderAcknowledgement(127); stream_.Flush(); - EXPECT_CALL(delegate_, WriteStreamData( - Eq(quiche::QuicheTextUtils::HexDecode("fff802")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802")))); stream_.SendHeaderAcknowledgement(503); stream_.Flush(); } TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) { - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("40")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40")))); stream_.SendStreamCancellation(0); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("53")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53")))); stream_.SendStreamCancellation(19); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("7f00")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00")))); stream_.SendStreamCancellation(63); stream_.Flush(); - EXPECT_CALL(delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("7f2f")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f")))); stream_.SendStreamCancellation(110); stream_.Flush(); } @@ -97,16 +86,14 @@ TEST_F(QpackDecoderStreamSenderTest, Coalesce) { stream_.SendHeaderAcknowledgement(37); stream_.SendStreamCancellation(0); - EXPECT_CALL(delegate_, WriteStreamData( - Eq(quiche::QuicheTextUtils::HexDecode("0aa540")))); + EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540")))); stream_.Flush(); stream_.SendInsertCountIncrement(63); stream_.SendStreamCancellation(110); - EXPECT_CALL( - delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("3f007f2f")))); + EXPECT_CALL(delegate_, + WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f")))); stream_.Flush(); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc index 8b546b0ed9f..cf7c9d39a5c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test.cc @@ -6,11 +6,13 @@ #include <algorithm> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" @@ -49,13 +51,12 @@ class QpackDecoderTest : public QuicTestWithParam<FragmentMode> { // Destroy QpackProgressiveDecoder on error to test that it does not crash. // See https://crbug.com/1025209. ON_CALL(handler_, OnDecodingErrorDetected(_)) - .WillByDefault( - Invoke([this](quiche::QuicheStringPiece /* error_message */) { - progressive_decoder_.reset(); - })); + .WillByDefault(Invoke([this](absl::string_view /* error_message */) { + progressive_decoder_.reset(); + })); } - void DecodeEncoderStreamData(quiche::QuicheStringPiece data) { + void DecodeEncoderStreamData(absl::string_view data) { qpack_decoder_.encoder_stream_receiver()->Decode(data); } @@ -71,7 +72,7 @@ class QpackDecoderTest : public QuicTestWithParam<FragmentMode> { // Pass header block data to QpackProgressiveDecoder::Decode() // in fragments dictated by |fragment_mode_|. - void DecodeData(quiche::QuicheStringPiece data) { + void DecodeData(absl::string_view data) { auto fragment_size_generator = FragmentModeToFragmentSizeGenerator(fragment_mode_); while (progressive_decoder_ && !data.empty()) { @@ -91,7 +92,7 @@ class QpackDecoderTest : public QuicTestWithParam<FragmentMode> { } // Decode an entire header block. - void DecodeHeaderBlock(quiche::QuicheStringPiece data) { + void DecodeHeaderBlock(absl::string_view data) { StartDecoding(); DecodeData(data); EndDecoding(); @@ -117,7 +118,7 @@ TEST_P(QpackDecoderTest, NoPrefix) { OnDecodingErrorDetected(Eq("Incomplete header data prefix."))); // Header Data Prefix is at least two bytes long. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00")); + DecodeHeaderBlock(absl::HexStringToBytes("00")); } // Regression test for https://1025209: QpackProgressiveDecoder must not crash @@ -129,52 +130,50 @@ TEST_P(QpackDecoderTest, InvalidPrefix) { OnDecodingErrorDetected(Eq("Encoded integer too large."))); // Encoded Required Insert Count in Header Data Prefix is too large. - DecodeData( - quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffffffffff")); + DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff")); } TEST_P(QpackDecoderTest, EmptyHeaderBlock) { EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0000")); + DecodeHeaderBlock(absl::HexStringToBytes("0000")); } TEST_P(QpackDecoderTest, LiteralEntryEmptyName) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo"))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002003666f6f")); + DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f")); } TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(""))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f00")); + DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00")); } TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq(""))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002000")); + DecodeHeaderBlock(absl::HexStringToBytes("00002000")); } TEST_P(QpackDecoderTest, SimpleLiteralEntry) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f03626172")); + DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172")); } TEST_P(QpackDecoderTest, MultipleLiteralEntries) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); std::string str(127, 'a'); - EXPECT_CALL(handler_, - OnHeaderDecoded(Eq("foobaar"), quiche::QuicheStringPiece(str))); + EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0000" // prefix "23666f6f03626172" // foo: bar "2700666f6f62616172" // 7 octet long header name, the smallest number @@ -192,8 +191,7 @@ TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Encoded integer too large."))); - DecodeHeaderBlock( - quiche::QuicheTextUtils::HexDecode("000027ffffffffffffffffffff")); + DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff")); } // Name Length value can be decoded by varint decoder but exceeds 1 MB limit. @@ -201,7 +199,7 @@ TEST_P(QpackDecoderTest, NameLenExceedsLimit) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("String literal too long."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000027ffff7f")); + DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f")); } // Value Length value is too large for varint decoder to decode. @@ -210,7 +208,7 @@ TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) { OnDecodingErrorDetected(Eq("Encoded integer too large."))); DecodeHeaderBlock( - quiche::QuicheTextUtils::HexDecode("000023666f6f7fffffffffffffffffffff")); + absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff")); } // Value Length value can be decoded by varint decoder but exceeds 1 MB limit. @@ -218,22 +216,22 @@ TEST_P(QpackDecoderTest, ValueLenExceedsLimit) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("String literal too long."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f7fffff7f")); + DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f")); } TEST_P(QpackDecoderTest, IncompleteHeaderBlock) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Incomplete header block."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002366")); + DecodeHeaderBlock(absl::HexStringToBytes("00002366")); } TEST_P(QpackDecoderTest, HuffmanSimple) { EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value"))); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( - "00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf")); + DecodeHeaderBlock( + absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf")); } TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) { @@ -241,7 +239,7 @@ TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) { .Times(4); EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0000" // Prefix. "2f0125a849e95ba97d7f" // Huffman-encoded name. "8925a849e95bb8e8b4bf" // Huffman-encoded value. @@ -254,45 +252,45 @@ TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) { } TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) { - EXPECT_CALL(handler_, OnDecodingErrorDetected(quiche::QuicheStringPiece( + EXPECT_CALL(handler_, OnDecodingErrorDetected(absl::string_view( "Error in Huffman-encoded string."))); // 'y' ends in 0b0 on the most significant bit of the last byte. // The remaining 7 bits must be a prefix of EOS, which is all 1s. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( - "00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf")); + DecodeHeaderBlock( + absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf")); } TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) { - EXPECT_CALL(handler_, OnDecodingErrorDetected(quiche::QuicheStringPiece( + EXPECT_CALL(handler_, OnDecodingErrorDetected(absl::string_view( "Error in Huffman-encoded string."))); // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte. // The remaining 5 bits must be a prefix of EOS, which is all 1s. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( - "00002f0125a849e95ba97d7f8925a849e95bb8e8b4be")); + DecodeHeaderBlock( + absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be")); } TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) { - EXPECT_CALL(handler_, OnDecodingErrorDetected(quiche::QuicheStringPiece( + EXPECT_CALL(handler_, OnDecodingErrorDetected(absl::string_view( "Error in Huffman-encoded string."))); // The trailing EOS prefix must be at most 7 bits long. Appending one octet // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a // prefix of EOS. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( - "00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf")); + DecodeHeaderBlock( + absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf")); } TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) { - EXPECT_CALL(handler_, OnDecodingErrorDetected(quiche::QuicheStringPiece( + EXPECT_CALL(handler_, OnDecodingErrorDetected(absl::string_view( "Error in Huffman-encoded string."))); // The trailing EOS prefix must be at most 7 bits long. Appending one octet // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a // prefix of EOS. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( - "00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff")); + DecodeHeaderBlock( + absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff")); } TEST_P(QpackDecoderTest, StaticTable) { @@ -313,7 +311,7 @@ TEST_P(QpackDecoderTest, StaticTable) { EXPECT_CALL(handler_, OnDecodingCompleted()); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000")); } @@ -326,11 +324,11 @@ TEST_P(QpackDecoderTest, TooHighStaticTableIndex) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Static table entry not found."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0000ff23ff24")); + DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24")); } TEST_P(QpackDecoderTest, DynamicTable) { - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode( + DecodeEncoderStreamData(absl::HexStringToBytes( "3fe107" // Set dynamic table capacity to 1024. "6294e703626172" // Add literal entry with name "foo" and value "bar". "80035a5a5a" // Add entry with name of dynamic table entry index 0 @@ -359,7 +357,7 @@ TEST_P(QpackDecoderTest, DynamicTable) { .InSequence(s); EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0500" // Required Insert Count 4 and Delta Base 0. // Base is 4 + 0 = 4. "83" // Dynamic table entry with relative index 3, absolute index 0. @@ -380,7 +378,7 @@ TEST_P(QpackDecoderTest, DynamicTable) { .InSequence(s); EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0502" // Required Insert Count 4 and Delta Base 2. // Base is 4 + 2 = 6. "85" // Dynamic table entry with relative index 5, absolute index 0. @@ -401,7 +399,7 @@ TEST_P(QpackDecoderTest, DynamicTable) { .InSequence(s); EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0582" // Required Insert Count 4 and Delta Base 2 with sign bit set. // Base is 4 - 2 - 1 = 1. "80" // Dynamic table entry with relative index 0, absolute index 0. @@ -414,28 +412,28 @@ TEST_P(QpackDecoderTest, DynamicTable) { TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) { // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnDecodingCompleted()); EXPECT_CALL(decoder_stream_sender_delegate_, WriteStreamData(Eq(kHeaderAcknowledgement))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80")); // Dynamic table entry with relative index 0, absolute index 0. // Change dynamic table capacity to 32 bytes, smaller than the entry. // This must cause the entry to be evicted. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f01")); + DecodeEncoderStreamData(absl::HexStringToBytes("3f01")); EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Dynamic table entry already evicted."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80")); // Dynamic table entry with relative index 0, absolute index 0. @@ -443,27 +441,40 @@ TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) { TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) { EXPECT_CALL(encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Error inserting literal entry."))); + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Error inserting literal entry."))); // Set dynamic table capacity to 34. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f03")); + DecodeEncoderStreamData(absl::HexStringToBytes("3f03")); // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); } TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) { EXPECT_CALL(encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Invalid static table entry."))); + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Invalid static table entry."))); // Address invalid static table entry index 99. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("ff2400")); + DecodeEncoderStreamData(absl::HexStringToBytes("ff2400")); } TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) { - EXPECT_CALL(encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Invalid relative index."))); + EXPECT_CALL( + encoder_stream_error_delegate_, + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Invalid relative index."))); - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode( + DecodeEncoderStreamData(absl::HexStringToBytes( "3fe107" // Set dynamic table capacity to 1024. "6294e703626172" // Add literal entry with name "foo" and value "bar". "8100")); // Address dynamic table entry with relative index 1. Such @@ -472,10 +483,15 @@ TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) { } TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) { - EXPECT_CALL(encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Invalid relative index."))); + EXPECT_CALL( + encoder_stream_error_delegate_, + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Invalid relative index."))); - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode( + DecodeEncoderStreamData(absl::HexStringToBytes( "3fe107" // Set dynamic table capacity to 1024. "6294e703626172" // Add literal entry with name "foo" and value "bar". "01")); // Duplicate dynamic table entry with relative index 1. Such @@ -485,21 +501,24 @@ TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) { TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) { EXPECT_CALL(encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Encoded integer too large."))); + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Encoded integer too large."))); - DecodeEncoderStreamData( - quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff")); } TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index."))); // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0280" // Required Insert Count is 1. Base 1 - 1 - 0 = 0 is explicitly // permitted by the spec. "80")); // However, addressing entry with relative index 0 would point to @@ -511,18 +530,18 @@ TEST_P(QpackDecoderTest, InvalidNegativeBase) { // Required Insert Count 1, Delta Base 1 with sign bit set, Base would // be 1 - 1 - 1 = -1, but it is not allowed to be negative. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0281")); + DecodeHeaderBlock(absl::HexStringToBytes("0281")); } TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) { // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "81")); // Indexed Header Field instruction addressing relative index 1. @@ -530,7 +549,7 @@ TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "4100")); // Literal Header Field with Name Reference instruction @@ -540,18 +559,18 @@ TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) { TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) { // Update dynamic table capacity to 128. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61")); + DecodeEncoderStreamData(absl::HexStringToBytes("3f61")); // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38. // This fits in the table three times. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); // Duplicate entry four times. This evicts the first two instances. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00000000")); + DecodeEncoderStreamData(absl::HexStringToBytes("00000000")); EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Dynamic table entry already evicted."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0500" // Required Insert Count 4 and Delta Base 0. // Base is 4 + 0 = 4. "82")); // Indexed Header Field instruction addressing relative index 2. @@ -560,7 +579,7 @@ TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) { EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Dynamic table entry already evicted."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0500" // Required Insert Count 4 and Delta Base 0. // Base is 4 + 0 = 4. "4200")); // Literal Header Field with Name Reference instruction @@ -570,7 +589,7 @@ TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) { EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Dynamic table entry already evicted."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0380" // Required Insert Count 2 and Delta Base 0 with sign bit set. // Base is 2 - 0 - 1 = 1 "10")); // Indexed Header Field instruction addressing dynamic table @@ -580,7 +599,7 @@ TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) { EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Dynamic table entry already evicted."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0380" // Required Insert Count 2 and Delta Base 0 with sign bit set. // Base is 2 - 0 - 1 = 1 "0000")); // Literal Header Field With Name Reference instruction @@ -589,17 +608,20 @@ TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) { } TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) { - EXPECT_CALL( - encoder_stream_error_delegate_, - OnEncoderStreamError(Eq("Error updating dynamic table capacity."))); + EXPECT_CALL(encoder_stream_error_delegate_, + OnEncoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY + : QUIC_QPACK_ENCODER_STREAM_ERROR, + Eq("Error updating dynamic table capacity."))); // Try to update dynamic table capacity to 2048, which exceeds the maximum. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe10f")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f")); } TEST_P(QpackDecoderTest, SetDynamicTableCapacity) { // Update dynamic table capacity to 128, which does not exceed the maximum. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61")); + DecodeEncoderStreamData(absl::HexStringToBytes("3f61")); } TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) { @@ -609,7 +631,7 @@ TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) { // A value of 1 cannot be encoded as 65 even though it has the same remainder. EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Error decoding Required Insert Count."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("4100")); + DecodeHeaderBlock(absl::HexStringToBytes("4100")); } // Regression test for https://crbug.com/970218: Decoder must stop processing @@ -618,7 +640,7 @@ TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) { EXPECT_CALL(handler_, OnDecodingErrorDetected( Eq("Error decoding Required Insert Count."))); // Header Block Prefix followed by some extra data. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("410000")); + DecodeHeaderBlock(absl::HexStringToBytes("410000")); } TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) { @@ -626,12 +648,12 @@ TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) { // MaxEntries is 1024 / 32 = 32. // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and a 600 byte long value. This will fit // in the dynamic table once but not twice. DecodeEncoderStreamData( - quiche::QuicheTextUtils::HexDecode("6294e7" // Name "foo". - "7fd903")); // Value length 600. + absl::HexStringToBytes("6294e7" // Name "foo". + "7fd903")); // Value length 600. std::string header_value(600, 'Z'); DecodeEncoderStreamData(header_value); @@ -646,7 +668,7 @@ TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) { WriteStreamData(Eq(kHeaderAcknowledgement))); // Send header block with Required Insert Count = 201. - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0a00" // Encoded Required Insert Count 10, Required Insert Count 201, // Delta Base 0, Base 201. "80")); // Emit dynamic table entry with relative index 0. @@ -654,31 +676,31 @@ TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) { TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) { // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET"))); EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Required Insert Count too large."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count is 1. "d1")); // But the only instruction references the static table. } TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) { // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); EXPECT_CALL( handler_, OnDecodingErrorDetected( Eq("Absolute Index must be smaller than Required Insert Count."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0201" // Required Insert Count 1 and Delta Base 1. // Base is 1 + 1 = 2. "80")); // Indexed Header Field instruction addressing dynamic table @@ -690,7 +712,7 @@ TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) { OnDecodingErrorDetected( Eq("Absolute Index must be smaller than Required Insert Count."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0201" // Required Insert Count 1 and Delta Base 1. // Base is 1 + 1 = 2. "4000")); // Literal Header Field with Name Reference instruction @@ -703,7 +725,7 @@ TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) { OnDecodingErrorDetected( Eq("Absolute Index must be smaller than Required Insert Count."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "10")); // Indexed Header Field with Post-Base Index instruction @@ -716,7 +738,7 @@ TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) { OnDecodingErrorDetected( Eq("Absolute Index must be smaller than Required Insert Count."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "0000")); // Literal Header Field with Post-Base Name Reference @@ -727,19 +749,19 @@ TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) { TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) { // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); // Duplicate entry twice so that decoding of header blocks with Required // Insert Count not exceeding 3 is not blocked. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00")); - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00")); + DecodeEncoderStreamData(absl::HexStringToBytes("00")); + DecodeEncoderStreamData(absl::HexStringToBytes("00")); EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Required Insert Count too large."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0300" // Required Insert Count 2 and Delta Base 0. // Base is 2 + 0 = 2. "81")); // Indexed Header Field instruction addressing dynamic table @@ -751,7 +773,7 @@ TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Required Insert Count too large."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0300" // Required Insert Count 2 and Delta Base 0. // Base is 2 + 0 = 2. "4100")); // Literal Header Field with Name Reference instruction @@ -763,7 +785,7 @@ TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Required Insert Count too large."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0481" // Required Insert Count 3 and Delta Base 1 with sign bit set. // Base is 3 - 1 - 1 = 1. "10")); // Indexed Header Field with Post-Base Index instruction @@ -775,7 +797,7 @@ TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) { EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Required Insert Count too large."))); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0481" // Required Insert Count 3 and Delta Base 1 with sign bit set. // Base is 3 - 1 - 1 = 1. "0000")); // Literal Header Field with Post-Base Name Reference @@ -785,7 +807,7 @@ TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) { } TEST_P(QpackDecoderTest, BlockedDecoding) { - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80")); // Indexed Header Field instruction addressing dynamic table @@ -797,14 +819,14 @@ TEST_P(QpackDecoderTest, BlockedDecoding) { WriteStreamData(Eq(kHeaderAcknowledgement))); // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); } TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { StartDecoding(); - DecodeData(quiche::QuicheTextUtils::HexDecode( + DecodeData(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80" // Indexed Header Field instruction addressing dynamic table @@ -812,7 +834,7 @@ TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { "d1")); // Static table entry with index 17. // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". Decoding is now // unblocked because dynamic table Insert Count reached the Required Insert @@ -820,14 +842,14 @@ TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { // the already consumed part of the header block. EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET"))); - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); Mock::VerifyAndClearExpectations(&handler_); // Rest of header block is processed by QpackProgressiveDecoder // in the unblocked state. EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https"))); - DecodeData(quiche::QuicheTextUtils::HexDecode( + DecodeData(absl::HexStringToBytes( "80" // Indexed Header Field instruction addressing dynamic table // entry with relative index 0, absolute index 0. "d7")); // Static table entry with index 23. @@ -843,7 +865,7 @@ TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { TEST_P(QpackDecoderTest, BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) { StartDecoding(); - DecodeData(quiche::QuicheTextUtils::HexDecode( + DecodeData(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80" // Indexed Header Field instruction addressing dynamic table @@ -851,7 +873,7 @@ TEST_P(QpackDecoderTest, "81")); // Relative index 1 is equal to Base, therefore invalid. // Set dynamic table capacity to 1024. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107")); + DecodeEncoderStreamData(absl::HexStringToBytes("3fe107")); // Add literal entry with name "foo" and value "bar". Decoding is now // unblocked because dynamic table Insert Count reached the Required Insert @@ -859,7 +881,7 @@ TEST_P(QpackDecoderTest, // the already consumed part of the header block. EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))); EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index."))); - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); } // Make sure that Required Insert Count is compared to Insert Count, @@ -867,19 +889,19 @@ TEST_P(QpackDecoderTest, TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) { // Update dynamic table capacity to 128. // At most three non-empty entries fit in the dynamic table. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61")); + DecodeEncoderStreamData(absl::HexStringToBytes("3f61")); - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0700" // Required Insert Count 6 and Delta Base 0. // Base is 6 + 0 = 6. "80")); // Indexed Header Field instruction addressing dynamic table // entry with relative index 0, absolute index 5. // Add literal entry with name "foo" and value "bar". - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172")); // Duplicate entry four times. This evicts the first two instances. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00000000")); + DecodeEncoderStreamData(absl::HexStringToBytes("00000000")); EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz"))); EXPECT_CALL(handler_, OnDecodingCompleted()); @@ -888,13 +910,13 @@ TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) { // Add literal entry with name "foo" and value "bar". // Insert Count is now 6, reaching Required Insert Count of the header block. - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e70362617a")); + DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a")); } TEST_P(QpackDecoderTest, TooManyBlockedStreams) { // Required Insert Count 1 and Delta Base 0. // Without any dynamic table entries received, decoding is blocked. - std::string data = quiche::QuicheTextUtils::HexDecode("0200"); + std::string data = absl::HexStringToBytes("0200"); auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1); progressive_decoder1->Decode(data); @@ -907,7 +929,7 @@ TEST_P(QpackDecoderTest, TooManyBlockedStreams) { } TEST_P(QpackDecoderTest, InsertCountIncrement) { - DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode( + DecodeEncoderStreamData(absl::HexStringToBytes( "3fe107" // Set dynamic table capacity to 1024. "6294e703626172" // Add literal entry with name "foo" and value "bar". "00")); // Duplicate entry. @@ -919,11 +941,11 @@ TEST_P(QpackDecoderTest, InsertCountIncrement) { // Known Insert Count to one. Decoder should send an Insert Count Increment // instruction with increment of one to update Known Insert Count to two. EXPECT_CALL(decoder_stream_sender_delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode( + WriteStreamData(Eq(absl::HexStringToBytes( "81" // Header Acknowledgement on stream 1 "01")))); // Insert Count Increment with increment of one - DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode( + DecodeHeaderBlock(absl::HexStringToBytes( "0200" // Required Insert Count 1 and Delta Base 0. // Base is 1 + 0 = 1. "80")); // Dynamic table entry with relative index 0, absolute index 0. 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 67adf1268eb..bf7cdc63a3f 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 @@ -7,13 +7,14 @@ #include <algorithm> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h" #include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -58,7 +59,7 @@ QpackInstructionWithValues QpackEncoder::EncodeLiteralHeaderFieldWithNameReference( bool is_static, uint64_t index, - quiche::QuicheStringPiece value, + absl::string_view value, QpackBlockingManager::IndexSet* referred_indices) { // Add |index| to |*referred_indices| only if entry is in the dynamic table. if (!is_static) { @@ -70,14 +71,14 @@ QpackEncoder::EncodeLiteralHeaderFieldWithNameReference( // static QpackInstructionWithValues QpackEncoder::EncodeLiteralHeaderField( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + absl::string_view name, + absl::string_view value) { return QpackInstructionWithValues::LiteralHeaderField(name, value); } QpackEncoder::Instructions QpackEncoder::FirstPassEncode( QuicStreamId stream_id, - const spdy::SpdyHeaderBlock& header_list, + const spdy::Http2HeaderBlock& header_list, QpackBlockingManager::IndexSet* referred_indices, QuicByteCount* encoder_stream_sent_byte_count) { // If previous instructions are buffered in |encoder_stream_sender_|, @@ -110,8 +111,8 @@ QpackEncoder::Instructions QpackEncoder::FirstPassEncode( for (const auto& header : ValueSplittingHeaderList(&header_list)) { // These strings are owned by |header_list|. - quiche::QuicheStringPiece name = header.first; - quiche::QuicheStringPiece value = header.second; + absl::string_view name = header.first; + absl::string_view value = header.second; bool is_static; uint64_t index; @@ -355,7 +356,7 @@ std::string QpackEncoder::SecondPassEncode( std::string QpackEncoder::EncodeHeaderList( QuicStreamId stream_id, - const spdy::SpdyHeaderBlock& header_list, + const spdy::Http2HeaderBlock& header_list, QuicByteCount* encoder_stream_sent_byte_count) { // Keep track of all dynamic table indices that this header block refers to so // that it can be passed to QpackBlockingManager. @@ -403,29 +404,32 @@ bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) { void QpackEncoder::OnInsertCountIncrement(uint64_t increment) { if (increment == 0) { - decoder_stream_error_delegate_->OnDecoderStreamError( - "Invalid increment value 0."); + OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT, + "Invalid increment value 0."); return; } if (!blocking_manager_.OnInsertCountIncrement(increment)) { - decoder_stream_error_delegate_->OnDecoderStreamError( - "Insert Count Increment instruction causes overflow."); + OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW, + "Insert Count Increment instruction causes overflow."); } if (blocking_manager_.known_received_count() > header_table_.inserted_entry_count()) { - decoder_stream_error_delegate_->OnDecoderStreamError(quiche::QuicheStrCat( - "Increment value ", increment, " raises known received count to ", - blocking_manager_.known_received_count(), - " exceeding inserted entry count ", - header_table_.inserted_entry_count())); + OnErrorDetected( + QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT, + quiche::QuicheStrCat("Increment value ", increment, + " raises known received count to ", + blocking_manager_.known_received_count(), + " exceeding inserted entry count ", + header_table_.inserted_entry_count())); } } void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId stream_id) { if (!blocking_manager_.OnHeaderAcknowledgement(stream_id)) { - decoder_stream_error_delegate_->OnDecoderStreamError( + OnErrorDetected( + QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT, quiche::QuicheStrCat("Header Acknowledgement received for stream ", stream_id, " with no outstanding header blocks.")); } @@ -435,8 +439,16 @@ void QpackEncoder::OnStreamCancellation(QuicStreamId stream_id) { blocking_manager_.OnStreamCancellation(stream_id); } -void QpackEncoder::OnErrorDetected(quiche::QuicheStringPiece error_message) { - decoder_stream_error_delegate_->OnDecoderStreamError(error_message); +void QpackEncoder::OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) { + if (GetQuicReloadableFlag(quic_granular_qpack_error_codes)) { + QUIC_CODE_COUNT_N(quic_granular_qpack_error_codes, 1, 2); + decoder_stream_error_delegate_->OnDecoderStreamError(error_code, + error_message); + } else { + decoder_stream_error_delegate_->OnDecoderStreamError( + QUIC_QPACK_DECODER_STREAM_ERROR, error_message); + } } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h index 202fc6d8ef1..c6c8aa5d8ae 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h @@ -10,21 +10,17 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" - -namespace spdy { - -class SpdyHeaderBlock; - -} // namespace spdy +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -45,8 +41,8 @@ class QUIC_EXPORT_PRIVATE QpackEncoder public: virtual ~DecoderStreamErrorDelegate() {} - virtual void OnDecoderStreamError( - quiche::QuicheStringPiece error_message) = 0; + virtual void OnDecoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) = 0; }; QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate); @@ -56,7 +52,7 @@ class QUIC_EXPORT_PRIVATE QpackEncoder // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent // on the encoder stream to insert dynamic table entries. std::string EncodeHeaderList(QuicStreamId stream_id, - const spdy::SpdyHeaderBlock& header_list, + const spdy::Http2HeaderBlock& header_list, QuicByteCount* encoder_stream_sent_byte_count); // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|, @@ -83,7 +79,8 @@ class QUIC_EXPORT_PRIVATE QpackEncoder void OnInsertCountIncrement(uint64_t increment) override; void OnHeaderAcknowledgement(QuicStreamId stream_id) override; void OnStreamCancellation(QuicStreamId stream_id) override; - void OnErrorDetected(quiche::QuicheStringPiece error_message) override; + void OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) override; // delegate must be set if dynamic table capacity is not zero. void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) { @@ -122,13 +119,13 @@ class QUIC_EXPORT_PRIVATE QpackEncoder static QpackInstructionWithValues EncodeLiteralHeaderFieldWithNameReference( bool is_static, uint64_t index, - quiche::QuicheStringPiece value, + absl::string_view value, QpackBlockingManager::IndexSet* referred_indices); // Generate literal header field instruction. static QpackInstructionWithValues EncodeLiteralHeaderField( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + absl::string_view name, + absl::string_view value); // Performs first pass of two-pass encoding: represent each header field in // |*header_list| as a reference to an existing entry, the name of an existing @@ -140,9 +137,9 @@ class QUIC_EXPORT_PRIVATE QpackEncoder // encoder stream to insert dynamic table entries. Returns list of header // field representations, with all dynamic table entries referred to with // absolute indices. Returned Instructions object may have - // quiche::QuicheStringPieces pointing to strings owned by |*header_list|. + // absl::string_views pointing to strings owned by |*header_list|. Instructions FirstPassEncode(QuicStreamId stream_id, - const spdy::SpdyHeaderBlock& header_list, + const spdy::Http2HeaderBlock& header_list, QpackBlockingManager::IndexSet* referred_indices, QuicByteCount* encoder_stream_sent_byte_count); diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc index 56ee23241db..95260ab3e7a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/decoder/decode_buffer.h" #include "net/third_party/quiche/src/http2/decoder/decode_status.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,7 +18,7 @@ QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate) DCHECK(delegate_); } -void QpackEncoderStreamReceiver::Decode(quiche::QuicheStringPiece data) { +void QpackEncoderStreamReceiver::Decode(absl::string_view data) { if (data.empty() || error_detected_) { return; } @@ -51,12 +51,29 @@ bool QpackEncoderStreamReceiver::OnInstructionDecoded( return true; } -void QpackEncoderStreamReceiver::OnError( - quiche::QuicheStringPiece error_message) { +void QpackEncoderStreamReceiver::OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message) { DCHECK(!error_detected_); error_detected_ = true; - delegate_->OnErrorDetected(error_message); + + QuicErrorCode quic_error_code; + switch (error_code) { + case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE: + quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE; + break; + case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG: + quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG; + break; + case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR: + quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR; + break; + default: + quic_error_code = QUIC_INTERNAL_ERROR; + } + + delegate_->OnErrorDetected(quic_error_code, error_message); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h index 80622e5460d..fa94a5353ee 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h @@ -8,10 +8,11 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,17 +30,17 @@ class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver // 5.2.1. Insert With Name Reference virtual void OnInsertWithNameReference(bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value) = 0; + absl::string_view value) = 0; // 5.2.2. Insert Without Name Reference - virtual void OnInsertWithoutNameReference( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) = 0; + virtual void OnInsertWithoutNameReference(absl::string_view name, + absl::string_view value) = 0; // 5.2.3. Duplicate virtual void OnDuplicate(uint64_t index) = 0; // 5.2.4. Set Dynamic Table Capacity virtual void OnSetDynamicTableCapacity(uint64_t capacity) = 0; // Decoding error - virtual void OnErrorDetected(quiche::QuicheStringPiece error_message) = 0; + virtual void OnErrorDetected(QuicErrorCode error_code, + absl::string_view error_message) = 0; }; explicit QpackEncoderStreamReceiver(Delegate* delegate); @@ -53,11 +54,12 @@ class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver // Decode data and call appropriate Delegate method after each decoded // instruction. Once an error occurs, Delegate::OnErrorDetected() is called, // and all further data is ignored. - void Decode(quiche::QuicheStringPiece data) override; + void Decode(absl::string_view data) override; // QpackInstructionDecoder::Delegate implementation. bool OnInstructionDecoded(const QpackInstruction* instruction) override; - void OnError(quiche::QuicheStringPiece error_message) override; + void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message) override; private: QpackInstructionDecoder instruction_decoder_; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc index 71b6d3438e4..31bea896899 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver_test.cc @@ -4,8 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using testing::Eq; @@ -21,19 +22,17 @@ class MockDelegate : public QpackEncoderStreamReceiver::Delegate { MOCK_METHOD(void, OnInsertWithNameReference, - (bool is_static, - uint64_t name_index, - quiche::QuicheStringPiece value), + (bool is_static, uint64_t name_index, absl::string_view value), (override)); MOCK_METHOD(void, OnInsertWithoutNameReference, - (quiche::QuicheStringPiece name, quiche::QuicheStringPiece value), + (absl::string_view name, absl::string_view value), (override)); MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override)); MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override)); MOCK_METHOD(void, OnErrorDetected, - (quiche::QuicheStringPiece error_message), + (QuicErrorCode error_code, absl::string_view error_message), (override)); }; @@ -42,7 +41,7 @@ class QpackEncoderStreamReceiverTest : public QuicTest { QpackEncoderStreamReceiverTest() : stream_(&delegate_) {} ~QpackEncoderStreamReceiverTest() override = default; - void Decode(quiche::QuicheStringPiece data) { stream_.Decode(data); } + void Decode(absl::string_view data) { stream_.Decode(data); } StrictMock<MockDelegate>* delegate() { return &delegate_; } private: @@ -62,7 +61,7 @@ TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) { EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z')))); - Decode(quiche::QuicheTextUtils::HexDecode( + Decode(absl::HexStringToBytes( "c500" "c28294e7" "bf4a03626172" @@ -73,15 +72,19 @@ TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) { } TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); - Decode(quiche::QuicheTextUtils::HexDecode("bfffffffffffffffffffffff")); + Decode(absl::HexStringToBytes("bfffffffffffffffffffffff")); } TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); - Decode(quiche::QuicheTextUtils::HexDecode("c57fffffffffffffffffffff")); + Decode(absl::HexStringToBytes("c57fffffffffffffffffffff")); } TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) { @@ -97,7 +100,7 @@ TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) { OnInsertWithoutNameReference(Eq(std::string(31, 'Z')), Eq(std::string(127, 'Z')))); - Decode(quiche::QuicheTextUtils::HexDecode( + Decode(absl::HexStringToBytes( "4000" "4362617203626172" "6294e78294e7" @@ -111,33 +114,41 @@ TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) { // Name Length value is too large for varint decoder to decode. TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReferenceNameTooLongForVarintDecoder) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); - Decode(quiche::QuicheTextUtils::HexDecode("5fffffffffffffffffffff")); + Decode(absl::HexStringToBytes("5fffffffffffffffffffff")); } // Name Length value can be decoded by varint decoder but exceeds 1 MB limit. TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReferenceNameExceedsLimit) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("String literal too long."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG, + Eq("String literal too long."))); - Decode(quiche::QuicheTextUtils::HexDecode("5fffff7f")); + Decode(absl::HexStringToBytes("5fffff7f")); } // Value Length value is too large for varint decoder to decode. TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReferenceValueTooLongForVarintDecoder) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); - Decode(quiche::QuicheTextUtils::HexDecode("436261727fffffffffffffffffffff")); + Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff")); } // Value Length value can be decoded by varint decoder but exceeds 1 MB limit. TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReferenceValueExceedsLimit) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("String literal too long."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG, + Eq("String literal too long."))); - Decode(quiche::QuicheTextUtils::HexDecode("436261727fffff7f")); + Decode(absl::HexStringToBytes("436261727fffff7f")); } TEST_F(QpackEncoderStreamReceiverTest, Duplicate) { @@ -146,13 +157,15 @@ TEST_F(QpackEncoderStreamReceiverTest, Duplicate) { // Large index requires two extension bytes. EXPECT_CALL(*delegate(), OnDuplicate(500)); - Decode(quiche::QuicheTextUtils::HexDecode("111fd503")); + Decode(absl::HexStringToBytes("111fd503")); } TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); - Decode(quiche::QuicheTextUtils::HexDecode("1fffffffffffffffffffff")); + Decode(absl::HexStringToBytes("1fffffffffffffffffffff")); } TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) { @@ -161,13 +174,23 @@ TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) { // Large capacity requires two extension bytes. EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500)); - Decode(quiche::QuicheTextUtils::HexDecode("313fd503")); + Decode(absl::HexStringToBytes("313fd503")); } TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) { - EXPECT_CALL(*delegate(), OnErrorDetected(Eq("Encoded integer too large."))); + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); + + Decode(absl::HexStringToBytes("3fffffffffffffffffffff")); +} + +TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) { + EXPECT_CALL(*delegate(), + OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR, + Eq("Error in Huffman-encoded string."))); - Decode(quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff")); + Decode(absl::HexStringToBytes("c281ff")); } } // namespace 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 0ae1aae7ff1..88214abee17 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 @@ -8,9 +8,9 @@ #include <limits> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -19,7 +19,7 @@ QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {} void QpackEncoderStreamSender::SendInsertWithNameReference( bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value) { + absl::string_view value) { instruction_encoder_.Encode( QpackInstructionWithValues::InsertWithNameReference(is_static, name_index, value), @@ -27,8 +27,8 @@ void QpackEncoderStreamSender::SendInsertWithNameReference( } void QpackEncoderStreamSender::SendInsertWithoutNameReference( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + absl::string_view name, + absl::string_view value) { instruction_encoder_.Encode( QpackInstructionWithValues::InsertWithoutNameReference(name, value), &buffer_); 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 dee23c50d5b..dbef027e1b7 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 @@ -7,11 +7,11 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -29,10 +29,10 @@ class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender { // 5.2.1. Insert With Name Reference void SendInsertWithNameReference(bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value); + absl::string_view value); // 5.2.2. Insert Without Name Reference - void SendInsertWithoutNameReference(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + void SendInsertWithoutNameReference(absl::string_view name, + absl::string_view value); // 5.2.3. Duplicate void SendDuplicate(uint64_t index); // 5.2.4. Set Dynamic Table Capacity diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc index ea45acc1abd..08138190c84 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender_test.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h" +#include "absl/strings/escaping.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" @@ -30,22 +31,21 @@ TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) { EXPECT_EQ(0u, stream_.BufferedByteCount()); // Static, index fits in prefix, empty value. - std::string expected_encoded_data = - quiche::QuicheTextUtils::HexDecode("c500"); + std::string expected_encoded_data = absl::HexStringToBytes("c500"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithNameReference(true, 5, ""); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); stream_.Flush(); // Static, index fits in prefix, Huffman encoded value. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode("c28294e7"); + expected_encoded_data = absl::HexStringToBytes("c28294e7"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithNameReference(true, 2, "foo"); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); stream_.Flush(); // Not static, index does not fit in prefix, not Huffman encoded value. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode("bf4a03626172"); + expected_encoded_data = absl::HexStringToBytes("bf4a03626172"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithNameReference(false, 137, "bar"); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); @@ -53,7 +53,7 @@ TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) { // Value length does not fit in prefix. // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode( + expected_encoded_data = absl::HexStringToBytes( "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a" "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a" "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a" @@ -68,23 +68,21 @@ TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) { EXPECT_EQ(0u, stream_.BufferedByteCount()); // Empty name and value. - std::string expected_encoded_data = - quiche::QuicheTextUtils::HexDecode("4000"); + std::string expected_encoded_data = absl::HexStringToBytes("4000"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithoutNameReference("", ""); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); stream_.Flush(); // Huffman encoded short strings. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode("6294e78294e7"); + expected_encoded_data = absl::HexStringToBytes("6294e78294e7"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithoutNameReference("foo", "foo"); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); stream_.Flush(); // Not Huffman encoded short strings. - expected_encoded_data = - quiche::QuicheTextUtils::HexDecode("4362617203626172"); + expected_encoded_data = absl::HexStringToBytes("4362617203626172"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendInsertWithoutNameReference("bar", "bar"); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); @@ -92,7 +90,7 @@ TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) { // Not Huffman encoded long strings; length does not fit on prefix. // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode( + expected_encoded_data = absl::HexStringToBytes( "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f" "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a" "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a" @@ -109,14 +107,14 @@ TEST_F(QpackEncoderStreamSenderTest, Duplicate) { EXPECT_EQ(0u, stream_.BufferedByteCount()); // Small index fits in prefix. - std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode("11"); + std::string expected_encoded_data = absl::HexStringToBytes("11"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendDuplicate(17); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); stream_.Flush(); // Large index requires two extension bytes. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode("1fd503"); + expected_encoded_data = absl::HexStringToBytes("1fd503"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendDuplicate(500); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); @@ -127,7 +125,7 @@ TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) { EXPECT_EQ(0u, stream_.BufferedByteCount()); // Small capacity fits in prefix. - std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode("31"); + std::string expected_encoded_data = absl::HexStringToBytes("31"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendSetDynamicTableCapacity(17); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); @@ -135,7 +133,7 @@ TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) { EXPECT_EQ(0u, stream_.BufferedByteCount()); // Large capacity requires two extension bytes. - expected_encoded_data = quiche::QuicheTextUtils::HexDecode("3fd503"); + expected_encoded_data = absl::HexStringToBytes("3fd503"); EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data))); stream_.SendSetDynamicTableCapacity(500); EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount()); @@ -157,7 +155,7 @@ TEST_F(QpackEncoderStreamSenderTest, Coalesce) { // Duplicate entry. stream_.SendDuplicate(17); - std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode( + std::string expected_encoded_data = absl::HexStringToBytes( "c500" // Insert entry with static name reference. "c28294e7" // Insert entry with static name reference. "6294e78294e7" // Insert literal entry. 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 e0d21c53269..08c6123fc82 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 @@ -7,13 +7,15 @@ #include <limits> #include <string> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using ::testing::_; @@ -35,7 +37,7 @@ class QpackEncoderTest : public QuicTest { ~QpackEncoderTest() override = default; - std::string Encode(const spdy::SpdyHeaderBlock& header_list) { + std::string Encode(const spdy::Http2HeaderBlock& header_list) { return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list, &encoder_stream_sent_byte_count_); } @@ -47,53 +49,53 @@ class QpackEncoderTest : public QuicTest { }; TEST_F(QpackEncoderTest, Empty) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000"), output); + EXPECT_EQ(absl::HexStringToBytes("0000"), output); } TEST_F(QpackEncoderTest, EmptyName) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[""] = "foo"; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000208294e7"), output); + EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output); } TEST_F(QpackEncoderTest, EmptyValue) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = ""; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002a94e700"), output); + EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output); } TEST_F(QpackEncoderTest, EmptyNameAndValue) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[""] = ""; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002000"), output); + EXPECT_EQ(absl::HexStringToBytes("00002000"), output); } TEST_F(QpackEncoderTest, Simple) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002a94e703626172"), output); + EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output); } TEST_F(QpackEncoderTest, Multiple) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used. header_list["ZZZZZZZ"] = std::string(127, 'Z'); std::string output = Encode(header_list); EXPECT_EQ( - quiche::QuicheTextUtils::HexDecode( + absl::HexStringToBytes( "0000" // prefix "2a94e703626172" // foo: bar "27005a5a5a5a5a5a5a" // 7 octet long header name, the smallest number @@ -109,63 +111,69 @@ TEST_F(QpackEncoderTest, Multiple) { TEST_F(QpackEncoderTest, StaticTable) { { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "GET"; header_list["accept-encoding"] = "gzip, deflate, br"; header_list["location"] = ""; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000d1dfcc"), output); + EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output); } { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "POST"; header_list["accept-encoding"] = "compress"; header_list["location"] = "foo"; std::string output = Encode(header_list); - EXPECT_EQ( - quiche::QuicheTextUtils::HexDecode("0000d45f108621e9aec2a11f5c8294e7"), - output); + EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"), + output); } { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "TRACE"; header_list["accept-encoding"] = ""; std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00005f000554524143455f1000"), - output); + EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output); } } TEST_F(QpackEncoderTest, DecoderStreamError) { EXPECT_CALL(decoder_stream_error_delegate_, - OnDecoderStreamError(Eq("Encoded integer too large."))); + OnDecoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE + : QUIC_QPACK_DECODER_STREAM_ERROR, + Eq("Encoded integer too large."))); QpackEncoder encoder(&decoder_stream_error_delegate_); encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_); encoder.decoder_stream_receiver()->Decode( - quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff")); + absl::HexStringToBytes("ffffffffffffffffffffff")); } TEST_F(QpackEncoderTest, SplitAlongNullCharacter) { - spdy::SpdyHeaderBlock header_list; - header_list["foo"] = quiche::QuicheStringPiece("bar\0bar\0baz", 11); + spdy::Http2HeaderBlock header_list; + header_list["foo"] = absl::string_view("bar\0bar\0baz", 11); std::string output = Encode(header_list); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000" // prefix - "2a94e703626172" // foo: bar - "2a94e703626172" // foo: bar - "2a94e70362617a" // foo: baz - ), + EXPECT_EQ(absl::HexStringToBytes("0000" // prefix + "2a94e703626172" // foo: bar + "2a94e703626172" // foo: bar + "2a94e70362617a" // foo: baz + ), output); } TEST_F(QpackEncoderTest, ZeroInsertCountIncrement) { // Encoder receives insert count increment with forbidden value 0. EXPECT_CALL(decoder_stream_error_delegate_, - OnDecoderStreamError(Eq("Invalid increment value 0."))); + OnDecoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT + : QUIC_QPACK_DECODER_STREAM_ERROR, + Eq("Invalid increment value 0."))); encoder_.OnInsertCountIncrement(0); } @@ -173,10 +181,13 @@ TEST_F(QpackEncoderTest, TooLargeInsertCountIncrement) { // Encoder receives insert count increment with value that increases Known // Received Count to a value (one) which is larger than the number of dynamic // table insertions sent (zero). - EXPECT_CALL( - decoder_stream_error_delegate_, - OnDecoderStreamError(Eq("Increment value 1 raises known received count " - "to 1 exceeding inserted entry count 0"))); + EXPECT_CALL(decoder_stream_error_delegate_, + OnDecoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT + : QUIC_QPACK_DECODER_STREAM_ERROR, + Eq("Increment value 1 raises known received count " + "to 1 exceeding inserted entry count 0"))); encoder_.OnInsertCountIncrement(1); } @@ -197,6 +208,9 @@ TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) { // received count. This must result in an error instead of a crash. EXPECT_CALL(decoder_stream_error_delegate_, OnDecoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW + : QUIC_QPACK_DECODER_STREAM_ERROR, Eq("Insert Count Increment instruction causes overflow."))); encoder_.OnInsertCountIncrement(std::numeric_limits<uint64_t>::max()); } @@ -204,10 +218,13 @@ TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) { TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) { // Encoder receives header acknowledgement for a stream on which no header // block with dynamic table entries was ever sent. - EXPECT_CALL( - decoder_stream_error_delegate_, - OnDecoderStreamError(Eq("Header Acknowledgement received for stream 0 " - "with no outstanding header blocks."))); + EXPECT_CALL(decoder_stream_error_delegate_, + OnDecoderStreamError( + GetQuicReloadableFlag(quic_granular_qpack_error_codes) + ? QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT + : QUIC_QPACK_DECODER_STREAM_ERROR, + Eq("Header Acknowledgement received for stream 0 " + "with no outstanding header blocks."))); encoder_.OnHeaderAcknowledgement(/* stream_id = */ 0); } @@ -216,17 +233,16 @@ TEST_F(QpackEncoderTest, DynamicTable) { encoder_.SetMaximumDynamicTableCapacity(4096); encoder_.SetDynamicTableCapacity(4096); - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; header_list.AppendValueOrAddHeader("foo", "baz"); // name matches dynamic entry header_list["cookie"] = "baz"; // name matches static entry // Set Dynamic Table Capacity instruction. - std::string set_dyanamic_table_capacity = - quiche::QuicheTextUtils::HexDecode("3fe11f"); + std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f"); // Insert three entries into the dynamic table. - std::string insert_entries = quiche::QuicheTextUtils::HexDecode( + std::string insert_entries = absl::HexStringToBytes( "62" // insert without name reference "94e7" // Huffman-encoded name "foo" "03626172" // value "bar" @@ -238,7 +254,7 @@ TEST_F(QpackEncoderTest, DynamicTable) { WriteStreamData(Eq(quiche::QuicheStrCat( set_dyanamic_table_capacity, insert_entries)))); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( + EXPECT_EQ(absl::HexStringToBytes( "0400" // prefix "828180"), // dynamic entries with relative index 0, 1, and 2 Encode(header_list)); @@ -252,7 +268,7 @@ TEST_F(QpackEncoderTest, SmallDynamicTable) { encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar")); encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar")); - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; header_list.AppendValueOrAddHeader("foo", "baz"); // name matches dynamic entry @@ -260,10 +276,9 @@ TEST_F(QpackEncoderTest, SmallDynamicTable) { header_list["bar"] = "baz"; // no match // Set Dynamic Table Capacity instruction. - std::string set_dyanamic_table_capacity = - quiche::QuicheTextUtils::HexDecode("3f07"); + std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07"); // Insert one entry into the dynamic table. - std::string insert_entry = quiche::QuicheTextUtils::HexDecode( + std::string insert_entry = absl::HexStringToBytes( "62" // insert without name reference "94e7" // Huffman-encoded name "foo" "03626172"); // value "bar" @@ -271,15 +286,14 @@ TEST_F(QpackEncoderTest, SmallDynamicTable) { WriteStreamData(Eq(quiche::QuicheStrCat( set_dyanamic_table_capacity, insert_entry)))); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "0200" // prefix - "80" // dynamic entry 0 - "40" // reference to dynamic entry 0 name - "0362617a" // with literal value "baz" - "55" // reference to static entry 5 name - "0362617a" // with literal value "baz" - "23626172" // literal name "bar" - "0362617a"), // with literal value "baz" + EXPECT_EQ(absl::HexStringToBytes("0200" // prefix + "80" // dynamic entry 0 + "40" // reference to dynamic entry 0 name + "0362617a" // with literal value "baz" + "55" // reference to static entry 5 name + "0362617a" // with literal value "baz" + "23626172" // literal name "bar" + "0362617a"), // with literal value "baz" Encode(header_list)); EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_); @@ -290,14 +304,13 @@ TEST_F(QpackEncoderTest, BlockedStream) { encoder_.SetMaximumDynamicTableCapacity(4096); encoder_.SetDynamicTableCapacity(4096); - spdy::SpdyHeaderBlock header_list1; + spdy::Http2HeaderBlock header_list1; header_list1["foo"] = "bar"; // Set Dynamic Table Capacity instruction. - std::string set_dyanamic_table_capacity = - quiche::QuicheTextUtils::HexDecode("3fe11f"); + std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f"); // Insert one entry into the dynamic table. - std::string insert_entry1 = quiche::QuicheTextUtils::HexDecode( + std::string insert_entry1 = absl::HexStringToBytes( "62" // insert without name reference "94e7" // Huffman-encoded name "foo" "03626172"); // value "bar" @@ -305,30 +318,29 @@ TEST_F(QpackEncoderTest, BlockedStream) { WriteStreamData(Eq(quiche::QuicheStrCat( set_dyanamic_table_capacity, insert_entry1)))); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0200" // prefix - "80"), // dynamic entry 0 + EXPECT_EQ(absl::HexStringToBytes("0200" // prefix + "80"), // dynamic entry 0 encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1, &encoder_stream_sent_byte_count_)); EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_); // Stream 1 is blocked. Stream 2 is not allowed to block. - spdy::SpdyHeaderBlock header_list2; + spdy::Http2HeaderBlock header_list2; header_list2["foo"] = "bar"; // name and value match dynamic entry header_list2.AppendValueOrAddHeader("foo", "baz"); // name matches dynamic entry header_list2["cookie"] = "baz"; // name matches static entry header_list2["bar"] = "baz"; // no match - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "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" - "23626172" // literal name "bar" - "0362617a"), // with literal value "baz" + 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" + "23626172" // literal name "bar" + "0362617a"), // with literal value "baz" encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2, &encoder_stream_sent_byte_count_)); EXPECT_EQ(0u, encoder_stream_sent_byte_count_); @@ -338,7 +350,7 @@ TEST_F(QpackEncoderTest, BlockedStream) { encoder_.OnInsertCountIncrement(1); // Insert three entries into the dynamic table. - std::string insert_entries = quiche::QuicheTextUtils::HexDecode( + std::string insert_entries = absl::HexStringToBytes( "80" // insert with name reference, dynamic index 0 "0362617a" // value "baz" "c5" // insert with name reference, static index 5 @@ -349,23 +361,22 @@ TEST_F(QpackEncoderTest, BlockedStream) { EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(Eq(insert_entries))); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0500" // prefix - "83828180"), // dynamic entries + EXPECT_EQ(absl::HexStringToBytes("0500" // prefix + "83828180"), // dynamic entries encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2, &encoder_stream_sent_byte_count_)); EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_); // Stream 3 is blocked. Stream 4 is not allowed to block, but it can // reference already acknowledged dynamic entry 0. - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "0200" // prefix - "80" // dynamic entry 0 - "2a94e7" // literal name "foo" - "0362617a" // with literal value "baz" - "2c21cfd4c5" // literal name "cookie" - "0362617a" // with literal value "baz" - "23626172" // literal name "bar" - "0362617a"), // with literal value "baz" + EXPECT_EQ(absl::HexStringToBytes("0200" // prefix + "80" // dynamic entry 0 + "2a94e7" // literal name "foo" + "0362617a" // with literal value "baz" + "2c21cfd4c5" // literal name "cookie" + "0362617a" // with literal value "baz" + "23626172" // literal name "bar" + "0362617a"), // with literal value "baz" encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2, &encoder_stream_sent_byte_count_)); EXPECT_EQ(0u, encoder_stream_sent_byte_count_); @@ -376,11 +387,10 @@ TEST_F(QpackEncoderTest, BlockedStream) { // Stream 5 is not allowed to block, but it can reference already acknowledged // dynamic entries 0, 1, and 2. - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "0400" // prefix - "828180" // dynamic entries - "23626172" // literal name "bar" - "0362617a"), // with literal value "baz" + EXPECT_EQ(absl::HexStringToBytes("0400" // prefix + "828180" // dynamic entries + "23626172" // literal name "bar" + "0362617a"), // with literal value "baz" encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2, &encoder_stream_sent_byte_count_)); EXPECT_EQ(0u, encoder_stream_sent_byte_count_); @@ -389,15 +399,15 @@ TEST_F(QpackEncoderTest, BlockedStream) { // Stream 3 is not blocked any longer. encoder_.OnHeaderAcknowledgement(3); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0500" // prefix - "83828180"), // dynamic entries + EXPECT_EQ(absl::HexStringToBytes("0500" // prefix + "83828180"), // dynamic entries encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2, &encoder_stream_sent_byte_count_)); EXPECT_EQ(0u, encoder_stream_sent_byte_count_); } TEST_F(QpackEncoderTest, Draining) { - spdy::SpdyHeaderBlock header_list1; + spdy::Http2HeaderBlock header_list1; header_list1["one"] = "foo"; header_list1["two"] = "foo"; header_list1["three"] = "foo"; @@ -425,26 +435,24 @@ TEST_F(QpackEncoderTest, Draining) { // dynamic table. EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_)); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "0b00" // prefix - "89888786858483828180"), // dynamic entries + EXPECT_EQ(absl::HexStringToBytes("0b00" // prefix + "89888786858483828180"), // dynamic entries Encode(header_list1)); // Entry is identical to oldest one, which is draining. It will be // duplicated and referenced. - spdy::SpdyHeaderBlock header_list2; + spdy::Http2HeaderBlock header_list2; header_list2["one"] = "foo"; // Duplicate oldest entry. EXPECT_CALL(encoder_stream_sender_delegate_, - WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("09")))); + WriteStreamData(Eq(absl::HexStringToBytes("09")))); - EXPECT_EQ(quiche::QuicheTextUtils::HexDecode( - "0c00" // prefix - "80"), // most recent dynamic table entry + EXPECT_EQ(absl::HexStringToBytes("0c00" // prefix + "80"), // most recent dynamic table entry Encode(header_list2)); - spdy::SpdyHeaderBlock header_list3; + spdy::Http2HeaderBlock header_list3; // Entry is identical to second oldest one, which is draining. There is no // room to duplicate, it will be encoded with string literals. header_list3.AppendValueOrAddHeader("two", "foo"); @@ -452,13 +460,12 @@ TEST_F(QpackEncoderTest, Draining) { // no room to insert new entry, it will be encoded with string literals. header_list3.AppendValueOrAddHeader("two", "bar"); - EXPECT_EQ( - quiche::QuicheTextUtils::HexDecode("0000" // prefix - "2374776f" // literal name "two" - "8294e7" // literal value "foo" - "2374776f" // literal name "two" - "03626172"), // literal value "bar" - Encode(header_list3)); + EXPECT_EQ(absl::HexStringToBytes("0000" // prefix + "2374776f" // literal name "two" + "8294e7" // literal value "foo" + "2374776f" // literal name "two" + "03626172"), // literal value "bar" + Encode(header_list3)); } TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) { diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc index 29e71488bda..1440ca58a1b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -51,8 +51,8 @@ const QpackEntry* QpackHeaderTable::LookupEntry(bool is_static, } QpackHeaderTable::MatchType QpackHeaderTable::FindHeaderField( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, + absl::string_view name, + absl::string_view value, bool* is_static, uint64_t* index) const { QpackEntry query(name, value); @@ -96,9 +96,8 @@ QpackHeaderTable::MatchType QpackHeaderTable::FindHeaderField( return MatchType::kNoMatch; } -const QpackEntry* QpackHeaderTable::InsertEntry( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +const QpackEntry* QpackHeaderTable::InsertEntry(absl::string_view name, + absl::string_view value) { const uint64_t entry_size = QpackEntry::Size(name, value); if (entry_size > dynamic_table_capacity_) { return nullptr; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h index bed1cc84afa..c9aa767ac10 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h @@ -10,8 +10,8 @@ #include <queue> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" @@ -70,16 +70,16 @@ class QUIC_EXPORT_PRIVATE QpackHeaderTable { // Returns the absolute index of an entry with matching name and value if such // exists, otherwise one with matching name is such exists. |index| is zero // based for both the static and the dynamic table. - MatchType FindHeaderField(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, + MatchType FindHeaderField(absl::string_view name, + absl::string_view value, bool* is_static, uint64_t* index) const; // Insert (name, value) into the dynamic table. May evict entries. Returns a // pointer to the inserted owned entry on success. Returns nullptr if entry // is larger than the capacity of the dynamic table. - const QpackEntry* InsertEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + const QpackEntry* InsertEntry(absl::string_view name, + absl::string_view value); // Returns the size of the largest entry that could be inserted into the // dynamic table without evicting entry |index|. |index| might be larger than diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc index a96159be486..b06786eb437 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table_test.cc @@ -6,10 +6,10 @@ #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h" using ::testing::Mock; @@ -40,8 +40,8 @@ class QpackHeaderTableTest : public QuicTest { void ExpectEntryAtIndex(bool is_static, uint64_t index, - quiche::QuicheStringPiece expected_name, - quiche::QuicheStringPiece expected_value) const { + absl::string_view expected_name, + absl::string_view expected_value) const { const auto* entry = table_.LookupEntry(is_static, index); ASSERT_TRUE(entry); EXPECT_EQ(expected_name, entry->name()); @@ -52,8 +52,8 @@ class QpackHeaderTableTest : public QuicTest { EXPECT_FALSE(table_.LookupEntry(is_static, index)); } - void ExpectMatch(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, + void ExpectMatch(absl::string_view name, + absl::string_view value, QpackHeaderTable::MatchType expected_match_type, bool expected_is_static, uint64_t expected_index) const { @@ -70,8 +70,7 @@ class QpackHeaderTableTest : public QuicTest { EXPECT_EQ(expected_index, index) << name << ": " << value; } - void ExpectNoMatch(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) const { + void ExpectNoMatch(absl::string_view name, absl::string_view value) const { bool is_static = false; uint64_t index = 0; @@ -82,13 +81,12 @@ class QpackHeaderTableTest : public QuicTest { << name << ": " << value; } - void InsertEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void InsertEntry(absl::string_view name, absl::string_view value) { EXPECT_TRUE(table_.InsertEntry(name, value)); } - void ExpectToFailInsertingEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void ExpectToFailInsertingEntry(absl::string_view name, + absl::string_view value) { EXPECT_FALSE(table_.InsertEntry(name, value)); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc index 1f85d7f1fa7..539e3109cca 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.cc @@ -7,9 +7,9 @@ #include <algorithm> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -33,7 +33,7 @@ QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language, error_detected_(false), state_(State::kStartInstruction) {} -bool QpackInstructionDecoder::Decode(quiche::QuicheStringPiece data) { +bool QpackInstructionDecoder::Decode(absl::string_view data) { DCHECK(!data.empty()); DCHECK(!error_detected_); @@ -77,8 +77,8 @@ bool QpackInstructionDecoder::Decode(quiche::QuicheStringPiece data) { DCHECK_LE(bytes_consumed, data.size()); - data = quiche::QuicheStringPiece(data.data() + bytes_consumed, - data.size() - bytes_consumed); + data = absl::string_view(data.data() + bytes_consumed, + data.size() - bytes_consumed); // Stop processing if no more data but next state would require it. if (data.empty() && (state_ != State::kStartField) && @@ -94,8 +94,7 @@ bool QpackInstructionDecoder::AtInstructionBoundary() const { return state_ == State::kStartInstruction; } -bool QpackInstructionDecoder::DoStartInstruction( - quiche::QuicheStringPiece data) { +bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) { DCHECK(!data.empty()); instruction_ = LookupOpcode(data[0]); @@ -133,7 +132,7 @@ bool QpackInstructionDecoder::DoStartField() { } } -bool QpackInstructionDecoder::DoReadBit(quiche::QuicheStringPiece data) { +bool QpackInstructionDecoder::DoReadBit(absl::string_view data) { DCHECK(!data.empty()); switch (field_->type) { @@ -163,7 +162,7 @@ bool QpackInstructionDecoder::DoReadBit(quiche::QuicheStringPiece data) { } } -bool QpackInstructionDecoder::DoVarintStart(quiche::QuicheStringPiece data, +bool QpackInstructionDecoder::DoVarintStart(absl::string_view data, size_t* bytes_consumed) { DCHECK(!data.empty()); DCHECK(field_->type == QpackInstructionFieldType::kVarint || @@ -184,7 +183,7 @@ bool QpackInstructionDecoder::DoVarintStart(quiche::QuicheStringPiece data, state_ = State::kVarintResume; return true; case http2::DecodeStatus::kDecodeError: - OnError("Encoded integer too large."); + OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large."); return false; default: QUIC_BUG << "Unknown decode status " << status; @@ -192,7 +191,7 @@ bool QpackInstructionDecoder::DoVarintStart(quiche::QuicheStringPiece data, } } -bool QpackInstructionDecoder::DoVarintResume(quiche::QuicheStringPiece data, +bool QpackInstructionDecoder::DoVarintResume(absl::string_view data, size_t* bytes_consumed) { DCHECK(!data.empty()); DCHECK(field_->type == QpackInstructionFieldType::kVarint || @@ -213,7 +212,7 @@ bool QpackInstructionDecoder::DoVarintResume(quiche::QuicheStringPiece data, DCHECK(buffer.Empty()); return true; case http2::DecodeStatus::kDecodeError: - OnError("Encoded integer too large."); + OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large."); return false; default: QUIC_BUG << "Unknown decode status " << status; @@ -245,7 +244,7 @@ bool QpackInstructionDecoder::DoVarintDone() { string_length_ = varint_decoder_.value(); if (string_length_ > kStringLiteralLengthLimit) { - OnError("String literal too long."); + OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long."); return false; } @@ -265,7 +264,7 @@ bool QpackInstructionDecoder::DoVarintDone() { return true; } -bool QpackInstructionDecoder::DoReadString(quiche::QuicheStringPiece data, +bool QpackInstructionDecoder::DoReadString(absl::string_view data, size_t* bytes_consumed) { DCHECK(!data.empty()); DCHECK(field_->type == QpackInstructionFieldType::kName || @@ -299,7 +298,8 @@ bool QpackInstructionDecoder::DoReadStringDone() { std::string decoded_value; huffman_decoder_.Decode(*string, &decoded_value); if (!huffman_decoder_.InputProperlyTerminated()) { - OnError("Error in Huffman-encoded string."); + OnError(ErrorCode::HUFFMAN_ENCODING_ERROR, + "Error in Huffman-encoded string."); return false; } *string = std::move(decoded_value); @@ -323,11 +323,12 @@ const QpackInstruction* QpackInstructionDecoder::LookupOpcode( return nullptr; } -void QpackInstructionDecoder::OnError(quiche::QuicheStringPiece error_message) { +void QpackInstructionDecoder::OnError(ErrorCode error_code, + absl::string_view error_message) { DCHECK(!error_detected_); error_detected_ = true; - delegate_->OnError(error_message); + delegate_->OnInstructionDecodingError(error_code, error_message); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h index 08eb665749b..b8edfb7dbf4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h @@ -9,11 +9,11 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h" #include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_decoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -22,6 +22,12 @@ namespace quic { // fields that follow each instruction. class QUIC_EXPORT_PRIVATE QpackInstructionDecoder { public: + enum class ErrorCode { + INTEGER_TOO_LARGE, + STRING_LITERAL_TOO_LONG, + HUFFMAN_ENCODING_ERROR, + }; + // Delegate is notified each time an instruction is decoded or when an error // occurs. class QUIC_EXPORT_PRIVATE Delegate { @@ -42,7 +48,9 @@ class QUIC_EXPORT_PRIVATE QpackInstructionDecoder { // No more data is processed afterwards. // Implementations are allowed to destroy the QpackInstructionDecoder // instance synchronously. - virtual void OnError(quiche::QuicheStringPiece error_message) = 0; + virtual void OnInstructionDecodingError( + ErrorCode error_code, + absl::string_view error_message) = 0; }; // Both |*language| and |*delegate| must outlive this object. @@ -53,8 +61,9 @@ class QUIC_EXPORT_PRIVATE QpackInstructionDecoder { // Provide a data fragment to decode. Must not be called after an error has // occurred. Must not be called with empty |data|. Return true on success, - // false on error (in which case Delegate::OnError() is called synchronously). - bool Decode(quiche::QuicheStringPiece data); + // false on error (in which case Delegate::OnInstructionDecodingError() is + // called synchronously). + bool Decode(absl::string_view data); // Returns true if no decoding has taken place yet or if the last instruction // has been entirely parsed. @@ -94,21 +103,21 @@ class QUIC_EXPORT_PRIVATE QpackInstructionDecoder { // data and set |*bytes_consumed| to the number of octets processed. Some // take input data but do not consume any bytes. Some do not take any // arguments because they only change internal state. - bool DoStartInstruction(quiche::QuicheStringPiece data); + bool DoStartInstruction(absl::string_view data); bool DoStartField(); - bool DoReadBit(quiche::QuicheStringPiece data); - bool DoVarintStart(quiche::QuicheStringPiece data, size_t* bytes_consumed); - bool DoVarintResume(quiche::QuicheStringPiece data, size_t* bytes_consumed); + bool DoReadBit(absl::string_view data); + bool DoVarintStart(absl::string_view data, size_t* bytes_consumed); + bool DoVarintResume(absl::string_view data, size_t* bytes_consumed); bool DoVarintDone(); - bool DoReadString(quiche::QuicheStringPiece data, size_t* bytes_consumed); + bool DoReadString(absl::string_view data, size_t* bytes_consumed); bool DoReadStringDone(); // Identify instruction based on opcode encoded in |byte|. // Returns a pointer to an element of |*language_|. const QpackInstruction* LookupOpcode(uint8_t byte) const; - // Stops decoding and calls Delegate::OnError(). - void OnError(quiche::QuicheStringPiece error_message); + // Stops decoding and calls Delegate::OnInstructionDecodingError(). + void OnError(ErrorCode error_code, absl::string_view error_message); // Describes the language used for decoding. const QpackLanguage* const language_; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc index a4bbc91aaf5..52ec38bc8c8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder_test.cc @@ -6,17 +6,18 @@ #include <algorithm> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using ::testing::_; using ::testing::Eq; using ::testing::Expectation; -using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; using ::testing::Return; using ::testing::StrictMock; using ::testing::Values; @@ -66,8 +67,9 @@ class MockDelegate : public QpackInstructionDecoder::Delegate { (const QpackInstruction*), (override)); MOCK_METHOD(void, - OnError, - (quiche::QuicheStringPiece error_message), + OnInstructionDecodingError, + (QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message), (override)); }; @@ -82,11 +84,8 @@ class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> { void SetUp() override { // Destroy QpackInstructionDecoder on error to test that it does not crash. // See https://crbug.com/1025209. - ON_CALL(delegate_, OnError(_)) - .WillByDefault( - Invoke([this](quiche::QuicheStringPiece /* error_message */) { - decoder_.reset(); - })); + ON_CALL(delegate_, OnInstructionDecodingError(_, _)) + .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); })); } // Decode one full instruction with fragment sizes dictated by @@ -95,7 +94,7 @@ class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> { // verifies that AtInstructionBoundary() returns true before and after the // instruction, and returns false while decoding is in progress. // Assumes that delegate methods destroy |decoder_| if they return false. - void DecodeInstruction(quiche::QuicheStringPiece data) { + void DecodeInstruction(absl::string_view data) { EXPECT_TRUE(decoder_->AtInstructionBoundary()); FragmentSizeGenerator fragment_size_generator = @@ -132,14 +131,14 @@ INSTANTIATE_TEST_SUITE_P(All, TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) { EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1())); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("7f01ff65")); + DecodeInstruction(absl::HexStringToBytes("7f01ff65")); EXPECT_TRUE(decoder_->s_bit()); EXPECT_EQ(64u, decoder_->varint()); EXPECT_EQ(356u, decoder_->varint2()); EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1())); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("05c8")); + DecodeInstruction(absl::HexStringToBytes("05c8")); EXPECT_FALSE(decoder_->s_bit()); EXPECT_EQ(5u, decoder_->varint()); @@ -148,69 +147,79 @@ TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) { TEST_P(QpackInstructionDecoderTest, NameAndValue) { EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2())); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("83666f6f03626172")); + DecodeInstruction(absl::HexStringToBytes("83666f6f03626172")); EXPECT_EQ("foo", decoder_->name()); EXPECT_EQ("bar", decoder_->value()); EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2())); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("8000")); + DecodeInstruction(absl::HexStringToBytes("8000")); EXPECT_EQ("", decoder_->name()); EXPECT_EQ("", decoder_->value()); EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2())); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c294e7838c767f")); + DecodeInstruction(absl::HexStringToBytes("c294e7838c767f")); EXPECT_EQ("foo", decoder_->name()); EXPECT_EQ("bar", decoder_->value()); } TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) { - EXPECT_CALL(delegate_, OnError(Eq("Error in Huffman-encoded string."))); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c1ff")); + EXPECT_CALL(delegate_, + OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR, + Eq("Error in Huffman-encoded string."))); + DecodeInstruction(absl::HexStringToBytes("c1ff")); } TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) { - EXPECT_CALL(delegate_, OnError(Eq("Encoded integer too large."))); - DecodeInstruction( - quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff")); + EXPECT_CALL(delegate_, + OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE, + Eq("Encoded integer too large."))); + DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff")); +} + +TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) { + EXPECT_CALL(delegate_, + OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG, + Eq("String literal too long."))); + DecodeInstruction(absl::HexStringToBytes("bfffff7f")); } TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) { // First instruction is valid. Expectation first_call = EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1())) - .WillOnce(Invoke( - [this](const QpackInstruction * /* instruction */) -> bool { - EXPECT_EQ(1u, decoder_->varint()); - return true; - })); + .WillOnce(InvokeWithoutArgs([this]() -> bool { + EXPECT_EQ(1u, decoder_->varint()); + return true; + })); // Second instruction is invalid. Decoding must halt. EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1())) .After(first_call) - .WillOnce( - Invoke([this](const QpackInstruction * /* instruction */) -> bool { - EXPECT_EQ(2u, decoder_->varint()); - return false; - })); + .WillOnce(InvokeWithoutArgs([this]() -> bool { + EXPECT_EQ(2u, decoder_->varint()); + return false; + })); - EXPECT_FALSE(decoder_->Decode( - quiche::QuicheTextUtils::HexDecode("01000200030004000500"))); + EXPECT_FALSE( + decoder_->Decode(absl::HexStringToBytes("01000200030004000500"))); } // QpackInstructionDecoder must not crash if it is destroyed from a // Delegate::OnInstructionDecoded() call as long as it returns false. TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) { EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1())) - .WillOnce( - Invoke([this](const QpackInstruction * /* instruction */) -> bool { - EXPECT_EQ(1u, decoder_->varint()); - decoder_.reset(); - return false; - })); - DecodeInstruction(quiche::QuicheTextUtils::HexDecode("0100")); + .WillOnce(InvokeWithoutArgs([this]() -> bool { + EXPECT_EQ(1u, decoder_->varint()); + decoder_.reset(); + return false; + })); + DecodeInstruction(absl::HexStringToBytes("0100")); } } // namespace diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc index 41e2d763455..c79665447f9 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.cc @@ -6,16 +6,27 @@ #include <limits> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" #include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { QpackInstructionEncoder::QpackInstructionEncoder() - : byte_(0), state_(State::kOpcode), instruction_(nullptr) {} + : use_huffman_(false), + string_length_(0), + byte_(0), + state_(State::kOpcode), + instruction_(nullptr), + use_fast_huffman_encoder_( + GetQuicReloadableFlag(quic_use_fast_huffman_encoder)) { + if (use_fast_huffman_encoder_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_use_fast_huffman_encoder); + } +} void QpackInstructionEncoder::Encode( const QpackInstructionWithValues& instruction_with_values, @@ -49,7 +60,8 @@ void QpackInstructionEncoder::Encode( instruction_with_values.value()); break; case State::kWriteString: - DoWriteString(output); + DoWriteString(instruction_with_values.name(), + instruction_with_values.value(), output); break; } } while (field_ != instruction_->fields.end()); @@ -110,7 +122,7 @@ void QpackInstructionEncoder::DoVarintEncode(uint64_t varint, integer_to_encode = varint2; break; default: - integer_to_encode = string_to_write_.size(); + integer_to_encode = string_length_; break; } @@ -128,30 +140,45 @@ void QpackInstructionEncoder::DoVarintEncode(uint64_t varint, state_ = State::kWriteString; } -void QpackInstructionEncoder::DoStartString(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +void QpackInstructionEncoder::DoStartString(absl::string_view name, + absl::string_view value) { DCHECK(field_->type == QpackInstructionFieldType::kName || field_->type == QpackInstructionFieldType::kValue); - string_to_write_ = + absl::string_view string_to_write = (field_->type == QpackInstructionFieldType::kName) ? name : value; - http2::HuffmanEncode(string_to_write_, &huffman_encoded_string_); + string_length_ = string_to_write.size(); - if (huffman_encoded_string_.size() < string_to_write_.size()) { - DCHECK_EQ(0, byte_ & (1 << field_->param)); + size_t encoded_size = http2::HuffmanSize(string_to_write); + use_huffman_ = encoded_size < string_length_; + if (use_huffman_) { + DCHECK_EQ(0, byte_ & (1 << field_->param)); byte_ |= (1 << field_->param); - string_to_write_ = huffman_encoded_string_; + + string_length_ = encoded_size; } state_ = State::kVarintEncode; } -void QpackInstructionEncoder::DoWriteString(std::string* output) { +void QpackInstructionEncoder::DoWriteString(absl::string_view name, + absl::string_view value, + std::string* output) { DCHECK(field_->type == QpackInstructionFieldType::kName || field_->type == QpackInstructionFieldType::kValue); - QuicStrAppend(output, string_to_write_); + absl::string_view string_to_write = + (field_->type == QpackInstructionFieldType::kName) ? name : value; + if (use_huffman_) { + if (use_fast_huffman_encoder_) { + http2::HuffmanEncodeFast(string_to_write, string_length_, output); + } else { + http2::HuffmanEncode(string_to_write, string_length_, output); + } + } else { + QuicStrAppend(output, string_to_write); + } ++field_; state_ = State::kStartField; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h index 2a955f88db4..4f6fac71c6b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h @@ -8,9 +8,9 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -38,11 +38,12 @@ class QUIC_EXPORT_PRIVATE QpackInstructionEncoder { // Encode an integer (|varint_| or |varint2_| or string length) with a // prefix, using |byte_| for the high bits. kVarintEncode, - // Determine if Huffman encoding should be used for |name_| or |value_|, set - // up |name_| or |value_| and |huffman_encoded_string_| accordingly, and - // write the Huffman bit to |byte_|. + // Determine if Huffman encoding should be used for the header name or + // value, set |use_huffman_| and |string_length_| appropriately, write the + // Huffman bit to |byte_|. kStartString, - // Write string. + // Write header name or value, performing Huffman encoding if |use_huffman_| + // is true. kWriteString }; @@ -52,19 +53,17 @@ class QUIC_EXPORT_PRIVATE QpackInstructionEncoder { void DoStartField(); void DoSBit(bool s_bit); void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output); - void DoStartString(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); - void DoWriteString(std::string* output); + void DoStartString(absl::string_view name, absl::string_view value); + void DoWriteString(absl::string_view name, + absl::string_view value, + std::string* output); + // True if name or value should be Huffman encoded. + bool use_huffman_; - // Storage for the Huffman encoded string literal to be written if Huffman - // encoding is used. - std::string huffman_encoded_string_; - - // If Huffman encoding is used, points to a substring of - // |huffman_encoded_string_|. - // Otherwise points to a substring of |name_| or |value_|. - quiche::QuicheStringPiece string_to_write_; + // Length of name or value string to be written. + // If |use_huffman_| is true, length is after Huffman encoding. + size_t string_length_; // Storage for a single byte that contains multiple fields, that is, multiple // states are writing it. @@ -78,6 +77,9 @@ class QUIC_EXPORT_PRIVATE QpackInstructionEncoder { // Field currently being decoded. QpackInstructionFields::const_iterator field_; + + // Latched value of gfe2_reloadable_flag_quic_use_fast_huffman_encoder. + const bool use_fast_huffman_encoder_; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc index 6f3337c1a61..893bc50670f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder_test.cc @@ -4,9 +4,10 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -37,12 +38,12 @@ class QpackInstructionWithValuesPeer { } static void set_name(QpackInstructionWithValues* instruction_with_values, - quiche::QuicheStringPiece name) { + absl::string_view name) { instruction_with_values->name_ = name; } static void set_value(QpackInstructionWithValues* instruction_with_values, - quiche::QuicheStringPiece value) { + absl::string_view value) { instruction_with_values->value_ = value; } }; @@ -62,12 +63,10 @@ class QpackInstructionEncoderTest : public QuicTest { // Compare substring appended to |output_| since last EncodedSegmentMatches() // call against hex-encoded argument. - bool EncodedSegmentMatches( - quiche::QuicheStringPiece hex_encoded_expected_substring) { + bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) { auto recently_encoded = - quiche::QuicheStringPiece(output_).substr(verified_position_); - auto expected = - quiche::QuicheTextUtils::HexDecode(hex_encoded_expected_substring); + absl::string_view(output_).substr(verified_position_); + auto expected = absl::HexStringToBytes(hex_encoded_expected_substring); verified_position_ = output_.size(); return recently_encoded == expected; } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc index 1e5d1124c57..12db3639d39 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.cc @@ -6,8 +6,8 @@ #include <limits> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -204,7 +204,7 @@ const QpackLanguage* QpackRequestStreamLanguage() { QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference( bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value) { + absl::string_view value) { QpackInstructionWithValues instruction_with_values; instruction_with_values.instruction_ = InsertWithNameReferenceInstruction(); instruction_with_values.s_bit_ = is_static; @@ -217,8 +217,8 @@ QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference( // static QpackInstructionWithValues QpackInstructionWithValues::InsertWithoutNameReference( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + absl::string_view name, + absl::string_view value) { QpackInstructionWithValues instruction_with_values; instruction_with_values.instruction_ = InsertWithoutNameReferenceInstruction(); @@ -307,7 +307,7 @@ QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderFieldNameReference( bool is_static, uint64_t index, - quiche::QuicheStringPiece value) { + absl::string_view value) { QpackInstructionWithValues instruction_with_values; instruction_with_values.instruction_ = QpackLiteralHeaderFieldNameReferenceInstruction(); @@ -320,8 +320,8 @@ QpackInstructionWithValues::LiteralHeaderFieldNameReference( // static QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderField( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + absl::string_view name, + absl::string_view value) { QpackInstructionWithValues instruction_with_values; instruction_with_values.instruction_ = QpackLiteralHeaderFieldInstruction(); instruction_with_values.name_ = name; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h index d63a1e26ba5..006c9a7ab2f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h @@ -10,8 +10,8 @@ #include <tuple> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -151,10 +151,10 @@ class QUIC_EXPORT_PRIVATE QpackInstructionWithValues { static QpackInstructionWithValues InsertWithNameReference( bool is_static, uint64_t name_index, - quiche::QuicheStringPiece value); + absl::string_view value); static QpackInstructionWithValues InsertWithoutNameReference( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + absl::string_view name, + absl::string_view value); static QpackInstructionWithValues Duplicate(uint64_t index); static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity); @@ -172,17 +172,16 @@ class QUIC_EXPORT_PRIVATE QpackInstructionWithValues { static QpackInstructionWithValues LiteralHeaderFieldNameReference( bool is_static, uint64_t index, - quiche::QuicheStringPiece value); - static QpackInstructionWithValues LiteralHeaderField( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + absl::string_view value); + static QpackInstructionWithValues LiteralHeaderField(absl::string_view name, + absl::string_view value); const QpackInstruction* instruction() const { return instruction_; } bool s_bit() const { return s_bit_; } uint64_t varint() const { return varint_; } uint64_t varint2() const { return varint2_; } - quiche::QuicheStringPiece name() const { return name_; } - quiche::QuicheStringPiece value() const { return value_; } + absl::string_view name() const { return name_; } + absl::string_view value() const { return value_; } // Used by QpackEncoder, because in the first pass it stores absolute indices, // which are converted into relative indices in the second pass after base is @@ -199,8 +198,8 @@ class QUIC_EXPORT_PRIVATE QpackInstructionWithValues { bool s_bit_; uint64_t varint_; uint64_t varint2_; - quiche::QuicheStringPiece name_; - quiche::QuicheStringPiece value_; + absl::string_view name_; + absl::string_view value_; }; } // 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 c1c002fd913..851efe73633 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 @@ -5,10 +5,10 @@ #include <cstddef> #include <iostream> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" int main(int argc, char* argv[]) { const char* usage = @@ -25,8 +25,8 @@ int main(int argc, char* argv[]) { size_t i; size_t success_count = 0; for (i = 0; 2 * i < args.size(); ++i) { - const quiche::QuicheStringPiece input_filename(args[2 * i]); - const quiche::QuicheStringPiece expected_headers_filename(args[2 * i + 1]); + const absl::string_view input_filename(args[2 * i]); + const absl::string_view expected_headers_filename(args[2 * i + 1]); // Every file represents a different connection, // therefore every file needs a fresh decoding context. diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc index cf20bde3c60..83c55e0b31b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.cc @@ -8,11 +8,11 @@ #include <limits> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_index_conversions.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -46,7 +46,7 @@ QpackProgressiveDecoder::~QpackProgressiveDecoder() { } } -void QpackProgressiveDecoder::Decode(quiche::QuicheStringPiece data) { +void QpackProgressiveDecoder::Decode(absl::string_view data) { DCHECK(decoding_); if (data.empty() || error_detected_) { @@ -89,6 +89,14 @@ void QpackProgressiveDecoder::EndHeaderBlock() { } } +void QpackProgressiveDecoder::OnError(absl::string_view error_message) { + DCHECK(!error_detected_); + + error_detected_ = true; + // Might destroy |this|. + handler_->OnDecodingErrorDetected(error_message); +} + bool QpackProgressiveDecoder::OnInstructionDecoded( const QpackInstruction* instruction) { if (instruction == QpackPrefixInstruction()) { @@ -114,12 +122,13 @@ bool QpackProgressiveDecoder::OnInstructionDecoded( return DoLiteralHeaderFieldInstruction(); } -void QpackProgressiveDecoder::OnError(quiche::QuicheStringPiece error_message) { - DCHECK(!error_detected_); - - error_detected_ = true; - // Might destroy |this|. - handler_->OnDecodingErrorDetected(error_message); +void QpackProgressiveDecoder::OnInstructionDecodingError( + QpackInstructionDecoder::ErrorCode /* error_code */, + absl::string_view error_message) { + // Ignore |error_code|, because header block decoding errors trigger a + // RESET_STREAM frame which cannot carry an error code more granular than + // QPACK_DECOMPRESSION_FAILED. + OnError(error_message); } void QpackProgressiveDecoder::OnInsertCountReachedThreshold() { diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h index f9c0224c637..dfc25f9177d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h @@ -9,12 +9,12 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -32,8 +32,8 @@ class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder // Called when a new header name-value pair is decoded. Multiple values for // a given name will be emitted as multiple calls to OnHeader. - virtual void OnHeaderDecoded(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) = 0; + virtual void OnHeaderDecoded(absl::string_view name, + absl::string_view value) = 0; // Called when the header block is completely decoded. // Indicates the total number of bytes in this block. @@ -46,8 +46,7 @@ class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder // Called when a decoding error has occurred. No other methods will be // called afterwards. Implementations are allowed to destroy // the QpackProgressiveDecoder instance synchronously. - virtual void OnDecodingErrorDetected( - quiche::QuicheStringPiece error_message) = 0; + virtual void OnDecodingErrorDetected(absl::string_view error_message) = 0; }; // Interface for keeping track of blocked streams for the purpose of enforcing @@ -90,15 +89,19 @@ class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder ~QpackProgressiveDecoder() override; // Provide a data fragment to decode. - void Decode(quiche::QuicheStringPiece data); + void Decode(absl::string_view data); // Signal that the entire header block has been received and passed in // through Decode(). No methods must be called afterwards. void EndHeaderBlock(); + // Called on error. + void OnError(absl::string_view error_message); + // QpackInstructionDecoder::Delegate implementation. bool OnInstructionDecoded(const QpackInstruction* instruction) override; - void OnError(quiche::QuicheStringPiece error_message) override; + void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code, + absl::string_view error_message) override; // QpackHeaderTable::Observer implementation. void OnInsertCountReachedThreshold() override; diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc index b2f15c4ecb3..c7291f7d779 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { QpackReceiveStream::QpackReceiveStream(PendingStream* pending, @@ -25,7 +25,7 @@ void QpackReceiveStream::OnDataAvailable() { while (!reading_stopped() && sequencer()->GetReadableRegion(&iov)) { DCHECK(!sequencer()->IsClosed()); - receiver_->Decode(quiche::QuicheStringPiece( + receiver_->Decode(absl::string_view( reinterpret_cast<const char*>(iov.iov_base), iov.iov_len)); sequencer()->MarkConsumed(iov.iov_len); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc index 8a8064e5a7e..88cb589a67e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream_test.cc @@ -4,11 +4,11 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -64,7 +64,7 @@ class QpackReceiveStreamTest : public QuicTestWithParam<TestParams> { : GetNthServerInitiatedUnidirectionalStreamId( session_.transport_version(), 3); char type[] = {0x03}; - QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); + QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1)); session_.OnStreamFrame(data1); qpack_receive_stream_ = QuicSpdySessionPeer::GetQpackDecoderReceiveStream(&session_); diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc index fce7de9af01..fca16c04745 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count_test.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -50,7 +50,7 @@ struct { {600, 100, 500}}; TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) { const uint64_t required_insert_count = kTestData[i].required_insert_count; const uint64_t max_entries = kTestData[i].max_entries; const uint64_t total_number_of_inserts = @@ -109,7 +109,7 @@ struct { {601, 100, 500}}; TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) { - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kInvalidTestData); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(kInvalidTestData); ++i) { uint64_t decoded_required_insert_count = 0; EXPECT_FALSE(QpackDecodeRequiredInsertCount( kInvalidTestData[i].encoded_required_insert_count, diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc index 8625baa3c5c..46e7e887a15 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_round_trip_test.cc @@ -5,11 +5,11 @@ #include <string> #include <tuple> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" using ::testing::Values; @@ -23,8 +23,8 @@ class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> { QpackRoundTripTest() = default; ~QpackRoundTripTest() override = default; - spdy::SpdyHeaderBlock EncodeThenDecode( - const spdy::SpdyHeaderBlock& header_list) { + spdy::Http2HeaderBlock EncodeThenDecode( + const spdy::Http2HeaderBlock& header_list) { NoopDecoderStreamErrorDelegate decoder_stream_error_delegate; NoopQpackStreamSenderDelegate encoder_stream_sender_delegate; QpackEncoder encoder(&decoder_stream_error_delegate); @@ -55,80 +55,80 @@ INSTANTIATE_TEST_SUITE_P(All, FragmentMode::kOctetByOctet)); TEST_P(QpackRoundTripTest, Empty) { - spdy::SpdyHeaderBlock header_list; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock header_list; + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } TEST_P(QpackRoundTripTest, EmptyName) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; header_list[""] = "bar"; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } TEST_P(QpackRoundTripTest, EmptyValue) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = ""; header_list[""] = ""; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } TEST_P(QpackRoundTripTest, MultipleWithLongEntries) { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list["foo"] = "bar"; header_list[":path"] = "/"; header_list["foobaar"] = std::string(127, 'Z'); header_list[std::string(1000, 'b')] = std::string(1000, 'c'); - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } TEST_P(QpackRoundTripTest, StaticTable) { { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "GET"; header_list["accept-encoding"] = "gzip, deflate"; header_list["cache-control"] = ""; header_list["foo"] = "bar"; header_list[":path"] = "/"; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "POST"; header_list["accept-encoding"] = "brotli"; header_list["cache-control"] = "foo"; header_list["foo"] = "bar"; header_list[":path"] = "/"; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } { - spdy::SpdyHeaderBlock header_list; + spdy::Http2HeaderBlock header_list; header_list[":method"] = "CONNECT"; header_list["accept-encoding"] = ""; header_list["foo"] = "bar"; header_list[":path"] = "/"; - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } } TEST_P(QpackRoundTripTest, ValueHasNullCharacter) { - spdy::SpdyHeaderBlock header_list; - header_list["foo"] = quiche::QuicheStringPiece("bar\0bar\0baz", 11); + spdy::Http2HeaderBlock header_list; + header_list["foo"] = absl::string_view("bar\0bar\0baz", 11); - spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list); + spdy::Http2HeaderBlock output = EncodeThenDecode(header_list); EXPECT_EQ(header_list, output); } 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 176c431afb9..d6919d73600 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 @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { QpackSendStream::QpackSendStream(QuicStreamId id, @@ -27,7 +27,7 @@ bool QpackSendStream::OnStopSending(QuicRstStreamErrorCode /* code */) { return false; } -void QpackSendStream::WriteStreamData(quiche::QuicheStringPiece data) { +void QpackSendStream::WriteStreamData(absl::string_view data) { QuicConnection::ScopedPacketFlusher flusher(session()->connection()); MaybeSendStreamType(); WriteOrBufferData(data, false, nullptr); @@ -36,10 +36,10 @@ void QpackSendStream::WriteStreamData(quiche::QuicheStringPiece data) { void QpackSendStream::MaybeSendStreamType() { if (!stream_type_sent_) { char type[sizeof(http3_stream_type_)]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(type), type); + QuicDataWriter writer(ABSL_ARRAYSIZE(type), type); writer.WriteVarInt62(http3_stream_type_); - WriteOrBufferData(quiche::QuicheStringPiece(writer.data(), writer.length()), - false, nullptr); + WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false, + nullptr); stream_type_sent_ = true; } } 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 e8a4ea797d2..d7f68ee887b 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 @@ -7,10 +7,10 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h" #include "net/third_party/quiche/src/quic/core/quic_stream.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -41,7 +41,7 @@ class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream, // Writes the instructions to peer. The stream type will be sent // before the first instruction so that the peer can open an qpack stream. - void WriteStreamData(quiche::QuicheStringPiece data) override; + void WriteStreamData(absl::string_view data) override; // TODO(b/112770235): Remove this method once QuicStreamIdManager supports // creating HTTP/3 unidirectional streams dynamically. diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc index 2ac3289d476..80c89863062 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc @@ -4,6 +4,8 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h" +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" @@ -11,7 +13,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -69,6 +70,9 @@ class QpackSendStreamTest : public QuicTestWithParam<TestParams> { session_(connection_) { EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber()); session_.Initialize(); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); if (connection_->version().SupportsAntiAmplificationLimit()) { QuicConnectionPeer::SetAddressValidated(connection_); } @@ -104,10 +108,10 @@ TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) { std::string data = "data"; EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _)); EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _)); - qpack_send_stream_->WriteStreamData(quiche::QuicheStringPiece(data)); + qpack_send_stream_->WriteStreamData(absl::string_view(data)); EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _)); - qpack_send_stream_->WriteStreamData(quiche::QuicheStringPiece(data)); + qpack_send_stream_->WriteStreamData(absl::string_view(data)); EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0); qpack_send_stream_->MaybeSendStreamType(); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc index 17138be94d5..e88abe00026 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table.cc @@ -4,15 +4,15 @@ #include "net/third_party/quiche/src/quic/core/qpack/qpack_static_table.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { // The "constructor" for a QpackStaticEntry that computes the lengths at // compile time. #define STATIC_ENTRY(name, value) \ - { name, QUICHE_ARRAYSIZE(name) - 1, value, QUICHE_ARRAYSIZE(value) - 1 } + { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 } const std::vector<QpackStaticEntry>& QpackStaticTableVector() { static const auto* kQpackStaticTable = new std::vector<QpackStaticEntry>{ diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc index 1376d2cd51a..a771cf3862d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_static_table_test.cc @@ -6,9 +6,9 @@ #include <set> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -32,7 +32,7 @@ TEST(QpackStaticTableTest, Initialize) { EXPECT_EQ(QpackStaticTableVector().size(), static_index.size()); auto static_name_index = table.GetStaticNameIndex(); - std::set<quiche::QuicheStringPiece> names; + std::set<absl::string_view> names; for (auto entry : static_index) { names.insert(entry->name()); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h index 01c2d5f4237..d7c4b550b1b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_stream_receiver.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_ #define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -16,7 +16,7 @@ class QUIC_EXPORT_PRIVATE QpackStreamReceiver { virtual ~QpackStreamReceiver() = default; // Decode data. - virtual void Decode(quiche::QuicheStringPiece data) = 0; + virtual void Decode(absl::string_view data) = 0; }; } // namespace quic 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 524b756653d..9f3faf80bb1 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 @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_ #define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -16,7 +16,7 @@ class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate { virtual ~QpackStreamSenderDelegate() = default; // Write data on the unidirectional stream. - virtual void WriteStreamData(quiche::QuicheStringPiece data) = 0; + virtual void WriteStreamData(absl::string_view data) = 0; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc index 65d1b99e0a8..c18610939f1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { namespace { @@ -16,8 +16,8 @@ const char kNonCookieSeparator = '\0'; } // namespace ValueSplittingHeaderList::const_iterator::const_iterator( - const spdy::SpdyHeaderBlock* header_list, - spdy::SpdyHeaderBlock::const_iterator header_list_iterator) + const spdy::Http2HeaderBlock* header_list, + spdy::Http2HeaderBlock::const_iterator header_list_iterator) : header_list_(header_list), header_list_iterator_(header_list_iterator), value_start_(0) { @@ -37,7 +37,7 @@ bool ValueSplittingHeaderList::const_iterator::operator!=( const ValueSplittingHeaderList::const_iterator& ValueSplittingHeaderList::const_iterator::operator++() { - if (value_end_ == quiche::QuicheStringPiece::npos) { + if (value_end_ == absl::string_view::npos) { // This was the last frament within |*header_list_iterator_|, // move on to the next header element of |header_list_|. ++header_list_iterator_; @@ -61,15 +61,14 @@ const ValueSplittingHeaderList::value_type* } void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() { - DCHECK(value_start_ != quiche::QuicheStringPiece::npos); + DCHECK(value_start_ != absl::string_view::npos); if (header_list_iterator_ == header_list_->end()) { return; } - const quiche::QuicheStringPiece name = header_list_iterator_->first; - const quiche::QuicheStringPiece original_value = - header_list_iterator_->second; + const absl::string_view name = header_list_iterator_->first; + const absl::string_view original_value = header_list_iterator_->second; if (name == kCookieKey) { value_end_ = original_value.find(kCookieSeparator, value_start_); @@ -77,12 +76,12 @@ void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() { value_end_ = original_value.find(kNonCookieSeparator, value_start_); } - const quiche::QuicheStringPiece value = + const absl::string_view value = original_value.substr(value_start_, value_end_ - value_start_); header_field_ = std::make_pair(name, value); // Skip character after ';' separator if it is a space. - if (name == kCookieKey && value_end_ != quiche::QuicheStringPiece::npos && + if (name == kCookieKey && value_end_ != absl::string_view::npos && value_end_ + 1 < original_value.size() && original_value[value_end_ + 1] == kOptionalSpaceAfterCookieSeparator) { ++value_end_; @@ -90,7 +89,7 @@ void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() { } ValueSplittingHeaderList::ValueSplittingHeaderList( - const spdy::SpdyHeaderBlock* header_list) + const spdy::Http2HeaderBlock* header_list) : header_list_(header_list) { DCHECK(header_list_); } diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h index 446548a23ab..06518a59075 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h @@ -5,24 +5,24 @@ #ifndef QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_ #define QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { -// A wrapper class around SpdyHeaderBlock that splits header values along ';' +// A wrapper class around Http2HeaderBlock that splits header values along ';' // separators (while also removing optional space following separator) for // cookies and along '\0' separators for other header fields. class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList { public: - using value_type = spdy::SpdyHeaderBlock::value_type; + using value_type = spdy::Http2HeaderBlock::value_type; class QUIC_EXPORT_PRIVATE const_iterator { public: // |header_list| must outlive this object. - const_iterator(const spdy::SpdyHeaderBlock* header_list, - spdy::SpdyHeaderBlock::const_iterator header_list_iterator); + const_iterator(const spdy::Http2HeaderBlock* header_list, + spdy::Http2HeaderBlock::const_iterator header_list_iterator); const_iterator(const const_iterator&) = default; const_iterator& operator=(const const_iterator&) = delete; @@ -38,15 +38,15 @@ class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList { // Find next separator; update |value_end_| and |header_field_|. void UpdateHeaderField(); - const spdy::SpdyHeaderBlock* const header_list_; - spdy::SpdyHeaderBlock::const_iterator header_list_iterator_; - quiche::QuicheStringPiece::size_type value_start_; - quiche::QuicheStringPiece::size_type value_end_; + const spdy::Http2HeaderBlock* const header_list_; + spdy::Http2HeaderBlock::const_iterator header_list_iterator_; + absl::string_view::size_type value_start_; + absl::string_view::size_type value_end_; value_type header_field_; }; // |header_list| must outlive this object. - explicit ValueSplittingHeaderList(const spdy::SpdyHeaderBlock* header_list); + explicit ValueSplittingHeaderList(const spdy::Http2HeaderBlock* header_list); ValueSplittingHeaderList(const ValueSplittingHeaderList&) = delete; ValueSplittingHeaderList& operator=(const ValueSplittingHeaderList&) = delete; @@ -54,7 +54,7 @@ class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList { const_iterator end() const; private: - const spdy::SpdyHeaderBlock* const header_list_; + const spdy::Http2HeaderBlock* const header_list_; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc index c1da85c8cd0..0fc04ccbf56 100644 --- a/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list_test.cc @@ -4,9 +4,9 @@ #include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -16,8 +16,8 @@ using ::testing::ElementsAre; using ::testing::Pair; TEST(ValueSplittingHeaderListTest, Comparison) { - spdy::SpdyHeaderBlock block; - block["foo"] = quiche::QuicheStringPiece("bar\0baz", 7); + spdy::Http2HeaderBlock block; + block["foo"] = absl::string_view("bar\0baz", 7); block["baz"] = "qux"; block["cookie"] = "foo; bar"; @@ -75,7 +75,7 @@ TEST(ValueSplittingHeaderListTest, Comparison) { } TEST(ValueSplittingHeaderListTest, Empty) { - spdy::SpdyHeaderBlock block; + spdy::Http2HeaderBlock block; ValueSplittingHeaderList headers(&block); EXPECT_THAT(headers, ElementsAre()); @@ -85,7 +85,7 @@ TEST(ValueSplittingHeaderListTest, Empty) { TEST(ValueSplittingHeaderListTest, Split) { struct { const char* name; - quiche::QuicheStringPiece value; + absl::string_view value; std::vector<const char*> expected_values; } kTestData[]{ // Empty value. @@ -113,8 +113,8 @@ TEST(ValueSplittingHeaderListTest, Split) { {"cookie", "; foobar; ", {"", "foobar", ""}}, }; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(kTestData); ++i) { - spdy::SpdyHeaderBlock block; + for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) { + spdy::Http2HeaderBlock block; block[kTestData[i].name] = kTestData[i].value; ValueSplittingHeaderList headers(&block); @@ -130,10 +130,10 @@ TEST(ValueSplittingHeaderListTest, Split) { } TEST(ValueSplittingHeaderListTest, MultipleFields) { - spdy::SpdyHeaderBlock block; - block["foo"] = quiche::QuicheStringPiece("bar\0baz\0", 8); + spdy::Http2HeaderBlock block; + block["foo"] = absl::string_view("bar\0baz\0", 8); block["cookie"] = "foo; bar"; - block["bar"] = quiche::QuicheStringPiece("qux\0foo", 7); + block["bar"] = absl::string_view("qux\0foo", 7); ValueSplittingHeaderList headers(&block); EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("foo", "baz"), @@ -143,7 +143,7 @@ TEST(ValueSplittingHeaderListTest, MultipleFields) { } TEST(ValueSplittingHeaderListTest, CookieStartsWithSpace) { - spdy::SpdyHeaderBlock block; + spdy::Http2HeaderBlock block; block["foo"] = "bar"; block["cookie"] = " foo"; block["bar"] = "baz"; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h b/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h index 92da3dbc9de..fdd0c2928b7 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h @@ -13,7 +13,6 @@ #include <cstdint> // for uintptr_t -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" @@ -21,7 +20,7 @@ namespace quic { template <typename T> class QUIC_NO_EXPORT QuicArenaScopedPtr { - static_assert(QUIC_ALIGN_OF(T*) > 1, + static_assert(alignof(T*) > 1, "QuicArenaScopedPtr can only store objects that are aligned to " "greater than 1 byte."); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc index ad2c03289a6..144a1765d62 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.cc @@ -7,8 +7,8 @@ #include <cinttypes> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h index e3e0cd1d8ba..97de22c9dcf 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth.h @@ -17,6 +17,7 @@ #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" namespace quic { @@ -54,8 +55,23 @@ class QUIC_EXPORT_PRIVATE QuicBandwidth { // Create a new QuicBandwidth based on the bytes per the elapsed delta. static inline QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes, QuicTime::Delta delta) { - return QuicBandwidth((8 * bytes * kNumMicrosPerSecond) / - delta.ToMicroseconds()); + if (!GetQuicReloadableFlag(quic_round_up_tiny_bandwidth)) { + return QuicBandwidth((8 * bytes * kNumMicrosPerSecond) / + delta.ToMicroseconds()); + } + + if (bytes == 0) { + return QuicBandwidth(0); + } + + // 1 bit is 1000000 micro bits. + int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond; + if (num_micro_bits < delta.ToMicroseconds()) { + QUIC_RELOADABLE_FLAG_COUNT(quic_round_up_tiny_bandwidth); + return QuicBandwidth(1); + } + + return QuicBandwidth(num_micro_bits / delta.ToMicroseconds()); } inline int64_t ToBitsPerSecond() const { return bits_per_second_; } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc index 005eef07f8f..0a32e4e9104 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_bandwidth_test.cc @@ -58,6 +58,18 @@ TEST_F(QuicBandwidthTest, TimeDelta) { EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10), QuicBandwidth::FromBytesAndTimeDelta( 1000, QuicTime::Delta::FromMilliseconds(100))); + + EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta( + 0, QuicTime::Delta::FromSeconds(9))); + + if (GetQuicReloadableFlag(quic_round_up_tiny_bandwidth)) { + EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1), + QuicBandwidth::FromBytesAndTimeDelta( + 1, QuicTime::Delta::FromSeconds(9))); + } else { + EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta( + 1, QuicTime::Delta::FromSeconds(9))); + } } TEST_F(QuicBandwidthTest, Scale) { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc index a90cef6d324..6de1ab0cfe0 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store.cc @@ -12,9 +12,9 @@ namespace quic { -typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; -typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; -typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; +using BufferedPacket = QuicBufferedPacketStore::BufferedPacket; +using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList; +using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult; // Max number of connections this store can keep track. static const size_t kDefaultMaxConnectionsInStore = 100; @@ -100,7 +100,7 @@ EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket( const bool is_first_packet = !QuicContainsKey(undecryptable_packets_, connection_id); if (is_first_packet) { - if (ShouldBufferPacket(is_chlo)) { + if (ShouldNotBufferPacket(is_chlo)) { // Drop the packet if the upper limit of undecryptable packets has been // reached or the whole capacity of the store has been reached. return TOO_MANY_CONNECTIONS; @@ -217,7 +217,7 @@ void QuicBufferedPacketStore::MaybeSetExpirationAlarm() { } } -bool QuicBufferedPacketStore::ShouldBufferPacket(bool is_chlo) { +bool QuicBufferedPacketStore::ShouldNotBufferPacket(bool is_chlo) { bool is_store_full = undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore; 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 b862b42ee4f..7cb179d6d95 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 @@ -77,10 +77,9 @@ class QUIC_NO_EXPORT QuicBufferedPacketStore { TlsChloExtractor tls_chlo_extractor; }; - typedef QuicLinkedHashMap<QuicConnectionId, - BufferedPacketList, - QuicConnectionIdHash> - BufferedPacketMap; + using BufferedPacketMap = QuicLinkedHashMap<QuicConnectionId, + BufferedPacketList, + QuicConnectionIdHash>; class QUIC_NO_EXPORT VisitorInterface { public: @@ -166,7 +165,7 @@ class QUIC_NO_EXPORT QuicBufferedPacketStore { // Return true if add an extra packet will go beyond allowed max connection // limit. The limit for non-CHLO packet and CHLO packet is different. - bool ShouldBufferPacket(bool is_chlo); + bool ShouldNotBufferPacket(bool is_chlo); // A map to store packet queues with creation time for each connection. BufferedPacketMap undecryptable_packets_; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc index 85e4e5db79e..ffb7b5f196b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_buffered_packet_store_test.cc @@ -15,10 +15,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" namespace quic { - -typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; -typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; - static const size_t kDefaultMaxConnectionsInStore = 100; static const size_t kMaxConnectionsWithoutCHLO = kDefaultMaxConnectionsInStore / 2; @@ -26,9 +22,9 @@ static const size_t kMaxConnectionsWithoutCHLO = namespace test { namespace { -typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; -typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; - +using BufferedPacket = QuicBufferedPacketStore::BufferedPacket; +using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList; +using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult; class QuicBufferedPacketStoreVisitor : public QuicBufferedPacketStore::VisitorInterface { public: diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_circular_deque_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_circular_deque_test.cc index 19005f694e2..f2e14a26530 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_circular_deque_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_circular_deque_test.cc @@ -20,7 +20,7 @@ namespace { template <typename T, template <typename> class BaseAllocator = std::allocator> class CountingAllocator : public BaseAllocator<T> { - typedef BaseAllocator<T> BaseType; + using BaseType = BaseAllocator<T>; public: using propagate_on_container_copy_assignment = std::true_type; @@ -582,7 +582,7 @@ TEST_F(QuicCircularDequeTest, RelocateNonTriviallyCopyable) { { // Move construct in Relocate. - typedef std::unique_ptr<Foo> MoveConstructible; + using MoveConstructible = std::unique_ptr<Foo>; ASSERT_FALSE(std::is_trivially_copyable<MoveConstructible>::value); ASSERT_TRUE(std::is_move_constructible<MoveConstructible>::value); QuicCircularDeque<MoveConstructible, 3, @@ -603,7 +603,7 @@ TEST_F(QuicCircularDequeTest, RelocateNonTriviallyCopyable) { { // Copy construct in Relocate. - typedef Foo NonMoveConstructible; + using NonMoveConstructible = Foo; ASSERT_FALSE(std::is_trivially_copyable<NonMoveConstructible>::value); ASSERT_FALSE(std::is_move_constructible<NonMoveConstructible>::value); QuicCircularDeque<NonMoveConstructible, 3, 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 bac4e181c20..20dcb902318 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 @@ -10,6 +10,8 @@ #include <string> #include <utility> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" @@ -20,10 +22,8 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -411,7 +411,7 @@ QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello( const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/, std::string* error_details) { - quiche::QuicheStringPiece address; + absl::string_view address; if (!peer_hello.GetStringPiece(tag_, &address)) { if (presence_ == PRESENCE_REQUIRED) { *error_details = "Missing " + QuicTagToString(tag_); @@ -448,6 +448,8 @@ QuicConfig::QuicConfig() initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL), connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL), support_handshake_done_(0, 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,6 +865,22 @@ bool QuicConfig::PeerSupportsHandshakeDone() const { return support_handshake_done_.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()) { @@ -1228,8 +1246,7 @@ bool QuicConfig::FillTransportParameters(TransportParameters* params) const { params->google_connection_options = connection_options_.GetSendValues(); } - if (GetQuicReloadableFlag(quic_send_key_update_not_yet_supported)) { - QUIC_RELOADABLE_FLAG_COUNT(quic_send_key_update_not_yet_supported); + if (!KeyUpdateSupportedLocally()) { params->key_update_not_yet_supported = true; } @@ -1339,6 +1356,9 @@ QuicErrorCode QuicConfig::ProcessTransportParameters( if (params.support_handshake_done) { support_handshake_done_.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 4132987fb95..6e9eee12807 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 @@ -9,13 +9,13 @@ #include <cstdint> #include <string> +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" namespace quic { @@ -27,7 +27,7 @@ class CryptoHandshakeMessage; // Describes whether or not a given QuicTag is required or optional in the // handshake message. -enum QuicConfigPresence { +enum QuicConfigPresence : uint8_t { // This negotiable value can be absent from the handshake message. Default // value is selected as the negotiated value in such a case. PRESENCE_OPTIONAL, @@ -91,10 +91,10 @@ class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue { std::string* error_details) override; private: - uint32_t send_value_; bool has_send_value_; - uint32_t receive_value_; bool has_receive_value_; + uint32_t send_value_; + uint32_t receive_value_; }; // Stores 62bit numbers from handshake messages that unilaterally shared by each @@ -128,10 +128,10 @@ class QUIC_EXPORT_PRIVATE QuicFixedUint62 : public QuicConfigValue { std::string* error_details) override; private: - uint64_t send_value_; bool has_send_value_; - uint64_t receive_value_; bool has_receive_value_; + uint64_t send_value_; + uint64_t receive_value_; }; // Stores uint128 from CHLO or SHLO messages that are not negotiated. @@ -161,10 +161,10 @@ class QUIC_EXPORT_PRIVATE QuicFixedUint128 : public QuicConfigValue { std::string* error_details) override; private: - QuicUint128 send_value_; bool has_send_value_; - QuicUint128 receive_value_; bool has_receive_value_; + QuicUint128 send_value_; + QuicUint128 receive_value_; }; // Stores tag from CHLO or SHLO messages that are not negotiated. @@ -197,10 +197,10 @@ class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue { std::string* error_details) override; private: - QuicTagVector send_values_; bool has_send_values_; - QuicTagVector receive_values_; bool has_receive_values_; + QuicTagVector send_values_; + QuicTagVector receive_values_; }; // Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated. @@ -228,10 +228,10 @@ class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue { std::string* error_details) override; private: - QuicSocketAddress send_value_; bool has_send_value_; - QuicSocketAddress receive_value_; bool has_receive_value_; + QuicSocketAddress send_value_; + QuicSocketAddress receive_value_; }; // QuicConfig contains non-crypto configuration options that are negotiated in @@ -387,6 +387,12 @@ class QUIC_EXPORT_PRIVATE QuicConfig { bool HandshakeDoneSupported() const; bool PeerSupportsHandshakeDone() 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); @@ -528,7 +534,7 @@ class QUIC_EXPORT_PRIVATE QuicConfig { // Note that received_max_idle_timeout_ is only populated if we receive the // peer's value, which isn't guaranteed in IETF QUIC as sending is optional. QuicTime::Delta max_idle_timeout_to_send_; - quiche::QuicheOptional<QuicTime::Delta> received_max_idle_timeout_; + absl::optional<QuicTime::Delta> received_max_idle_timeout_; // Maximum number of dynamic streams that a Google QUIC connection // can support or the maximum number of bidirectional streams that // an IETF QUIC connection can support. @@ -580,6 +586,13 @@ class QUIC_EXPORT_PRIVATE QuicConfig { // Uses the support_handshake_done transport parameter in IETF QUIC. QuicFixedUint32 support_handshake_done_; + // 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. @@ -628,24 +641,20 @@ class QUIC_EXPORT_PRIVATE QuicConfig { // Initial packet sent by the client. // Uses the original_destination_connection_id transport parameter in // IETF QUIC. - quiche::QuicheOptional<QuicConnectionId> - original_destination_connection_id_to_send_; - quiche::QuicheOptional<QuicConnectionId> - received_original_destination_connection_id_; + absl::optional<QuicConnectionId> original_destination_connection_id_to_send_; + absl::optional<QuicConnectionId> received_original_destination_connection_id_; // The value that the endpoint included in the Source Connection ID field of // the first Initial packet it sent. // Uses the initial_source_connection_id transport parameter in IETF QUIC. - quiche::QuicheOptional<QuicConnectionId> - initial_source_connection_id_to_send_; - quiche::QuicheOptional<QuicConnectionId> - received_initial_source_connection_id_; + absl::optional<QuicConnectionId> initial_source_connection_id_to_send_; + absl::optional<QuicConnectionId> received_initial_source_connection_id_; // The value that the server included in the Source Connection ID field of a // Retry packet it sent. // Uses the retry_source_connection_id transport parameter in IETF QUIC. - quiche::QuicheOptional<QuicConnectionId> retry_source_connection_id_to_send_; - quiche::QuicheOptional<QuicConnectionId> received_retry_source_connection_id_; + absl::optional<QuicConnectionId> retry_source_connection_id_to_send_; + absl::optional<QuicConnectionId> received_retry_source_connection_id_; // Custom transport parameters that can be sent and received in the TLS // handshake. 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 dad24230b1c..f7f1618fe03 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 @@ -55,6 +55,9 @@ 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) { @@ -505,8 +508,7 @@ TEST_P(QuicConfigTest, FillTransportParams) { EXPECT_EQ( static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli, params.min_ack_delay_us.value()); - EXPECT_EQ(params.key_update_not_yet_supported, - GetQuicReloadableFlag(quic_send_key_update_not_yet_supported)); + EXPECT_TRUE(params.key_update_not_yet_supported); } TEST_P(QuicConfigTest, ProcessTransportParametersServer) { @@ -674,6 +676,83 @@ 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()); +} + } // namespace } // namespace test } // namespace quic 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 e1799817168..845e07871b6 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 @@ -15,6 +15,8 @@ #include <string> #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" @@ -27,6 +29,7 @@ #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h" #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" +#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" @@ -41,7 +44,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -170,6 +172,24 @@ class ProcessUndecryptablePacketsAlarmDelegate : public QuicAlarm::Delegate { QuicConnection* connection_; }; +class DiscardPreviousOneRttKeysAlarmDelegate : public QuicAlarm::Delegate { + public: + explicit DiscardPreviousOneRttKeysAlarmDelegate(QuicConnection* connection) + : connection_(connection) {} + DiscardPreviousOneRttKeysAlarmDelegate( + const DiscardPreviousOneRttKeysAlarmDelegate&) = delete; + DiscardPreviousOneRttKeysAlarmDelegate& operator=( + const DiscardPreviousOneRttKeysAlarmDelegate&) = delete; + + void OnAlarm() override { + DCHECK(connection_->connected()); + connection_->DiscardPreviousOneRttKeys(); + } + + private: + QuicConnection* connection_; +}; + // When the clearer goes out of scope, the coalesced packet gets cleared. class ScopedCoalescedPacketClearer { public: @@ -211,6 +231,7 @@ CongestionControlType GetDefaultCongestionControlType() { QuicConnection::QuicConnection( QuicConnectionId server_connection_id, + QuicSocketAddress initial_self_address, QuicSocketAddress initial_peer_address, QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory, @@ -237,9 +258,16 @@ QuicConnection::QuicConnection( server_connection_id_(server_connection_id), client_connection_id_(EmptyQuicConnectionId()), client_connection_id_is_set_(false), + self_address_( + GetQuicReloadableFlag(quic_connection_set_initial_self_address) + ? initial_self_address + : QuicSocketAddress()), peer_address_(initial_peer_address), direct_peer_address_(initial_peer_address), active_effective_peer_migration_type_(NO_CHANGE), + support_key_update_for_connection_(false), + enable_aead_limits_(GetQuicReloadableFlag(quic_enable_aead_limits) && + version().UsesTls()), last_packet_decrypted_(false), last_size_(0), current_packet_data_(nullptr), @@ -257,6 +285,7 @@ QuicConnection::QuicConnection( ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)), initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()), consecutive_retransmittable_on_wire_ping_count_(0), + retransmittable_on_wire_ping_count_(0), arena_(), ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this), &arena_)), @@ -275,6 +304,9 @@ QuicConnection::QuicConnection( process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm( arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this), &arena_)), + discard_previous_one_rtt_keys_alarm_(alarm_factory_->CreateAlarm( + arena_.New<DiscardPreviousOneRttKeysAlarmDelegate>(this), + &arena_)), visitor_(nullptr), debug_visitor_(nullptr), packet_creator_(server_connection_id_, &framer_, random_generator_, this), @@ -317,10 +349,24 @@ QuicConnection::QuicConnection( clock_->ApproximateNow(), &arena_, alarm_factory_), - support_handshake_done_(version().HasHandshakeDone()) { + support_handshake_done_(version().HasHandshakeDone()), + encrypted_control_frames_( + GetQuicReloadableFlag(quic_encrypted_control_frames) && + packet_creator_.let_connection_handle_pings()), + use_encryption_level_context_( + encrypted_control_frames_ && + GetQuicReloadableFlag(quic_use_encryption_level_context)) { QUIC_BUG_IF(!start_peer_migration_earlier_ && send_path_response_); - if (fix_missing_connected_checks_) { - QUIC_RELOADABLE_FLAG_COUNT(quic_add_missing_connected_checks); + if (GetQuicReloadableFlag(quic_connection_set_initial_self_address)) { + DCHECK(perspective_ == Perspective::IS_CLIENT || + self_address_.IsInitialized()); + QUIC_RELOADABLE_FLAG_COUNT(quic_connection_set_initial_self_address); + } + if (enable_aead_limits_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_enable_aead_limits); + } + if (use_encryption_level_context_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_use_encryption_level_context); } QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID " << server_connection_id @@ -336,6 +382,8 @@ QuicConnection::QuicConnection( // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument // and make it required non-null, because it's always used. sent_packet_manager_.SetNetworkChangeVisitor(this); + sent_packet_manager_.ReserveUnackedPacketsInitialCapacity( + GetUnackedMapInitialCapacity()); if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) { sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero()); release_time_into_future_ = @@ -533,8 +581,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { config.IdleNetworkTimeout()); idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::SILENT_CLOSE; - if (GetQuicReloadableFlag(quic_add_silent_idle_timeout) && - perspective_ == Perspective::IS_SERVER) { + if (perspective_ == Perspective::IS_SERVER) { idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior:: SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED; } @@ -545,6 +592,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { if (!ValidateConfigConnectionIds(config)) { return; } + support_key_update_for_connection_ = + config.KeyUpdateSupportedForConnection(); + framer_.SetKeyUpdateSupportForConnection( + support_key_update_for_connection_); } else { SetNetworkTimeouts(config.max_time_before_crypto_handshake(), config.max_idle_time_before_crypto_handshake()); @@ -554,6 +605,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { } sent_packet_manager_.SetFromConfig(config); + if (perspective_ == Perspective::IS_SERVER && + config.HasClientSentConnectionOption(kAFF2, perspective_)) { + send_ack_frequency_on_handshake_completion_ = true; + } if (config.HasReceivedBytesForConnectionId() && can_truncate_connection_ids_) { packet_creator_.SetServerConnectionIdLength( @@ -690,7 +745,7 @@ bool QuicConnection::MaybeTestLiveness() { } const QuicTime now = clock_->ApproximateNow(); if (now > idle_network_deadline) { - QUIC_BUG << "Idle network deadline has passed"; + QUIC_DLOG(WARNING) << "Idle network deadline has passed"; return false; } const QuicTime::Delta timeout = idle_network_deadline - now; @@ -878,12 +933,11 @@ void QuicConnection::OnVersionNegotiationPacket( } // Handles retry for client connection. -void QuicConnection::OnRetryPacket( - QuicConnectionId original_connection_id, - QuicConnectionId new_connection_id, - quiche::QuicheStringPiece retry_token, - quiche::QuicheStringPiece retry_integrity_tag, - quiche::QuicheStringPiece retry_without_tag) { +void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id, + QuicConnectionId new_connection_id, + absl::string_view retry_token, + absl::string_view retry_integrity_tag, + absl::string_view retry_without_tag) { DCHECK_EQ(Perspective::IS_CLIENT, perspective_); if (version().HasRetryIntegrityTag()) { if (!CryptoUtils::ValidateRetryIntegrityTag( @@ -897,21 +951,20 @@ void QuicConnection::OnRetryPacket( QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID " << original_connection_id << " not matching expected " << server_connection_id_ << " token " - << quiche::QuicheTextUtils::HexEncode(retry_token); + << absl::BytesToHexString(retry_token); return; } } if (drop_incoming_retry_packets_) { QUIC_DLOG(ERROR) << "Ignoring RETRY with token " - << quiche::QuicheTextUtils::HexEncode(retry_token); + << absl::BytesToHexString(retry_token); return; } drop_incoming_retry_packets_ = true; stats_.retry_packet_processed = true; QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID " << server_connection_id_ << " with " << new_connection_id - << ", received token " - << quiche::QuicheTextUtils::HexEncode(retry_token); + << ", received token " << absl::BytesToHexString(retry_token); if (!original_destination_connection_id_.has_value()) { original_destination_connection_id_ = server_connection_id_; } @@ -1094,10 +1147,20 @@ bool QuicConnection::HasPendingAcks() const { void QuicConnection::OnDecryptedPacket(EncryptionLevel level) { last_decrypted_packet_level_ = level; last_packet_decrypted_ = true; - if (EnforceAntiAmplificationLimit() && - last_decrypted_packet_level_ >= ENCRYPTION_HANDSHAKE) { - // Address is validated by successfully processing a HANDSHAKE packet. - address_validated_ = true; + if (EnforceAntiAmplificationLimit()) { + bool address_validated = + last_decrypted_packet_level_ >= ENCRYPTION_HANDSHAKE; + if (GetQuicReloadableFlag(quic_fix_address_validation)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_address_validation); + address_validated = + (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE || + last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE); + } + if (address_validated) { + // Address is validated by successfully processing a HANDSHAKE or 1-RTT + // packet. + address_validated_ = true; + } } idle_network_detector_.OnPacketReceived(time_of_last_received_packet_); @@ -1113,7 +1176,8 @@ QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket() bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { if (debug_visitor_ != nullptr) { - debug_visitor_->OnPacketHeader(header); + debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(), + last_decrypted_packet_level_); } // Will be decremented below if we fall through to return true. @@ -1681,7 +1745,7 @@ bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) { } MaybeUpdateAckTimeout(); visitor_->OnMessageReceived( - quiche::QuicheStringPiece(frame.data, frame.message_length)); + absl::string_view(frame.data, frame.message_length)); return connected_; } @@ -1714,6 +1778,9 @@ bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) { } bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) { + if (debug_visitor_ != nullptr) { + debug_visitor_->OnAckFrequencyFrame(frame); + } UpdatePacketContent(ACK_FREQUENCY_FRAME); if (!can_receive_ack_frequency_frame_) { QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame."; @@ -1784,8 +1851,8 @@ void QuicConnection::OnPacketComplete() { if (!should_last_packet_instigate_acks_) { uber_received_packet_manager_.MaybeUpdateAckTimeout( should_last_packet_instigate_acks_, last_decrypted_packet_level_, - last_header_.packet_number, - clock_->ApproximateNow(), sent_packet_manager_.GetRttStats()); + last_header_.packet_number, clock_->ApproximateNow(), + sent_packet_manager_.GetRttStats()); } ClearLastFrames(); @@ -1877,6 +1944,45 @@ void QuicConnection::OnAuthenticatedIetfStatelessResetPacket( ConnectionCloseSource::FROM_PEER); } +void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) { + DCHECK(support_key_update_for_connection_); + QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason; + + lowest_packet_sent_in_current_key_phase_.Clear(); + stats_.key_update_count++; + + // If another key update triggers while the previous + // discard_previous_one_rtt_keys_alarm_ hasn't fired yet, cancel it since the + // old keys would already be discarded. + discard_previous_one_rtt_keys_alarm_->Cancel(); + + visitor_->OnKeyUpdate(reason); +} + +void QuicConnection::OnDecryptedFirstPacketInKeyPhase() { + QUIC_DLOG(INFO) << ENDPOINT << "OnDecryptedFirstPacketInKeyPhase"; + // An endpoint SHOULD retain old read keys for no more than three times the + // PTO after having received a packet protected using the new keys. After this + // period, old read keys and their corresponding secrets SHOULD be discarded. + // + // Note that this will cause an unnecessary + // discard_previous_one_rtt_keys_alarm_ on the first packet in the 1RTT + // encryption level, but this is harmless. + discard_previous_one_rtt_keys_alarm_->Set( + clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3); +} + +std::unique_ptr<QuicDecrypter> +QuicConnection::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + QUIC_DLOG(INFO) << ENDPOINT << "AdvanceKeysAndCreateCurrentOneRttDecrypter"; + return visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter(); +} + +std::unique_ptr<QuicEncrypter> QuicConnection::CreateCurrentOneRttEncrypter() { + QUIC_DLOG(INFO) << ENDPOINT << "CreateCurrentOneRttEncrypter"; + return visitor_->CreateCurrentOneRttEncrypter(); +} + void QuicConnection::ClearLastFrames() { should_last_packet_instigate_acks_ = false; } @@ -2116,6 +2222,30 @@ void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet, debug_visitor_->OnUndecryptablePacket(decryption_level, /*dropped=*/!should_enqueue); } + + if (has_decryption_key) { + stats_.num_failed_authentication_packets_received++; + if (enable_aead_limits_) { + // Should always be non-null if has_decryption_key is true. + DCHECK(framer_.GetDecrypter(decryption_level)); + const QuicPacketCount integrity_limit = + framer_.GetDecrypter(decryption_level)->GetIntegrityLimit(); + QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD integrity limits:" + << " num_failed_authentication_packets_received=" + << stats_.num_failed_authentication_packets_received + << " integrity_limit=" << integrity_limit; + if (stats_.num_failed_authentication_packets_received >= + integrity_limit) { + const std::string error_details = quiche::QuicheStrCat( + "decrypter integrity limit reached:" + " num_failed_authentication_packets_received=", + stats_.num_failed_authentication_packets_received, + " integrity_limit=", integrity_limit); + CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details, + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + } + } + } } bool QuicConnection::ShouldEnqueueUnDecryptablePacket( @@ -2184,8 +2314,8 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address, } QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length() << " bytes:" << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( - packet.data(), packet.length())); + << quiche::QuicheTextUtils::HexDump( + absl::string_view(packet.data(), packet.length())); QUIC_BUG_IF(current_packet_data_ != nullptr) << "ProcessUdpPacket must not be called while processing a packet."; if (debug_visitor_ != nullptr) { @@ -2508,12 +2638,7 @@ void QuicConnection::MarkZeroRttPacketsForRetransmission(int reject_reason) { void QuicConnection::NeuterUnencryptedPackets() { sent_packet_manager_.NeuterUnencryptedPackets(); - if (!fix_missing_initial_keys_ && - GetQuicReloadableFlag( - quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded) && - version().CanSendCoalescedPackets()) { - QUIC_RELOADABLE_FLAG_COUNT( - quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded); + if (!fix_missing_initial_keys_ && version().CanSendCoalescedPackets()) { coalesced_packet_.NeuterInitialPacket(); } // This may have changed the retransmission timer, so re-arm it. @@ -2545,6 +2670,16 @@ bool QuicConnection::ShouldGeneratePacket( } const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() { + if (!ack_frequency_sent_ && sent_packet_manager_.CanSendAckFrequency()) { + if (packet_creator_.NextSendingPacketNumber() >= + FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 3, 3); + ack_frequency_sent_ = true; + auto frame = sent_packet_manager_.GetUpdatedAckFrequencyFrame(); + visitor_->SendAckFrequency(frame); + } + } + QuicFrames frames; const bool has_pending_ack = uber_received_packet_manager_ @@ -2678,7 +2813,6 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { termination_packets_->emplace_back( new QuicEncryptedPacket(buffer_copy, encrypted_length, true)); if (error_code == QUIC_SILENT_IDLE_TIMEOUT) { - QUIC_RELOADABLE_FLAG_COUNT(quic_add_silent_idle_timeout); DCHECK_EQ(Perspective::IS_SERVER, perspective_); // TODO(fayang): populate histogram indicating the time elapsed from this // connection gets closed to following client packets get received. @@ -2706,7 +2840,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number " << packet_number << " of length " << encrypted_length << ": " << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( + << quiche::QuicheTextUtils::HexDump(absl::string_view( packet->encrypted_buffer, encrypted_length)); // Measure the RTT from before the write begins to avoid underestimating the @@ -2805,8 +2939,8 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { QuicPacketLength encapsulated_length = QuicLegacyVersionEncapsulator::Encapsulate( legacy_version_encapsulation_sni_, - quiche::QuicheStringPiece(packet->encrypted_buffer, - packet->encrypted_length), + absl::string_view(packet->encrypted_buffer, + packet->encrypted_length), server_connection_id_, framer_.creation_time(), GetLimitedMaxPacketSize(long_term_mtu_), const_cast<char*>(packet->encrypted_buffer)); @@ -2819,7 +2953,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { << "Successfully performed Legacy Version Encapsulation on " << packet->encryption_level << " packet number " << packet_number << " of length " << encrypted_length << ": " << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( + << quiche::QuicheTextUtils::HexDump(absl::string_view( packet->encrypted_buffer, encrypted_length)); } else { QUIC_BUG << ENDPOINT @@ -2973,6 +3107,19 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { handshake_packet_sent_ = true; } + if (packet->encryption_level == ENCRYPTION_FORWARD_SECURE) { + if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) { + QUIC_DLOG(INFO) << ENDPOINT + << "lowest_packet_sent_in_current_key_phase_ = " + << packet_number; + lowest_packet_sent_in_current_key_phase_ = packet_number; + } + if (!is_termination_packet && + MaybeHandleAeadConfidentialityLimits(*packet)) { + return true; + } + } + if (in_flight || !retransmission_alarm_->IsSet()) { SetRetransmissionAlarm(); } @@ -2994,6 +3141,112 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { return true; } +bool QuicConnection::MaybeHandleAeadConfidentialityLimits( + const SerializedPacket& packet) { + if (!enable_aead_limits_) { + return false; + } + + if (packet.encryption_level != ENCRYPTION_FORWARD_SECURE) { + QUIC_BUG + << "MaybeHandleAeadConfidentialityLimits called on non 1-RTT packet"; + return false; + } + if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) { + QUIC_BUG << "lowest_packet_sent_in_current_key_phase_ must be initialized " + "before calling MaybeHandleAeadConfidentialityLimits"; + return false; + } + + // Calculate the number of packets encrypted from the packet number, which is + // simpler than keeping another counter. The packet number space may be + // sparse, so this might overcount, but doing a key update earlier than + // necessary would only improve security and has negligible cost. + if (packet.packet_number < lowest_packet_sent_in_current_key_phase_) { + const std::string error_details = quiche::QuicheStrCat( + "packet_number(", packet.packet_number.ToString(), + ") < lowest_packet_sent_in_current_key_phase_ (", + lowest_packet_sent_in_current_key_phase_.ToString(), ")"); + QUIC_BUG << error_details; + CloseConnection(QUIC_INTERNAL_ERROR, error_details, + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + return true; + } + const QuicPacketCount num_packets_encrypted_in_current_key_phase = + packet.packet_number - lowest_packet_sent_in_current_key_phase_ + 1; + + const QuicPacketCount confidentiality_limit = + framer_.GetOneRttEncrypterConfidentialityLimit(); + + // Attempt to initiate a key update before reaching the AEAD + // confidentiality limit when the number of packets sent in the current + // key phase gets within |kKeyUpdateConfidentialityLimitOffset| packets of + // the limit, unless overridden by + // FLAGS_quic_key_update_confidentiality_limit. + constexpr QuicPacketCount kKeyUpdateConfidentialityLimitOffset = 1000; + QuicPacketCount key_update_limit = 0; + if (confidentiality_limit > kKeyUpdateConfidentialityLimitOffset) { + key_update_limit = + confidentiality_limit - kKeyUpdateConfidentialityLimitOffset; + } + const QuicPacketCount key_update_limit_override = + GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit); + if (key_update_limit_override) { + key_update_limit = key_update_limit_override; + } + + QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD confidentiality limits: " + << "num_packets_encrypted_in_current_key_phase=" + << num_packets_encrypted_in_current_key_phase + << " key_update_limit=" << key_update_limit + << " confidentiality_limit=" << confidentiality_limit + << " IsKeyUpdateAllowed()=" << IsKeyUpdateAllowed(); + + if (num_packets_encrypted_in_current_key_phase >= confidentiality_limit) { + // Reached the confidentiality limit without initiating a key update, + // must close the connection. + const std::string error_details = quiche::QuicheStrCat( + "encrypter confidentiality limit reached: " + "num_packets_encrypted_in_current_key_phase=", + num_packets_encrypted_in_current_key_phase, + " key_update_limit=", key_update_limit, + " confidentiality_limit=", confidentiality_limit, + " IsKeyUpdateAllowed()=", IsKeyUpdateAllowed()); + CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details, + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + return true; + } + + if (IsKeyUpdateAllowed() && + num_packets_encrypted_in_current_key_phase >= key_update_limit) { + // Approaching the confidentiality limit, initiate key update so that + // the next set of keys will be ready for the next packet before the + // limit is reached. + KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit; + if (key_update_limit_override) { + QUIC_DLOG(INFO) << ENDPOINT + << "reached FLAGS_quic_key_update_confidentiality_limit, " + "initiating key update: " + << "num_packets_encrypted_in_current_key_phase=" + << num_packets_encrypted_in_current_key_phase + << " key_update_limit=" << key_update_limit + << " confidentiality_limit=" << confidentiality_limit; + reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride; + } else { + QUIC_DLOG(INFO) << ENDPOINT + << "approaching AEAD confidentiality limit, " + "initiating key update: " + << "num_packets_encrypted_in_current_key_phase=" + << num_packets_encrypted_in_current_key_phase + << " key_update_limit=" << key_update_limit + << " confidentiality_limit=" << confidentiality_limit; + } + InitiateKeyUpdate(reason); + } + + return false; +} + void QuicConnection::FlushPackets() { if (!connected_) { return; @@ -3189,6 +3442,20 @@ void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) { void QuicConnection::OnHandshakeComplete() { sent_packet_manager_.SetHandshakeConfirmed(); + if (send_ack_frequency_on_handshake_completion_ && + sent_packet_manager_.CanSendAckFrequency()) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 2, 3); + auto ack_frequency_frame = + sent_packet_manager_.GetUpdatedAckFrequencyFrame(); + // This AckFrequencyFrame is meant to only update the max_ack_delay. Set + // packet tolerance to the default value for now. + ack_frequency_frame.packet_tolerance = + kDefaultRetransmittablePacketsBeforeAck; + visitor_->SendAckFrequency(ack_frequency_frame); + if (!connected_) { + return; + } + } // This may have changed the retransmission timer, so re-arm it. SetRetransmissionAlarm(); if (default_enable_5rto_blackhole_detection_) { @@ -3221,7 +3488,13 @@ void QuicConnection::OnPingTimeout() { !visitor_->ShouldKeepConnectionAlive()) { return; } - visitor_->SendPing(); + if (packet_creator_.let_connection_handle_pings()) { + SendPingAtLevel(use_encryption_level_context_ + ? framer().GetEncryptionLevelToSendApplicationData() + : encryption_level_); + } else { + visitor_->SendPing(); + } } void QuicConnection::SendAck() { @@ -3258,7 +3531,7 @@ void QuicConnection::OnRetransmissionTimeout() { DCHECK(!IsHandshakeComplete()); } #endif - if (fix_missing_connected_checks_ && !connected_) { + if (!connected_) { return; } @@ -3317,7 +3590,19 @@ void QuicConnection::OnRetransmissionTimeout() { << "No packet gets sent when timer fires in mode " << retransmission_mode << ", send PING"; DCHECK_LT(0u, sent_packet_manager_.pending_timer_transmission_count()); - visitor_->SendPing(); + if (packet_creator_.let_connection_handle_pings()) { + EncryptionLevel level = encryption_level_; + PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES; + if (SupportsMultiplePacketNumberSpaces() && + sent_packet_manager_ + .GetEarliestPacketSentTimeForPto(&packet_number_space) + .IsInitialized()) { + level = QuicUtils::GetEncryptionLevel(packet_number_space); + } + SendPingAtLevel(level); + } else { + visitor_->SendPing(); + } } if (retransmission_mode == QuicSentPacketManager::PTO_MODE) { sent_packet_manager_.AdjustPendingTimerTransmissions(); @@ -3424,6 +3709,36 @@ void QuicConnection::RemoveDecrypter(EncryptionLevel level) { framer_.RemoveDecrypter(level); } +void QuicConnection::DiscardPreviousOneRttKeys() { + framer_.DiscardPreviousOneRttKeys(); +} + +bool QuicConnection::IsKeyUpdateAllowed() const { + return support_key_update_for_connection_ && + GetLargestAckedPacket().IsInitialized() && + lowest_packet_sent_in_current_key_phase_.IsInitialized() && + GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_; +} + +bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const { + return lowest_packet_sent_in_current_key_phase_.IsInitialized() && + (!GetLargestAckedPacket().IsInitialized() || + GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_); +} + +QuicPacketCount QuicConnection::PotentialPeerKeyUpdateAttemptCount() const { + return framer_.PotentialPeerKeyUpdateAttemptCount(); +} + +bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) { + QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate"; + if (!IsKeyUpdateAllowed()) { + QUIC_BUG << "key update not allowed"; + return false; + } + return framer_.DoKeyUpdate(reason); +} + const QuicDecrypter* QuicConnection::decrypter() const { return framer_.decrypter(); } @@ -3444,6 +3759,9 @@ void QuicConnection::QueueUndecryptablePacket( } QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet."; undecryptable_packets_.emplace_back(packet, decryption_level); + if (perspective_ == Perspective::IS_CLIENT) { + SetRetransmissionAlarm(); + } } void QuicConnection::MaybeProcessUndecryptablePackets() { @@ -3531,6 +3849,9 @@ void QuicConnection::MaybeProcessUndecryptablePackets() { } undecryptable_packets_.clear(); } + if (perspective_ == Perspective::IS_CLIENT) { + SetRetransmissionAlarm(); + } } void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) { @@ -3596,7 +3917,12 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, peer_address()); if (!SupportsMultiplePacketNumberSpaces()) { QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet."; - SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel()); + if (!use_encryption_level_context_) { + SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel()); + } + ScopedEncryptionLevelContext context( + use_encryption_level_context_ ? this : nullptr, + GetConnectionCloseEncryptionLevel()); if (version().CanSendCoalescedPackets()) { coalesced_packet_.Clear(); } @@ -3639,7 +3965,11 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, } QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet at level: " << level; - SetDefaultEncryptionLevel(level); + if (!use_encryption_level_context_) { + SetDefaultEncryptionLevel(level); + } + ScopedEncryptionLevelContext context( + use_encryption_level_context_ ? this : nullptr, level); // Bundle an ACK of the corresponding packet number space for debugging // purpose. if (error != QUIC_PACKET_WRITE_ERROR && @@ -3650,6 +3980,11 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, packet_creator_.FlushAckFrame(frames); } + if (level == ENCRYPTION_FORWARD_SECURE && + perspective_ == Perspective::IS_SERVER) { + visitor_->BeforeConnectionCloseSent(); + } + auto* frame = new QuicConnectionCloseFrame(transport_version(), error, details, framer_.current_received_frame_type()); @@ -3662,7 +3997,9 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, // Since the connection is closing, if the connection close packets were not // sent, then they should be discarded. ClearQueuedPackets(); - SetDefaultEncryptionLevel(current_encryption_level); + if (!use_encryption_level_context_) { + SetDefaultEncryptionLevel(current_encryption_level); + } } void QuicConnection::TearDownLocalConnectionState( @@ -3708,6 +4045,7 @@ void QuicConnection::CancelAllAlarms() { send_alarm_->Cancel(); mtu_discovery_alarm_->Cancel(); process_undecryptable_packets_alarm_->Cancel(); + discard_previous_one_rtt_keys_alarm_->Cancel(); blackhole_detector_.StopDetection(); idle_network_detector_.StopDetection(); } @@ -3752,7 +4090,9 @@ void QuicConnection::SetPingAlarm() { return; } if (initial_retransmittable_on_wire_timeout_.IsInfinite() || - sent_packet_manager_.HasInFlightPackets()) { + sent_packet_manager_.HasInFlightPackets() || + retransmittable_on_wire_ping_count_ > + GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) { // Extend the ping alarm. ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_, QuicTime::Delta::FromSeconds(1)); @@ -3788,6 +4128,7 @@ void QuicConnection::SetPingAlarm() { if (max_aggressive_retransmittable_on_wire_ping_count != 0) { consecutive_retransmittable_on_wire_ping_count_++; } + retransmittable_on_wire_ping_count_++; return; } @@ -3796,7 +4137,7 @@ void QuicConnection::SetPingAlarm() { } void QuicConnection::SetRetransmissionAlarm() { - if (fix_missing_connected_checks_ && !connected_) { + if (!connected_) { if (retransmission_alarm_->IsSet()) { QUIC_BUG << ENDPOINT << "Retransmission alarm is set while disconnected"; retransmission_alarm_->Cancel(); @@ -3814,8 +4155,7 @@ void QuicConnection::SetRetransmissionAlarm() { return; } - retransmission_alarm_->Update(sent_packet_manager_.GetRetransmissionTime(), - kAlarmGranularity); + retransmission_alarm_->Update(GetRetransmissionDeadline(), kAlarmGranularity); } void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) { @@ -3923,6 +4263,24 @@ QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() { !connection_->packet_creator_.PacketFlusherAttached()); } +QuicConnection::ScopedEncryptionLevelContext::ScopedEncryptionLevelContext( + QuicConnection* connection, + EncryptionLevel encryption_level) + : connection_(connection), latched_encryption_level_(ENCRYPTION_INITIAL) { + if (connection_ == nullptr) { + return; + } + latched_encryption_level_ = connection_->encryption_level_; + connection_->SetDefaultEncryptionLevel(encryption_level); +} + +QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() { + if (connection_ == nullptr || !connection_->connected_) { + return; + } + connection_->SetDefaultEncryptionLevel(latched_encryption_level_); +} + QuicConnection::BufferedPacket::BufferedPacket( const SerializedPacket& packet, const QuicSocketAddress& self_address, @@ -4081,24 +4439,32 @@ bool QuicConnection::SendGenericPathProbePacket( transmitted_connectivity_probe_payload_ = nullptr; } } - DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA); + return WritePacketUsingWriter(std::move(probing_packet), probing_writer, + self_address(), peer_address, + /*measure_rtt=*/true); +} +bool QuicConnection::WritePacketUsingWriter( + std::unique_ptr<SerializedPacket> packet, + QuicPacketWriter* writer, + const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + bool measure_rtt) { const QuicTime packet_send_time = clock_->Now(); QUIC_DVLOG(2) << ENDPOINT << "Sending path probe packet for server connection ID " << server_connection_id_ << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( - probing_packet->encrypted_buffer, - probing_packet->encrypted_length)); - WriteResult result = probing_writer->WritePacket( - probing_packet->encrypted_buffer, probing_packet->encrypted_length, - self_address().host(), peer_address, per_packet_options_); + << quiche::QuicheTextUtils::HexDump(absl::string_view( + packet->encrypted_buffer, packet->encrypted_length)); + WriteResult result = writer->WritePacket( + packet->encrypted_buffer, packet->encrypted_length, self_address.host(), + peer_address, per_packet_options_); // If using a batch writer and the probing packet is buffered, flush it. - if (probing_writer->IsBatchMode() && result.status == WRITE_STATUS_OK && + if (writer->IsBatchMode() && result.status == WRITE_STATUS_OK && result.bytes_written == 0) { - result = probing_writer->Flush(); + result = writer->Flush(); } if (IsWriteError(result.status)) { @@ -4111,14 +4477,14 @@ bool QuicConnection::SendGenericPathProbePacket( if (!sent_packet_manager_.give_sent_packet_to_debug_visitor_after_sent() && debug_visitor_ != nullptr) { - debug_visitor_->OnPacketSent( - *probing_packet, probing_packet->transmission_type, packet_send_time); + debug_visitor_->OnPacketSent(*packet, packet->transmission_type, + packet_send_time); } // Send in currrent path. Call OnPacketSent regardless of the write result. - sent_packet_manager_.OnPacketSent( - probing_packet.get(), packet_send_time, probing_packet->transmission_type, - NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + sent_packet_manager_.OnPacketSent(packet.get(), packet_send_time, + packet->transmission_type, + NO_RETRANSMITTABLE_DATA, measure_rtt); if (sent_packet_manager_.give_sent_packet_to_debug_visitor_after_sent() && debug_visitor_ != nullptr) { @@ -4128,18 +4494,18 @@ bool QuicConnection::SendGenericPathProbePacket( QUIC_BUG << "Unacked map is empty right after packet is sent"; } else { debug_visitor_->OnPacketSent( - probing_packet->packet_number, probing_packet->encrypted_length, - probing_packet->has_crypto_handshake, - probing_packet->transmission_type, probing_packet->encryption_level, + packet->packet_number, packet->encrypted_length, + packet->has_crypto_handshake, packet->transmission_type, + packet->encryption_level, sent_packet_manager_.unacked_packets() .rbegin() ->retransmittable_frames, - probing_packet->nonretransmittable_frames, packet_send_time); + packet->nonretransmittable_frames, packet_send_time); } } if (IsWriteBlockedStatus(result.status)) { - if (probing_writer == writer_) { + if (writer == writer_) { // Visitor should not be write blocked if the probing writer is not the // default packet writer. visitor_->OnWriteBlocked(); @@ -4222,11 +4588,11 @@ bool QuicConnection::ack_frame_updated() const { return uber_received_packet_manager_.IsAckFrameUpdated(); } -quiche::QuicheStringPiece QuicConnection::GetCurrentPacket() { +absl::string_view QuicConnection::GetCurrentPacket() { if (current_packet_data_ == nullptr) { - return quiche::QuicheStringPiece(); + return absl::string_view(); } - return quiche::QuicheStringPiece(current_packet_data_, last_size_); + return absl::string_view(current_packet_data_, last_size_); } bool QuicConnection::MaybeConsiderAsMemoryCorruption( @@ -4274,8 +4640,7 @@ void QuicConnection::MaybeSendProbingRetransmissions() { } void QuicConnection::CheckIfApplicationLimited() { - if ((fix_missing_connected_checks_ && !connected_) || - probing_retransmission_pending_) { + if (!connected_ || probing_retransmission_pending_) { return; } @@ -4582,7 +4947,12 @@ void QuicConnection::SendAllPendingAcks() { << PacketNumberSpaceToString( static_cast<PacketNumberSpace>(i)); // Switch to the appropriate encryption level. - SetDefaultEncryptionLevel( + if (!use_encryption_level_context_) { + SetDefaultEncryptionLevel( + QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i))); + } + ScopedEncryptionLevelContext context( + use_encryption_level_context_ ? this : nullptr, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i))); QuicFrames frames; frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame( @@ -4598,8 +4968,10 @@ void QuicConnection::SendAllPendingAcks() { } ResetAckStates(); } - // Restores encryption level. - SetDefaultEncryptionLevel(current_encryption_level); + if (!use_encryption_level_context_) { + // Restores encryption level. + SetDefaultEncryptionLevel(current_encryption_level); + } const QuicTime timeout = uber_received_packet_manager_.GetEarliestAckTimeout(); @@ -4672,7 +5044,7 @@ void QuicConnection::MaybeCoalescePacketOfHigherSpace() { bool QuicConnection::FlushCoalescedPacket() { ScopedCoalescedPacketClearer clearer(&coalesced_packet_); - if (fix_missing_connected_checks_ && !connected_) { + if (!connected_) { return false; } if (!version().CanSendCoalescedPackets()) { @@ -4773,7 +5145,8 @@ void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() { << " supports multiple packet number spaces"; framer_.EnableMultiplePacketNumberSpacesSupport(); sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport(); - uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport(); + uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport( + perspective_); } bool QuicConnection::SupportsMultiplePacketNumberSpaces() const { @@ -5000,8 +5373,8 @@ void QuicConnection::MaybeUpdateAckTimeout() { should_last_packet_instigate_acks_ = true; uber_received_packet_manager_.MaybeUpdateAckTimeout( /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_, - last_header_.packet_number, - clock_->ApproximateNow(), sent_packet_manager_.GetRttStats()); + last_header_.packet_number, clock_->ApproximateNow(), + sent_packet_manager_.GetRttStats()); } QuicTime QuicConnection::GetPathDegradingDeadline() const { @@ -5050,6 +5423,40 @@ bool QuicConnection::ShouldDetectBlackhole() const { return num_rtos_for_blackhole_detection_ > 0; } +QuicTime QuicConnection::GetRetransmissionDeadline() const { + if (perspective_ == Perspective::IS_CLIENT && + SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() && + stats_.pto_count == 0 && + !framer_.HasDecrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE) && + !undecryptable_packets_.empty()) { + // Retransmits ClientHello quickly when a Handshake or 1-RTT packet is + // received prior to having Handshake keys. Adding kAlarmGranulary will + // avoid spurious retransmissions in the case of small-scale reordering. + return clock_->ApproximateNow() + kAlarmGranularity; + } + return sent_packet_manager_.GetRetransmissionTime(); +} + +void QuicConnection::SendPathChallenge(QuicPathFrameBuffer* data_buffer, + const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + QuicPacketWriter* writer) { + if (writer == writer_) { + // It's on current path, add the PATH_CHALLENGE the same way as other + // frames. + QuicPacketCreator::ScopedPeerAddressContext context(&packet_creator_, + peer_address); + packet_creator_.AddPathChallengeFrame(data_buffer); + return; + } + std::unique_ptr<SerializedPacket> probing_packet = + packet_creator_.SerializePathChallengeConnectivityProbingPacket( + data_buffer); + DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA); + WritePacketUsingWriter(std::move(probing_packet), writer, self_address, + peer_address, /*measure_rtt=*/false); +} + bool QuicConnection::SendPathResponse(const QuicPathFrameBuffer& data_buffer, QuicSocketAddress peer_address_to_send) { // Send PATH_RESPONSE using the provided peer address. If the creator has been @@ -5066,5 +5473,11 @@ void QuicConnection::UpdatePeerAddress(QuicSocketAddress peer_address) { packet_creator_.SetDefaultPeerAddress(peer_address); } +void QuicConnection::SendPingAtLevel(EncryptionLevel level) { + DCHECK(packet_creator_.let_connection_handle_pings()); + ScopedEncryptionLevelContext context(this, level); + SendControlFrame(QuicFrame(QuicPingFrame())); +} + #undef ENDPOINT // undef for jumbo builds } // namespace quic 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 9b4544ff7b4..35d15ffee92 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 @@ -24,9 +24,12 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h" #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h" #include "net/third_party/quiche/src/quic/core/quic_alarm.h" @@ -35,6 +38,7 @@ #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_connection_stats.h" +#include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_idle_network_detector.h" #include "net/third_party/quiche/src/quic/core/quic_mtu_discovery.h" @@ -50,9 +54,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -92,7 +94,7 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface { virtual void OnGoAway(const QuicGoAwayFrame& frame) = 0; // Called when |message| has been received. - virtual void OnMessageReceived(quiche::QuicheStringPiece message) = 0; + virtual void OnMessageReceived(absl::string_view message) = 0; // Called when a HANDSHAKE_DONE frame has been received. virtual void OnHandshakeDoneReceived() = 0; @@ -158,6 +160,9 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface { // Called when a ping needs to be sent. virtual void SendPing() = 0; + // Called when an AckFrequency frame need to be sent. + virtual void SendAckFrequency(const QuicAckFrequencyFrame& frame) = 0; + // Called to ask if the visitor wants to schedule write resumption as it both // has pending data to write, and is able to write (e.g. based on flow control // limits). @@ -191,6 +196,23 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface { // Called when a packet of ENCRYPTION_HANDSHAKE gets sent. virtual void OnHandshakePacketSent() = 0; + + // Called when a key update has occurred. + virtual void OnKeyUpdate(KeyUpdateReason reason) = 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> + AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0; + + // Called to generate an encrypter for the same key phase of the last + // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter(). + virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0; + + // Called when connection is being closed right before a CONNECTION_CLOSE + // frame is serialized, but only on the server and only if forward secure + // encryption has already been established. + virtual void BeforeConnectionCloseSent() = 0; }; // Interface which gets callbacks from the QuicConnection at interesting @@ -256,7 +278,9 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor virtual void OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) {} // Called when the complete header of a packet has been parsed. - virtual void OnPacketHeader(const QuicPacketHeader& /*header*/) {} + virtual void OnPacketHeader(const QuicPacketHeader& /*header*/, + QuicTime /*receive_time*/, + EncryptionLevel /*level*/) {} // Called when a StreamFrame has been parsed. virtual void OnStreamFrame(const QuicStreamFrame& /*frame*/) {} @@ -357,6 +381,9 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor // Called when a MaxStreamsFrame has been parsed. virtual void OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) {} + // Called when an AckFrequencyFrame has been parsed. + virtual void OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) {} + // Called when |count| packet numbers have been skipped. virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/, QuicTime /*now*/) {} @@ -412,6 +439,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection // specifies whether the connection takes ownership of |writer|. |helper| must // outlive this connection. QuicConnection(QuicConnectionId server_connection_id, + QuicSocketAddress initial_self_address, QuicSocketAddress initial_peer_address, QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory, @@ -499,6 +527,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection QuicConnectionStats& mutable_stats() { return stats_; } + int retransmittable_on_wire_ping_count() const { + return retransmittable_on_wire_ping_count_; + } + // Returns statistics tracked for this connection. const QuicConnectionStats& GetStats(); @@ -579,9 +611,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection const QuicVersionNegotiationPacket& packet) override; void OnRetryPacket(QuicConnectionId original_connection_id, QuicConnectionId new_connection_id, - quiche::QuicheStringPiece retry_token, - quiche::QuicheStringPiece retry_integrity_tag, - quiche::QuicheStringPiece retry_without_tag) override; + absl::string_view retry_token, + absl::string_view retry_integrity_tag, + absl::string_view retry_without_tag) override; bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override; bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override; void OnDecryptedPacket(EncryptionLevel level) override; @@ -622,6 +654,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& packet) override; + void OnKeyUpdate(KeyUpdateReason reason) override; + void OnDecryptedFirstPacketInKeyPhase() override; + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override; + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; // QuicPacketCreator::DelegateInterface bool ShouldGeneratePacket(HasRetransmittableData retransmittable, @@ -782,6 +819,25 @@ class QUIC_EXPORT_PRIVATE QuicConnection std::unique_ptr<QuicDecrypter> decrypter); void RemoveDecrypter(EncryptionLevel level); + // Discard keys for the previous key phase. + void DiscardPreviousOneRttKeys(); + + // Returns true if it is currently allowed to initiate a key update. + bool IsKeyUpdateAllowed() const; + + // Returns true if packets have been sent in the current 1-RTT key phase but + // none of these packets have been acked. + bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const; + + // Returns the count of packets received that appeared to attempt a key + // update but failed decryption that have been received since the last + // successfully decrypted packet. + QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const; + + // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed() + // is false. Returns false on error. + bool InitiateKeyUpdate(KeyUpdateReason reason); + const QuicDecrypter* decrypter() const; const QuicDecrypter* alternative_decrypter() const; @@ -825,6 +881,18 @@ class QUIC_EXPORT_PRIVATE QuicConnection const bool handshake_packet_sent_; }; + class QUIC_EXPORT_PRIVATE ScopedEncryptionLevelContext { + public: + ScopedEncryptionLevelContext(QuicConnection* connection, + EncryptionLevel level); + ~ScopedEncryptionLevelContext(); + + private: + QuicConnection* connection_; + // Latched current write encryption level on creation of this context. + EncryptionLevel latched_encryption_level_; + }; + QuicPacketWriter* writer() { return writer_; } const QuicPacketWriter* writer() const { return writer_; } @@ -882,6 +950,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection // connection ID lengths do not change. QuicPacketLength GetGuaranteedLargestMessagePayload() const; + virtual int GetUnackedMapInitialCapacity() const { + return kDefaultUnackedPacketsInitialCapacity; + } + // Returns the id of the cipher last used for decrypting packets. uint32_t cipher_id() const; @@ -895,7 +967,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection const QuicConnectionHelperInterface* helper() const { return helper_; } QuicAlarmFactory* alarm_factory() { return alarm_factory_; } - quiche::QuicheStringPiece GetCurrentPacket(); + absl::string_view GetCurrentPacket(); const QuicFramer& framer() const { return framer_; } @@ -1037,6 +1109,17 @@ class QUIC_EXPORT_PRIVATE QuicConnection // false. bool MaybeTestLiveness(); + // Send PATH_CHALLENGE using the given path information. If |writer| is the + // default writer, PATH_CHALLENGE can be bundled with other frames, and the + // containing packet can be buffered if the writer is blocked. Otherwise, + // PATH_CHALLENGE will be written in an individual packet and it will be + // dropped if write fails. |data_buffer| will be populated with the payload + // for future validation. + void SendPathChallenge(QuicPathFrameBuffer* data_buffer, + const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + QuicPacketWriter* writer); + bool can_receive_ack_frequency_frame() const { return can_receive_ack_frequency_frame_; } @@ -1047,6 +1130,14 @@ class QUIC_EXPORT_PRIVATE QuicConnection bool check_keys_before_writing() const { return check_keys_before_writing_; } + bool is_processing_packet() const { return framer_.is_processing_packet(); } + + bool encrypted_control_frames() const { return encrypted_control_frames_; } + + bool use_encryption_level_context() const { + return use_encryption_level_context_; + } + protected: // Calls cancel() on all the alarms owned by this connection. void CancelAllAlarms(); @@ -1126,7 +1217,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection private: friend class test::QuicConnectionPeer; - typedef std::list<SerializedPacket> QueuedPacketList; + using QueuedPacketList = std::list<SerializedPacket>; // BufferedPacket stores necessary information (encrypted buffer and self/peer // addresses) of those packets which are serialized but failed to send because @@ -1146,7 +1237,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection ~BufferedPacket(); // encrypted_buffer is owned by buffered packet. - quiche::QuicheStringPiece encrypted_buffer; + absl::string_view encrypted_buffer; // Self and peer addresses when the packet is serialized. const QuicSocketAddress self_address; const QuicSocketAddress peer_address; @@ -1190,6 +1281,12 @@ class QUIC_EXPORT_PRIVATE QuicConnection // writer is write blocked. bool WritePacket(SerializedPacket* packet); + // Enforce AEAD Confidentiality limits by iniating key update or closing + // connection if too many packets have been encrypted with the current key. + // Returns true if the connection was closed. Should not be called for + // termination packets. + bool MaybeHandleAeadConfidentialityLimits(const SerializedPacket& packet); + // Flush packets buffered in the writer, if any. void FlushPackets(); @@ -1373,6 +1470,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection // Returns true if network blackhole should be detected. bool ShouldDetectBlackhole() const; + // Returns retransmission deadline. + QuicTime GetRetransmissionDeadline() const; + // Validate connection IDs used during the handshake. Closes the connection // on validation failure. bool ValidateConfigConnectionIds(const QuicConfig& config); @@ -1416,6 +1516,16 @@ class QUIC_EXPORT_PRIVATE QuicConnection // Update both connection's and packet creator's peer address. void UpdatePeerAddress(QuicSocketAddress peer_address); + // Send PING at encryption level. + void SendPingAtLevel(EncryptionLevel level); + + // Write the given packet with |self_address| and |peer_address| using + // |writer|. + bool WritePacketUsingWriter(std::unique_ptr<SerializedPacket> packet, + QuicPacketWriter* writer, + const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + bool measure_rtt); QuicFramer framer_; // Contents received in the current packet, especially used to identify @@ -1472,6 +1582,18 @@ class QUIC_EXPORT_PRIVATE QuicConnection // started. QuicPacketNumber highest_packet_sent_before_effective_peer_migration_; + // True if Key Update is supported on this connection. + bool support_key_update_for_connection_; + + // Tracks the lowest packet sent in the current key phase. Will be + // uninitialized before the first one-RTT packet has been sent or after a + // key update but before the first packet has been sent. + QuicPacketNumber lowest_packet_sent_in_current_key_phase_; + + // Honor the AEAD confidentiality and integrity limits by initiating key + // update (if allowed) and/or closing the connection, as necessary. + bool enable_aead_limits_; + // True if the last packet has gotten far enough in the framer to be // decrypted. bool last_packet_decrypted_; @@ -1525,6 +1647,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection // When > 0, close the QUIC connection after this number of RTOs. size_t num_rtos_for_blackhole_detection_; + // Statistics for this session. + QuicConnectionStats stats_; + UberReceivedPacketManager uber_received_packet_manager_; // Indicates how many consecutive times an ack has arrived which indicates @@ -1549,6 +1674,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection // receiving any new data in between. int consecutive_retransmittable_on_wire_ping_count_; + // Indicates how many retransmittable-on-wire pings have been emitted. + int retransmittable_on_wire_ping_count_; + // Arena to store class implementations within the QuicConnection. QuicConnectionArena arena_; @@ -1566,15 +1694,15 @@ class QUIC_EXPORT_PRIVATE QuicConnection // An alarm that fires to process undecryptable packets when new decyrption // keys are available. QuicArenaScopedPtr<QuicAlarm> process_undecryptable_packets_alarm_; + // An alarm that fires to discard keys for the previous key phase some time + // after a key update has completed. + QuicArenaScopedPtr<QuicAlarm> discard_previous_one_rtt_keys_alarm_; // Neither visitor is owned by this class. QuicConnectionVisitorInterface* visitor_; QuicConnectionDebugVisitor* debug_visitor_; QuicPacketCreator packet_creator_; - // Statistics for this session. - QuicConnectionStats stats_; - // The time that a packet is received for this connection. Initialized to // connection creation time. // This does not indicate the packet was processed. @@ -1715,11 +1843,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection // |server_connection_id_| with the value from that packet and save off the // original value of |server_connection_id_| into // |original_destination_connection_id_| for validation. - quiche::QuicheOptional<QuicConnectionId> original_destination_connection_id_; + absl::optional<QuicConnectionId> original_destination_connection_id_; // After we receive a RETRY packet, |retry_source_connection_id_| contains // the source connection ID from that packet. - quiche::QuicheOptional<QuicConnectionId> retry_source_connection_id_; + absl::optional<QuicConnectionId> retry_source_connection_id_; // Indicates whether received RETRY packets should be dropped. bool drop_incoming_retry_packets_; @@ -1780,9 +1908,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection bool start_peer_migration_earlier_ = GetQuicReloadableFlag(quic_start_peer_migration_earlier); - bool fix_missing_connected_checks_ = - GetQuicReloadableFlag(quic_add_missing_connected_checks); - // latch --gfe2_reloadable_flag_quic_send_path_response and // --gfe2_reloadable_flag_quic_start_peer_migration_earlier. bool send_path_response_ = start_peer_migration_earlier_ && @@ -1796,6 +1921,14 @@ class QUIC_EXPORT_PRIVATE QuicConnection // Indicate whether any ENCRYPTION_HANDSHAKE packet has been sent. bool handshake_packet_sent_ = false; + // Indicate whether to send an AckFrequencyFrame upon handshake completion. + // The AckFrequencyFrame sent will updates client's max_ack_delay, which if + // chosen properly can reduce the CPU and bandwidth usage for ACK frames. + bool send_ack_frequency_on_handshake_completion_ = false; + + // Indicate whether AckFrequency frame has been sent. + bool ack_frequency_sent_ = false; + const bool fix_missing_initial_keys_ = GetQuicReloadableFlag(quic_fix_missing_initial_keys2); @@ -1804,6 +1937,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection const bool check_keys_before_writing_ = GetQuicReloadableFlag(quic_check_keys_before_writing); + + const bool encrypted_control_frames_; + + const bool use_encryption_level_context_; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc index 7e31f16adb2..e682ee32c6a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.cc @@ -10,6 +10,7 @@ #include <iomanip> #include <string> +#include "absl/strings/escaping.h" #include "third_party/boringssl/src/include/openssl/siphash.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -17,8 +18,8 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -50,7 +51,12 @@ class QuicConnectionIdHasher { } // namespace -QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {} +QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) { + static_assert(offsetof(QuicConnectionId, padding_) == + offsetof(QuicConnectionId, length_), + "bad offset"); + static_assert(sizeof(QuicConnectionId) <= 16, "bad size"); +} QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) { length_ = length; @@ -139,7 +145,7 @@ std::string QuicConnectionId::ToString() const { if (IsEmpty()) { return std::string("0"); } - return quiche::QuicheTextUtils::HexEncode(data(), length_); + return absl::BytesToHexString(absl::string_view(data(), length_)); } std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h index 52d5e11a354..d3706c83020 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id.h @@ -99,7 +99,6 @@ class QUIC_EXPORT_PRIVATE QuicConnectionId { bool operator<(const QuicConnectionId& v) const; private: - uint8_t length_; // length of the connection ID, in bytes. // The connection ID is represented in network byte order. union { // If the connection ID fits in |data_short_|, it is stored in the @@ -107,9 +106,16 @@ class QUIC_EXPORT_PRIVATE QuicConnectionId { // Otherwise it is stored in |data_long_| which is guaranteed to have a size // equal to |length_|. // A value of 11 was chosen because our commonly used connection ID length - // is 8 and with the length, the class is padded to 12 bytes anyway. - char data_short_[11]; - char* data_long_; + // is 8 and with the length, the class is padded to at least 12 bytes + // anyway. + struct { + uint8_t padding_; // Match length_ field of the other union member. + char data_short_[11]; + }; + struct { + uint8_t length_; // length of the connection ID, in bytes. + char* data_long_; + }; }; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc index 3fa7c020b40..84d30900551 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_id_test.cc @@ -8,10 +8,10 @@ #include <cstring> #include <string> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc index 191918c9887..d7440b4589b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc @@ -55,6 +55,9 @@ std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) { os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs; os << " sent_legacy_version_encapsulated_packets: " << s.sent_legacy_version_encapsulated_packets; + os << " key_update_count: " << s.key_update_count; + os << " num_failed_authentication_packets_received: " + << s.num_failed_authentication_packets_received; os << " }"; return os; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h index 5a568e19f9c..95cf61eed5a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h @@ -169,6 +169,15 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionStats { // Number of times when the connection tries to send data but gets throttled // by amplification factor. size_t num_amplification_throttling = 0; + + // Number of key phase updates that have occurred. In the case of a locally + // initiated key update, this is incremented when the keys are updated, before + // the peer has acknowledged the key update. + uint32_t key_update_count = 0; + + // Counts the number of undecryptable packets received across all keys. Does + // not include packets where a decryption key for that level was absent. + QuicPacketCount num_failed_authentication_packets_received = 0; }; } // namespace quic 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 3acac1c22dc..1d55c1a78c4 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 @@ -11,14 +11,18 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h" #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -40,9 +44,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::AnyNumber; @@ -108,23 +110,36 @@ QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) { } } -// StringTaggingDecrypter ensures that the final kTagSize bytes of the message -// match the expected value. -class StrictTaggingDecrypter : public TaggingDecrypter { +// A NullEncrypterWithConfidentialityLimit is a NullEncrypter that allows +// specifying the confidentiality limit on the maximum number of packets that +// may be encrypted per key phase in TLS+QUIC. +class NullEncrypterWithConfidentialityLimit : public NullEncrypter { public: - explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {} - ~StrictTaggingDecrypter() override {} + NullEncrypterWithConfidentialityLimit(Perspective perspective, + QuicPacketCount confidentiality_limit) + : NullEncrypter(perspective), + confidentiality_limit_(confidentiality_limit) {} - // TaggingQuicDecrypter - uint8_t GetTag(quiche::QuicheStringPiece /*ciphertext*/) override { - return tag_; + QuicPacketCount GetConfidentialityLimit() const override { + return confidentiality_limit_; } - // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. - uint32_t cipher_id() const override { return 0xFFFFFFF1; } + private: + QuicPacketCount confidentiality_limit_; +}; + +class StrictTaggingDecrypterWithIntegrityLimit : public StrictTaggingDecrypter { + public: + StrictTaggingDecrypterWithIntegrityLimit(uint8_t tag, + QuicPacketCount integrity_limit) + : StrictTaggingDecrypter(tag), integrity_limit_(integrity_limit) {} + + QuicPacketCount GetIntegrityLimit() const override { + return integrity_limit_; + } private: - const uint8_t tag_; + QuicPacketCount integrity_limit_; }; class TestConnectionHelper : public QuicConnectionHelperInterface { @@ -181,14 +196,16 @@ class TestAlarmFactory : public QuicAlarmFactory { class TestConnection : public QuicConnection { public: TestConnection(QuicConnectionId connection_id, - QuicSocketAddress address, + QuicSocketAddress initial_self_address, + QuicSocketAddress initial_peer_address, TestConnectionHelper* helper, TestAlarmFactory* alarm_factory, TestPacketWriter* writer, Perspective perspective, ParsedQuicVersion version) : QuicConnection(connection_id, - address, + initial_self_address, + initial_peer_address, helper, alarm_factory, writer, @@ -250,7 +267,7 @@ class TestConnection : public QuicConnection { } QuicConsumedData SendStreamDataWithString(QuicStreamId id, - quiche::QuicheStringPiece data, + absl::string_view data, QuicStreamOffset offset, StreamSendingState state) { ScopedPacketFlusher flusher(this); @@ -271,7 +288,7 @@ class TestConnection : public QuicConnection { QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level, QuicStreamId id, - quiche::QuicheStringPiece data, + absl::string_view data, QuicStreamOffset offset, StreamSendingState state) { ScopedPacketFlusher flusher(this); @@ -308,7 +325,7 @@ class TestConnection : public QuicConnection { // tests for some cases for this stream. QuicConsumedData SendCryptoStreamData() { QuicStreamOffset offset = 0; - quiche::QuicheStringPiece data("chlo"); + absl::string_view data("chlo"); if (!QuicVersionUsesCryptoFrames(transport_version())) { return SendCryptoDataWithString(data, offset); } @@ -324,12 +341,12 @@ class TestConnection : public QuicConnection { return QuicConsumedData(bytes_written, /*fin_consumed*/ false); } - QuicConsumedData SendCryptoDataWithString(quiche::QuicheStringPiece data, + QuicConsumedData SendCryptoDataWithString(absl::string_view data, QuicStreamOffset offset) { return SendCryptoDataWithString(data, offset, ENCRYPTION_INITIAL); } - QuicConsumedData SendCryptoDataWithString(quiche::QuicheStringPiece data, + QuicConsumedData SendCryptoDataWithString(absl::string_view data, QuicStreamOffset offset, EncryptionLevel encryption_level) { if (!QuicVersionUsesCryptoFrames(transport_version())) { @@ -438,6 +455,11 @@ class TestConnection : public QuicConnection { QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this)); } + TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() { + return reinterpret_cast<TestAlarmFactory::TestAlarm*>( + QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this)); + } + TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() { return reinterpret_cast<TestAlarmFactory::TestAlarm*>( QuicConnectionPeer::GetBlackholeDetectorAlarm(this)); @@ -593,6 +615,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { writer_( new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)), connection_(connection_id_, + kSelfAddress, kPeerAddress, helper_.get(), alarm_factory_.get(), @@ -601,9 +624,9 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { version()), creator_(QuicConnectionPeer::GetPacketCreator(&connection_)), manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)), - frame1_(0, false, 0, quiche::QuicheStringPiece(data1)), - frame2_(0, false, 3, quiche::QuicheStringPiece(data2)), - crypto_frame_(ENCRYPTION_INITIAL, 0, quiche::QuicheStringPiece(data1)), + frame1_(0, false, 0, absl::string_view(data1)), + frame2_(0, false, 3, absl::string_view(data2)), + crypto_frame_(ENCRYPTION_INITIAL, 0, absl::string_view(data1)), packet_number_length_(PACKET_4BYTE_PACKET_NUMBER), connection_id_included_(CONNECTION_ID_PRESENT), notifier_(&connection_), @@ -747,28 +770,33 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { } return QuicFrame(QuicStreamFrame( QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, - 0u, quiche::QuicheStringPiece())); + 0u, absl::string_view())); } void ProcessFramePacket(QuicFrame frame) { - ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress); + ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress, + ENCRYPTION_FORWARD_SECURE); } void ProcessFramePacketWithAddresses(QuicFrame frame, QuicSocketAddress self_address, - QuicSocketAddress peer_address) { + QuicSocketAddress peer_address, + EncryptionLevel level) { QuicFrames frames; frames.push_back(QuicFrame(frame)); - return ProcessFramesPacketWithAddresses(frames, self_address, peer_address); + return ProcessFramesPacketWithAddresses(frames, self_address, peer_address, + level); } void ProcessFramesPacketWithAddresses(QuicFrames frames, QuicSocketAddress self_address, - QuicSocketAddress peer_address) { + QuicSocketAddress peer_address, + EncryptionLevel level) { + DCHECK(peer_framer_.HasEncrypterOfEncryptionLevel(level)); + peer_creator_.set_encryption_level(level); QuicPacketCreatorPeer::SetSendVersionInPacket( &peer_creator_, - QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) < - ENCRYPTION_FORWARD_SECURE && + level < ENCRYPTION_FORWARD_SECURE && connection_.perspective() == Perspective::IS_SERVER); char buffer[kMaxOutgoingPacketSize]; @@ -998,7 +1026,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { } QuicByteCount SendStreamDataToPeer(QuicStreamId id, - quiche::QuicheStringPiece data, + absl::string_view data, QuicStreamOffset offset, StreamSendingState state, QuicPacketNumber* last_packet) { @@ -1035,7 +1063,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { void SendPing() { notifier_.WriteOrBufferPing(); } - MessageStatus SendMessage(quiche::QuicheStringPiece message) { + MessageStatus SendMessage(absl::string_view message) { connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); return connection_.SendMessage( @@ -1142,6 +1170,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { } std::unique_ptr<SerializedPacket> ConstructProbingPacket() { + peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); if (VersionHasIetfQuicFrames(version().transport_version)) { QuicPathFrameBuffer payload = { {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}}; @@ -1154,6 +1183,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> { } std::unique_ptr<QuicPacket> ConstructClosePacket(uint64_t number) { + peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); QuicPacketHeader header; // Set connection_id to peer's in memory representation as this connection // close packet is created by peer_framer. @@ -1446,8 +1476,8 @@ TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); // Cause change in self_address. QuicIpAddress host; host.FromString("1.1.1.1"); @@ -1457,8 +1487,8 @@ TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_TRUE(connection_.connected()); } @@ -1474,16 +1504,19 @@ TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); // Cause change in self_address. QuicIpAddress host; host.FromString("1.1.1.1"); QuicSocketAddress self_address(host, 123); EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false)); + if (version().handshake_protocol == PROTOCOL_TLS1_3) { + EXPECT_CALL(visitor_, BeforeConnectionCloseSent()); + } EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_FALSE(connection_.connected()); TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS); } @@ -1503,19 +1536,20 @@ TEST_P(QuicConnectionTest, AllowSelfAddressChangeToMappedIpv4AddressAtServer) { QuicIpAddress host; host.FromString("1.1.1.1"); QuicSocketAddress self_address1(host, 443); + connection_.SetSelfAddress(self_address1); ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1, - kPeerAddress); + kPeerAddress, ENCRYPTION_INITIAL); // Cause self_address change to mapped Ipv4 address. QuicIpAddress host2; host2.FromString(quiche::QuicheStrCat( "::ffff:", connection_.self_address().host().ToString())); QuicSocketAddress self_address2(host2, connection_.self_address().port()); ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address2, - kPeerAddress); + kPeerAddress, ENCRYPTION_INITIAL); EXPECT_TRUE(connection_.connected()); // self_address change back to Ipv4 address. ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1, - kPeerAddress); + kPeerAddress, ENCRYPTION_INITIAL); EXPECT_TRUE(connection_.connected()); } @@ -1540,7 +1574,7 @@ TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) { QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456); ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kNewPeerAddress); + kNewPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address()); @@ -1548,8 +1582,8 @@ TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) { QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4); // This is an old packet, do not migrate. EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address()); } @@ -1559,7 +1593,6 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) { QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false); EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective()); connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); // Prevent packets from being coalesced. EXPECT_CALL(visitor_, GetHandshakeState()) .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); @@ -1586,7 +1619,8 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) { })); QuicFrames frames; frames.push_back(QuicFrame(frame1_)); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress, + ENCRYPTION_FORWARD_SECURE); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -1595,7 +1629,8 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) { EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1); QuicFrames frames2; frames2.push_back(QuicFrame(frame2_)); - ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address()); } @@ -1623,8 +1658,8 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address()); @@ -1634,8 +1669,8 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) { QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321); connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress); EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address()); @@ -1651,7 +1686,7 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) { QuicAckFrame ack_frame = InitAckFrame(1); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)); ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress, - kNewPeerAddress); + kNewPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address()); @@ -1665,7 +1700,7 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) { kNewerEffectivePeerAddress); EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1); ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kFinalPeerAddress); + kFinalPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kFinalPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address()); EXPECT_EQ(PORT_CHANGE, connection_.active_effective_peer_migration_type()); @@ -1680,7 +1715,7 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) { EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1); EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1); ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kFinalPeerAddress); + kFinalPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kFinalPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address()); EXPECT_EQ(IPV6_TO_IPV4_CHANGE, @@ -1703,8 +1738,8 @@ TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -1818,8 +1853,8 @@ TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -1854,8 +1889,8 @@ TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) { // Process another packet with the old peer address on server side will not // start peer migration. EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); } @@ -1879,8 +1914,8 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -1912,7 +1947,8 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) { uint64_t num_probing_received = connection_.GetStats().num_connectivity_probing_received; - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_INITIAL); if (GetParam().version.HasIetfQuicFrames()) { // Padded PING with port changen is not considered as connectivity probe but @@ -1934,8 +1970,8 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) { } else { EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); } @@ -1957,8 +1993,8 @@ TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -2012,8 +2048,8 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -2045,7 +2081,7 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) { EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1); ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kNewPeerAddress); + kNewPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address()); } @@ -2067,8 +2103,8 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingPacketAtClient) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -2120,8 +2156,8 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -2172,8 +2208,8 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -2183,7 +2219,7 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) { QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456); EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kNewPeerAddress); + kNewPeerAddress, ENCRYPTION_INITIAL); EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address()); } @@ -2220,8 +2256,8 @@ TEST_P(QuicConnectionTest, PeerCannotRaiseMaxPacketSize) { } TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) { - TestConnection connection(TestConnectionId(), kPeerAddress, helper_.get(), - alarm_factory_.get(), writer_.get(), + TestConnection connection(TestConnectionId(), kSelfAddress, kPeerAddress, + helper_.get(), alarm_factory_.get(), writer_.get(), Perspective::IS_SERVER, version()); EXPECT_EQ(Perspective::IS_SERVER, connection.perspective()); EXPECT_EQ(1000u, connection.max_packet_length()); @@ -2335,8 +2371,8 @@ TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) { const QuicConnectionId connection_id = TestConnectionId(17); const QuicByteCount lower_max_packet_size = 1240; writer_->set_max_packet_size(lower_max_packet_size); - TestConnection connection(connection_id, kPeerAddress, helper_.get(), - alarm_factory_.get(), writer_.get(), + TestConnection connection(connection_id, kSelfAddress, kPeerAddress, + helper_.get(), alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT, version()); EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective()); EXPECT_EQ(lower_max_packet_size, connection.max_packet_length()); @@ -2612,7 +2648,6 @@ TEST_P(QuicConnectionTest, AckDecimationReducesAcks) { QuicTime::Delta::Zero(), QuicTime::Zero()); EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber()); - // Start ack decimation from 10th packet. connection_.set_min_received_before_ack_decimation(10); @@ -3111,7 +3146,7 @@ TEST_P(QuicConnectionTest, FramePackingSendv) { QuicStreamFrame* frame = writer_->stream_frames()[0].get(); EXPECT_EQ(stream_id, frame->stream_id); EXPECT_EQ("ABCDEF", - quiche::QuicheStringPiece(frame->data_buffer, frame->data_length)); + absl::string_view(frame->data_buffer, frame->data_length)); } TEST_P(QuicConnectionTest, FramePackingSendvQueued) { @@ -4012,7 +4047,11 @@ TEST_P(QuicConnectionTest, TailLossProbeDelayForNonStreamDataInTLPR) { connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); // Simulate firing of the retransmittable on wire and send a PING. - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); @@ -4026,13 +4065,21 @@ TEST_P(QuicConnectionTest, TailLossProbeDelayForNonStreamDataInTLPR) { QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); srtt = manager_->GetRttStats()->SmoothedOrInitialRtt(); - // First TLP without unacked stream data will no longer use TLPR. - expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout); + if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + // Arm RTO mode since there is only PING in flight. + expected_delay = manager_->GetPtoDelay(); + } else { + // First TLP without unacked stream data will no longer use TLPR. + expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout); + } EXPECT_EQ(expected_delay, connection_.GetRetransmissionAlarm()->deadline() - clock_.Now()); // Verify the path degrading delay = TLP delay + 1st RTO + 2nd RTO. // Add 1st RTO. + if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + 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(), @@ -4059,7 +4106,12 @@ TEST_P(QuicConnectionTest, TailLossProbeDelayForNonStreamDataInTLPR) { // Verify the retransmission delay. // First TLP without unacked stream data will no longer use TLPR. - expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout); + if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + // Arm RTO mode since there is only PING in flight. + expected_delay = manager_->GetPtoDelay(); + } else { + expected_delay = std::max(2 * srtt, 1.5 * srtt + 0.5 * min_rto_timeout); + } expected_delay = expected_delay - QuicTime::Delta::FromMilliseconds(5); EXPECT_EQ(expected_delay, connection_.GetRetransmissionAlarm()->deadline() - clock_.Now()); @@ -4585,7 +4637,11 @@ TEST_P(QuicConnectionTest, PingAfterSend) { writer_->Reset(); clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } connection_.GetPingAlarm()->Fire(); size_t padding_frame_count = writer_->padding_frames().size(); EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count()); @@ -4639,9 +4695,11 @@ TEST_P(QuicConnectionTest, ReducedPingTimeout) { writer_->Reset(); clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); + })); + } connection_.GetPingAlarm()->Fire(); size_t padding_frame_count = writer_->padding_frames().size(); EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count()); @@ -6432,6 +6490,9 @@ TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) { TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) { PathProbeTestInit(Perspective::IS_SERVER); + if (version().SupportsAntiAmplificationLimit()) { + QuicConnectionPeer::SetAddressValidated(&connection_); + } // Block next write so that sending connectivity probe will encounter a // blocked write when send a connectivity probe to the peer. @@ -6442,8 +6503,16 @@ TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) { EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _)) .Times(1); - connection_.SendConnectivityProbingPacket(writer_.get(), - connection_.peer_address()); + if (connection_.send_path_response() && + VersionHasIetfQuicFrames(GetParam().version.transport_version)) { + QuicPathFrameBuffer payload; + QuicConnection::ScopedPacketFlusher flusher(&connection_); + connection_.SendPathChallenge(&payload, connection_.self_address(), + connection_.peer_address(), writer_.get()); + } else { + connection_.SendConnectivityProbingPacket(writer_.get(), + connection_.peer_address()); + } } TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) { @@ -6814,18 +6883,18 @@ TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) { MockQuicConnectionDebugVisitor debug_visitor; connection_.set_debug_visitor(&debug_visitor); - EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header))).Times(1); + EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header), _, _)).Times(1); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1); EXPECT_CALL(debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1); connection_.OnPacketHeader(header); } TEST_P(QuicConnectionTest, Pacing) { - TestConnection server(connection_id_, kSelfAddress, helper_.get(), - alarm_factory_.get(), writer_.get(), + TestConnection server(connection_id_, kPeerAddress, kSelfAddress, + helper_.get(), alarm_factory_.get(), writer_.get(), Perspective::IS_SERVER, version()); - TestConnection client(connection_id_, kPeerAddress, helper_.get(), - alarm_factory_.get(), writer_.get(), + TestConnection client(connection_id_, kSelfAddress, kPeerAddress, + helper_.get(), alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT, version()); EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing( static_cast<const QuicSentPacketManager*>( @@ -7147,9 +7216,11 @@ TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) { // Simulate firing the ping alarm and sending a PING. clock_.AdvanceTime(retransmittable_on_wire_timeout); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); + })); + } connection_.GetPingAlarm()->Fire(); // Now there's a retransmittable packet (PING) on the wire, so the path @@ -7365,6 +7436,9 @@ TEST_P(QuicConnectionTest, ServerReceivesChloOnNonCryptoStream) { frame1_.data_buffer = data->data(); frame1_.data_length = data->length(); + if (version().handshake_protocol == PROTOCOL_TLS1_3) { + EXPECT_CALL(visitor_, BeforeConnectionCloseSent()); + } EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)); ForceProcessFramePacket(QuicFrame(frame1_)); @@ -7621,6 +7695,9 @@ TEST_P(QuicConnectionTest, DoNotPadServerInitialConnectionClose) { } set_perspective(Perspective::IS_SERVER); + if (version().handshake_protocol == PROTOCOL_TLS1_3) { + EXPECT_CALL(visitor_, BeforeConnectionCloseSent()); + } EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR; connection_.CloseConnection( @@ -7850,9 +7927,11 @@ TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) { EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline()); // Simulate the alarm firing and check that a PING is sent. - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); + })); + } connection_.GetPingAlarm()->Fire(); size_t padding_frame_count = writer_->padding_frames().size(); if (GetParam().no_stop_waiting) { @@ -7923,9 +8002,11 @@ TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) { // Simulate the alarm firing and check that a PING is sent. writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + connection_.SendControlFrame(QuicFrame(QuicPingFrame(1))); + })); + } connection_.GetPingAlarm()->Fire(); size_t padding_frame_count = writer_->padding_frames().size(); if (GetParam().no_stop_waiting) { @@ -7985,9 +8066,11 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) { connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); // Simulate the alarm firing and check that a PING is sent. writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - SendPing(); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(initial_retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); } @@ -8012,9 +8095,11 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) { // Simulate the alarm firing and check that a PING is sent. writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - SendPing(); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); } @@ -8080,7 +8165,11 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) { // Simulate the alarm firing and check that a PING is sent. writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(initial_retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); @@ -8116,9 +8205,11 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) { connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); // Simulate the alarm firing and check that a PING is sent. writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { - SendPing(); - })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(initial_retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); // Advance 5ms to receive next packet. @@ -8136,7 +8227,11 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) { connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); writer_->Reset(); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout); connection_.GetPingAlarm()->Fire(); @@ -8156,6 +8251,75 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) { connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); } +// Make sure that we never send more retransmissible on the wire pings than +// the limit in FLAGS_quic_max_retransmittable_on_wire_ping_count. +TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) { + static constexpr int kMaxRetransmittableOnWirePingCount = 3; + SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count, + kMaxRetransmittableOnWirePingCount); + static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout = + QuicTime::Delta::FromMilliseconds(200); + static constexpr QuicTime::Delta short_delay = + QuicTime::Delta::FromMilliseconds(5); + ASSERT_LT(short_delay * 10, initial_retransmittable_on_wire_timeout); + connection_.set_initial_retransmittable_on_wire_timeout( + initial_retransmittable_on_wire_timeout); + + EXPECT_TRUE(connection_.connected()); + EXPECT_CALL(visitor_, ShouldKeepConnectionAlive()) + .WillRepeatedly(Return(true)); + + const char data[] = "data"; + // Advance 5ms, send a retransmittable data packet to the peer. + clock_.AdvanceTime(short_delay); + EXPECT_FALSE(connection_.GetPingAlarm()->IsSet()); + connection_.SendStreamDataWithString(1, data, 0, NO_FIN); + EXPECT_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()); + + EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)) + .Times(AnyNumber()); + + // Verify that the first few consecutive retransmittable on wire pings are + // sent with aggressive timeout. + for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) { + // Receive an ACK of the previous packet. This should set the ping alarm + // with the initial retransmittable-on-wire timeout. + clock_.AdvanceTime(short_delay); + QuicPacketNumber ack_num = creator_->packet_number(); + QuicAckFrame frame = InitAckFrame( + {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}}); + ProcessAckPacket(&frame); + EXPECT_TRUE(connection_.GetPingAlarm()->IsSet()); + EXPECT_EQ(initial_retransmittable_on_wire_timeout, + connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); + // Simulate the alarm firing and check that a PING is sent. + writer_->Reset(); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } + clock_.AdvanceTime(initial_retransmittable_on_wire_timeout); + connection_.GetPingAlarm()->Fire(); + } + + // Receive an ACK of the previous packet. This should set the ping alarm + // but this time with the default ping timeout. + QuicPacketNumber ack_num = creator_->packet_number(); + QuicAckFrame frame = InitAckFrame( + {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}}); + ProcessAckPacket(&frame); + EXPECT_TRUE(connection_.GetPingAlarm()->IsSet()); + EXPECT_EQ(connection_.ping_timeout(), + connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow()); +} + TEST_P(QuicConnectionTest, ValidStatelessResetToken) { const QuicUint128 kTestToken = 1010101; const QuicUint128 kWrongTestToken = 1010100; @@ -8199,7 +8363,7 @@ TEST_P(QuicConnectionTest, SendMessage) { connection_.SetFromConfig(config); } std::string message(connection_.GetCurrentLargestMessagePayload() * 2, 'a'); - quiche::QuicheStringPiece message_data(message); + absl::string_view message_data(message); QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); { QuicConnection::ScopedPacketFlusher flusher(&connection_); @@ -8212,7 +8376,7 @@ TEST_P(QuicConnectionTest, SendMessage) { connection_.SendMessage( 1, MakeSpan(connection_.helper()->GetStreamSendBufferAllocator(), - quiche::QuicheStringPiece( + absl::string_view( message_data.data(), connection_.GetCurrentLargestMessagePayload()), &storage), @@ -8233,7 +8397,7 @@ TEST_P(QuicConnectionTest, SendMessage) { connection_.SendMessage( 3, MakeSpan(connection_.helper()->GetStreamSendBufferAllocator(), - quiche::QuicheStringPiece( + absl::string_view( message_data.data(), connection_.GetCurrentLargestMessagePayload() + 1), &storage), @@ -8445,8 +8609,8 @@ TEST_P(QuicConnectionTest, } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -8579,8 +8743,8 @@ TEST_P(QuicConnectionTest, StopProcessingGQuicPacketInIetfQuicConnection) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); // Let connection process a Google QUIC packet. peer_framer_.set_version_for_tests(ParsedQuicVersion::Q043()); @@ -8895,11 +9059,12 @@ TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_TRUE(connection_.HasPendingAcks()); ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()), - kSelfAddress, kPeerAddress); + kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); // Verify ack alarm is not set. EXPECT_FALSE(connection_.HasPendingAcks()); } @@ -9097,7 +9262,11 @@ TEST_P(QuicConnectionTest, RtoForcesSendingPing) { // RTO fires, verify a PING packet gets sent because there is no data to send. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } clock_.AdvanceTime(retransmission_time - clock_.Now()); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(1u, connection_.GetStats().tlp_count); @@ -9317,7 +9486,11 @@ TEST_P(QuicConnectionTest, DeprecateHandshakeMode) { ? QuicPacketNumber(2) : QuicPacketNumber(3), _, _)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(1u, connection_.GetStats().pto_count); EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count); @@ -9614,7 +9787,11 @@ TEST_P(QuicConnectionTest, RtoPacketAsTwo) { // Fires TLP, verify a PING gets sent because packet 3 is marked // RTO_RETRANSMITTED. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } connection_.GetRetransmissionAlarm()->Fire(); } @@ -9756,6 +9933,9 @@ TEST_P(QuicConnectionTest, ServerReceivedHandshakeDone) { } set_perspective(Perspective::IS_SERVER); EXPECT_CALL(visitor_, OnHandshakeDoneReceived()).Times(0); + if (version().handshake_protocol == PROTOCOL_TLS1_3) { + EXPECT_CALL(visitor_, BeforeConnectionCloseSent()); + } EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)) .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame)); QuicFrames frames; @@ -9877,10 +10057,10 @@ void QuicConnectionTest::TestClientRetryHandling( size_t retry_packet_length; if (version() == ParsedQuicVersion::Draft29()) { retry_packet = retry_packet29; - retry_packet_length = QUICHE_ARRAYSIZE(retry_packet29); + retry_packet_length = ABSL_ARRAYSIZE(retry_packet29); } else if (version() == ParsedQuicVersion::Draft27()) { retry_packet = retry_packet27; - retry_packet_length = QUICHE_ARRAYSIZE(retry_packet27); + retry_packet_length = ABSL_ARRAYSIZE(retry_packet27); } else { // TODO(dschinazi) generate retry packets for all versions once we have // server-side support for generating these programmatically. @@ -9895,12 +10075,11 @@ void QuicConnectionTest::TestClientRetryHandling( QuicConnectionId original_connection_id( original_connection_id_bytes, - QUICHE_ARRAYSIZE(original_connection_id_bytes)); + ABSL_ARRAYSIZE(original_connection_id_bytes)); QuicConnectionId new_connection_id(new_connection_id_bytes, - QUICHE_ARRAYSIZE(new_connection_id_bytes)); + ABSL_ARRAYSIZE(new_connection_id_bytes)); - std::string retry_token(retry_token_bytes, - QUICHE_ARRAYSIZE(retry_token_bytes)); + std::string retry_token(retry_token_bytes, ABSL_ARRAYSIZE(retry_token_bytes)); if (invalid_retry_tag) { // Flip the last bit of the retry packet to prevent the integrity tag @@ -10205,7 +10384,11 @@ TEST_P(QuicConnectionTest, SendPingWhenSkipPacketNumberForPto) { // PTO fires, verify a PING packet gets sent because there is no data to // send. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _)); - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(1u, connection_.GetStats().pto_count); EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count); @@ -10233,7 +10416,7 @@ TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) { frames.push_back(QuicFrame(QuicStreamFrame( QuicUtils::GetFirstBidirectionalStreamId( connection_.version().transport_version, Perspective::IS_CLIENT), - false, 0u, quiche::QuicheStringPiece()))); + false, 0u, absl::string_view()))); QuicAckFrame ack_frame = InitAckFrame(1); frames.push_back(QuicFrame(&ack_frame)); // Receiving stream frame causes something to send. @@ -10937,51 +11120,17 @@ TEST_P(QuicConnectionTest, SilentIdleTimeout) { EXPECT_TRUE(connection_.connected()); EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_CALL(visitor_, - OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); - connection_.GetTimeoutAlarm()->Fire(); - if (GetQuicReloadableFlag(quic_add_silent_idle_timeout)) { - // Verify the connection close packets get serialized and added to - // termination packets list. - EXPECT_NE(nullptr, - QuicConnectionPeer::GetConnectionClosePacket(&connection_)); - } else { - // Verify no connection close packet is serialized. - EXPECT_EQ(nullptr, - QuicConnectionPeer::GetConnectionClosePacket(&connection_)); - } -} - -TEST_P(QuicConnectionTest, NoSilentClose) { - SetQuicReloadableFlag(quic_add_silent_idle_timeout, false); - set_perspective(Perspective::IS_SERVER); - QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false); - if (version().SupportsAntiAmplificationLimit()) { - QuicConnectionPeer::SetAddressValidated(&connection_); - } - - QuicConfig config; - QuicTagVector connection_options; - connection_options.push_back(kNSLC); - config.SetInitialReceivedConnectionOptions(connection_options); - QuicConfigPeer::SetNegotiated(&config, true); - if (connection_.version().AuthenticatesHandshakeConnectionIds()) { - QuicConfigPeer::SetReceivedOriginalConnectionId( - &config, connection_.connection_id()); - QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config, - QuicConnectionId()); + if (version().handshake_protocol == PROTOCOL_TLS1_3) { + EXPECT_CALL(visitor_, BeforeConnectionCloseSent()); } - EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); - connection_.SetFromConfig(config); - - EXPECT_TRUE(connection_.connected()); - EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); connection_.GetTimeoutAlarm()->Fire(); - TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT); + // Verify the connection close packets get serialized and added to + // termination packets list. + EXPECT_NE(nullptr, + QuicConnectionPeer::GetConnectionClosePacket(&connection_)); } TEST_P(QuicConnectionTest, DonotSendPing) { @@ -11009,7 +11158,7 @@ TEST_P(QuicConnectionTest, DonotSendPing) { frames.push_back(QuicFrame(&ack_frame)); frames.push_back(QuicFrame(QuicStreamFrame( GetNthClientInitiatedStreamId(0, connection_.transport_version()), true, - 0u, quiche::QuicheStringPiece()))); + 0u, absl::string_view()))); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); @@ -11027,7 +11176,11 @@ TEST_P(QuicConnectionTest, DonotSendPing) { EXPECT_CALL(visitor_, ShouldKeepConnectionAlive()) .WillRepeatedly(Return(false)); // Verify PING does not get sent. - EXPECT_CALL(visitor_, SendPing()).Times(0); + if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); + } else { + EXPECT_CALL(visitor_, SendPing()).Times(0); + } connection_.GetPingAlarm()->Fire(); } @@ -11038,7 +11191,6 @@ TEST_P(QuicConnectionTest, DuplicateAckCausesLostPackets) { } // Finish handshake. connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); notifier_.NeuterUnencryptedData(); connection_.NeuterUnencryptedPackets(); connection_.OnHandshakeComplete(); @@ -11144,8 +11296,6 @@ TEST_P(QuicConnectionTest, ShorterIdleTimeoutOnSentPackets) { // Regression test for b/166255274 TEST_P(QuicConnectionTest, ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) { - SetQuicReloadableFlag( - quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded, true); if (!connection_.version().CanSendCoalescedPackets() || !GetQuicReloadableFlag(quic_fix_missing_initial_keys2)) { // Cannot set quic_fix_missing_initial_keys in the test since connection_ is @@ -11174,9 +11324,6 @@ TEST_P(QuicConnectionTest, // Flush pending ACKs. connection_.GetAckAlarm()->Fire(); } - // If not setting - // quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded, there - // will be pending frames in the creator. EXPECT_FALSE(connection_.packet_creator().HasPendingFrames()); // The ACK frame is deleted along with initial_packet_ in coalescer. Sending // connection close would cause this (released) ACK frame be serialized (and @@ -11186,6 +11333,178 @@ TEST_P(QuicConnectionTest, EXPECT_TRUE(connection_.connected()); } +TEST_P(QuicConnectionTest, SendPathChallenge) { + if (!VersionHasIetfQuicFrames(connection_.version().transport_version) || + !connection_.send_path_response()) { + return; + } + PathProbeTestInit(Perspective::IS_CLIENT); + const QuicSocketAddress kNewSourceAddress(QuicIpAddress::Any6(), 12345); + EXPECT_NE(kNewSourceAddress, connection_.self_address()); + TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT); + QuicPathFrameBuffer payload; + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(Invoke([&]() { + EXPECT_EQ(1u, new_writer.packets_write_attempts()); + EXPECT_EQ(1u, new_writer.path_challenge_frames().size()); + EXPECT_EQ( + 0, memcmp(payload.data(), + &(new_writer.path_challenge_frames().front().data_buffer), + sizeof(payload))); + EXPECT_EQ(1u, new_writer.padding_frames().size()); + EXPECT_EQ(kNewSourceAddress.host(), + new_writer.last_write_source_address()); + })); + connection_.SendPathChallenge(&payload, kNewSourceAddress, + connection_.peer_address(), &new_writer); + EXPECT_EQ(0u, writer_->packets_write_attempts()); +} + +TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedNewSocket) { + if (!VersionHasIetfQuicFrames(connection_.version().transport_version) || + !connection_.send_path_response()) { + return; + } + PathProbeTestInit(Perspective::IS_CLIENT); + const QuicSocketAddress kNewSourceAddress(QuicIpAddress::Any6(), 12345); + EXPECT_NE(kNewSourceAddress, connection_.self_address()); + TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT); + new_writer.BlockOnNextWrite(); + QuicPathFrameBuffer payload; + EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(Invoke([&]() { + // Even though the socket is blocked, the PATH_CHALLENGE should still be + // treated as sent. + EXPECT_EQ(1u, new_writer.packets_write_attempts()); + EXPECT_EQ(1u, new_writer.path_challenge_frames().size()); + EXPECT_EQ( + 0, memcmp(payload.data(), + &(new_writer.path_challenge_frames().front().data_buffer), + sizeof(payload))); + EXPECT_EQ(1u, new_writer.padding_frames().size()); + EXPECT_EQ(kNewSourceAddress.host(), + new_writer.last_write_source_address()); + })); + connection_.SendPathChallenge(&payload, kNewSourceAddress, + connection_.peer_address(), &new_writer); + EXPECT_EQ(0u, writer_->packets_write_attempts()); + + new_writer.SetWritable(); + // Write event on the default socket shouldn't make any difference. + connection_.OnCanWrite(); + EXPECT_EQ(0u, writer_->packets_write_attempts()); + EXPECT_EQ(1u, new_writer.packets_write_attempts()); +} + +TEST_P(QuicConnectionTest, SendPathChallengeWithDefaultSocketBlocked) { + if (!VersionHasIetfQuicFrames(connection_.version().transport_version) || + !connection_.send_path_response()) { + return; + } + PathProbeTestInit(Perspective::IS_SERVER); + if (version().SupportsAntiAmplificationLimit()) { + QuicConnectionPeer::SetAddressValidated(&connection_); + } + const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any6(), 12345); + writer_->BlockOnNextWrite(); + QuicPathFrameBuffer payload; + // 1st time is after writer returns WRITE_STATUS_BLOCKED. 2nd time is in + // ShouldGeneratePacket(); + EXPECT_CALL(visitor_, OnWriteBlocked()).Times(2u); + // This packet isn't sent actually, instead it is buffered in the connection. + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(Invoke([&]() { + EXPECT_EQ(1u, writer_->path_challenge_frames().size()); + EXPECT_EQ( + 0, memcmp(payload.data(), + &(writer_->path_challenge_frames().front().data_buffer), + sizeof(payload))); + EXPECT_EQ(1u, writer_->padding_frames().size()); + EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address()); + })); + connection_.SendPathChallenge(&payload, connection_.self_address(), + kNewPeerAddress, writer_.get()); + EXPECT_EQ(1u, writer_->packets_write_attempts()); + + memset(payload.data(), 0, sizeof(payload)); + // Try again with the new socket blocked from the beginning. The 2nd + // PATH_CHALLENGE shouldn't be serialized, but be dropped. + connection_.SendPathChallenge(&payload, connection_.self_address(), + kNewPeerAddress, writer_.get()); + // No more write attempt should be made. + EXPECT_EQ(1u, writer_->packets_write_attempts()); + + writer_->SetWritable(); + // OnCanWrite() should actually write out the 1st PATH_CHALLENGE packet + // buffered earlier, thus incrementing the write counter. + connection_.OnCanWrite(); + EXPECT_EQ(2u, writer_->packets_write_attempts()); +} + +// Tests that write error on the alternate socket should be ignored. +TEST_P(QuicConnectionTest, SendPathChallengeFailOnNewSocket) { + if (!VersionHasIetfQuicFrames(connection_.version().transport_version) || + !connection_.send_path_response()) { + return; + } + PathProbeTestInit(Perspective::IS_CLIENT); + const QuicSocketAddress kNewSourceAddress(QuicIpAddress::Any6(), 12345); + EXPECT_NE(kNewSourceAddress, connection_.self_address()); + TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT); + new_writer.SetShouldWriteFail(); + QuicPathFrameBuffer payload; + EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)) + .Times(0); + + connection_.SendPathChallenge(&payload, kNewSourceAddress, + connection_.peer_address(), &new_writer); + // Regardless of the write error, the PATH_CHALLENGE should still be + // treated as sent. + EXPECT_EQ(1u, new_writer.packets_write_attempts()); + EXPECT_EQ(1u, new_writer.path_challenge_frames().size()); + EXPECT_EQ(0, memcmp(payload.data(), + &(new_writer.path_challenge_frames().front().data_buffer), + sizeof(payload))); + EXPECT_EQ(1u, new_writer.padding_frames().size()); + EXPECT_EQ(kNewSourceAddress.host(), new_writer.last_write_source_address()); + EXPECT_EQ(0u, writer_->packets_write_attempts()); + EXPECT_TRUE(connection_.connected()); +} + +// Tests that write error while sending PATH_CHALLANGE from the default socket +// should close the connection. +TEST_P(QuicConnectionTest, SendPathChallengeFailOnDefaultPath) { + if (!VersionHasIetfQuicFrames(connection_.version().transport_version) || + !connection_.send_path_response()) { + return; + } + PathProbeTestInit(Perspective::IS_CLIENT); + writer_->SetShouldWriteFail(); + QuicPathFrameBuffer payload; + EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF)) + .WillOnce( + Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) { + EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code); + })); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u); + { + // Add a flusher to force flush, otherwise the frames will remain in the + // packet creator. + QuicConnection::ScopedPacketFlusher flusher(&connection_); + connection_.SendPathChallenge(&payload, connection_.self_address(), + connection_.peer_address(), writer_.get()); + } + EXPECT_EQ(1u, writer_->packets_write_attempts()); + EXPECT_EQ(1u, writer_->path_challenge_frames().size()); + EXPECT_EQ(0, memcmp(payload.data(), + &(writer_->path_challenge_frames().front().data_buffer), + sizeof(payload))); + EXPECT_EQ(1u, writer_->padding_frames().size()); + EXPECT_EQ(connection_.peer_address(), writer_->last_write_peer_address()); + EXPECT_FALSE(connection_.connected()); +} + // Check that if there are two PATH_CHALLENGE frames in the packet, the latter // one is ignored. TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) { @@ -11207,8 +11526,8 @@ TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_FORWARD_SECURE); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -11253,7 +11572,8 @@ TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) { // address. EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address()); })); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); } TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) { @@ -11276,8 +11596,8 @@ TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -11302,7 +11622,8 @@ TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) { NO_FIN); })); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); // Verify that this packet contains a STREAM_FRAME and a // PATH_RESPONSE_FRAME. @@ -11337,8 +11658,8 @@ TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) { } else { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -11382,7 +11703,8 @@ TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) { NO_FIN); })); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); } // Tests that a PATH_CHALLENGE is received in between other frames in an out of @@ -11408,8 +11730,8 @@ TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_FORWARD_SECURE); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -11468,7 +11790,8 @@ TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) { // Lower the packet number so that receiving this packet shouldn't trigger // peer migration. QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); } // Tests that a PATH_CHALLENGE is cached if its PATH_RESPONSE can't be sent. @@ -11493,8 +11816,8 @@ TEST_P(QuicConnectionTest, FailToWritePathResponse) { EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber()); } QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2); - ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, - kPeerAddress); + ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress, + ENCRYPTION_INITIAL); EXPECT_EQ(kPeerAddress, connection_.peer_address()); EXPECT_EQ(kPeerAddress, connection_.effective_peer_address()); @@ -11510,7 +11833,8 @@ TEST_P(QuicConnectionTest, FailToWritePathResponse) { QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1); EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1)); writer_->SetWriteBlocked(); - ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress); + ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress, + ENCRYPTION_FORWARD_SECURE); EXPECT_EQ( 1u, @@ -11601,6 +11925,10 @@ TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) { if (!GetQuicReloadableFlag(quic_fix_missing_initial_keys2)) { EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1); } + } else if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + if (!GetQuicReloadableFlag(quic_fix_missing_initial_keys2)) { + EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1); + } } else { EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(0); EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { @@ -11612,10 +11940,15 @@ TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) { // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced. EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet()); } else { - // Verify an 1-RTT PING gets sent because there is nothing to PTO, bummer, - // since this 1-RTT PING cannot be processed by peer and there is a - // deadlock. - EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet()); + if (GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + // Verify PING is sent in the right encryption level. + EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet()); + } else { + // Verify an 1-RTT PING gets sent because there is nothing to PTO, bummer, + // since this 1-RTT PING cannot be processed by peer and there is a + // deadlock. + EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet()); + } EXPECT_FALSE(writer_->ping_frames().empty()); } } @@ -11704,14 +12037,18 @@ TEST_P(QuicConnectionTest, ZeroRttRejectionAndMissingInitialKeys) { EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); // Fire retransmission alarm. - EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); + if (!GetQuicReloadableFlag(quic_let_connection_handle_pings)) { + EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { + SendPing(); + })); + } connection_.GetRetransmissionAlarm()->Fire(); QuicFrames frames1; frames1.push_back(QuicFrame(&crypto_frame_)); QuicFrames frames2; QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0, - quiche::QuicheStringPiece(data1)); + absl::string_view(data1)); frames2.push_back(QuicFrame(&crypto_frame)); ProcessCoalescedPacket( {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}}); @@ -11742,7 +12079,7 @@ TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) { QuicFrames frames2; QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0, - quiche::QuicheStringPiece(data1)); + absl::string_view(data1)); frames2.push_back(QuicFrame(&crypto_frame)); EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0); EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1); @@ -11764,6 +12101,849 @@ TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) { ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}}); } +TEST_P(QuicConnectionTest, InitiateKeyUpdate) { + if (!connection_.version().UsesTls()) { + return; + } + + 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().AuthenticatesHandshakeConnectionIds()) { + QuicConfigPeer::SetReceivedOriginalConnectionId( + &config, connection_.connection_id()); + QuicConfigPeer::SetReceivedInitialSourceConnectionId( + &config, connection_.connection_id()); + } + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + + MockFramerVisitor peer_framer_visitor_; + peer_framer_.set_visitor(&peer_framer_visitor_); + + use_tagging_decrypter(); + + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0x01)); + SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(0x01)); + EXPECT_CALL(visitor_, GetHandshakeState()) + .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); + connection_.OnHandshakeComplete(); + + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0x01)); + + // Key update should still not be allowed, since no packet has been acked + // from the current key phase. + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Send packet 1. + QuicPacketNumber last_packet; + SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(1u), last_packet); + + // Key update should still not be allowed, even though a packet was sent in + // the current key phase it hasn't been acked yet. + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + // Receive ack for packet 1. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame1 = InitAckFrame(1); + ProcessAckPacket(&frame1); + + // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase, + // so discard_previous_keys_alarm_ should be set now. + EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Key update should now be allowed. + EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x02); }); + EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { + return std::make_unique<TaggingEncrypter>(0x02); + }); + EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests)); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + // discard_previous_keys_alarm_ should not be set until a packet from the new + // key phase has been received. (The alarm that was set above should be + // cleared if it hasn't fired before the next key update happened.) + EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Pretend that peer accepts the key update. + EXPECT_CALL(peer_framer_visitor_, + AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x02); }); + EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) + .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); }); + peer_framer_.SetKeyUpdateSupportForConnection(true); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); + + // Another key update should not be allowed yet. + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + + // Send packet 2. + SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(2u), last_packet); + EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + // Receive ack for packet 2. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame2 = InitAckFrame(2); + ProcessAckPacket(&frame2); + EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Key update should be allowed again now that a packet has been acked from + // the current key phase. + EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x03); }); + EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { + return std::make_unique<TaggingEncrypter>(0x03); + }); + EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests)); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + + // Pretend that peer accepts the key update. + EXPECT_CALL(peer_framer_visitor_, + AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x03); }); + EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) + .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); }); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); + + // Another key update should not be allowed yet. + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + + // Send packet 3. + SendStreamDataToPeer(3, "baz", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(3u), last_packet); + + // Another key update should not be allowed yet. + EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); + EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Receive ack for packet 3. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame3 = InitAckFrame(3); + ProcessAckPacket(&frame3); + EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); + + // Key update should be allowed now. + EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x04); }); + EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { + return std::make_unique<TaggingEncrypter>(0x04); + }); + EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests)); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); + EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked()); +} + +TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 3U); + + 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().AuthenticatesHandshakeConnectionIds()) { + QuicConfigPeer::SetReceivedOriginalConnectionId( + &config, connection_.connection_id()); + QuicConfigPeer::SetReceivedInitialSourceConnectionId( + &config, connection_.connection_id()); + } + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + + MockFramerVisitor peer_framer_visitor_; + peer_framer_.set_visitor(&peer_framer_visitor_); + + use_tagging_decrypter(); + + uint8_t current_tag = 0x01; + + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(current_tag)); + SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(current_tag)); + EXPECT_CALL(visitor_, GetHandshakeState()) + .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); + connection_.OnHandshakeComplete(); + + peer_framer_.SetKeyUpdateSupportForConnection(true); + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(current_tag)); + + const QuicConnectionStats& stats = connection_.GetStats(); + + for (int packet_num = 1; packet_num <= 8; ++packet_num) { + if (packet_num == 3 || packet_num == 6) { + current_tag++; + EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce([current_tag]() { + return std::make_unique<StrictTaggingDecrypter>(current_tag); + }); + EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()) + .WillOnce([current_tag]() { + return std::make_unique<TaggingEncrypter>(current_tag); + }); + EXPECT_CALL(visitor_, + OnKeyUpdate(KeyUpdateReason::kLocalKeyUpdateLimitOverride)); + } + // Send packet. + QuicPacketNumber last_packet; + SendStreamDataToPeer(packet_num, "foo", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(packet_num), last_packet); + if (packet_num >= 6) { + EXPECT_EQ(2U, stats.key_update_count); + } else if (packet_num >= 3) { + EXPECT_EQ(1U, stats.key_update_count); + } else { + EXPECT_EQ(0U, stats.key_update_count); + } + + if (packet_num == 4 || packet_num == 7) { + // Pretend that peer accepts the key update. + EXPECT_CALL(peer_framer_visitor_, + AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce([current_tag]() { + return std::make_unique<StrictTaggingDecrypter>(current_tag); + }); + EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) + .WillOnce([current_tag]() { + return std::make_unique<TaggingEncrypter>(current_tag); + }); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); + } + // Receive ack for packet. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame1 = InitAckFrame(packet_num); + ProcessAckPacket(&frame1); + } +} + +TEST_P(QuicConnectionTest, + CloseConnectionOnConfidentialityLimitKeyUpdateNotAllowed) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + // 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 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().AuthenticatesHandshakeConnectionIds()) { + 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 without receiving acks for any of them. Key update will not + // be allowed, so the confidentiality limit should be reached, forcing the + // connection to be closed. + SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); + EXPECT_TRUE(connection_.connected()); + SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet); + EXPECT_TRUE(connection_.connected()); + 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, + CloseConnectionOnConfidentialityLimitKeyUpdateNotSupportedByPeer) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + // 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().AuthenticatesHandshakeConnectionIds()) { + 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; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + // 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().AuthenticatesHandshakeConnectionIds()) { + 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; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + + constexpr uint8_t correct_tag = 0x01; + constexpr uint8_t wrong_tag = 0xFE; + constexpr QuicPacketCount kIntegrityLimit = 3; + + SetDecrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + correct_tag, kIntegrityLimit)); + connection_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(correct_tag)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE); + peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(wrong_tag)); + for (uint64_t i = 1; i <= kIntegrityLimit; ++i) { + EXPECT_TRUE(connection_.connected()); + if (i == kIntegrityLimit) { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); + EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber()); + } + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + EXPECT_FALSE(connection_.connected()); + TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED); +} + +TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAfterHandshake) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + + constexpr uint8_t correct_tag = 0x01; + constexpr uint8_t wrong_tag = 0xFE; + constexpr QuicPacketCount kIntegrityLimit = 3; + + use_tagging_decrypter(); + SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + correct_tag, kIntegrityLimit)); + connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(correct_tag)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + EXPECT_CALL(visitor_, GetHandshakeState()) + .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); + connection_.OnHandshakeComplete(); + connection_.RemoveEncrypter(ENCRYPTION_INITIAL); + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(wrong_tag)); + for (uint64_t i = 1; i <= kIntegrityLimit; ++i) { + EXPECT_TRUE(connection_.connected()); + if (i == kIntegrityLimit) { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); + } + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + EXPECT_FALSE(connection_.connected()); + TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED); +} + +TEST_P(QuicConnectionTest, + CloseConnectionOnIntegrityLimitAcrossEncryptionLevels) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + + constexpr uint8_t correct_tag = 0x01; + constexpr uint8_t wrong_tag = 0xFE; + constexpr QuicPacketCount kIntegrityLimit = 4; + + use_tagging_decrypter(); + SetDecrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + correct_tag, kIntegrityLimit)); + connection_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(correct_tag)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE); + peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(wrong_tag)); + for (uint64_t i = 1; i <= 2; ++i) { + EXPECT_TRUE(connection_.connected()); + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + + SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + correct_tag, kIntegrityLimit)); + connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(correct_tag)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + EXPECT_CALL(visitor_, GetHandshakeState()) + .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); + connection_.OnHandshakeComplete(); + connection_.RemoveEncrypter(ENCRYPTION_INITIAL); + connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE); + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(wrong_tag)); + for (uint64_t i = 3; i <= kIntegrityLimit; ++i) { + EXPECT_TRUE(connection_.connected()); + if (i == kIntegrityLimit) { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); + } + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + EXPECT_FALSE(connection_.connected()); + TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED); +} + +TEST_P(QuicConnectionTest, IntegrityLimitDoesNotApplyWithoutDecryptionKey) { + if (!connection_.version().UsesTls()) { + return; + } + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + + constexpr uint8_t correct_tag = 0x01; + constexpr uint8_t wrong_tag = 0xFE; + constexpr QuicPacketCount kIntegrityLimit = 3; + + use_tagging_decrypter(); + SetDecrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + correct_tag, kIntegrityLimit)); + connection_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(correct_tag)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE); + connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE); + + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(wrong_tag)); + for (uint64_t i = 1; i <= kIntegrityLimit * 2; ++i) { + EXPECT_TRUE(connection_.connected()); + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ( + 0u, connection_.GetStats().num_failed_authentication_packets_received); + } + EXPECT_TRUE(connection_.connected()); +} + +TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) { + if (!connection_.version().UsesTls()) { + return; + } + + constexpr QuicPacketCount kIntegrityLimit = 4; + + QuicConnectionPeer::SetEnableAeadLimits(&connection_, true); + 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().AuthenticatesHandshakeConnectionIds()) { + QuicConfigPeer::SetReceivedOriginalConnectionId( + &config, connection_.connection_id()); + QuicConfigPeer::SetReceivedInitialSourceConnectionId( + &config, connection_.connection_id()); + } + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + + MockFramerVisitor peer_framer_visitor_; + peer_framer_.set_visitor(&peer_framer_visitor_); + + use_tagging_decrypter(); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0x01)); + SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + 0x01, kIntegrityLimit)); + EXPECT_CALL(visitor_, GetHandshakeState()) + .WillRepeatedly(Return(HANDSHAKE_CONFIRMED)); + connection_.OnHandshakeComplete(); + connection_.RemoveEncrypter(ENCRYPTION_INITIAL); + + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0xFF)); + for (uint64_t i = 1; i <= 2; ++i) { + EXPECT_TRUE(connection_.connected()); + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0x01)); + // Send packet 1. + QuicPacketNumber last_packet; + SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(1u), last_packet); + // Receive ack for packet 1. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame1 = InitAckFrame(1); + ProcessAckPacket(&frame1); + // Key update should now be allowed, initiate it. + EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce([kIntegrityLimit]() { + return std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>( + 0x02, kIntegrityLimit); + }); + EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { + return std::make_unique<TaggingEncrypter>(0x02); + }); + EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests)); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); + + // Pretend that peer accepts the key update. + EXPECT_CALL(peer_framer_visitor_, + AdvanceKeysAndCreateCurrentOneRttDecrypter()) + .WillOnce( + []() { return std::make_unique<StrictTaggingDecrypter>(0x02); }); + EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) + .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); }); + peer_framer_.SetKeyUpdateSupportForConnection(true); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests); + + // Send packet 2. + SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet); + EXPECT_EQ(QuicPacketNumber(2u), last_packet); + // Receive ack for packet 2. + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _)); + QuicAckFrame frame2 = InitAckFrame(2); + ProcessAckPacket(&frame2); + + EXPECT_EQ(2u, + connection_.GetStats().num_failed_authentication_packets_received); + + // Do two more undecryptable packets. Integrity limit should be reached. + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(0xFF)); + for (uint64_t i = 3; i <= kIntegrityLimit; ++i) { + EXPECT_TRUE(connection_.connected()); + if (i == kIntegrityLimit) { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)); + } + ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ( + i, connection_.GetStats().num_failed_authentication_packets_received); + } + EXPECT_FALSE(connection_.connected()); + TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED); +} + +TEST_P(QuicConnectionTest, SendAckFrequencyFrame) { + if (!version().HasIetfQuicFrames()) { + return; + } + SetQuicReloadableFlag(quic_can_send_ack_frequency, true); + set_perspective(Perspective::IS_SERVER); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)) + .Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + + QuicConfig config; + QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + QuicConnectionPeer::SetAddressValidated(&connection_); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); + + connection_.OnHandshakeComplete(); + + writer_->SetWritable(); + QuicPacketCreatorPeer::SetPacketNumber(creator_, 99); + // Send packet 100 + SendStreamDataToPeer(/*id=*/1, "foo", /*offset=*/0, NO_FIN, nullptr); + + QuicAckFrequencyFrame captured_frame; + EXPECT_CALL(visitor_, SendAckFrequency(_)) + .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) { + captured_frame = frame; + })); + // Send packet 101. + SendStreamDataToPeer(/*id=*/1, "bar", /*offset=*/3, NO_FIN, nullptr); + + EXPECT_EQ(captured_frame.packet_tolerance, 10u); + EXPECT_EQ(captured_frame.max_ack_delay, + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)); + + // Sending packet 102 does not trigger sending another AckFrequencyFrame. + SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr); +} + +TEST_P(QuicConnectionTest, SendAckFrequencyFrameUponHandshakeCompletion) { + if (!version().HasIetfQuicFrames()) { + return; + } + SetQuicReloadableFlag(quic_can_send_ack_frequency, true); + set_perspective(Perspective::IS_SERVER); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)) + .Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + + QuicConfig config; + QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1); + QuicTagVector quic_tag_vector; + // Enable sending AckFrequency upon handshake completion. + quic_tag_vector.push_back(kAFF2); + QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + QuicConnectionPeer::SetAddressValidated(&connection_); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); + + QuicAckFrequencyFrame captured_frame; + EXPECT_CALL(visitor_, SendAckFrequency(_)) + .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) { + captured_frame = frame; + })); + + connection_.OnHandshakeComplete(); + + EXPECT_EQ(captured_frame.packet_tolerance, 2u); + EXPECT_EQ(captured_frame.max_ack_delay, + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)); +} + +TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) { + if (!connection_.SupportsMultiplePacketNumberSpaces()) { + return; + } + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + QuicConfig config; + connection_.SetFromConfig(config); + + use_tagging_decrypter(); + connection_.SetEncrypter(ENCRYPTION_INITIAL, + std::make_unique<TaggingEncrypter>(0x01)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); + connection_.SendCryptoStreamData(); + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); + + // Assume ServerHello gets lost. + peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(0x02)); + ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE); + ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); + // Shorten PTO for fast recovery from lost ServerHello. + EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity, + connection_.GetRetransmissionAlarm()->deadline()); +} + +TEST_P(QuicConnectionTest, ServerHelloGetsReordered) { + if (!connection_.SupportsMultiplePacketNumberSpaces()) { + return; + } + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + QuicConfig config; + connection_.SetFromConfig(config); + EXPECT_CALL(visitor_, OnCryptoFrame(_)) + .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) { + if (frame.level == ENCRYPTION_INITIAL) { + // Install handshake read keys. + SetDecrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<StrictTaggingDecrypter>(0x02)); + connection_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(0x02)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE); + } + })); + + use_tagging_decrypter(); + connection_.SetEncrypter(ENCRYPTION_INITIAL, + std::make_unique<TaggingEncrypter>(0x01)); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); + connection_.SendCryptoStreamData(); + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); + + // Assume ServerHello gets reordered. + peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE, + std::make_unique<TaggingEncrypter>(0x02)); + ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE); + ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL); + // Verify fast recovery is not enabled. + EXPECT_EQ(connection_.sent_packet_manager().GetRetransmissionTime(), + connection_.GetRetransmissionAlarm()->deadline()); +} + } // namespace } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_constants.h b/chromium/net/third_party/quiche/src/quic/core/quic_constants.h index eaf0170c7ac..4cd6ba59901 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_constants.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_constants.h @@ -89,8 +89,8 @@ const QuicByteCount kDefaultSocketReceiveBuffer = 1024 * 1024; // Don't allow a client to suggest an RTT shorter than 10ms. const uint32_t kMinInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli; -// Don't allow a client to suggest an RTT longer than 15 seconds. -const uint32_t kMaxInitialRoundTripTimeUs = 15 * kNumMicrosPerSecond; +// Don't allow a client to suggest an RTT longer than 1 second. +const uint32_t kMaxInitialRoundTripTimeUs = kNumMicrosPerSecond; // Maximum number of open streams per connection. const size_t kDefaultMaxStreamsPerConnection = 100; @@ -104,6 +104,10 @@ const size_t kQuicVersionSize = 4; // https://tools.ietf.org/html/draft-ietf-quic-transport-25#section-17.2.5 const size_t kRetryIntegrityTagLength = 16; +// By default, UnackedPacketsMap allocates buffer of 64 after the first packet +// is added. +const int kDefaultUnackedPacketsInitialCapacity = 64; + // Signifies that the QuicPacket will contain version of the protocol. const bool kIncludeVersion = true; // Signifies that the QuicPacket will include a diversification nonce. @@ -120,7 +124,7 @@ const int64_t kDefaultDelayedAckTimeMs = 25; // Default minimum delayed ack time, in ms (used only for sender control of ack // frequency). -const uint32_t kDefaultMinAckDelayTimeMs = 1; +const uint32_t kDefaultMinAckDelayTimeMs = 5; // Default shift of the ACK delay in the IETF QUIC ACK frame. const uint32_t kDefaultAckDelayExponent = 3; @@ -265,6 +269,8 @@ const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10; // This intends to avoid the beginning of slow start, when CWNDs may be // rapidly increasing. const QuicPacketCount kMinReceivedBeforeAckDecimation = 100; +// One quarter RTT delay when doing ack decimation. +const float kAckDecimationDelay = 0.25; // The default alarm granularity assumed by QUIC code. const QuicTime::Delta kAlarmGranularity = QuicTime::Delta::FromMilliseconds(1); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc index 28b3446fb02..fddf0878586 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.cc @@ -120,13 +120,16 @@ void QuicControlFrameManager::WriteOrBufferHandshakeDone() { } void QuicControlFrameManager::WriteOrBufferAckFrequency( - uint64_t packet_tolerance, - QuicTime::Delta max_ack_delay) { + const QuicAckFrequencyFrame& ack_frequency_frame) { QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame"; QuicControlFrameId control_frame_id = ++last_control_frame_id_; - WriteOrBufferQuicFrame(QuicFrame(new QuicAckFrequencyFrame( - control_frame_id, - /*sequence_number=*/control_frame_id, packet_tolerance, max_ack_delay))); + // Using the control_frame_id for sequence_number here leaves gaps in + // sequence_number. + WriteOrBufferQuicFrame( + QuicFrame(new QuicAckFrequencyFrame(control_frame_id, + /*sequence_number=*/control_frame_id, + ack_frequency_frame.packet_tolerance, + ack_frequency_frame.max_ack_delay))); } void QuicControlFrameManager::WritePing() { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h index d79b679c984..493e7f02416 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager.h @@ -86,8 +86,8 @@ class QUIC_EXPORT_PRIVATE QuicControlFrameManager { // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be // sent immediately. - void WriteOrBufferAckFrequency(uint64_t packet_tolerance, - QuicTime::Delta max_ack_delay); + void WriteOrBufferAckFrequency( + const QuicAckFrequencyFrame& ack_frequency_frame); // Sends a PING_FRAME. Do not send PING if there is buffered frames. void WritePing(); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc index 68176997944..68658bb32c3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_control_frame_manager_test.cc @@ -6,6 +6,7 @@ #include <utility> +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" @@ -37,7 +38,7 @@ const QuicRstStreamErrorCode kTestStopSendingCode = class QuicControlFrameManagerTest : public QuicTest { public: - bool SaveControlFrame(const QuicFrame& frame) { + bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) { frame_ = frame; return true; } @@ -54,13 +55,16 @@ class QuicControlFrameManagerTest : public QuicTest { void Initialize() { connection_ = new MockQuicConnection(&helper_, &alarm_factory_, Perspective::IS_SERVER); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_); manager_ = std::make_unique<QuicControlFrameManager>(session_.get()); EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get())); EXPECT_FALSE(manager_->HasPendingRetransmission()); EXPECT_FALSE(manager_->WillingToWrite()); - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0); manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId, "Going away."); @@ -103,10 +107,10 @@ class QuicControlFrameManagerTest : public QuicTest { TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) { Initialize(); InSequence s; - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(3) - .WillRepeatedly(Invoke(&ClearControlFrame)); - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); // Send control frames 1, 2, 3. manager_->OnCanWrite(); EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_))); @@ -139,8 +143,8 @@ TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) { EXPECT_TRUE(manager_->WillingToWrite()); // Send control frames 4, 5. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); manager_->WritePing(); EXPECT_FALSE(manager_->WillingToWrite()); @@ -149,10 +153,10 @@ TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) { TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) { Initialize(); InSequence s; - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(3) - .WillRepeatedly(Invoke(&ClearControlFrame)); - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); // Send control frames 1, 2, 3. manager_->OnCanWrite(); @@ -166,17 +170,17 @@ TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) { manager_->OnControlFrameAcked(QuicFrame(&goaway_)); // Retransmit control frames 1, 3. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(2) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); EXPECT_FALSE(manager_->HasPendingRetransmission()); EXPECT_TRUE(manager_->WillingToWrite()); // Send control frames 4, 5, and 6. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(number_of_frames_ - 2u) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); manager_->WritePing(); EXPECT_FALSE(manager_->WillingToWrite()); @@ -186,26 +190,26 @@ TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) { Initialize(); InSequence s; // Send control frames 1, 2, 3, 4. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(number_of_frames_) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); // Ack control frame 2. manager_->OnControlFrameAcked(QuicFrame(&goaway_)); - // Do not retransmit an acked frame. - EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0); + // Do not retransmit an acked frame + EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0); EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_), PTO_RETRANSMISSION)); // Retransmit control frame 3. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&window_update_), PTO_RETRANSMISSION)); // Retransmit control frame 4, and connection is write blocked. - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(&window_update_), PTO_RETRANSMISSION)); } @@ -213,9 +217,9 @@ TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) { TEST_F(QuicControlFrameManagerTest, DonotSendPingWithBufferedFrames) { Initialize(); InSequence s; - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); // Send control frame 1. manager_->OnCanWrite(); EXPECT_FALSE(manager_->HasPendingRetransmission()); @@ -224,9 +228,9 @@ TEST_F(QuicControlFrameManagerTest, DonotSendPingWithBufferedFrames) { // Send PING when there is buffered frames. manager_->WritePing(); // Verify only the buffered frames are sent. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(number_of_frames_ - 1) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); EXPECT_FALSE(manager_->HasPendingRetransmission()); EXPECT_FALSE(manager_->WillingToWrite()); @@ -236,23 +240,26 @@ TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) { Initialize(); InSequence s; // Send Non-AckFrequency frame 1-5. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(5) - .WillRepeatedly(Invoke(&ClearControlFrame)); - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); manager_->OnCanWrite(); // Send AckFrequencyFrame as frame 6. - QuicAckFrequencyFrame ack_frequency = {6, 6, 10, - QuicTime::Delta::FromMilliseconds(24)}; - manager_->WriteOrBufferAckFrequency(10, - QuicTime::Delta::FromMilliseconds(24)); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + QuicAckFrequencyFrame frame_to_send; + frame_to_send.packet_tolerance = 10; + frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24); + manager_->WriteOrBufferAckFrequency(frame_to_send); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); // Ack AckFrequencyFrame. - EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&ack_frequency))); + QuicAckFrequencyFrame expected_ack_frequency = { + 6, 6, 10, QuicTime::Delta::FromMilliseconds(24)}; + EXPECT_TRUE( + manager_->OnControlFrameAcked(QuicFrame(&expected_ack_frequency))); } TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) { @@ -267,8 +274,8 @@ TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) { 300); InSequence s; // Flush all buffered control frames. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); // Mark all 3 window updates as lost. @@ -279,7 +286,7 @@ TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) { EXPECT_TRUE(manager_->WillingToWrite()); // Verify only the latest window update gets retransmitted. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame)); manager_->OnCanWrite(); EXPECT_EQ(number_of_frames_ + 2u, @@ -299,8 +306,8 @@ TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) { QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300); InSequence s; // Flush all buffered control frames. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); // Mark all 3 window updates as lost. @@ -311,9 +318,9 @@ TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) { EXPECT_TRUE(manager_->WillingToWrite()); // Verify all 3 window updates get retransmitted. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(3) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); manager_->OnCanWrite(); EXPECT_FALSE(manager_->HasPendingRetransmission()); EXPECT_FALSE(manager_->WillingToWrite()); @@ -321,13 +328,13 @@ TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) { TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) { Initialize(); - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(5) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); // Flush buffered frames. manager_->OnCanWrite(); // Write 995 control frames. - EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false)); for (size_t i = 0; i < 995; ++i) { manager_->WriteOrBufferRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0); } 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 b60b02643b6..74f0724e368 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 @@ -175,6 +175,24 @@ 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. + DCHECK(false); + return nullptr; +} + +std::unique_ptr<QuicEncrypter> +QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() { + // Key update is only defined in QUIC+TLS. + DCHECK(false); + return nullptr; +} + void QuicCryptoClientHandshaker::OnConnectionClosed( QuicErrorCode /*error*/, ConnectionCloseSource /*source*/) { @@ -299,7 +317,8 @@ void QuicCryptoClientHandshaker::DoSendCHLO( early_data_reason_ = ssl_early_data_no_session_offered; fill_inchoate_client_hello = true; } else if (session()->config()->HasClientRequestedIndependentOption( - kQNZR, session()->perspective())) { + kQNZ2, session()->perspective()) && + num_client_hellos_ == 1) { early_data_reason_ = ssl_early_data_disabled; fill_inchoate_client_hello = true; } @@ -328,7 +347,7 @@ void QuicCryptoClientHandshaker::DoSendCHLO( chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT); session()->connection()->set_fully_pad_crypto_handshake_packets( crypto_config_->pad_inchoate_hello()); - SendHandshakeMessage(out); + SendHandshakeMessage(out, ENCRYPTION_INITIAL); return; } @@ -355,7 +374,7 @@ void QuicCryptoClientHandshaker::DoSendCHLO( next_state_ = STATE_RECV_SHLO; session()->connection()->set_fully_pad_crypto_handshake_packets( crypto_config_->pad_full_hello()); - SendHandshakeMessage(out); + SendHandshakeMessage(out, ENCRYPTION_INITIAL); // Be prepared to decrypt with the new server write key. delegate_->OnNewEncryptionKeyAvailable( ENCRYPTION_ZERO_RTT, 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 605318edc06..49fa405c469 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,6 +51,10 @@ 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; void OnOneRttPacketAcknowledged() override {} void OnHandshakePacketSent() override {} void OnConnectionClosed(QuicErrorCode /*error*/, diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc index 3ea08a51941..2d6db7f28f7 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker_test.cc @@ -6,10 +6,10 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace { @@ -34,7 +34,7 @@ class InsecureProofVerifier : public ProofVerifier { const uint16_t /*port*/, const std::string& /*server_config*/, QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, + absl::string_view /*chlo_hash*/, const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/, const std::string& /*signature*/, @@ -54,6 +54,7 @@ class InsecureProofVerifier : public ProofVerifier { const ProofVerifyContext* /*context*/, std::string* /*error_details*/, std::unique_ptr<ProofVerifyDetails>* /*details*/, + uint8_t* /*out_alert*/, std::unique_ptr<ProofVerifierCallback> /*callback*/) override { return QUIC_SUCCESS; } @@ -74,7 +75,7 @@ class DummyProofSource : public ProofSource { const std::string& hostname, const std::string& /*server_config*/, QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, + absl::string_view /*chlo_hash*/, std::unique_ptr<Callback> callback) override { QuicReferenceCountedPointer<ProofSource::Chain> chain = GetCertChain(server_address, client_address, hostname); @@ -99,7 +100,7 @@ class DummyProofSource : public ProofSource { const QuicSocketAddress& /*client_address*/, const std::string& /*hostname*/, uint16_t /*signature_algorit*/, - quiche::QuicheStringPiece /*in*/, + absl::string_view /*in*/, std::unique_ptr<SignatureCallback> callback) override { callback->Run(true, "Dummy signature", /*details=*/nullptr); } 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 67a9a113510..94a894836b4 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 @@ -109,6 +109,20 @@ size_t QuicCryptoClientStream::BufferSizeLimitForLevel( return handshaker_->BufferSizeLimitForLevel(level); } +bool QuicCryptoClientStream::KeyUpdateSupportedLocally() const { + return handshaker_->KeyUpdateSupportedLocally(); +} + +std::unique_ptr<QuicDecrypter> +QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter(); +} + +std::unique_ptr<QuicEncrypter> +QuicCryptoClientStream::CreateCurrentOneRttEncrypter() { + return handshaker_->CreateCurrentOneRttEncrypter(); +} + std::string QuicCryptoClientStream::chlo_hash() const { return handshaker_->chlo_hash(); } 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 1d9b04b35fc..123bdfeaffb 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 @@ -151,6 +151,18 @@ 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> + AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0; + + // Called to generate an encrypter for the same key phase of the last + // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter(). + virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0; + // Returns current handshake state. virtual HandshakeState GetHandshakeState() const = 0; @@ -228,6 +240,10 @@ 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; std::string chlo_hash() const; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc index 52791b3d8e1..86fa3b8b341 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc @@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" using testing::_; @@ -69,7 +69,8 @@ class QuicCryptoClientStreamTest : public QuicTest { void CompleteCryptoHandshake() { int proof_verify_details_calls = 1; if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) { - EXPECT_CALL(*session_, OnProofValid(testing::_)); + EXPECT_CALL(*session_, OnProofValid(testing::_)) + .Times(testing::AtLeast(1)); proof_verify_details_calls = 0; } EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_)) @@ -172,14 +173,13 @@ TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) { // Set connection option. QuicTagVector options; - options.push_back(kQNZR); + options.push_back(kQNZ2); session_->config()->SetClientConnectionOptions(options); - EXPECT_CALL(*session_, OnProofValid(testing::_)); - stream()->CryptoConnect(); - // Check that a client hello was sent. - ASSERT_EQ(1u, connection_->encrypted_packets_.size()); - EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level()); + CompleteCryptoHandshake(); + // Check that two client hellos were sent, one inchoate and one normal. + EXPECT_EQ(2, stream()->num_sent_client_hellos()); + EXPECT_FALSE(stream()->EarlyDataAccepted()); EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_disabled); } @@ -265,7 +265,7 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) { const std::string& cached_scfg = state->server_config(); quiche::test::CompareCharArraysWithHexError( "scfg", cached_scfg.data(), cached_scfg.length(), - reinterpret_cast<char*>(scfg), QUICHE_ARRAYSIZE(scfg)); + reinterpret_cast<char*>(scfg), ABSL_ARRAYSIZE(scfg)); QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream()); EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc index d608ead807c..8adf83b7e86 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.cc @@ -20,13 +20,16 @@ QuicCryptoHandshaker::QuicCryptoHandshaker(QuicCryptoStream* stream, QuicCryptoHandshaker::~QuicCryptoHandshaker() {} void QuicCryptoHandshaker::SendHandshakeMessage( - const CryptoHandshakeMessage& message) { + const CryptoHandshakeMessage& message, + EncryptionLevel level) { QUIC_DVLOG(1) << ENDPOINT << "Sending " << message.DebugString(); session()->NeuterUnencryptedData(); session()->OnCryptoHandshakeMessageSent(message); last_sent_handshake_message_tag_ = message.tag(); const QuicData& data = message.GetSerialized(); - stream_->WriteCryptoData(session_->connection()->encryption_level(), + stream_->WriteCryptoData(session_->use_write_or_buffer_data_at_level() + ? level + : session_->connection()->encryption_level(), data.AsStringPiece()); } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h index e5d8d51894e..b971580a4a3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h @@ -21,7 +21,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoHandshaker // Sends |message| to the peer. // TODO(wtc): return a success/failure status. - void SendHandshakeMessage(const CryptoHandshakeMessage& message); + void SendHandshakeMessage(const CryptoHandshakeMessage& message, + EncryptionLevel level); void OnError(CryptoFramer* framer) override; void OnHandshakeMessage(const CryptoHandshakeMessage& message) 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 5fc683944ab..2bad8ecfdcd 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 @@ -7,10 +7,10 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -173,7 +173,8 @@ void QuicCryptoServerStream:: if (reply->tag() != kSHLO) { session()->connection()->set_fully_pad_crypto_handshake_packets( crypto_config_->pad_rej()); - SendHandshakeMessage(*reply); + // Send REJ in plaintext. + SendHandshakeMessage(*reply, ENCRYPTION_INITIAL); return; } @@ -213,7 +214,8 @@ void QuicCryptoServerStream:: session()->connection()->set_fully_pad_crypto_handshake_packets( crypto_config_->pad_shlo()); - SendHandshakeMessage(*reply); + // Send SHLO in ENCRYPTION_ZERO_RTT. + SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT); delegate_->OnNewEncryptionKeyAvailable( ENCRYPTION_FORWARD_SECURE, std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter)); @@ -284,12 +286,15 @@ void QuicCryptoServerStream::FinishSendServerConfigUpdate( QUIC_DVLOG(1) << "Server: Sending server config update: " << message.DebugString(); - if (!QuicVersionUsesCryptoFrames(transport_version())) { + + if (!session()->use_write_or_buffer_data_at_level() && + !QuicVersionUsesCryptoFrames(transport_version())) { const QuicData& data = message.GetSerialized(); - WriteOrBufferData(quiche::QuicheStringPiece(data.data(), data.length()), - false, nullptr); + WriteOrBufferData(absl::string_view(data.data(), data.length()), false, + nullptr); } else { - SendHandshakeMessage(message); + // Send server config update in ENCRYPTION_FORWARD_SECURE. + SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE); } ++num_server_config_update_messages_sent_; @@ -355,8 +360,7 @@ bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID( SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(), digest); - quiche::QuicheTextUtils::Base64Encode(digest, QUICHE_ARRAYSIZE(digest), - output); + quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output); return true; } @@ -402,6 +406,24 @@ 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. + DCHECK(false); + return nullptr; +} + +std::unique_ptr<QuicEncrypter> +QuicCryptoServerStream::CreateCurrentOneRttEncrypter() { + // Key update is only defined in QUIC+TLS. + DCHECK(false); + return nullptr; +} + void QuicCryptoServerStream::ProcessClientHello( QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result, @@ -418,7 +440,7 @@ void QuicCryptoServerStream::ProcessClientHello( return; } - quiche::QuicheStringPiece user_agent_id; + absl::string_view user_agent_id; message.GetStringPiece(quic::kUAID, &user_agent_id); if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) { session()->SetUserAgentId(std::string(user_agent_id)); @@ -430,7 +452,7 @@ void QuicCryptoServerStream::ProcessClientHello( if (num_handshake_messages_ == 1) { // Client attempts zero RTT handshake by sending a non-inchoate CHLO. - quiche::QuicheStringPiece public_value; + absl::string_view public_value; zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value); } 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 29d680ec98d..c99a13689d8 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 @@ -61,6 +61,10 @@ 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; // From QuicCryptoHandshaker void OnHandshakeMessage(const CryptoHandshakeMessage& message) override; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc index 9ff7dc05d47..2831dc03b64 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc @@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" @@ -32,7 +33,6 @@ #include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h" #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { class QuicConnection; @@ -96,7 +96,7 @@ class QuicCryptoServerStreamTest : public QuicTest { .Times(testing::AnyNumber()); EXPECT_CALL(*server_session_, SelectAlpn(_)) .WillRepeatedly( - [this](const std::vector<quiche::QuicheStringPiece>& alpns) { + [this](const std::vector<absl::string_view>& alpns) { return std::find( alpns.cbegin(), alpns.cend(), AlpnForVersion(server_session_->connection()->version())); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc index ae2f067466d..5cdae35e3ea 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc @@ -6,6 +6,8 @@ #include <string> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" @@ -15,8 +17,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -108,8 +108,7 @@ void QuicCryptoStream::OnDataAvailableInSequencer( EncryptionLevel level) { struct iovec iov; while (sequencer->GetReadableRegion(&iov)) { - quiche::QuicheStringPiece data(static_cast<char*>(iov.iov_base), - iov.iov_len); + absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len); if (!crypto_message_parser()->ProcessInput(data, level)) { OnUnrecoverableError(crypto_message_parser()->error(), crypto_message_parser()->error_detail()); @@ -126,8 +125,8 @@ void QuicCryptoStream::OnDataAvailableInSequencer( } } -bool QuicCryptoStream::ExportKeyingMaterial(quiche::QuicheStringPiece label, - quiche::QuicheStringPiece context, +bool QuicCryptoStream::ExportKeyingMaterial(absl::string_view label, + absl::string_view context, size_t result_len, std::string* result) const { if (!one_rtt_keys_available()) { @@ -141,8 +140,13 @@ bool QuicCryptoStream::ExportKeyingMaterial(quiche::QuicheStringPiece label, } void QuicCryptoStream::WriteCryptoData(EncryptionLevel level, - quiche::QuicheStringPiece data) { + absl::string_view data) { if (!QuicVersionUsesCryptoFrames(session()->transport_version())) { + if (session()->use_write_or_buffer_data_at_level()) { + WriteOrBufferDataAtLevel(data, /*fin=*/false, level, + /*ack_listener=*/nullptr); + return; + } // The QUIC crypto handshake takes care of setting the appropriate // encryption level before writing data. Since that is the only handshake // supported in versions less than 47, |level| can be ignored here. @@ -308,7 +312,7 @@ bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset, QuicByteCount data_length, bool /*fin*/, TransmissionType type) { - DCHECK_EQ(HANDSHAKE_RETRANSMISSION, type); + DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION); QuicIntervalSet<QuicStreamOffset> retransmission(offset, offset + data_length); // Determine the encryption level to send data. This only needs to be once as @@ -341,7 +345,7 @@ QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel( QuicByteCount retransmission_length, EncryptionLevel encryption_level, TransmissionType type) { - DCHECK_EQ(HANDSHAKE_RETRANSMISSION, type); + DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION); const auto consumed = stream_delegate()->WritevData( id(), retransmission_length, retransmission_offset, NO_FIN, type, encryption_level); 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 d73d97080a8..ea15ded0a33 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 @@ -9,6 +9,7 @@ #include <cstddef> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" @@ -17,7 +18,6 @@ #include "net/third_party/quiche/src/quic/core/quic_stream.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -64,14 +64,13 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream { // dependent on |label|, |context|, and the stream's negotiated subkey secret. // Returns false if the handshake has not been confirmed or the parameters are // invalid (e.g. |label| contains null bytes); returns true on success. - bool ExportKeyingMaterial(quiche::QuicheStringPiece label, - quiche::QuicheStringPiece context, + bool ExportKeyingMaterial(absl::string_view label, + absl::string_view context, size_t result_len, std::string* result) const; // Writes |data| to the QuicStream at level |level|. - virtual void WriteCryptoData(EncryptionLevel level, - quiche::QuicheStringPiece data); + virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data); // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or // rejected. Note that the value returned by this function may vary during the @@ -127,6 +126,18 @@ 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> + AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0; + + // Called to generate an encrypter for the same key phase of the last + // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter(). + virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0; + // Called to cancel retransmission of unencrypted crypto stream data. void NeuterUnencryptedStreamData(); 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 f7e24830943..c67a5dcd797 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 @@ -66,6 +66,14 @@ 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; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } private: QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; @@ -433,7 +441,7 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamData) { .WillOnce(InvokeWithoutArgs([this]() { return session_.ConsumeData( QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150, - 1350, NO_FIN, HANDSHAKE_RETRANSMISSION, QUICHE_NULLOPT); + 1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt); })); EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false, diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc index c82e051c342..be533b13677 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.cc @@ -4,17 +4,17 @@ #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { -QuicDataReader::QuicDataReader(quiche::QuicheStringPiece data) +QuicDataReader::QuicDataReader(absl::string_view data) : quiche::QuicheDataReader(data) {} QuicDataReader::QuicDataReader(const char* data, const size_t len) @@ -165,8 +165,7 @@ bool QuicDataReader::ReadVarInt62(uint64_t* result) { return false; } -bool QuicDataReader::ReadStringPieceVarInt62( - quiche::QuicheStringPiece* result) { +bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) { uint64_t result_length; if (!ReadVarInt62(&result_length)) { return false; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h index 13499ea83dd..00b1dba34c6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_data_reader.h @@ -8,11 +8,11 @@ #include <cstddef> #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/quiche_data_reader.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -34,7 +34,7 @@ class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader { public: // Constructs a reader using NETWORK_BYTE_ORDER endianness. // Caller must provide an underlying buffer to work on. - explicit QuicDataReader(quiche::QuicheStringPiece data); + explicit QuicDataReader(absl::string_view data); // Constructs a reader using NETWORK_BYTE_ORDER endianness. // Caller must provide an underlying buffer to work on. QuicDataReader(const char* data, const size_t len); @@ -85,7 +85,7 @@ class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader { // // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPieceVarInt62(quiche::QuicheStringPiece* result); + bool ReadStringPieceVarInt62(absl::string_view* result); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc index 41c374cc6d6..91645b8d04a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.cc @@ -7,13 +7,13 @@ #include <algorithm> #include <limits> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -234,7 +234,7 @@ QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) { } bool QuicDataWriter::WriteStringPieceVarInt62( - const quiche::QuicheStringPiece& string_piece) { + const absl::string_view& string_piece) { if (!WriteVarInt62(string_piece.size())) { return false; } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h index 3926c1a6aa5..e0a27c60766 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer.h @@ -8,11 +8,11 @@ #include <cstddef> #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/quiche_data_writer.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -69,7 +69,7 @@ class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter { // Writes a string piece as a consecutive length/content pair. The // length is VarInt62 encoded. - bool WriteStringPieceVarInt62(const quiche::QuicheStringPiece& string_piece); + bool WriteStringPieceVarInt62(const absl::string_view& string_piece); // Utility function to return the number of bytes needed to encode // the given value using IETF VarInt62 encoding. Returns the number diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc index e05af218994..ef83ac82a63 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_data_writer_test.cc @@ -7,6 +7,8 @@ #include <cstdint> #include <cstring> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -15,10 +17,8 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" namespace quic { @@ -269,7 +269,7 @@ TEST_P(QuicDataWriterTest, WriteConnectionId) { char big_endian[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, }; - EXPECT_EQ(connection_id.length(), QUICHE_ARRAYSIZE(big_endian)); + EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian)); ASSERT_LE(connection_id.length(), 255); char buffer[255]; QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness); @@ -280,8 +280,8 @@ TEST_P(QuicDataWriterTest, WriteConnectionId) { QuicConnectionId read_connection_id; QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness); - EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, - QUICHE_ARRAYSIZE(big_endian))); + EXPECT_TRUE( + reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian))); EXPECT_EQ(connection_id, read_connection_id); } @@ -291,35 +291,35 @@ TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) { char length_prefixed_connection_id[] = { 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, }; - EXPECT_EQ(QUICHE_ARRAYSIZE(length_prefixed_connection_id), + EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id), kConnectionIdLengthSize + connection_id.length()); char buffer[kConnectionIdLengthSize + 255] = {}; - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer); + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer); EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id)); quiche::test::CompareCharArraysWithHexError( "WriteLengthPrefixedConnectionId", buffer, writer.length(), length_prefixed_connection_id, - QUICHE_ARRAYSIZE(length_prefixed_connection_id)); + ABSL_ARRAYSIZE(length_prefixed_connection_id)); // Verify that writing length then connection ID produces the same output. - memset(buffer, 0, QUICHE_ARRAYSIZE(buffer)); - QuicDataWriter writer2(QUICHE_ARRAYSIZE(buffer), buffer); + memset(buffer, 0, ABSL_ARRAYSIZE(buffer)); + QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer); EXPECT_TRUE(writer2.WriteUInt8(connection_id.length())); EXPECT_TRUE(writer2.WriteConnectionId(connection_id)); quiche::test::CompareCharArraysWithHexError( "Write length then ConnectionId", buffer, writer2.length(), length_prefixed_connection_id, - QUICHE_ARRAYSIZE(length_prefixed_connection_id)); + ABSL_ARRAYSIZE(length_prefixed_connection_id)); QuicConnectionId read_connection_id; - QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer)); + QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer)); EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id)); EXPECT_EQ(connection_id, read_connection_id); // Verify that reading length then connection ID produces the same output. uint8_t read_connection_id_length2 = 33; QuicConnectionId read_connection_id2; - QuicDataReader reader2(buffer, QUICHE_ARRAYSIZE(buffer)); + QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer)); ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2)); EXPECT_EQ(connection_id.length(), read_connection_id_length2); EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2, @@ -330,8 +330,7 @@ TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) { TEST_P(QuicDataWriterTest, EmptyConnectionIds) { QuicConnectionId empty_connection_id = EmptyQuicConnectionId(); char buffer[2]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, - GetParam().endianness); + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id)); EXPECT_TRUE(writer.WriteUInt8(1)); EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id)); @@ -344,8 +343,7 @@ TEST_P(QuicDataWriterTest, EmptyConnectionIds) { QuicConnectionId read_connection_id = TestConnectionId(); uint8_t read_byte; - QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer), - GetParam().endianness); + QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness); EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0)); EXPECT_EQ(read_connection_id, empty_connection_id); EXPECT_TRUE(reader.ReadUInt8(&read_byte)); @@ -663,10 +661,10 @@ TEST_P(QuicDataWriterTest, WriteIntegers) { TEST_P(QuicDataWriterTest, WriteBytes) { char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - char buf[QUICHE_ARRAYSIZE(bytes)]; - QuicDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness); - EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes))); - for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) { + char buf[ABSL_ARRAYSIZE(bytes)]; + QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness); + EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes))); + for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) { EXPECT_EQ(bytes[i], buf[i]); } } @@ -1178,14 +1176,13 @@ TEST_P(QuicDataWriterTest, ValidStreamCount) { TEST_P(QuicDataWriterTest, Seek) { char buffer[3] = {}; - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, - GetParam().endianness); + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.WriteUInt8(42)); EXPECT_TRUE(writer.Seek(1)); EXPECT_TRUE(writer.WriteUInt8(3)); char expected[] = {42, 0, 3}; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) { EXPECT_EQ(buffer[i], expected[i]); } } @@ -1195,7 +1192,7 @@ TEST_P(QuicDataWriterTest, SeekTooFarFails) { // Check that one can seek to the end of the writer, but not past. { - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.Seek(20)); EXPECT_FALSE(writer.Seek(1)); @@ -1203,14 +1200,14 @@ TEST_P(QuicDataWriterTest, SeekTooFarFails) { // Seeking several bytes past the end fails. { - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_FALSE(writer.Seek(100)); } // Seeking so far that arithmetic overflow could occur also fails. { - QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, + QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness); EXPECT_TRUE(writer.Seek(10)); EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max())); @@ -1227,24 +1224,22 @@ TEST_P(QuicDataWriterTest, PayloadReads) { quiche::test::CompareCharArraysWithHexError( "first read", first_read_buffer, sizeof(first_read_buffer), expected_first_read, sizeof(expected_first_read)); - quiche::QuicheStringPiece peeked_remaining_payload = - reader.PeekRemainingPayload(); + absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload(); quiche::test::CompareCharArraysWithHexError( "peeked_remaining_payload", peeked_remaining_payload.data(), peeked_remaining_payload.length(), expected_remaining, sizeof(expected_remaining)); - quiche::QuicheStringPiece full_payload = reader.FullPayload(); + absl::string_view full_payload = reader.FullPayload(); quiche::test::CompareCharArraysWithHexError( "full_payload", full_payload.data(), full_payload.length(), buffer, sizeof(buffer)); - quiche::QuicheStringPiece read_remaining_payload = - reader.ReadRemainingPayload(); + absl::string_view read_remaining_payload = reader.ReadRemainingPayload(); quiche::test::CompareCharArraysWithHexError( "read_remaining_payload", read_remaining_payload.data(), read_remaining_payload.length(), expected_remaining, sizeof(expected_remaining)); EXPECT_TRUE(reader.IsDoneReading()); - quiche::QuicheStringPiece full_payload2 = reader.FullPayload(); + absl::string_view full_payload2 = reader.FullPayload(); quiche::test::CompareCharArraysWithHexError( "full_payload2", full_payload2.data(), full_payload2.length(), buffer, sizeof(buffer)); @@ -1253,14 +1248,13 @@ TEST_P(QuicDataWriterTest, PayloadReads) { TEST_P(QuicDataWriterTest, StringPieceVarInt62) { char inner_buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - quiche::QuicheStringPiece inner_payload_write(inner_buffer, - sizeof(inner_buffer)); + absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer)); char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {}; QuicDataWriter writer(sizeof(buffer), buffer); EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write)); EXPECT_EQ(0u, writer.remaining()); QuicDataReader reader(buffer, sizeof(buffer)); - quiche::QuicheStringPiece inner_payload_read; + absl::string_view inner_payload_read; EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read)); quiche::test::CompareCharArraysWithHexError( "inner_payload", inner_payload_write.data(), inner_payload_write.length(), diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc index 22a57cd8336..e10a91904c1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.cc @@ -12,7 +12,6 @@ namespace quic { -using quiche::QuicheOptional; constexpr float kExpiryInMinRtts = 1.25; constexpr float kMinPacingWindows = 4; @@ -37,10 +36,10 @@ MessageStatus QuicDatagramQueue::SendOrQueueDatagram(QuicMemSlice datagram) { return MESSAGE_STATUS_BLOCKED; } -QuicheOptional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() { +absl::optional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() { RemoveExpiredDatagrams(); if (queue_.empty()) { - return QuicheOptional<MessageStatus>(); + return absl::nullopt; } QuicMemSliceSpan span(&queue_.front().datagram); @@ -54,7 +53,7 @@ QuicheOptional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() { size_t QuicDatagramQueue::SendDatagrams() { size_t num_datagrams = 0; for (;;) { - QuicheOptional<MessageStatus> status = TrySendingNextDatagram(); + absl::optional<MessageStatus> status = TrySendingNextDatagram(); if (!status.has_value()) { break; } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h index ac78ad4f82b..09524027533 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue.h @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_ #define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_ +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" namespace quic { @@ -29,7 +29,7 @@ class QUIC_EXPORT_PRIVATE QuicDatagramQueue { // Attempts to send a single datagram from the queue. Returns the result of // SendMessage(), or nullopt if there were no unexpired datagrams to send. - quiche::QuicheOptional<MessageStatus> TrySendingNextDatagram(); + absl::optional<MessageStatus> TrySendingNextDatagram(); // Sends all of the unexpired datagrams until either the connection becomes // write-blocked or the queue is empty. Returns the number of datagrams sent. diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc index 34ccccc482e..0e6e3dec39a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_datagram_queue_test.cc @@ -4,20 +4,20 @@ #include "net/third_party/quiche/src/quic/core/quic_datagram_queue.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { namespace { -using quiche::QuicheOptional; using testing::_; using testing::ElementsAre; @@ -39,9 +39,12 @@ class QuicDatagramQueueTest : public QuicTest { session_(connection_), queue_(&session_) { session_.SetCryptoStream(new EstablishedCryptoStream(&session_)); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); } - QuicMemSlice CreateMemSlice(quiche::QuicheStringPiece data) { + QuicMemSlice CreateMemSlice(absl::string_view data) { QuicUniqueBufferPtr buffer = MakeUniqueBuffer(helper_.GetStreamSendBufferAllocator(), data.size()); memcpy(buffer.get(), data.data(), data.size()); @@ -75,7 +78,7 @@ TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) { // Verify getting write blocked does not remove the datagram from the queue. EXPECT_CALL(*connection_, SendMessage(_, _, _)) .WillOnce(Return(MESSAGE_STATUS_BLOCKED)); - QuicheOptional<MessageStatus> status = queue_.TrySendingNextDatagram(); + absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram(); ASSERT_TRUE(status.has_value()); EXPECT_EQ(MESSAGE_STATUS_BLOCKED, *status); EXPECT_EQ(1u, queue_.queue_size()); @@ -89,7 +92,7 @@ TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) { } TEST_F(QuicDatagramQueueTest, EmptyBuffer) { - QuicheOptional<MessageStatus> status = queue_.TrySendingNextDatagram(); + absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram(); EXPECT_FALSE(status.has_value()); size_t num_messages = queue_.SendDatagrams(); 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 972a9ac0f86..d048e60af29 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 @@ -7,6 +7,7 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/chlo_extractor.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" @@ -22,14 +23,13 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { -typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; -typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; -typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; +using BufferedPacket = QuicBufferedPacketStore::BufferedPacket; +using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList; +using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult; namespace { @@ -190,12 +190,12 @@ class ChloAlpnExtractor : public ChloExtractor::Delegate { void OnChlo(QuicTransportVersion version, QuicConnectionId /*server_connection_id*/, const CryptoHandshakeMessage& chlo) override { - quiche::QuicheStringPiece alpn_value; + absl::string_view alpn_value; if (chlo.GetStringPiece(kALPN, &alpn_value)) { alpn_ = std::string(alpn_value); } if (version == LegacyVersionForEncapsulation().transport_version) { - quiche::QuicheStringPiece qlve_value; + absl::string_view qlve_value; if (chlo.GetStringPiece(kQLVE, &qlve_value)) { legacy_version_encapsulation_inner_packet_ = std::string(qlve_value); } @@ -231,7 +231,7 @@ bool MaybeHandleLegacyVersionEncapsulation( ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported(); QuicConnectionId destination_connection_id, source_connection_id; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(), @@ -338,12 +338,12 @@ void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address, const QuicReceivedPacket& packet) { QUIC_DVLOG(2) << "Dispatcher received encrypted " << packet.length() << " bytes:" << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( - packet.data(), packet.length())); + << quiche::QuicheTextUtils::HexDump( + absl::string_view(packet.data(), packet.length())); ReceivedPacketInfo packet_info(self_address, peer_address, packet); std::string detailed_error; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( packet, expected_server_connection_id_length_, &packet_info.form, &packet_info.long_packet_type, &packet_info.version_flag, @@ -465,7 +465,16 @@ bool QuicDispatcher::MaybeDispatchPacket( // connection ID, the dispatcher picks a new one of its expected length. // Therefore we should never receive a connection ID that is smaller // than 64 bits and smaller than what we expect. - if (server_connection_id.length() < kQuicMinimumInitialConnectionIdLength && + bool should_check_short_connection_ids = true; + if (GetQuicReloadableFlag( + quic_send_version_negotiation_for_short_connection_ids)) { + QUIC_RELOADABLE_FLAG_COUNT( + quic_send_version_negotiation_for_short_connection_ids); + should_check_short_connection_ids = + packet_info.version_flag && packet_info.version.IsKnown(); + } + if (should_check_short_connection_ids && + server_connection_id.length() < kQuicMinimumInitialConnectionIdLength && server_connection_id.length() < expected_server_connection_id_length_ && !allow_short_initial_server_connection_ids_) { DCHECK(packet_info.version_flag); 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 e4c61e529a1..92c73208412 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 @@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h" @@ -25,7 +26,6 @@ #include "net/third_party/quiche/src/quic/core/quic_version_manager.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -41,7 +41,7 @@ class QUIC_NO_EXPORT QuicDispatcher public QuicBufferedPacketStore::VisitorInterface { public: // Ideally we'd have a linked_hash_set: the boolean is unused. - typedef QuicLinkedHashMap<QuicBlockedWriterInterface*, bool> WriteBlockedList; + using WriteBlockedList = QuicLinkedHashMap<QuicBlockedWriterInterface*, bool>; QuicDispatcher( const QuicConfig* config, @@ -140,7 +140,7 @@ class QUIC_NO_EXPORT QuicDispatcher QuicConnectionId server_connection_id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const ParsedQuicVersion& version) = 0; // Tries to validate and dispatch packet based on available information. @@ -321,6 +321,11 @@ class QUIC_NO_EXPORT QuicDispatcher const QuicConnectionId& server_connection_id, const ParsedQuicVersion& version) const; + // Sends public/stateless reset packets with no version and unknown + // connection ID according to the packet's size. + virtual void MaybeResetPacketsWithNoVersion( + const quic::ReceivedPacketInfo& packet_info); + private: friend class test::QuicDispatcherPeer; @@ -336,10 +341,6 @@ class QUIC_NO_EXPORT QuicDispatcher // Returns true if |version| is a supported protocol version. bool IsSupportedVersion(const ParsedQuicVersion version); - // Sends public/stateless reset packets with no version and unknown - // connection ID according to the packet's size. - void MaybeResetPacketsWithNoVersion(const ReceivedPacketInfo& packet_info); - const QuicConfig* config_; const QuicCryptoServerConfig* crypto_config_; 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 e90489a9f93..9f692a8029a 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 @@ -9,6 +9,7 @@ #include <string> #include <utility> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/chlo_extractor.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" @@ -36,7 +37,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -135,7 +135,7 @@ class TestDispatcher : public QuicDispatcher { (QuicConnectionId connection_id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const quic::ParsedQuicVersion& version), (override)); @@ -471,6 +471,10 @@ class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> { void TestTlsMultiPacketClientHello(bool add_reordering); + void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId( + const QuicConnectionId& server_connection_id, + const QuicConnectionId& client_connection_id); + ParsedQuicVersion version_; MockQuicConnectionHelper mock_helper_; MockAlarmFactory mock_alarm_factory_; @@ -605,7 +609,7 @@ TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) { ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported(); QuicConnectionId destination_connection_id, source_connection_id; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( QuicEncryptedPacket(packets[0]->data(), packets[0]->length()), @@ -1054,7 +1058,7 @@ TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) { } TEST_P(QuicDispatcherTestAllVersions, - ProcessPacketWithInvalidShortInitialConnectionId) { + DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) { if (!version_.AllowsVariableLengthConnectionIds()) { return; } @@ -1063,14 +1067,59 @@ TEST_P(QuicDispatcherTestAllVersions, QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); // dispatcher_ should drop this packet. - EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address, _, _)) - .Times(0); + EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessFirstFlight(client_address, EmptyQuicConnectionId()); } +void QuicDispatcherTestBase:: + TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId( + const QuicConnectionId& server_connection_id, + const QuicConnectionId& client_connection_id) { + SetQuicReloadableFlag(quic_send_version_negotiation_for_short_connection_ids, + true); + CreateTimeWaitListManager(); + + QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); + + EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); + EXPECT_CALL(*time_wait_list_manager_, + SendVersionNegotiationPacket( + server_connection_id, client_connection_id, + /*ietf_quic=*/true, + /*use_length_prefix=*/true, _, _, client_address, _)) + .Times(1); + ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(), + client_address, server_connection_id, + client_connection_id); +} + +TEST_P(QuicDispatcherTestOneVersion, + VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) { + TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId( + EmptyQuicConnectionId(), EmptyQuicConnectionId()); +} + +TEST_P(QuicDispatcherTestOneVersion, + VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) { + char server_connection_id_bytes[3] = {1, 2, 3}; + QuicConnectionId server_connection_id(server_connection_id_bytes, + sizeof(server_connection_id_bytes)); + TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId( + server_connection_id, EmptyQuicConnectionId()); +} + +TEST_P(QuicDispatcherTestOneVersion, + VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) { + char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + QuicConnectionId client_connection_id(client_connection_id_bytes, + sizeof(client_connection_id_bytes)); + TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId( + EmptyQuicConnectionId(), client_connection_id); +} + TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) { VerifyVersionNotSupported(QuicVersionReservedForNegotiation()); for (ParsedQuicVersion version : CurrentSupportedVersions()) { @@ -1088,7 +1137,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1105,7 +1154,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1122,7 +1171,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1139,7 +1188,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1156,7 +1205,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1173,7 +1222,7 @@ TEST_P(QuicDispatcherTestOneVersion, CreateTimeWaitListManager(); char packet[kMinPacketSizeForVersionNegotiation] = { 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50}; - QuicReceivedPacket received_packet(packet, QUICHE_ARRAYSIZE(packet), + QuicReceivedPacket received_packet(packet, ABSL_ARRAYSIZE(packet), QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL( @@ -1206,37 +1255,7 @@ static_assert(quic::SupportedVersions().size() == 7u, "Please add new RejectDeprecatedVersion tests above this assert " "when deprecating versions"); -TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeOld) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false); - QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); - CreateTimeWaitListManager(); - char packet[1200]; - char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70, - 0x6c, 0x7a, 0x20, 0x21}; - EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket( - packet, sizeof(packet), destination_connection_id_bytes, - sizeof(destination_connection_id_bytes))); - QuicEncryptedPacket encrypted(packet, sizeof(packet), false); - std::unique_ptr<QuicReceivedPacket> received_packet( - ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now())); - QuicConnectionId client_connection_id = EmptyQuicConnectionId(); - QuicConnectionId server_connection_id( - destination_connection_id_bytes, sizeof(destination_connection_id_bytes)); - bool ietf_quic = true; - bool use_length_prefix = - GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids); - EXPECT_CALL( - *time_wait_list_manager_, - SendVersionNegotiationPacket(server_connection_id, client_connection_id, - ietf_quic, use_length_prefix, _, _, _, _)) - .Times(1); - EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); - - dispatcher_->ProcessPacket(server_address_, client_address, *received_packet); -} - TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true); QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); CreateTimeWaitListManager(); char packet[1200]; @@ -1251,13 +1270,10 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) { QuicConnectionId client_connection_id = EmptyQuicConnectionId(); QuicConnectionId server_connection_id( destination_connection_id_bytes, sizeof(destination_connection_id_bytes)); - bool ietf_quic = true; - bool use_length_prefix = - GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids); - EXPECT_CALL( - *time_wait_list_manager_, - SendVersionNegotiationPacket(server_connection_id, client_connection_id, - ietf_quic, use_length_prefix, _, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, + SendVersionNegotiationPacket( + server_connection_id, client_connection_id, + /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _)) .Times(1); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); @@ -1288,9 +1304,7 @@ class SavingWriter : public QuicPacketWriterWrapper { std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_; }; -TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false); - +TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) { SavingWriter* saving_writer = new SavingWriter(); // dispatcher_ takes ownership of saving_writer. QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer); @@ -1317,7 +1331,7 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) { ASSERT_EQ(1u, saving_writer->packets()->size()); char source_connection_id_bytes[255] = {}; - uint8_t source_connection_id_length = 0; + uint8_t source_connection_id_length = sizeof(source_connection_id_bytes); std::string detailed_error = "foobar"; EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse( (*(saving_writer->packets()))[0]->data(), @@ -1332,9 +1346,9 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) { destination_connection_id_bytes, sizeof(destination_connection_id_bytes)); } -TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true); - +TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) { + // WARNING: do not remove or modify this test without making sure that we + // still have adequate coverage for the Android conformance test. SavingWriter* saving_writer = new SavingWriter(); // dispatcher_ takes ownership of saving_writer. QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer); @@ -1345,13 +1359,20 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) { // dispatcher_ takes ownership of time_wait_list_manager. QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), time_wait_list_manager); - char packet[1200] = {}; - char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70, - 0x6c, 0x7a, 0x20, 0x21}; - EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket( - packet, sizeof(packet), destination_connection_id_bytes, - sizeof(destination_connection_id_bytes))); - QuicEncryptedPacket encrypted(packet, sizeof(packet), false); + // clang-format off + static const unsigned char packet[1200] = { + // Android UDP network conformance test packet as it was after this change: + // https://android-review.googlesource.com/c/platform/cts/+/1454515 + 0xc0, // long header + 0xaa, 0xda, 0xca, 0xca, // reserved-space version number + 0x08, // destination connection ID length + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID + 0x00, // source connection ID length + }; + // clang-format on + + QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet), + sizeof(packet), false); std::unique_ptr<QuicReceivedPacket> received_packet( ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now())); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); @@ -1360,25 +1381,22 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) { dispatcher_->ProcessPacket(server_address_, client_address, *received_packet); ASSERT_EQ(1u, saving_writer->packets()->size()); - char source_connection_id_bytes[255] = {}; - uint8_t source_connection_id_length = 0; - std::string detailed_error = "foobar"; - EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse( - (*(saving_writer->packets()))[0]->data(), - (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes, - &source_connection_id_length, &detailed_error)); - EXPECT_EQ("", detailed_error); - - // The source connection ID of the probe response should match the - // destination connection ID of the probe request. + // The Android UDP network conformance test directly checks that these bytes + // of the response match the connection ID that was sent. + ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u); quiche::test::CompareCharArraysWithHexError( - "parsed probe", source_connection_id_bytes, source_connection_id_length, - destination_connection_id_bytes, sizeof(destination_connection_id_bytes)); + "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8, + reinterpret_cast<const char*>(&packet[6]), 8); } -TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) { - // WARNING: do not remove or modify this test without making sure that we - // still have adequate coverage for the Android conformance test. +TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) { + // WARNING: this test covers an old Android Conformance Test that has now been + // changed, but it'll take time for the change to propagate through the + // Android ecosystem. The Android team has asked us to keep this test + // supported until at least 2021-03-31. After that date, and when we drop + // support for sending QUIC version negotiation packets using the legacy + // Google QUIC format (Q001-Q043), then we can delete this test. + // TODO(dschinazi) delete this test after 2021-03-31 SavingWriter* saving_writer = new SavingWriter(); // dispatcher_ takes ownership of saving_writer. QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer); @@ -1393,6 +1411,8 @@ TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) { static const unsigned char packet[1200] = { // Android UDP network conformance test packet as it was after this change: // https://android-review.googlesource.com/c/platform/cts/+/1104285 + // but before this change: + // https://android-review.googlesource.com/c/platform/cts/+/1454515 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number 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 8a075984be1..9abde9f52b1 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 @@ -7,7 +7,6 @@ #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_client_stats.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" @@ -188,6 +187,27 @@ const char* QuicErrorCodeToString(QuicErrorCode error) { RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED); RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR); RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC); + RETURN_STRING_LITERAL( + QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX); + RETURN_STRING_LITERAL( + QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL); + RETURN_STRING_LITERAL( + QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX); + RETURN_STRING_LITERAL( + QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND); + RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY); + RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE); + RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT); + RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW); + RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT); + RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT); RETURN_STRING_LITERAL(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET); RETURN_STRING_LITERAL(QUIC_STREAM_MULTIPLE_OFFSET); RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_TOO_LARGE); @@ -209,6 +229,7 @@ const char* QuicErrorCodeToString(QuicErrorCode error) { RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID); RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS); RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_SETTING); + RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_FRAME); RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR); RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR); RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR); @@ -232,6 +253,9 @@ const char* QuicErrorCodeToString(QuicErrorCode error) { RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED); RETURN_STRING_LITERAL(QUIC_SILENT_IDLE_TIMEOUT); RETURN_STRING_LITERAL(QUIC_MISSING_WRITE_KEYS); + RETURN_STRING_LITERAL(QUIC_KEY_UPDATE_ERROR); + RETURN_STRING_LITERAL(QUIC_AEAD_LIMIT_REACHED); + RETURN_STRING_LITERAL(QUIC_MAX_AGE_TIMEOUT); RETURN_STRING_LITERAL(QUIC_LAST_ERROR); // Intentionally have no default case, so we'll break the build @@ -270,6 +294,8 @@ std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) { RETURN_STRING_LITERAL(PROTOCOL_VIOLATION); RETURN_STRING_LITERAL(INVALID_TOKEN); RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED); + RETURN_STRING_LITERAL(KEY_UPDATE_ERROR); + RETURN_STRING_LITERAL(AEAD_LIMIT_REACHED); // CRYPTO_ERROR is handled in the if before this switch, these cases do not // change behavior and are only here to make the compiler happy. case CRYPTO_ERROR_FIRST: @@ -539,6 +565,57 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode( case QUIC_QPACK_DECODER_STREAM_ERROR: return {false, static_cast<uint64_t>( QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)}; + case QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; + case QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; + case QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; + case QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; + case QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT: + return {false, static_cast<uint64_t>( + QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}; case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET: return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)}; case QUIC_STREAM_MULTIPLE_OFFSET: @@ -590,6 +667,9 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode( return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)}; case QUIC_HTTP_RECEIVE_SPDY_SETTING: return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)}; + case QUIC_HTTP_RECEIVE_SPDY_FRAME: + return {false, + static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)}; case QUIC_HPACK_INDEX_VARINT_ERROR: return {true, static_cast<uint64_t>(INTERNAL_ERROR)}; case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR: @@ -630,6 +710,12 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode( return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)}; case QUIC_MISSING_WRITE_KEYS: return {true, static_cast<uint64_t>(INTERNAL_ERROR)}; + case QUIC_KEY_UPDATE_ERROR: + return {true, static_cast<uint64_t>(KEY_UPDATE_ERROR)}; + case QUIC_AEAD_LIMIT_REACHED: + return {true, static_cast<uint64_t>(AEAD_LIMIT_REACHED)}; + case QUIC_MAX_AGE_TIMEOUT: + return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR)}; case QUIC_LAST_ERROR: return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)}; } @@ -770,13 +856,6 @@ QuicRstStreamErrorCode IetfResetStreamErrorCodeToRstStreamErrorCode( return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE; } -void RecordFailToSerializePacketLocation( - QuicFailToSerializePacketLocation location) { - QUIC_CLIENT_HISTOGRAM_ENUM("QuicSession.FailToSerializePacketLocation", - location, kMaxFailLocationValue, - "The reason why a packet fails to serialize"); -} - #undef RETURN_STRING_LITERAL // undef for jumbo builds } // namespace quic 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 180dff7baf1..a1cd7a6eac9 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 @@ -19,92 +19,92 @@ enum QuicRstStreamErrorCode { QUIC_STREAM_NO_ERROR = 0, // There was some error which halted stream processing. - QUIC_ERROR_PROCESSING_STREAM, + QUIC_ERROR_PROCESSING_STREAM = 1, // We got two fin or reset offsets which did not match. - QUIC_MULTIPLE_TERMINATION_OFFSETS, + QUIC_MULTIPLE_TERMINATION_OFFSETS = 2, // We got bad payload and can not respond to it at the protocol level. - QUIC_BAD_APPLICATION_PAYLOAD, + QUIC_BAD_APPLICATION_PAYLOAD = 3, // Stream closed due to connection error. No reset frame is sent when this // happens. - QUIC_STREAM_CONNECTION_ERROR, + QUIC_STREAM_CONNECTION_ERROR = 4, // GoAway frame sent. No more stream can be created. - QUIC_STREAM_PEER_GOING_AWAY, + QUIC_STREAM_PEER_GOING_AWAY = 5, // The stream has been cancelled. - QUIC_STREAM_CANCELLED, + QUIC_STREAM_CANCELLED = 6, // Closing stream locally, sending a RST to allow for proper flow control // accounting. Sent in response to a RST from the peer. - QUIC_RST_ACKNOWLEDGEMENT, + QUIC_RST_ACKNOWLEDGEMENT = 7, // Receiver refused to create the stream (because its limit on open streams // has been reached). The sender should retry the request later (using // another stream). - QUIC_REFUSED_STREAM, + QUIC_REFUSED_STREAM = 8, // Invalid URL in PUSH_PROMISE request header. - QUIC_INVALID_PROMISE_URL, + QUIC_INVALID_PROMISE_URL = 9, // Server is not authoritative for this URL. - QUIC_UNAUTHORIZED_PROMISE_URL, + QUIC_UNAUTHORIZED_PROMISE_URL = 10, // Can't have more than one active PUSH_PROMISE per URL. - QUIC_DUPLICATE_PROMISE_URL, + QUIC_DUPLICATE_PROMISE_URL = 11, // Vary check failed. - QUIC_PROMISE_VARY_MISMATCH, + QUIC_PROMISE_VARY_MISMATCH = 12, // Only GET and HEAD methods allowed. - QUIC_INVALID_PROMISE_METHOD, + QUIC_INVALID_PROMISE_METHOD = 13, // The push stream is unclaimed and timed out. - QUIC_PUSH_STREAM_TIMED_OUT, + QUIC_PUSH_STREAM_TIMED_OUT = 14, // Received headers were too large. - QUIC_HEADERS_TOO_LARGE, + QUIC_HEADERS_TOO_LARGE = 15, // The data is not likely arrive in time. - QUIC_STREAM_TTL_EXPIRED, + QUIC_STREAM_TTL_EXPIRED = 16, // The stream received data that goes beyond its close offset. - QUIC_DATA_AFTER_CLOSE_OFFSET, + QUIC_DATA_AFTER_CLOSE_OFFSET = 17, // Peer violated protocol requirements in a way which does not match a more // specific error code, or endpoint declines to use the more specific error // code. - QUIC_STREAM_GENERAL_PROTOCOL_ERROR, + QUIC_STREAM_GENERAL_PROTOCOL_ERROR = 18, // An internal error has occurred. - QUIC_STREAM_INTERNAL_ERROR, + QUIC_STREAM_INTERNAL_ERROR = 19, // Peer created a stream that will not be accepted. - QUIC_STREAM_STREAM_CREATION_ERROR, + QUIC_STREAM_STREAM_CREATION_ERROR = 20, // A stream required by the connection was closed or reset. - QUIC_STREAM_CLOSED_CRITICAL_STREAM, + QUIC_STREAM_CLOSED_CRITICAL_STREAM = 21, // A frame was received which was not permitted in the current state or on the // current stream. - QUIC_STREAM_FRAME_UNEXPECTED, + QUIC_STREAM_FRAME_UNEXPECTED = 22, // A frame that fails to satisfy layout requirements or with an invalid size // was received. - QUIC_STREAM_FRAME_ERROR, + QUIC_STREAM_FRAME_ERROR = 23, // Peer exhibits a behavior that might be generating excessive load. - QUIC_STREAM_EXCESSIVE_LOAD, + QUIC_STREAM_EXCESSIVE_LOAD = 24, // A Stream ID or Push ID was used incorrectly, such as exceeding a limit, // reducing a limit, or being reused. - QUIC_STREAM_ID_ERROR, + QUIC_STREAM_ID_ERROR = 25, // Error in the payload of a SETTINGS frame. - QUIC_STREAM_SETTINGS_ERROR, + QUIC_STREAM_SETTINGS_ERROR = 26, // No SETTINGS frame was received at the beginning of the control stream. - QUIC_STREAM_MISSING_SETTINGS, + QUIC_STREAM_MISSING_SETTINGS = 27, // A server rejected a request without performing any application processing. - QUIC_STREAM_REQUEST_REJECTED, + QUIC_STREAM_REQUEST_REJECTED = 28, // The client's stream terminated without containing a fully-formed request. - QUIC_STREAM_REQUEST_INCOMPLETE, + QUIC_STREAM_REQUEST_INCOMPLETE = 29, // The connection established in response to a CONNECT request was reset or // abnormally closed. - QUIC_STREAM_CONNECT_ERROR, + QUIC_STREAM_CONNECT_ERROR = 30, // The requested operation cannot be served over HTTP/3. // The peer should retry over HTTP/1.1. - QUIC_STREAM_VERSION_FALLBACK, + QUIC_STREAM_VERSION_FALLBACK = 31, // The QPACK decoder failed to interpret a header block and is not able to // continue decoding that header block. - QUIC_STREAM_DECOMPRESSION_FAILED, + QUIC_STREAM_DECOMPRESSION_FAILED = 32, // The QPACK decoder failed to interpret an encoder instruction received on // the encoder stream. - QUIC_STREAM_ENCODER_STREAM_ERROR, + QUIC_STREAM_ENCODER_STREAM_ERROR = 33, // The QPACK encoder failed to interpret a decoder instruction received on the // decoder stream. - QUIC_STREAM_DECODER_STREAM_ERROR, + QUIC_STREAM_DECODER_STREAM_ERROR = 34, // IETF RESET_FRAME application error code not matching any HTTP/3 or QPACK // error codes. - QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE, + QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE = 35, // No error. Used as bound while iterating. - QUIC_STREAM_LAST_ERROR, + QUIC_STREAM_LAST_ERROR = 36, }; // QuicRstStreamErrorCode is encoded as a single octet on-the-wire. static_assert(static_cast<int>(QUIC_STREAM_LAST_ERROR) <= @@ -391,9 +391,58 @@ enum QuicErrorCode { // Internal error codes for QPACK errors. QUIC_QPACK_DECOMPRESSION_FAILED = 126, + + // Obsolete generic QPACK encoder and decoder stream error codes. + // (Obsoleted by gfe2_reloadable_flag_quic_granular_qpack_error_codes.) QUIC_QPACK_ENCODER_STREAM_ERROR = 127, QUIC_QPACK_DECODER_STREAM_ERROR = 128, + // QPACK encoder stream errors. + + // Variable integer exceeding 2^64-1 received. + QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE = 174, + // String literal exceeding kStringLiteralLengthLimit in length received. + QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG = 175, + // String literal with invalid Huffman encoding received. + QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR = 176, + // Invalid static table index in Insert With Name Reference instruction. + QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY = 177, + // Error inserting entry with static name reference in Insert With Name + // Reference instruction due to entry size exceeding dynamic table capacity. + QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC = 178, + // Invalid relative index in Insert With Name Reference instruction. + QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX = 179, + // Dynamic entry not found in Insert With Name Reference instruction. + QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND = 180, + // Error inserting entry with dynamic name reference in Insert With Name + // Reference instruction due to entry size exceeding dynamic table capacity. + QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC = 181, + // Error inserting entry in Insert With Literal Name instruction due to entry + // size exceeding dynamic table capacity. + QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL = 182, + // Invalid relative index in Duplicate instruction. + QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX = 183, + // Dynamic entry not found in Duplicate instruction. + QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND = 184, + // Error in Set Dynamic Table Capacity instruction due to new capacity + // exceeding maximum dynamic table capacity. + QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY = 185, + + // QPACK decoder stream errors. + + // Variable integer exceeding 2^64-1 received. + QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE = 186, + // Insert Count Increment instruction received with invalid 0 increment. + QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT = 187, + // Insert Count Increment instruction causes uint64_t overflow. + QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW = 188, + // Insert Count Increment instruction increases Known Received Count beyond + // inserted entry cound. + QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT = 189, + // Header Acknowledgement received for stream that has no outstanding header + // blocks. + QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT = 190, + // Received stream data beyond close offset. QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET = 129, @@ -445,6 +494,8 @@ enum QuicErrorCode { // HTTP/3 session received SETTINGS frame which contains HTTP/2 specific // settings. QUIC_HTTP_RECEIVE_SPDY_SETTING = 169, + // HTTP/3 session received an HTTP/2 only frame. + QUIC_HTTP_RECEIVE_SPDY_FRAME = 171, // HPACK header block decoding errors. // Index varint beyond implementation limit. @@ -498,8 +549,22 @@ enum QuicErrorCode { // Try to write data without the right write keys. QUIC_MISSING_WRITE_KEYS = 170, + // An endpoint detected errors in performing key updates. + QUIC_KEY_UPDATE_ERROR = 172, + + // An endpoint has reached the confidentiality or integrity limit for the + // AEAD algorithm used by the given connection. + QUIC_AEAD_LIMIT_REACHED = 173, + + // Connection reached maximum age (regardless of activity), no new requests + // are accepted. This error code is sent in transport layer GOAWAY frame when + // using gQUIC, and only used internally when using HTTP/3. Active requests + // are still served, after which connection will be closed due to idle + // timeout. + QUIC_MAX_AGE_TIMEOUT = 191, + // No error. Used as bound while iterating. - QUIC_LAST_ERROR = 171, + QUIC_LAST_ERROR = 192, }; // 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 @@ -531,6 +596,8 @@ enum QuicIetfTransportErrorCodes : uint64_t { PROTOCOL_VIOLATION = 0xA, INVALID_TOKEN = 0xB, CRYPTO_BUFFER_EXCEEDED = 0xD, + KEY_UPDATE_ERROR = 0xE, + AEAD_LIMIT_REACHED = 0xF, CRYPTO_ERROR_FIRST = 0x100, CRYPTO_ERROR_LAST = 0x1FF, }; @@ -604,36 +671,6 @@ QUIC_EXPORT_PRIVATE inline std::string HistogramEnumDescription( return "cause"; } -enum QuicFailToSerializePacketLocation { - kQuicFailToAppendPacketHeaderFastPath = 0, - kQuicFailToAppendTypeFastPath = 1, - kQuicFailToAppendStreamFrameFastPath = 2, - kQuicFailToAddPaddingFastPath = 3, - kQuicFailToWriteIetfLongHeaderLengthFastPath = 4, - kQuicFailToEncryptPacketFastPath = 5, - kQuicSerializePacketNonEmptyBuffer = 6, - kQuicMissingInitialKey = 7, - kQuicMissingHandshakeKey = 8, - kQuicMissingZeroRttKey = 9, - kQuicMissingOneRttKey = 10, - kQuicFailToBuildPacketWithPaddingInitial = 11, - kQuicFailToBuildPacketInitial = 12, - kQuicFailToBuildPacketWithPaddingHandshake = 13, - kQuicFailToBuildPacketHandshake = 14, - kQuicFailToBuildPacketWithPaddingZeroRtt = 15, - kQuicFailToBuildPacketZeroRtt = 16, - kQuicFailToBuildPacketWithPaddingOneRtt = 17, - kQuicFailToBuildPacketOneRtt = 18, - kQuicFailToEncryptInitial = 19, - kQuicFailToEncryptHandshake = 20, - kQuicFailToEncryptZeroRtt = 21, - kQuicFailToEncryptOneRtt = 22, - kMaxFailLocationValue = kQuicFailToEncryptOneRtt -}; - -QUIC_EXPORT_PRIVATE void RecordFailToSerializePacketLocation( - QuicFailToSerializePacketLocation location); - } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_ diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc index 0f567df48c2..ee4cacdbdf4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes_test.cc @@ -53,6 +53,10 @@ TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) { EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN)); EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED", QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED)); + EXPECT_EQ("KEY_UPDATE_ERROR", + QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR)); + EXPECT_EQ("AEAD_LIMIT_REACHED", + QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED)); EXPECT_EQ("Unknown(1024)", QuicIetfTransportErrorCodeString( @@ -74,7 +78,7 @@ TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) { if (ietf_error_code.is_transport_close) { QuicIetfTransportErrorCodes transport_error_code = static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code); - bool is_valid_transport_error_code = transport_error_code <= 0x0d; + bool is_valid_transport_error_code = transport_error_code <= 0x0f; EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string; } else { // Non-transport errors are application errors, either HTTP/3 or QPACK. 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 new file mode 100644 index 00000000000..72cd4bb38df --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/quic_flags_list.h @@ -0,0 +1,92 @@ +// Copyright (c) 2020 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. + +// This file is autogenerated by the QUICHE Copybara export script. + +QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_use_fast_huffman_encoder, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_close, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ack_delay_alarm_granularity, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allocate_stream_sequencer_buffer_blocks_on_demand, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_exit_startup_on_loss_with_bw_growth, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_loss_exit_use_max_delivered, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_support_max_bootstrap_cwnd, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_post_inflight_to_detect_queuing, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_tcp_inflight_hi_headroom, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_check_keys_before_writing, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_clean_up_spdy_session_destructor, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_close_connection_in_on_can_write_with_blocked_writer, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_set_initial_self_address, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_copy_bbr_cwnd_to_bbr2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_deallocate_message_right_after_sent, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_2_rttvar, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_initial_ack, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_27, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t050, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_clip_received_error_code, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_aead_limits, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_encrypted_control_frames, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_extract_x509_subject_using_certificate_view, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_address_validation, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_arm_pto_for_application_data, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_http3_goaway_stream_id, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_missing_initial_keys2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_out_of_order_sending2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pto_pending_timer_count, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_undecryptable_packets2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_willing_and_able_to_write2, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_give_sent_packet_to_debug_visitor_after_sent, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_goaway_with_max_stream_id, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_granular_qpack_error_codes, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_key_update_supported, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_let_connection_handle_pings, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_max_age_send_goaway, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_new_priority_update_frame, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_process_undecryptable_packets_after_async_decrypt_callback, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_record_received_min_ack_delay, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_frames, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_settings, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_round_up_tiny_bandwidth, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_version_negotiation_for_short_connection_ids, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_split_up_send_rst_2, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_start_peer_migration_earlier, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_stop_sending_uses_ietf_error_code, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_circular_deque_for_unacked_packets, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_encryption_level_context, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_fast_huffman_encoder, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_write_or_buffer_data_at_level, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false) +QUIC_FLAG(FLAGS_quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_enable_zero_rtt_for_tls_v2, true) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_session_tickets_always_enabled, true) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_support_release_time_for_gso, false) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true) diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc index 29a9ba37649..5a275700502 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller_test.cc @@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" @@ -39,6 +40,9 @@ class QuicFlowControllerTest : public QuicTest { void Initialize() { connection_ = new MockQuicConnection(&helper_, &alarm_factory_, Perspective::IS_CLIENT); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_ = std::make_unique<MockQuicSession>(connection_); flow_controller_ = std::make_unique<QuicFlowController>( session_.get(), stream_id_, /*is_connection_flow_controller*/ false, @@ -115,7 +119,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytes) { QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); // Consume enough bytes to send a WINDOW_UPDATE frame. - EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1); flow_controller_->AddBytesConsumed(1 + receive_window_ / 2); @@ -185,7 +189,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) { should_auto_tune_receive_window_ = true; Initialize(); // This test will generate two WINDOW_UPDATE frames. - EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1); EXPECT_TRUE(flow_controller_->auto_tune_receive_window()); // Make sure clock is inititialized. @@ -237,9 +241,9 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) { TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) { Initialize(); // This test will generate two WINDOW_UPDATE frames. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(2) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); EXPECT_FALSE(flow_controller_->auto_tune_receive_window()); // Make sure clock is inititialized. @@ -292,7 +296,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) { should_auto_tune_receive_window_ = true; Initialize(); // This test will generate two WINDOW_UPDATE frames. - EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1); + EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1); EXPECT_TRUE(flow_controller_->auto_tune_receive_window()); // Make sure clock is inititialized. @@ -347,9 +351,9 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) { TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) { Initialize(); // This test will generate two WINDOW_UPDATE frames. - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(2) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); EXPECT_FALSE(flow_controller_->auto_tune_receive_window()); // Make sure clock is inititialized. 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 e57277c672a..90f4370b063 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 @@ -11,6 +11,13 @@ #include <string> #include <utility> +#include "absl/base/attributes.h" +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/strings/escaping.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" @@ -34,18 +41,14 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_client_stats.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -295,14 +298,14 @@ EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) { return NUM_ENCRYPTION_LEVELS; } -quiche::QuicheStringPiece TruncateErrorString(quiche::QuicheStringPiece error) { +absl::string_view TruncateErrorString(absl::string_view error) { if (error.length() <= kMaxErrorStringLength) { return error; } - return quiche::QuicheStringPiece(error.data(), kMaxErrorStringLength); + return absl::string_view(error.data(), kMaxErrorStringLength); } -size_t TruncatedErrorStringSize(const quiche::QuicheStringPiece& error) { +size_t TruncatedErrorStringSize(const absl::string_view& error) { if (error.length() < kMaxErrorStringLength) { return error.length(); } @@ -412,6 +415,9 @@ QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions, process_timestamps_(false), creation_time_(creation_time), last_timestamp_(QuicTime::Delta::Zero()), + support_key_update_for_connection_(false), + current_key_phase_bit_(false), + potential_peer_key_update_attempt_count_(0), first_sending_packet_number_(FirstSendingPacketNumber()), data_producer_(nullptr), infer_packet_header_type_from_version_(perspective == @@ -942,7 +948,7 @@ size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header, break; case MTU_DISCOVERY_FRAME: // MTU discovery frames are serialized as ping frames. - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case PING_FRAME: // Ping has no payload. break; @@ -1088,7 +1094,7 @@ size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames, return 0; case MTU_DISCOVERY_FRAME: // MTU discovery frames are serialized as ping frames. - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case PING_FRAME: // Ping has no payload. break; @@ -1304,6 +1310,15 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket( bool ietf_quic, bool use_length_prefix, const ParsedQuicVersionVector& versions) { + QUIC_CODE_COUNT(quic_build_version_negotiation); + if (use_length_prefix) { + DCHECK(ietf_quic); + QUIC_CODE_COUNT(quic_build_version_negotiation_ietf); + } else if (ietf_quic) { + QUIC_CODE_COUNT(quic_build_version_negotiation_old_ietf); + } else { + QUIC_CODE_COUNT(quic_build_version_negotiation_old_gquic); + } ParsedQuicVersionVector wire_versions = versions; // Add a version reserved for negotiation as suggested by the // "Using Reserved Versions" section of draft-ietf-quic-transport. @@ -1413,6 +1428,13 @@ QuicFramer::BuildIetfVersionNegotiationPacket( } bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) { + is_processing_packet_ = true; + bool result = ProcessPacketInternal(packet); + is_processing_packet_ = false; + return result; +} + +bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) { QuicDataReader reader(packet.data(), packet.length()); bool packet_has_ietf_packet_header = false; @@ -1480,13 +1502,13 @@ bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) { } else if (packet.length() <= kMaxIncomingPacketSize) { // The optimized decryption algorithm implementations run faster when // operating on aligned memory. - QUIC_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize]; + ABSL_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize]; if (packet_has_ietf_packet_header) { rv = ProcessIetfDataPacket(&reader, &header, packet, buffer, - QUICHE_ARRAYSIZE(buffer)); + ABSL_ARRAYSIZE(buffer)); } else { rv = ProcessDataPacket(&reader, &header, packet, buffer, - QUICHE_ARRAYSIZE(buffer)); + ABSL_ARRAYSIZE(buffer)); } } else { std::unique_ptr<char[]> large_buffer(new char[packet.length()]); @@ -1547,14 +1569,13 @@ bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader, const size_t retry_token_length = bytes_remaining - kRetryIntegrityTagLength; DCHECK_GT(retry_token_length, 0u); - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; if (!reader->ReadStringPiece(&retry_token, retry_token_length)) { set_detailed_error("Failed to read retry token."); return false; } - quiche::QuicheStringPiece retry_without_tag = - reader->PreviouslyReadPayload(); - quiche::QuicheStringPiece integrity_tag = reader->ReadRemainingPayload(); + absl::string_view retry_without_tag = reader->PreviouslyReadPayload(); + absl::string_view integrity_tag = reader->ReadRemainingPayload(); DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength); visitor_->OnRetryPacket(EmptyQuicConnectionId(), header.source_connection_id, retry_token, @@ -1591,11 +1612,11 @@ bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader, return false; } - quiche::QuicheStringPiece retry_token = reader->ReadRemainingPayload(); + absl::string_view retry_token = reader->ReadRemainingPayload(); visitor_->OnRetryPacket(original_destination_connection_id, header.source_connection_id, retry_token, - /*retry_integrity_tag=*/quiche::QuicheStringPiece(), - /*retry_without_tag=*/quiche::QuicheStringPiece()); + /*retry_integrity_tag=*/absl::string_view(), + /*retry_without_tag=*/absl::string_view()); return true; } @@ -1611,8 +1632,7 @@ void QuicFramer::MaybeProcessCoalescedPacket( return; } - quiche::QuicheStringPiece remaining_data = - encrypted_reader.PeekRemainingPayload(); + absl::string_view remaining_data = encrypted_reader.PeekRemainingPayload(); DCHECK_EQ(remaining_data.length(), remaining_bytes_length); const char* coalesced_data = @@ -1630,8 +1650,8 @@ void QuicFramer::MaybeProcessCoalescedPacket( << "Failed to parse received coalesced header of length " << coalesced_data_length << " with error: " << detailed_error_ << ": " - << quiche::QuicheTextUtils::HexEncode(coalesced_data, - coalesced_data_length) + << absl::BytesToHexString(absl::string_view( + coalesced_data, coalesced_data_length)) << " previous header was " << header; return; } @@ -1695,8 +1715,7 @@ bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader, perspective_ == Perspective::IS_CLIENT) { // Peek possible stateless reset token. Will only be used on decryption // failure. - quiche::QuicheStringPiece remaining = - encrypted_reader->PeekRemainingPayload(); + absl::string_view remaining = encrypted_reader->PeekRemainingPayload(); if (remaining.length() >= sizeof(header->possible_stateless_reset_token)) { header->has_possible_stateless_reset_token = true; memcpy(&header->possible_stateless_reset_token, @@ -1710,7 +1729,7 @@ bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader, return false; } - quiche::QuicheStringPiece associated_data; + absl::string_view associated_data; std::vector<char> ad_storage; QuicPacketNumber base_packet_number; if (header->form == IETF_QUIC_SHORT_HEADER_PACKET || @@ -1736,8 +1755,7 @@ bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader, &full_packet_number, &ad_storage)) { hp_removal_failed = true; } - associated_data = - quiche::QuicheStringPiece(ad_storage.data(), ad_storage.size()); + associated_data = absl::string_view(ad_storage.data(), ad_storage.size()); } else if (!ProcessAndCalculatePacketNumber( encrypted_reader, header->packet_number_length, base_packet_number, &full_packet_number)) { @@ -1801,8 +1819,7 @@ bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader, return false; } - quiche::QuicheStringPiece encrypted = - encrypted_reader->ReadRemainingPayload(); + absl::string_view encrypted = encrypted_reader->ReadRemainingPayload(); if (!version_.HasHeaderProtection()) { associated_data = GetAssociatedDataFromEncryptedPacket( version_.transport_version, packet, @@ -1906,16 +1923,14 @@ bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader, return false; } - quiche::QuicheStringPiece encrypted = - encrypted_reader->ReadRemainingPayload(); - quiche::QuicheStringPiece associated_data = - GetAssociatedDataFromEncryptedPacket( - version_.transport_version, packet, - GetIncludedDestinationConnectionIdLength(*header), - GetIncludedSourceConnectionIdLength(*header), header->version_flag, - header->nonce != nullptr, header->packet_number_length, - header->retry_token_length_length, header->retry_token.length(), - header->length_length); + absl::string_view encrypted = encrypted_reader->ReadRemainingPayload(); + absl::string_view associated_data = GetAssociatedDataFromEncryptedPacket( + version_.transport_version, packet, + GetIncludedDestinationConnectionIdLength(*header), + GetIncludedSourceConnectionIdLength(*header), header->version_flag, + header->nonce != nullptr, header->packet_number_length, + header->retry_token_length_length, header->retry_token.length(), + header->length_length); size_t decrypted_length = 0; EncryptionLevel decrypted_level; @@ -1995,7 +2010,7 @@ bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader, } // TODO(satyamshekhar): validate nonce to protect against DoS. - quiche::QuicheStringPiece address; + absl::string_view address; if (reset->GetStringPiece(kCADR, &address)) { QuicSocketAddressCoder address_coder; if (address_coder.Decode(address.data(), address.length())) { @@ -2004,7 +2019,7 @@ bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader, } } - quiche::QuicheStringPiece endpoint_id; + absl::string_view endpoint_id; if (perspective_ == Perspective::IS_CLIENT && reset->GetStringPiece(kEPID, &endpoint_id)) { packet.endpoint_id = std::string(endpoint_id); @@ -2051,6 +2066,20 @@ bool QuicFramer::HasAnEncrypterForSpace(PacketNumberSpace space) const { return false; } +EncryptionLevel QuicFramer::GetEncryptionLevelToSendApplicationData() const { + if (!HasAnEncrypterForSpace(APPLICATION_DATA)) { + QUIC_BUG + << "Tried to get encryption level to send application data with no " + "encrypter available."; + return NUM_ENCRYPTION_LEVELS; + } + if (HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) { + return ENCRYPTION_FORWARD_SECURE; + } + DCHECK(HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)); + return ENCRYPTION_ZERO_RTT; +} + bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header, QuicDataWriter* writer, size_t* length_field_offset) { @@ -2143,7 +2172,7 @@ bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header, PacketNumberLengthToOnWireValue(header.packet_number_length)); } else { type = static_cast<uint8_t>( - FLAGS_FIXED_BIT | + FLAGS_FIXED_BIT | (current_key_phase_bit_ ? FLAGS_KEY_PHASE_BIT : 0) | PacketNumberLengthToOnWireValue(header.packet_number_length)); } return writer->WriteUInt8(type); @@ -2992,7 +3021,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader, continue; } case IETF_EXTENSION_MESSAGE_NO_LENGTH: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case IETF_EXTENSION_MESSAGE: { QuicMessageFrame message_frame; if (!ProcessMessageFrame(reader, @@ -3339,7 +3368,7 @@ bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader, break; } case IETF_EXTENSION_MESSAGE_NO_LENGTH_V99: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case IETF_EXTENSION_MESSAGE_V99: { QuicMessageFrame message_frame; if (!ProcessMessageFrame( @@ -3476,8 +3505,8 @@ bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, return false; } - // TODO(ianswett): Don't use quiche::QuicheStringPiece as an intermediary. - quiche::QuicheStringPiece data; + // TODO(ianswett): Don't use absl::string_view as an intermediary. + absl::string_view data; if (has_data_length) { if (!reader->ReadStringPiece16(&data)) { set_detailed_error("Unable to read frame data."); @@ -3538,8 +3567,8 @@ bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader, frame->fin = false; } - // TODO(ianswett): Don't use quiche::QuicheStringPiece as an intermediary. - quiche::QuicheStringPiece data; + // TODO(ianswett): Don't use absl::string_view as an intermediary. + absl::string_view data; if (!reader->ReadStringPiece(&data, frame->data_length)) { set_detailed_error("Unable to read frame data."); return false; @@ -3566,8 +3595,8 @@ bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader, } frame->data_length = len; - // TODO(ianswett): Don't use quiche::QuicheStringPiece as an intermediary. - quiche::QuicheStringPiece data; + // TODO(ianswett): Don't use absl::string_view as an intermediary. + absl::string_view data; if (!reader->ReadStringPiece(&data, frame->data_length)) { set_detailed_error("Unable to read frame data."); return false; @@ -4058,10 +4087,13 @@ bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader, return false; } - if (!GetQuicReloadableFlag(quic_do_not_clip_received_error_code) && - error_code >= QUIC_LAST_ERROR) { - // Ignore invalid QUIC error code if any. - error_code = QUIC_LAST_ERROR; + if (GetQuicReloadableFlag(quic_do_not_clip_received_error_code)) { + QUIC_CODE_COUNT_N(quic_do_not_clip_received_error_code, 1, 2); + } else { + if (error_code >= QUIC_LAST_ERROR) { + // Ignore invalid QUIC error code if any. + error_code = QUIC_LAST_ERROR; + } } // For Google QUIC connection closes, |wire_error_code| and |quic_error_code| @@ -4069,7 +4101,7 @@ bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader, frame->wire_error_code = error_code; frame->quic_error_code = static_cast<QuicErrorCode>(error_code); - quiche::QuicheStringPiece error_details; + absl::string_view error_details; if (!reader->ReadStringPiece16(&error_details)) { set_detailed_error("Unable to read connection close error details."); return false; @@ -4087,10 +4119,13 @@ bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader, return false; } - if (!GetQuicReloadableFlag(quic_do_not_clip_received_error_code) && - error_code >= QUIC_LAST_ERROR) { - // Ignore invalid QUIC error code if any. - error_code = QUIC_LAST_ERROR; + if (GetQuicReloadableFlag(quic_do_not_clip_received_error_code)) { + QUIC_CODE_COUNT_N(quic_do_not_clip_received_error_code, 2, 2); + } else { + if (error_code >= QUIC_LAST_ERROR) { + // Ignore invalid QUIC error code if any. + error_code = QUIC_LAST_ERROR; + } } frame->error_code = static_cast<QuicErrorCode>(error_code); @@ -4101,7 +4136,7 @@ bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader, } frame->last_good_stream_id = static_cast<QuicStreamId>(stream_id); - quiche::QuicheStringPiece reason_phrase; + absl::string_view reason_phrase; if (!reader->ReadStringPiece16(&reason_phrase)) { set_detailed_error("Unable to read goaway reason."); return false; @@ -4155,7 +4190,7 @@ bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader, bool no_message_length, QuicMessageFrame* frame) { if (no_message_length) { - quiche::QuicheStringPiece remaining(reader->ReadRemainingPayload()); + absl::string_view remaining(reader->ReadRemainingPayload()); frame->data = remaining.data(); frame->message_length = remaining.length(); return true; @@ -4167,7 +4202,7 @@ bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader, return false; } - quiche::QuicheStringPiece message_piece; + absl::string_view message_piece; if (!reader->ReadStringPiece(&message_piece, message_length)) { set_detailed_error("Unable to read message data"); return false; @@ -4180,7 +4215,7 @@ bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader, } // static -quiche::QuicheStringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( +absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket( QuicTransportVersion version, const QuicEncryptedPacket& encrypted, QuicConnectionIdLength destination_connection_id_length, @@ -4192,7 +4227,7 @@ quiche::QuicheStringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( uint64_t retry_token_length, QuicVariableLengthIntegerLength length_length) { // TODO(ianswett): This is identical to QuicData::AssociatedData. - return quiche::QuicheStringPiece( + return absl::string_view( encrypted.data(), GetStartOfEncryptedData(version, destination_connection_id_length, source_connection_id_length, includes_version, @@ -4242,6 +4277,48 @@ void QuicFramer::RemoveDecrypter(EncryptionLevel level) { decrypter_[level] = nullptr; } +void QuicFramer::SetKeyUpdateSupportForConnection(bool enabled) { + QUIC_DVLOG(1) << ENDPOINT << "SetKeyUpdateSupportForConnection: " << enabled; + support_key_update_for_connection_ = enabled; + if (enabled) { + QUIC_RELOADABLE_FLAG_COUNT(quic_key_update_supported); + } +} + +void QuicFramer::DiscardPreviousOneRttKeys() { + DCHECK(support_key_update_for_connection_); + QUIC_DVLOG(1) << ENDPOINT << "Discarding previous set of 1-RTT keys"; + previous_decrypter_ = nullptr; +} + +bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) { + DCHECK(support_key_update_for_connection_); + if (!next_decrypter_) { + // If key update is locally initiated, next decrypter might not be created + // yet. + next_decrypter_ = visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter(); + } + std::unique_ptr<QuicEncrypter> next_encrypter = + visitor_->CreateCurrentOneRttEncrypter(); + if (!next_decrypter_ || !next_encrypter) { + QUIC_BUG << "Failed to create next crypters"; + return false; + } + current_key_phase_bit_ = !current_key_phase_bit_; + QUIC_DLOG(INFO) << ENDPOINT << "DoKeyUpdate: new current_key_phase_bit_=" + << current_key_phase_bit_; + current_key_phase_first_received_packet_number_.Clear(); + previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]); + decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_); + encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter); + visitor_->OnKeyUpdate(reason); + return true; +} + +QuicPacketCount QuicFramer::PotentialPeerKeyUpdateAttemptCount() const { + return potential_peer_key_update_attempt_count_; +} + const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const { DCHECK(version_.KnowsWhichDecrypterToUse()); return decrypter_[level].get(); @@ -4297,10 +4374,10 @@ size_t QuicFramer::EncryptInPlace(EncryptionLevel level, size_t output_length = 0; if (!encrypter_[level]->EncryptPacket( packet_number.ToUint64(), - quiche::QuicheStringPiece(buffer, ad_len), // Associated data - quiche::QuicheStringPiece(buffer + ad_len, - total_len - ad_len), // Plaintext - buffer + ad_len, // Destination buffer + absl::string_view(buffer, ad_len), // Associated data + absl::string_view(buffer + ad_len, + total_len - ad_len), // Plaintext + buffer + ad_len, // Destination buffer &output_length, buffer_len - ad_len)) { RaiseError(QUIC_ENCRYPTION_FAILURE); return 0; @@ -4339,7 +4416,7 @@ bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, // Sample the ciphertext and generate the mask to use for header protection. size_t sample_offset = pn_offset + 4; QuicDataReader sample_reader(buffer, buffer_len); - quiche::QuicheStringPiece sample; + absl::string_view sample; if (!sample_reader.Seek(sample_offset) || !sample_reader.ReadStringPiece(&sample, kHPSampleLen)) { QUIC_BUG << "Not enough bytes to sample: sample_offset " << sample_offset @@ -4434,11 +4511,11 @@ bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader, // Read a sample from the ciphertext and compute the mask to use for header // protection. - quiche::QuicheStringPiece remaining_packet = reader->PeekRemainingPayload(); + absl::string_view remaining_packet = reader->PeekRemainingPayload(); QuicDataReader sample_reader(remaining_packet); // The sample starts 4 bytes after the start of the packet number. - quiche::QuicheStringPiece pn; + absl::string_view pn; if (!sample_reader.ReadStringPiece(&pn, 4)) { QUIC_DVLOG(1) << "Not enough data to sample"; return false; @@ -4475,7 +4552,7 @@ bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader, static_cast<QuicPacketNumberLength>((header->type_byte & 0x03) + 1); char pn_buffer[IETF_MAX_PACKET_NUMBER_LENGTH] = {}; - QuicDataWriter pn_writer(QUICHE_ARRAYSIZE(pn_buffer), pn_buffer); + QuicDataWriter pn_writer(ABSL_ARRAYSIZE(pn_buffer), pn_buffer); // Read the (protected) packet number from the reader and unmask the packet // number. @@ -4506,7 +4583,7 @@ bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader, } // Get the associated data, and apply the same unmasking operations to it. - quiche::QuicheStringPiece ad = GetAssociatedDataFromEncryptedPacket( + absl::string_view ad = GetAssociatedDataFromEncryptedPacket( version_.transport_version, packet, GetIncludedDestinationConnectionIdLength(*header), GetIncludedSourceConnectionIdLength(*header), header->version_flag, @@ -4548,7 +4625,7 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level, return 0; } - quiche::QuicheStringPiece associated_data = + absl::string_view associated_data = packet.AssociatedData(version_.transport_version); // Copy in the header, because the encrypter only populates the encrypted // plaintext content. @@ -4609,8 +4686,16 @@ size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) { return min_plaintext_size; } -bool QuicFramer::DecryptPayload(quiche::QuicheStringPiece encrypted, - quiche::QuicheStringPiece associated_data, +QuicPacketCount QuicFramer::GetOneRttEncrypterConfidentialityLimit() const { + if (!encrypter_[ENCRYPTION_FORWARD_SECURE]) { + QUIC_BUG << "1-RTT encrypter not set"; + return 0; + } + return encrypter_[ENCRYPTION_FORWARD_SECURE]->GetConfidentialityLimit(); +} + +bool QuicFramer::DecryptPayload(absl::string_view encrypted, + absl::string_view associated_data, const QuicPacketHeader& header, char* decrypted_buffer, size_t buffer_length, @@ -4623,6 +4708,9 @@ bool QuicFramer::DecryptPayload(quiche::QuicheStringPiece encrypted, EncryptionLevel level = decrypter_level_; QuicDecrypter* decrypter = decrypter_[level].get(); QuicDecrypter* alternative_decrypter = nullptr; + bool key_phase_parsed = false; + bool key_phase; + bool attempt_key_update = false; if (version().KnowsWhichDecrypterToUse()) { if (header.form == GOOGLE_QUIC_PACKET) { QUIC_BUG << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that " @@ -4642,6 +4730,46 @@ bool QuicFramer::DecryptPayload(quiche::QuicheStringPiece encrypted, perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) { decrypter->SetDiversificationNonce(*header.nonce); } + if (support_key_update_for_connection_ && + header.form == IETF_QUIC_SHORT_HEADER_PACKET) { + DCHECK(version().UsesTls()); + DCHECK_EQ(level, ENCRYPTION_FORWARD_SECURE); + key_phase = (header.type_byte & FLAGS_KEY_PHASE_BIT) != 0; + key_phase_parsed = true; + QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number + << " received key_phase=" << key_phase + << " current_key_phase_bit_=" << current_key_phase_bit_; + if (key_phase != current_key_phase_bit_) { + if (current_key_phase_first_received_packet_number_.IsInitialized() && + header.packet_number > + current_key_phase_first_received_packet_number_) { + if (!next_decrypter_) { + next_decrypter_ = + visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter(); + if (!next_decrypter_) { + QUIC_BUG << "Failed to create next_decrypter"; + return false; + } + } + QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number + << " attempt_key_update=true"; + attempt_key_update = true; + potential_peer_key_update_attempt_count_++; + decrypter = next_decrypter_.get(); + } else { + if (previous_decrypter_) { + QUIC_DVLOG(1) << ENDPOINT + << "trying previous_decrypter_ for packet " + << header.packet_number; + decrypter = previous_decrypter_.get(); + } else { + QUIC_DVLOG(1) << ENDPOINT << "dropping packet " + << header.packet_number << " with old key phase"; + return false; + } + } + } + } } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) { if (!EncryptionLevelIsValid(alternative_decrypter_level_)) { QUIC_BUG << "Attempted to decrypt with bad alternative_decrypter_level_"; @@ -4662,6 +4790,28 @@ bool QuicFramer::DecryptPayload(quiche::QuicheStringPiece encrypted, if (success) { visitor_->OnDecryptedPacket(level); *decrypted_level = level; + potential_peer_key_update_attempt_count_ = 0; + if (attempt_key_update) { + if (!DoKeyUpdate(KeyUpdateReason::kRemote)) { + set_detailed_error("Key update failed due to internal error"); + return RaiseError(QUIC_INTERNAL_ERROR); + } + DCHECK_EQ(current_key_phase_bit_, key_phase); + } + if (key_phase_parsed && + !current_key_phase_first_received_packet_number_.IsInitialized() && + key_phase == current_key_phase_bit_) { + // Set packet number for current key phase if it hasn't been initialized + // yet. This is set outside of attempt_key_update since the key update + // may have been initiated locally, and in that case we don't know yet + // which packet number from the remote side to use until we receive a + // packet with that phase. + QUIC_DVLOG(1) << ENDPOINT + << "current_key_phase_first_received_packet_number_ = " + << header.packet_number; + current_key_phase_first_received_packet_number_ = header.packet_number; + visitor_->OnDecryptedFirstPacketInKeyPhase(); + } } else if (alternative_decrypter != nullptr) { if (header.nonce != nullptr) { DCHECK_EQ(perspective_, Perspective::IS_CLIENT); @@ -5142,8 +5292,8 @@ bool QuicFramer::ProcessNewTokenFrame(QuicDataReader* reader, return false; } - // TODO(ianswett): Don't use quiche::QuicheStringPiece as an intermediary. - quiche::QuicheStringPiece data; + // TODO(ianswett): Don't use absl::string_view as an intermediary. + absl::string_view data; if (!reader->ReadStringPiece(&data, length)) { set_detailed_error("Unable to read new token data."); return false; @@ -5556,9 +5706,9 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame, const uint64_t ack_range = iter->Length() - 1; if (writer->remaining() < ecn_size || - static_cast<size_t>(writer->remaining() - ecn_size) < - QuicDataWriter::GetVarInt62Len(gap) + - QuicDataWriter::GetVarInt62Len(ack_range)) { + writer->remaining() - ecn_size < + static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) + + QuicDataWriter::GetVarInt62Len(ack_range))) { // ACK range does not fit, truncate it. break; } @@ -5813,7 +5963,7 @@ bool QuicFramer::ProcessIetfConnectionCloseFrame( return false; } - quiche::QuicheStringPiece phrase; + absl::string_view phrase; if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) { set_detailed_error("Unable to read connection close error details."); return false; @@ -6284,7 +6434,7 @@ QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher( QuicConnectionId* destination_connection_id, QuicConnectionId* source_connection_id, bool* retry_token_present, - quiche::QuicheStringPiece* retry_token, + absl::string_view* retry_token, std::string* detailed_error) { QuicDataReader reader(packet.data(), packet.length()); if (reader.IsDoneReading()) { @@ -6454,7 +6604,7 @@ QuicErrorCode QuicFramer::ParsePublicHeader( QuicConnectionId* source_connection_id, QuicLongHeaderType* long_packet_type, QuicVariableLengthIntegerLength* retry_token_length_length, - quiche::QuicheStringPiece* retry_token, + absl::string_view* retry_token, std::string* detailed_error) { *version_present = false; *has_length_prefix = false; @@ -6463,7 +6613,7 @@ QuicErrorCode QuicFramer::ParsePublicHeader( *source_connection_id = EmptyQuicConnectionId(); *long_packet_type = INVALID_PACKET_TYPE; *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0; - *retry_token = quiche::QuicheStringPiece(); + *retry_token = absl::string_view(); *detailed_error = ""; if (!reader->ReadUInt8(first_byte)) { @@ -6563,14 +6713,10 @@ bool QuicFramer::WriteClientVersionNegotiationProbePacket( return false; } if (destination_connection_id_length > kQuicMaxConnectionId4BitLength || - destination_connection_id_length < - kQuicMinimumInitialConnectionIdLength) { + destination_connection_id_length < kQuicDefaultConnectionIdLength) { QUIC_BUG << "Invalid connection_id_length"; return false; } - const bool use_length_prefix = - GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids); - const uint8_t last_version_byte = use_length_prefix ? 0xda : 0xba; // clang-format off const unsigned char packet_start_bytes[] = { // IETF long header with fixed bit set, type initial, all-0 encrypted bits. @@ -6578,7 +6724,7 @@ bool QuicFramer::WriteClientVersionNegotiationProbePacket( // Version, part of the IETF space reserved for negotiation. // This intentionally differs from QuicVersionReservedForNegotiation() // to allow differentiating them over the wire. - 0xca, 0xba, 0xda, last_version_byte, + 0xca, 0xba, 0xda, 0xda, }; // clang-format on static_assert(sizeof(packet_start_bytes) == 5, "bad packet_start_bytes size"); @@ -6591,8 +6737,8 @@ bool QuicFramer::WriteClientVersionNegotiationProbePacket( QuicConnectionId destination_connection_id(destination_connection_id_bytes, destination_connection_id_length); if (!AppendIetfConnectionIds( - /*version_flag=*/true, use_length_prefix, destination_connection_id, - EmptyQuicConnectionId(), &writer)) { + /*version_flag=*/true, /*use_length_prefix=*/true, + destination_connection_id, EmptyQuicConnectionId(), &writer)) { QUIC_BUG << "Failed to write connection IDs"; return false; } @@ -6676,46 +6822,28 @@ bool QuicFramer::ParseServerVersionNegotiationProbeResponse( *detailed_error = "Packet is not a version negotiation packet"; return false; } - const bool use_length_prefix = - GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids); + QuicConnectionId destination_connection_id, source_connection_id; - if (use_length_prefix) { - if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) { - *detailed_error = "Failed to read destination connection ID"; - return false; - } - if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) { - *detailed_error = "Failed to read source connection ID"; - return false; - } - } else { - uint8_t expected_server_connection_id_length = 0, - destination_connection_id_length = 0, - source_connection_id_length = 0; - if (!ProcessAndValidateIetfConnectionIdLength( - &reader, UnsupportedQuicVersion(), Perspective::IS_CLIENT, - /*should_update_expected_server_connection_id_length=*/true, - &expected_server_connection_id_length, - &destination_connection_id_length, &source_connection_id_length, - detailed_error)) { - return false; - } - if (!reader.ReadConnectionId(&destination_connection_id, - destination_connection_id_length)) { - *detailed_error = "Failed to read destination connection ID"; - return false; - } - if (!reader.ReadConnectionId(&source_connection_id, - source_connection_id_length)) { - *detailed_error = "Failed to read source connection ID"; - return false; - } + if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) { + *detailed_error = "Failed to read destination connection ID"; + return false; + } + if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) { + *detailed_error = "Failed to read source connection ID"; + return false; } if (destination_connection_id.length() != 0) { *detailed_error = "Received unexpected destination connection ID length"; return false; } + if (*source_connection_id_length_out < source_connection_id.length()) { + *detailed_error = quiche::QuicheStrCat( + "*source_connection_id_length_out too small ", + static_cast<int>(*source_connection_id_length_out), " < ", + static_cast<int>(source_connection_id.length())); + return false; + } memcpy(source_connection_id_bytes, source_connection_id.data(), source_connection_id.length()); @@ -6731,11 +6859,10 @@ bool QuicFramer::ParseServerVersionNegotiationProbeResponse( // the string is not found, or is not properly formed, it returns // ErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) { - std::vector<quiche::QuicheStringPiece> ed = - quiche::QuicheTextUtils::Split(frame->error_details, ':'); + std::vector<absl::string_view> ed = absl::StrSplit(frame->error_details, ':'); uint64_t extracted_error_code; if (ed.size() < 2 || !quiche::QuicheTextUtils::IsAllDigits(ed[0]) || - !quiche::QuicheTextUtils::StringToUint64(ed[0], &extracted_error_code)) { + !absl::SimpleAtoi(ed[0], &extracted_error_code)) { if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE && frame->wire_error_code == NO_IETF_QUIC_ERROR) { frame->quic_error_code = QUIC_NO_ERROR; @@ -6749,7 +6876,7 @@ void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) { // including, the split character, so the length of ed[0] is just the number // of digits in the error number. In removing the prefix, 1 is added to the // length to account for the : - quiche::QuicheStringPiece x = quiche::QuicheStringPiece(frame->error_details); + absl::string_view x = absl::string_view(frame->error_details); x.remove_prefix(ed[0].length() + 1); frame->error_details = std::string(x); frame->quic_error_code = static_cast<QuicErrorCode>(extracted_error_code); 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 4fcd67110f6..fba99f875d5 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 @@ -10,6 +10,7 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" @@ -17,7 +18,6 @@ #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -106,9 +106,9 @@ class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface { // the entire RETRY packet except the Retry Integrity Tag field. virtual void OnRetryPacket(QuicConnectionId original_connection_id, QuicConnectionId new_connection_id, - quiche::QuicheStringPiece retry_token, - quiche::QuicheStringPiece retry_integrity_tag, - quiche::QuicheStringPiece retry_without_tag) = 0; + absl::string_view retry_token, + absl::string_view retry_integrity_tag, + absl::string_view retry_without_tag) = 0; // Called when all fields except packet number has been parsed, but has not // been authenticated. If it returns false, framing for this packet will @@ -237,6 +237,25 @@ class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface { // Called when an IETF StreamsBlocked frame has been parsed. virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0; + + // Called when a Key Phase Update has been initiated. This is called for both + // locally and peer initiated key updates. If the key update was locally + // initiated, this does not indicate the peer has received the key update yet. + virtual void OnKeyUpdate(KeyUpdateReason reason) = 0; + + // Called on the first decrypted packet in each key phase (including the + // first key phase.) + virtual void OnDecryptedFirstPacketInKeyPhase() = 0; + + // Called when the framer needs to generate a decrypter for the next key + // phase. Each call should generate the key for phase n+1. + virtual std::unique_ptr<QuicDecrypter> + AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0; + + // Called when the framer needs to generate an encrypter. The key corresponds + // to the key phase of the last decrypter returned by + // AdvanceKeysAndCreateCurrentOneRttDecrypter(). + virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0; }; // Class for parsing and constructing QUIC packets. It has a @@ -300,6 +319,9 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // ignored. bool ProcessPacket(const QuicEncryptedPacket& packet); + // Whether we are in the middle of a call to this->ProcessPacket. + bool is_processing_packet() const { return is_processing_packet_; } + // Largest size in bytes of all stream frame fields without the payload. static size_t GetMinStreamFrameSize(QuicTransportVersion version, QuicStreamId stream_id, @@ -385,7 +407,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // Returns the associated data from the encrypted packet |encrypted| as a // stringpiece. - static quiche::QuicheStringPiece GetAssociatedDataFromEncryptedPacket( + static absl::string_view GetAssociatedDataFromEncryptedPacket( QuicTransportVersion version, const QuicEncryptedPacket& encrypted, QuicConnectionIdLength destination_connection_id_length, @@ -397,7 +419,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer { uint64_t retry_token_length, QuicVariableLengthIntegerLength length_length); - // Parses the unencryoted fields in a QUIC header using |reader| as input, + // Parses the unencrypted fields in a QUIC header using |reader| as input, // stores the result in the other parameters. // |expected_destination_connection_id_length| is only used for short headers. static QuicErrorCode ParsePublicHeader( @@ -414,10 +436,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer { QuicConnectionId* source_connection_id, QuicLongHeaderType* long_packet_type, QuicVariableLengthIntegerLength* retry_token_length_length, - quiche::QuicheStringPiece* retry_token, + absl::string_view* retry_token, std::string* detailed_error); - // Parses the unencryoted fields in |packet| and stores them in the other + // Parses the unencrypted fields in |packet| and stores them in the other // parameters. This can only be called on the server. // |expected_destination_connection_id_length| is only used for short headers. static QuicErrorCode ParsePublicHeaderDispatcher( @@ -432,7 +454,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer { QuicConnectionId* destination_connection_id, QuicConnectionId* source_connection_id, bool* retry_token_present, - quiche::QuicheStringPiece* retry_token, + absl::string_view* retry_token, std::string* detailed_error); // Serializes a packet containing |frames| into |buffer|. @@ -519,6 +541,17 @@ class QUIC_EXPORT_PRIVATE QuicFramer { std::unique_ptr<QuicDecrypter> decrypter); void RemoveDecrypter(EncryptionLevel level); + // Enables key update support. + void SetKeyUpdateSupportForConnection(bool enabled); + // Discard the decrypter for the previous key phase. + void DiscardPreviousOneRttKeys(); + // Update the key phase. + bool DoKeyUpdate(KeyUpdateReason reason); + // Returns the count of packets received that appeared to attempt a key + // update but failed decryption which have been received since the last + // successfully decrypted packet. + QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const; + const QuicDecrypter* GetDecrypter(EncryptionLevel level) const; const QuicDecrypter* decrypter() const; const QuicDecrypter* alternative_decrypter() const; @@ -559,6 +592,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // to ciphertext no larger than |ciphertext_size|. size_t GetMaxPlaintextSize(size_t ciphertext_size); + // Returns the maximum number of packets that can be safely encrypted with + // the active AEAD. 1-RTT keys must be set before calling this method. + QuicPacketCount GetOneRttEncrypterConfidentialityLimit() const; + const std::string& detailed_error() { return detailed_error_; } // The minimum packet number length required to represent |packet_number|. @@ -584,6 +621,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // Returns true if an encrypter of |space| is available. bool HasAnEncrypterForSpace(PacketNumberSpace space) const; + // Returns the encryption level to send application data. This should be only + // called with available encrypter for application data. + EncryptionLevel GetEncryptionLevelToSendApplicationData() const; + void set_validate_flags(bool value) { validate_flags_ = value; } Perspective perspective() const { return perspective_; } @@ -637,10 +678,12 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // WriteClientVersionNegotiationProbePacket. |packet_bytes| must point to // |packet_length| bytes in memory which represent the response. // |packet_length| must be greater or equal to 6. This method will fill in - // |source_connection_id_bytes| which must point to at least 18 bytes in - // memory. |source_connection_id_length_out| will contain the length of the - // received source connection ID, which on success will match the contents of - // the destination connection ID passed in to + // |source_connection_id_bytes| which must point to at least + // |*source_connection_id_length_out| bytes in memory. + // |*source_connection_id_length_out| must be at least 18. + // |*source_connection_id_length_out| will contain the length of the received + // source connection ID, which on success will match the contents of the + // destination connection ID passed in to // WriteClientVersionNegotiationProbePacket. In the case of a failure, // |detailed_error| will be filled in with an explanation of what failed. static bool ParseServerVersionNegotiationProbeResponse( @@ -665,7 +708,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer { private: friend class test::QuicFramerPeer; - typedef std::map<QuicPacketNumber, uint8_t> NackRangeMap; + using NackRangeMap = std::map<QuicPacketNumber, uint8_t>; struct QUIC_EXPORT_PRIVATE AckFrameInfo { AckFrameInfo(); @@ -806,8 +849,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer { bool no_message_length, QuicMessageFrame* frame); - bool DecryptPayload(quiche::QuicheStringPiece encrypted, - quiche::QuicheStringPiece associated_data, + bool DecryptPayload(absl::string_view encrypted, + absl::string_view associated_data, const QuicPacketHeader& header, char* decrypted_buffer, size_t buffer_length, @@ -1010,6 +1053,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer { QuicIetfFrameType type, QuicStreamId* id); + bool ProcessPacketInternal(const QuicEncryptedPacket& packet); + std::string detailed_error_; QuicFramerVisitorInterface* visitor_; QuicErrorCode error_; @@ -1057,6 +1102,27 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // The last timestamp received if process_timestamps_ is true. QuicTime::Delta last_timestamp_; + // Whether IETF QUIC Key Update is supported on this connection. + bool support_key_update_for_connection_; + // The value of the current key phase bit, which is toggled when the keys are + // changed. + bool current_key_phase_bit_; + // Tracks the first packet received in the current key phase. Will be + // uninitialized before the first one-RTT packet has been received or after a + // locally initiated key update but before the first packet from the peer in + // the new key phase is received. + QuicPacketNumber current_key_phase_first_received_packet_number_; + // Counts the number of packets received that might have been failed key + // update attempts. Reset to zero every time a packet is successfully + // decrypted. + QuicPacketCount potential_peer_key_update_attempt_count_; + // Decrypter for the previous key phase. Will be null if in the first key + // phase or previous keys have been discarded. + std::unique_ptr<QuicDecrypter> previous_decrypter_; + // Decrypter for the next key phase. May be null if next keys haven't been + // generated yet. + std::unique_ptr<QuicDecrypter> next_decrypter_; + // If this is a framer of a connection, this is the packet number of first // sending packet. If this is a framer of a framer of dispatcher, this is the // packet number of sent packets (for those which have packet number). @@ -1066,6 +1132,9 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // owned. TODO(fayang): Consider add data producer to framer's constructor. QuicStreamFrameDataProducer* data_producer_; + // Whether we are in the middle of a call to this->ProcessPacket. + bool is_processing_packet_ = false; + // If true, framer infers packet header type (IETF/GQUIC) from version_. // Otherwise, framer infers packet header type from first byte of a received // packet. 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 4da3e03fb99..ba9a70e46fc 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 @@ -12,6 +12,10 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" @@ -30,8 +34,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -92,17 +94,17 @@ const uint8_t kVarInt62EightBytes = 0xc0; class TestEncrypter : public QuicEncrypter { public: ~TestEncrypter() override {} - bool SetKey(quiche::QuicheStringPiece /*key*/) override { return true; } - bool SetNoncePrefix(quiche::QuicheStringPiece /*nonce_prefix*/) override { + bool SetKey(absl::string_view /*key*/) override { return true; } + bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override { return true; } - bool SetIV(quiche::QuicheStringPiece /*iv*/) override { return true; } - bool SetHeaderProtectionKey(quiche::QuicheStringPiece /*key*/) override { + bool SetIV(absl::string_view /*iv*/) override { return true; } + bool SetHeaderProtectionKey(absl::string_view /*key*/) override { return true; } bool EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t /*max_output_length*/) override { @@ -114,7 +116,7 @@ class TestEncrypter : public QuicEncrypter { return true; } std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece /*sample*/) override { + absl::string_view /*sample*/) override { return std::string(5, 0); } size_t GetKeySize() const override { return 0; } @@ -126,11 +128,12 @@ class TestEncrypter : public QuicEncrypter { size_t GetCiphertextSize(size_t plaintext_size) const override { return plaintext_size; } - quiche::QuicheStringPiece GetKey() const override { - return quiche::QuicheStringPiece(); + QuicPacketCount GetConfidentialityLimit() const override { + return std::numeric_limits<QuicPacketCount>::max(); } - quiche::QuicheStringPiece GetNoncePrefix() const override { - return quiche::QuicheStringPiece(); + absl::string_view GetKey() const override { return absl::string_view(); } + absl::string_view GetNoncePrefix() const override { + return absl::string_view(); } QuicPacketNumber packet_number_; @@ -141,15 +144,15 @@ class TestEncrypter : public QuicEncrypter { class TestDecrypter : public QuicDecrypter { public: ~TestDecrypter() override {} - bool SetKey(quiche::QuicheStringPiece /*key*/) override { return true; } - bool SetNoncePrefix(quiche::QuicheStringPiece /*nonce_prefix*/) override { + bool SetKey(absl::string_view /*key*/) override { return true; } + bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override { return true; } - bool SetIV(quiche::QuicheStringPiece /*iv*/) override { return true; } - bool SetHeaderProtectionKey(quiche::QuicheStringPiece /*key*/) override { + bool SetIV(absl::string_view /*iv*/) override { return true; } + bool SetHeaderProtectionKey(absl::string_view /*key*/) override { return true; } - bool SetPreliminaryKey(quiche::QuicheStringPiece /*key*/) override { + bool SetPreliminaryKey(absl::string_view /*key*/) override { QUIC_BUG << "should not be called"; return false; } @@ -157,8 +160,8 @@ class TestDecrypter : public QuicDecrypter { return true; } bool DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t /*max_output_length*/) override { @@ -176,19 +179,45 @@ class TestDecrypter : public QuicDecrypter { size_t GetKeySize() const override { return 0; } size_t GetNoncePrefixSize() const override { return 0; } size_t GetIVSize() const override { return 0; } - quiche::QuicheStringPiece GetKey() const override { - return quiche::QuicheStringPiece(); - } - quiche::QuicheStringPiece GetNoncePrefix() const override { - return quiche::QuicheStringPiece(); + absl::string_view GetKey() const override { return absl::string_view(); } + absl::string_view GetNoncePrefix() const override { + return absl::string_view(); } // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. uint32_t cipher_id() const override { return 0xFFFFFFF2; } + QuicPacketCount GetIntegrityLimit() const override { + return std::numeric_limits<QuicPacketCount>::max(); + } QuicPacketNumber packet_number_; std::string associated_data_; std::string ciphertext_; }; +std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase( + 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; + } else { + packet_data[0] &= ~FLAGS_KEY_PHASE_BIT; + } + + TaggingEncrypter crypter(tag); + const size_t packet_size = crypter.GetCiphertextSize(packet_data.size()); + char* buffer = new char[packet_size]; + size_t buf_len = 0; + if (!crypter.EncryptPacket(0, absl::string_view(), packet_data, buffer, + &buf_len, packet_size)) { + delete[] buffer; + return nullptr; + } + + return std::make_unique<QuicEncryptedPacket>(buffer, buf_len, + /*owns_buffer=*/true); +} + class TestQuicVisitor : public QuicFramerVisitorInterface { public: TestQuicVisitor() @@ -197,6 +226,8 @@ class TestQuicVisitor : public QuicFramerVisitorInterface { packet_count_(0), frame_count_(0), complete_packets_(0), + derive_next_key_count_(0), + decrypted_first_packet_in_key_phase_count_(0), accept_packet_(true), accept_public_header_(true) {} @@ -224,9 +255,9 @@ class TestQuicVisitor : public QuicFramerVisitorInterface { void OnRetryPacket(QuicConnectionId original_connection_id, QuicConnectionId new_connection_id, - quiche::QuicheStringPiece retry_token, - quiche::QuicheStringPiece retry_integrity_tag, - quiche::QuicheStringPiece retry_without_tag) override { + absl::string_view retry_token, + absl::string_view retry_integrity_tag, + absl::string_view retry_without_tag) override { on_retry_packet_called_ = true; retry_original_connection_id_ = std::make_unique<QuicConnectionId>(original_connection_id); @@ -551,17 +582,39 @@ class TestQuicVisitor : public QuicFramerVisitorInterface { EXPECT_EQ(0u, framer_->current_received_frame_type()); } + void OnKeyUpdate(KeyUpdateReason reason) override { + key_update_reasons_.push_back(reason); + } + + void OnDecryptedFirstPacketInKeyPhase() override { + decrypted_first_packet_in_key_phase_count_++; + } + + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + derive_next_key_count_++; + return std::make_unique<StrictTaggingDecrypter>(derive_next_key_count_); + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return std::make_unique<TaggingEncrypter>(derive_next_key_count_); + } + void set_framer(QuicFramer* framer) { framer_ = framer; transport_version_ = framer->transport_version(); } + size_t key_update_count() const { return key_update_reasons_.size(); } + // Counters from the visitor_ callbacks. int error_count_; int version_mismatch_; int packet_count_; int frame_count_; int complete_packets_; + std::vector<KeyUpdateReason> key_update_reasons_; + int derive_next_key_count_; + int decrypted_first_packet_in_key_phase_count_; bool accept_packet_; bool accept_public_header_; @@ -707,7 +760,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> { << " actual: " << decrypter_->packet_number_; return false; } - quiche::QuicheStringPiece associated_data = + absl::string_view associated_data = QuicFramer::GetAssociatedDataFromEncryptedPacket( framer_.transport_version(), encrypted, destination_connection_id_length, source_connection_id_length, @@ -716,13 +769,11 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> { retry_token_length, length_length); if (associated_data != decrypter_->associated_data_) { QUIC_LOG(ERROR) << "Decrypted incorrect associated data. expected " - << quiche::QuicheTextUtils::HexEncode(associated_data) - << " actual: " - << quiche::QuicheTextUtils::HexEncode( - decrypter_->associated_data_); + << absl::BytesToHexString(associated_data) << " actual: " + << absl::BytesToHexString(decrypter_->associated_data_); return false; } - quiche::QuicheStringPiece ciphertext( + absl::string_view ciphertext( encrypted.AsStringPiece().substr(GetStartOfEncryptedData( framer_.transport_version(), destination_connection_id_length, source_connection_id_length, includes_version, @@ -730,12 +781,10 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> { retry_token_length_length, retry_token_length, length_length))); if (ciphertext != decrypter_->ciphertext_) { QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data. expected " - << quiche::QuicheTextUtils::HexEncode(ciphertext) - << " actual: " - << quiche::QuicheTextUtils::HexEncode( - decrypter_->ciphertext_) + << absl::BytesToHexString(ciphertext) << " actual: " + << absl::BytesToHexString(decrypter_->ciphertext_) << " associated data: " - << quiche::QuicheTextUtils::HexEncode(associated_data); + << absl::BytesToHexString(associated_data); return false; } return true; @@ -1002,10 +1051,10 @@ TEST_P(QuicFramerTest, LargePacket) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } const size_t header_size = GetPacketHeaderSize( @@ -1070,7 +1119,7 @@ TEST_P(QuicFramerTest, PacketHeader) { QuicVersionLabel version_label; std::string detailed_error; bool retry_token_present, use_length_prefix; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; ParsedQuicVersion parsed_version = UnsupportedQuicVersion(); const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher( *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, @@ -1135,7 +1184,7 @@ TEST_P(QuicFramerTest, LongPacketHeader) { QuicVersionLabel version_label; std::string detailed_error; bool retry_token_present, use_length_prefix; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; ParsedQuicVersion parsed_version = UnsupportedQuicVersion(); const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher( *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, @@ -1201,10 +1250,10 @@ TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -1215,7 +1264,7 @@ TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) { QuicVersionLabel version_label = 0; std::string detailed_error = ""; bool retry_token_present, use_length_prefix; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; ParsedQuicVersion parsed_version = UnsupportedQuicVersion(); const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher( encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, @@ -1286,13 +1335,13 @@ TEST_P(QuicFramerTest, ParsePublicHeader) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_length = QUICHE_ARRAYSIZE(packet46); + p_length = ABSL_ARRAYSIZE(packet46); } uint8_t first_byte = 0x33; @@ -1305,7 +1354,7 @@ TEST_P(QuicFramerTest, ParsePublicHeader) { QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE; QuicVariableLengthIntegerLength retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_4; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error = "foobar"; QuicDataReader reader(AsChars(p), p_length); @@ -1328,7 +1377,7 @@ TEST_P(QuicFramerTest, ParsePublicHeader) { EXPECT_EQ(FramerTestConnectionId(), destination_connection_id); EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id); EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length); - EXPECT_EQ(quiche::QuicheStringPiece(), retry_token); + EXPECT_EQ(absl::string_view(), retry_token); if (VersionHasIetfInvariantHeader(framer_.transport_version())) { EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format); EXPECT_EQ(HANDSHAKE, long_packet_type); @@ -1363,7 +1412,7 @@ TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); uint8_t first_byte = 0x33; PacketHeaderFormat format = GOOGLE_QUIC_PACKET; @@ -1375,7 +1424,7 @@ TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) { QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE; QuicVariableLengthIntegerLength retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_4; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error = "foobar"; QuicDataReader reader(AsChars(p), p_length); @@ -1395,7 +1444,7 @@ TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) { EXPECT_EQ(FramerTestConnectionId(), destination_connection_id); EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id); EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length); - EXPECT_EQ(quiche::QuicheStringPiece(), retry_token); + EXPECT_EQ(absl::string_view(), retry_token); EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format); } @@ -1420,8 +1469,7 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToClient) { 0x00, }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsQuicNoError()); EXPECT_EQ("", framer_.detailed_error()); @@ -1455,8 +1503,7 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToServer) { 0x00, }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsQuicNoError()); EXPECT_EQ("", framer_.detailed_error()); @@ -1944,13 +1991,13 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) { } unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_size = QUICHE_ARRAYSIZE(packet49); + p_size = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -2019,13 +2066,13 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_size = QUICHE_ARRAYSIZE(packet49); + p_size = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -2122,13 +2169,13 @@ TEST_P(QuicFramerTest, PaddingFrame) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -2391,13 +2438,13 @@ TEST_P(QuicFramerTest, MissingDiversificationNonce) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_length = QUICHE_ARRAYSIZE(packet46); + p_length = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); @@ -2974,8 +3021,8 @@ TEST_P(QuicFramerTest, RejectPacket) { } QuicEncryptedPacket encrypted(AsChars(p), framer_.version().HasIetfInvariantHeader() - ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet), + ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -3013,8 +3060,8 @@ TEST_P(QuicFramerTest, RejectPublicHeader) { QuicEncryptedPacket encrypted( framer_.version().HasIetfInvariantHeader() ? AsChars(packet46) : AsChars(packet), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet), + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -4029,10 +4076,10 @@ TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) { } QuicEncryptedPacket encrypted( AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet), - QUICHE_ARRAYSIZE(packet), false); + ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - EXPECT_TRUE(quiche::QuicheTextUtils::StartsWith( - framer_.detailed_error(), "delta_from_largest_observed too high")); + EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(), + "delta_from_largest_observed too high")); } TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) { @@ -4102,10 +4149,10 @@ TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) { } QuicEncryptedPacket encrypted( AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet), - QUICHE_ARRAYSIZE(packet), false); + ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - EXPECT_TRUE(quiche::QuicheTextUtils::StartsWith( - framer_.detailed_error(), "delta_from_largest_observed too high")); + EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(), + "delta_from_largest_observed too high")); } TEST_P(QuicFramerTest, NewStopWaitingFrame) { @@ -4211,8 +4258,8 @@ TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) { QuicEncryptedPacket encrypted( AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet), + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_STOP_WAITING_DATA)); @@ -5313,10 +5360,10 @@ TEST_P(QuicFramerTest, PingFrame) { : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet)), VersionHasIetfQuicFrames(framer_.transport_version()) - ? QUICHE_ARRAYSIZE(packet99) + ? ABSL_ARRAYSIZE(packet99) : (framer_.version().HasIetfInvariantHeader() - ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)), + ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -5351,8 +5398,7 @@ TEST_P(QuicFramerTest, HandshakeDoneFrame) { return; } - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsQuicNoError()); @@ -5392,8 +5438,7 @@ TEST_P(QuicFramerTest, ParseAckFrequencyFrame) { return; } - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsQuicNoError()); @@ -5635,8 +5680,7 @@ TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) { return; } - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); ASSERT_THAT(framer_.error(), IsError(QUIC_INVALID_PUBLIC_RST_PACKET)); EXPECT_EQ("Unable to read reset message.", framer_.detailed_error()); @@ -5737,8 +5781,7 @@ TEST_P(QuicFramerTest, IetfStatelessResetPacket) { ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false); } // This packet cannot be decrypted because diversification nonce is missing. - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); ASSERT_THAT(framer_.error(), IsQuicNoError()); ASSERT_TRUE(visitor_.stateless_reset_packet_.get()); @@ -5781,8 +5824,7 @@ TEST_P(QuicFramerTest, IetfStatelessResetPacketInvalidStatelessResetToken) { ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false); } // This packet cannot be decrypted because diversification nonce is missing. - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE)); ASSERT_FALSE(visitor_.stateless_reset_packet_); @@ -5902,10 +5944,10 @@ TEST_P(QuicFramerTest, VersionNegotiationPacketServer) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLengthPrefixedConnectionIds()) { p = packet2; - p_length = QUICHE_ARRAYSIZE(packet2); + p_length = ABSL_ARRAYSIZE(packet2); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -6018,13 +6060,13 @@ TEST_P(QuicFramerTest, ParseIetfRetryPacket) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasRetryIntegrityTag()) { p = packet_with_tag; - p_length = QUICHE_ARRAYSIZE(packet_with_tag); + p_length = ABSL_ARRAYSIZE(packet_with_tag); } else if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -6046,7 +6088,7 @@ TEST_P(QuicFramerTest, ParseIetfRetryPacket) { "retry integrity tag", visitor_.retry_token_integrity_tag_->data(), visitor_.retry_token_integrity_tag_->length(), reinterpret_cast<const char*>(expected_integrity_tag), - QUICHE_ARRAYSIZE(expected_integrity_tag)); + ABSL_ARRAYSIZE(expected_integrity_tag)); ASSERT_TRUE(visitor_.retry_without_tag_.get()); quiche::test::CompareCharArraysWithHexError( "retry without tag", visitor_.retry_without_tag_->data(), @@ -6155,8 +6197,8 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) { @@ -6167,7 +6209,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) { header.version_flag = false; header.packet_number = kPacketNumber; QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, - quiche::QuicheStringPiece("hello world!")); + absl::string_view("hello world!")); QuicPaddingFrame padding_frame(2); QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(stream_frame), QuicFrame(padding_frame)}; @@ -6259,13 +6301,13 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -6344,8 +6386,8 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) { @@ -6419,8 +6461,8 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) { @@ -6494,8 +6536,8 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildStreamFramePacket) { @@ -6510,7 +6552,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) { } QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, - quiche::QuicheStringPiece("hello world!")); + absl::string_view("hello world!")); QuicFrames frames = {QuicFrame(stream_frame)}; @@ -6583,13 +6625,13 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), p_size); @@ -6609,7 +6651,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) { } QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, - quiche::QuicheStringPiece("hello world!")); + absl::string_view("hello world!")); QuicFrames frames = {QuicFrame(stream_frame)}; // clang-format off @@ -6713,16 +6755,16 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_size = QUICHE_ARRAYSIZE(packet49); + p_size = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), p_size); @@ -6742,7 +6784,7 @@ TEST_P(QuicFramerTest, BuildCryptoFramePacket) { SimpleDataProducer data_producer; framer_.set_data_producer(&data_producer); - quiche::QuicheStringPiece crypto_frame_contents("hello world!"); + absl::string_view crypto_frame_contents("hello world!"); QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, kStreamOffset, crypto_frame_contents.length()); data_producer.SaveCryptoData(ENCRYPTION_INITIAL, kStreamOffset, @@ -6795,10 +6837,10 @@ TEST_P(QuicFramerTest, BuildCryptoFramePacket) { // clang-format on unsigned char* packet = packet48; - size_t packet_size = QUICHE_ARRAYSIZE(packet48); + size_t packet_size = ABSL_ARRAYSIZE(packet48); if (framer_.version().HasIetfQuicFrames()) { packet = packet99; - packet_size = QUICHE_ARRAYSIZE(packet99); + packet_size = ABSL_ARRAYSIZE(packet99); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -6934,13 +6976,13 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_size = QUICHE_ARRAYSIZE(packet49); + p_size = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicConnectionId connection_id = FramerTestConnectionId(); @@ -6987,7 +7029,7 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacketWithClientConnectionId) { SupportedVersions(GetParam()))); quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) { @@ -7068,13 +7110,13 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -7161,13 +7203,13 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -7309,13 +7351,13 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -7618,13 +7660,13 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) { }; // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -7672,7 +7714,7 @@ TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildRstFramePacketQuic) { @@ -7756,13 +7798,13 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -7850,13 +7892,13 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -7956,13 +7998,13 @@ TEST_P(QuicFramerTest, BuildCloseFramePacketExtendedInfo) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -8137,13 +8179,13 @@ TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -8201,7 +8243,7 @@ TEST_P(QuicFramerTest, BuildApplicationCloseFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) { @@ -8282,7 +8324,7 @@ TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildGoAwayPacket) { @@ -8354,10 +8396,10 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -8491,10 +8533,10 @@ TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -8575,13 +8617,13 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } quiche::test::CompareCharArraysWithHexError( @@ -8630,7 +8672,7 @@ TEST_P(QuicFramerTest, BuildMaxStreamDataPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildMaxDataPacket) { @@ -8674,7 +8716,7 @@ TEST_P(QuicFramerTest, BuildMaxDataPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildBlockedPacket) { @@ -8747,13 +8789,13 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) { ASSERT_TRUE(data != nullptr); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } quiche::test::CompareCharArraysWithHexError( @@ -8820,8 +8862,8 @@ TEST_P(QuicFramerTest, BuildPingPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildHandshakeDonePacket) { @@ -8855,7 +8897,7 @@ TEST_P(QuicFramerTest, BuildHandshakeDonePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildAckFrequencyPacket) { @@ -8902,7 +8944,7 @@ TEST_P(QuicFramerTest, BuildAckFrequencyPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildMessagePacket) { @@ -8973,7 +9015,7 @@ TEST_P(QuicFramerTest, BuildMessagePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - QUICHE_ARRAYSIZE(packet46)); + ABSL_ARRAYSIZE(packet46)); } // Test that the MTU discovery packet is serialized correctly as a PING packet. @@ -9037,8 +9079,8 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.version().HasIetfInvariantHeader() ? QUICHE_ARRAYSIZE(packet46) - : QUICHE_ARRAYSIZE(packet)); + framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46) + : ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildPublicResetPacket) { @@ -9075,7 +9117,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacket) { ASSERT_TRUE(data != nullptr); quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) { @@ -9124,7 +9166,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) { @@ -9198,11 +9240,11 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) { if ('d' == data->data()[data->length() - 1]) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(packet_variant1), QUICHE_ARRAYSIZE(packet_variant1)); + AsChars(packet_variant1), ABSL_ARRAYSIZE(packet_variant1)); } else { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), - AsChars(packet_variant2), QUICHE_ARRAYSIZE(packet_variant2)); + AsChars(packet_variant2), ABSL_ARRAYSIZE(packet_variant2)); } } @@ -9234,7 +9276,7 @@ TEST_P(QuicFramerTest, BuildIetfStatelessResetPacket) { "constructed packet", data->data() + data->length() - sizeof(kTestStatelessResetToken), sizeof(kTestStatelessResetToken), - AsChars(packet) + QUICHE_ARRAYSIZE(packet) - + AsChars(packet) + ABSL_ARRAYSIZE(packet) - sizeof(kTestStatelessResetToken), sizeof(kTestStatelessResetToken)); } @@ -9290,10 +9332,10 @@ TEST_P(QuicFramerTest, EncryptPacket) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (framer_.version().HasHeaderProtection()) { p = packet50; - p_size = QUICHE_ARRAYSIZE(packet50); + p_size = ABSL_ARRAYSIZE(packet50); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; } @@ -9393,14 +9435,14 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); // TODO(ianswett): see todo in previous test. if (framer_.version().HasHeaderProtection()) { p = packet50; - p_size = QUICHE_ARRAYSIZE(packet50); + p_size = ABSL_ARRAYSIZE(packet50); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<QuicPacket> raw(new QuicPacket( @@ -9726,13 +9768,13 @@ TEST_P(QuicFramerTest, StopPacketProcessing) { EXPECT_CALL(visitor, OnDecryptedPacket(_)); unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -9917,7 +9959,7 @@ TEST_P(QuicFramerTest, BuildIetfBlockedPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, IetfStreamBlockedFrame) { @@ -10005,7 +10047,7 @@ TEST_P(QuicFramerTest, BuildIetfStreamBlockedPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BiDiMaxStreamsFrame) { @@ -10205,7 +10247,7 @@ TEST_P(QuicFramerTest, BiDiMaxStreamsFrameTooBig) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsQuicNoError()); @@ -10242,7 +10284,7 @@ TEST_P(QuicFramerTest, ClientBiDiMaxStreamsFrameTooBig) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -10282,7 +10324,7 @@ TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrameTooBig) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -10320,7 +10362,7 @@ TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrameTooBig) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -10358,7 +10400,7 @@ TEST_P(QuicFramerTest, MaxStreamsFrameZeroCount) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); EXPECT_TRUE(framer_.ProcessPacket(encrypted)); } @@ -10563,7 +10605,7 @@ TEST_P(QuicFramerTest, StreamsBlockedFrameTooBig) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet99), QUICHE_ARRAYSIZE(packet99), + QuicEncryptedPacket encrypted(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); @@ -10658,7 +10700,7 @@ TEST_P(QuicFramerTest, BuildBiDiStreamsBlockedPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) { @@ -10700,7 +10742,7 @@ TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) { @@ -10742,7 +10784,7 @@ TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) { @@ -10787,7 +10829,7 @@ TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, NewConnectionIdFrame) { @@ -11056,7 +11098,7 @@ TEST_P(QuicFramerTest, BuildNewConnectionIdFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, NewTokenFrame) { @@ -11150,7 +11192,7 @@ TEST_P(QuicFramerTest, BuildNewTokenFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet), - QUICHE_ARRAYSIZE(packet)); + ABSL_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, IetfStopSendingFrame) { @@ -11247,7 +11289,7 @@ TEST_P(QuicFramerTest, BuildIetfStopSendingPacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, IetfPathChallengeFrame) { @@ -11330,7 +11372,7 @@ TEST_P(QuicFramerTest, BuildIetfPathChallengePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, IetfPathResponseFrame) { @@ -11413,7 +11455,7 @@ TEST_P(QuicFramerTest, BuildIetfPathResponsePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, GetRetransmittableControlFrameSize) { @@ -12218,7 +12260,7 @@ TEST_P(QuicFramerTest, BuildRetireConnectionIdFramePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(packet99), - QUICHE_ARRAYSIZE(packet99)); + ABSL_ARRAYSIZE(packet99)); } TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) { @@ -12286,10 +12328,10 @@ TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; } @@ -12364,13 +12406,13 @@ TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -12472,13 +12514,13 @@ TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) { // clang-format on unsigned char* p = packet; - size_t p_size = QUICHE_ARRAYSIZE(packet); + size_t p_size = ABSL_ARRAYSIZE(packet); if (VersionHasIetfQuicFrames(framer_.transport_version())) { p = packet99; - p_size = QUICHE_ARRAYSIZE(packet99); + p_size = ABSL_ARRAYSIZE(packet99); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_size = QUICHE_ARRAYSIZE(packet46); + p_size = ABSL_ARRAYSIZE(packet46); } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -12619,10 +12661,10 @@ TEST_P(QuicFramerTest, CoalescedPacket) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -12738,10 +12780,10 @@ TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -12889,10 +12931,10 @@ TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -12996,13 +13038,13 @@ TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_length = QUICHE_ARRAYSIZE(packet46); + p_length = ABSL_ARRAYSIZE(packet46); } // First attempt decryption without the handshake crypter. EXPECT_FALSE( @@ -13098,13 +13140,13 @@ TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } else if (framer_.version().HasIetfInvariantHeader()) { p = packet46; - p_length = QUICHE_ARRAYSIZE(packet46); + p_length = ABSL_ARRAYSIZE(packet46); } EXPECT_FALSE( @@ -13262,10 +13304,10 @@ TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) { const size_t length_of_first_coalesced_packet = 46; unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -13429,10 +13471,10 @@ TEST_P(QuicFramerTest, MismatchedCoalescedPacket) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -13534,10 +13576,10 @@ TEST_P(QuicFramerTest, InvalidCoalescedPacket) { // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasIetfQuicFrames()) { p = packet99; - p_length = QUICHE_ARRAYSIZE(packet99); + p_length = ABSL_ARRAYSIZE(packet99); } QuicEncryptedPacket encrypted(AsChars(p), p_length, false); @@ -13596,7 +13638,7 @@ TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) { unsigned char packet[kMaxOutgoingPacketSize] = {}; size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *data, - AsChars(packet), QUICHE_ARRAYSIZE(packet)); + AsChars(packet), ABSL_ARRAYSIZE(packet)); ASSERT_NE(0u, encrypted_length); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); @@ -13608,8 +13650,7 @@ TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) { std::move(server_crypters.decrypter)); // Make sure the first long header initial packet parses correctly. - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); // Make sure we discard the subsequent zeroes. EXPECT_TRUE(framer_.ProcessPacket(encrypted)); @@ -13639,8 +13680,7 @@ TEST_P(QuicFramerTest, ClientReceivesInvalidVersion) { }; // clang-format on - QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet), - false); + QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false); EXPECT_FALSE(framer_.ProcessPacket(encrypted)); EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_VERSION)); @@ -13763,11 +13803,11 @@ TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) { if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) { EXPECT_TRUE(framer_.ProcessPacket( QuicEncryptedPacket(AsChars(long_header_packet), - QUICHE_ARRAYSIZE(long_header_packet), false))); + ABSL_ARRAYSIZE(long_header_packet), false))); } else { EXPECT_TRUE(framer_.ProcessPacket( QuicEncryptedPacket(AsChars(long_header_packet99), - QUICHE_ARRAYSIZE(long_header_packet99), false))); + ABSL_ARRAYSIZE(long_header_packet99), false))); } EXPECT_THAT(framer_.error(), IsQuicNoError()); @@ -13794,8 +13834,7 @@ TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) { // clang-format on QuicEncryptedPacket short_header_encrypted( - AsChars(short_header_packet), QUICHE_ARRAYSIZE(short_header_packet), - false); + AsChars(short_header_packet), ABSL_ARRAYSIZE(short_header_packet), false); if (framer_.version().KnowsWhichDecrypterToUse()) { framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, std::make_unique<TestDecrypter>()); @@ -13952,106 +13991,7 @@ TEST_P(QuicFramerTest, ProcessMismatchedHeaderVersion) { CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER); } -TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacketOld) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false); - // clang-format off - static const char expected_packet[1200] = { - // IETF long header with fixed bit set, type initial, all-0 encrypted bits. - 0xc0, - // Version, part of the IETF space reserved for negotiation. - 0xca, 0xba, 0xda, 0xba, - // Destination connection ID length 8, source connection ID length 0. - 0x50, - // 8-byte destination connection ID. - 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21, - // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does - // not parse with any known version. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - // 2 bytes of zeroes to pad to 16 byte boundary. - 0x00, 0x00, - // A polite greeting in case a human sees this in tcpdump. - 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63, - 0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67, - 0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, - 0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67, - 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, - 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68, - 0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79, - 0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, - 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69, - 0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00, - }; - // clang-format on - char packet[1200]; - char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70, - 0x6c, 0x7a, 0x20, 0x21}; - EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket( - packet, sizeof(packet), destination_connection_id_bytes, - sizeof(destination_connection_id_bytes))); - quiche::test::CompareCharArraysWithHexError("constructed packet", packet, - sizeof(packet), expected_packet, - sizeof(expected_packet)); - QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet), - sizeof(packet), false); - // Make sure we fail to parse this packet for the version under test. - if (!framer_.version().HasIetfInvariantHeader()) { - // We can only parse the connection ID with an IETF parser. - EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - return; - } - EXPECT_TRUE(framer_.ProcessPacket(encrypted)); - ASSERT_TRUE(visitor_.header_.get()); - QuicConnectionId probe_payload_connection_id( - reinterpret_cast<const char*>(destination_connection_id_bytes), - sizeof(destination_connection_id_bytes)); - EXPECT_EQ(probe_payload_connection_id, - visitor_.header_.get()->destination_connection_id); - - PacketHeaderFormat format = GOOGLE_QUIC_PACKET; - QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE; - bool version_present = false, has_length_prefix = false; - QuicVersionLabel version_label = 0; - ParsedQuicVersion parsed_version = QuicVersionReservedForNegotiation(); - QuicConnectionId destination_connection_id = TestConnectionId(0x33); - QuicConnectionId source_connection_id = TestConnectionId(0x34); - bool retry_token_present = true; - quiche::QuicheStringPiece retry_token; - std::string detailed_error = "foobar"; - - QuicErrorCode parse_result = QuicFramer::ParsePublicHeaderDispatcher( - encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, - &version_present, &has_length_prefix, &version_label, &parsed_version, - &destination_connection_id, &source_connection_id, &retry_token_present, - &retry_token, &detailed_error); - EXPECT_THAT(parse_result, IsQuicNoError()); - EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format); - EXPECT_TRUE(version_present); - EXPECT_FALSE(has_length_prefix); - EXPECT_EQ(0xcabadaba, version_label); - EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, parsed_version.transport_version); - EXPECT_EQ(probe_payload_connection_id, destination_connection_id); - EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id); - EXPECT_FALSE(retry_token_present); - EXPECT_EQ(quiche::QuicheStringPiece(), retry_token); - EXPECT_EQ("", detailed_error); -} - TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacket) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true); // clang-format off static const char expected_packet[1200] = { // IETF long header with fixed bit set, type initial, all-0 encrypted bits. @@ -14181,7 +14121,7 @@ TEST_P(QuicFramerTest, DispatcherParseOldClientVersionNegotiationProbePacket) { QuicConnectionId destination_connection_id = TestConnectionId(1); QuicConnectionId source_connection_id = TestConnectionId(2); bool retry_token_present = true; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error = "foobar"; QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher( encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, @@ -14260,7 +14200,7 @@ TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) { QuicConnectionId destination_connection_id = TestConnectionId(1); QuicConnectionId source_connection_id = TestConnectionId(2); bool retry_token_present = true; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error = "foobar"; QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher( encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type, @@ -14277,8 +14217,7 @@ TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) { EXPECT_EQ("", detailed_error); } -TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponseOld) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false); +TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) { // clang-format off const char packet[] = { // IETF long header with fixed bit set, type initial, all-0 encrypted bits. @@ -14286,7 +14225,7 @@ TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponseOld) { // Version of 0, indicating version negotiation. 0x00, 0x00, 0x00, 0x00, // Destination connection ID length 0, source connection ID length 8. - 0x05, + 0x00, 0x08, // 8-byte source connection ID. 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21, // A few supported versions. @@ -14296,7 +14235,7 @@ TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponseOld) { // clang-format on char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21}; char parsed_probe_payload_bytes[255] = {}; - uint8_t parsed_probe_payload_length = 0; + uint8_t parsed_probe_payload_length = sizeof(parsed_probe_payload_bytes); std::string parse_detailed_error = ""; EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse( reinterpret_cast<const char*>(packet), sizeof(packet), @@ -14308,35 +14247,47 @@ TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponseOld) { probe_payload_bytes, sizeof(probe_payload_bytes)); } -TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) { - SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true); - // clang-format off - const char packet[] = { - // IETF long header with fixed bit set, type initial, all-0 encrypted bits. - 0xc0, - // Version of 0, indicating version negotiation. - 0x00, 0x00, 0x00, 0x00, - // Destination connection ID length 0, source connection ID length 8. - 0x00, 0x08, - // 8-byte source connection ID. - 0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21, - // A few supported versions. - 0xaa, 0xaa, 0xaa, 0xaa, - QUIC_VERSION_BYTES, - }; - // clang-format on - char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21}; - char parsed_probe_payload_bytes[255] = {}; - uint8_t parsed_probe_payload_length = 0; - std::string parse_detailed_error = ""; - EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse( - reinterpret_cast<const char*>(packet), sizeof(packet), - reinterpret_cast<char*>(parsed_probe_payload_bytes), - &parsed_probe_payload_length, &parse_detailed_error)); - EXPECT_EQ("", parse_detailed_error); +TEST_P(QuicFramerTest, ParseClientVersionNegotiationProbePacket) { + char packet[1200]; + char input_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70, + 0x6c, 0x7a, 0x20, 0x21}; + ASSERT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket( + packet, sizeof(packet), input_destination_connection_id_bytes, + sizeof(input_destination_connection_id_bytes))); + char parsed_destination_connection_id_bytes[255] = {0}; + uint8_t parsed_destination_connection_id_length = + sizeof(parsed_destination_connection_id_bytes); + ASSERT_TRUE(ParseClientVersionNegotiationProbePacket( + packet, sizeof(packet), parsed_destination_connection_id_bytes, + &parsed_destination_connection_id_length)); quiche::test::CompareCharArraysWithHexError( - "parsed probe", parsed_probe_payload_bytes, parsed_probe_payload_length, - probe_payload_bytes, sizeof(probe_payload_bytes)); + "parsed destination connection ID", + parsed_destination_connection_id_bytes, + parsed_destination_connection_id_length, + input_destination_connection_id_bytes, + sizeof(input_destination_connection_id_bytes)); +} + +TEST_P(QuicFramerTest, WriteServerVersionNegotiationProbeResponse) { + char packet[1200]; + size_t packet_length = sizeof(packet); + char input_source_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70, + 0x6c, 0x7a, 0x20, 0x21}; + ASSERT_TRUE(WriteServerVersionNegotiationProbeResponse( + packet, &packet_length, input_source_connection_id_bytes, + sizeof(input_source_connection_id_bytes))); + char parsed_source_connection_id_bytes[255] = {0}; + uint8_t parsed_source_connection_id_length = + sizeof(parsed_source_connection_id_bytes); + std::string detailed_error; + ASSERT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse( + packet, packet_length, parsed_source_connection_id_bytes, + &parsed_source_connection_id_length, &detailed_error)) + << detailed_error; + quiche::test::CompareCharArraysWithHexError( + "parsed destination connection ID", parsed_source_connection_id_bytes, + parsed_source_connection_id_length, input_source_connection_id_bytes, + sizeof(input_source_connection_id_bytes)); } TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) { @@ -14385,10 +14336,10 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } const bool parse_success = framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)); @@ -14450,10 +14401,10 @@ TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) { }; // clang-format on unsigned char* p = packet; - size_t p_length = QUICHE_ARRAYSIZE(packet); + size_t p_length = ABSL_ARRAYSIZE(packet); if (framer_.version().HasLongHeaderLengths()) { p = packet49; - p_length = QUICHE_ARRAYSIZE(packet49); + p_length = ABSL_ARRAYSIZE(packet49); } const bool parse_success = framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)); @@ -14665,14 +14616,566 @@ TEST_P(QuicFramerTest, OverlyLargeAckDelay) { }; // clang-format on - framer_.ProcessPacket(QuicEncryptedPacket(AsChars(packet99), - QUICHE_ARRAYSIZE(packet99), false)); + framer_.ProcessPacket( + QuicEncryptedPacket(AsChars(packet99), ABSL_ARRAYSIZE(packet99), false)); ASSERT_EQ(1u, visitor_.ack_frames_.size()); // Verify ack_delay_time is set correctly. EXPECT_EQ(QuicTime::Delta::Infinite(), visitor_.ack_frames_[0]->ack_delay_time); } +TEST_P(QuicFramerTest, KeyUpdate) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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)); + // Processed valid packet with phase=0, key=1: no key update. + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + // Processed valid packet with phase=1, key=2: key update should have + // occurred. + ASSERT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + // Processed another valid packet with phase=1, key=2: no key update. + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process another key update. + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 2, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + ASSERT_EQ(2u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]); + EXPECT_EQ(2, visitor_.derive_next_key_count_); + EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterUpdate) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + // Process packet N with phase 0. + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+2 with phase 1. + header.packet_number = kPacketNumber + 2; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+1 with phase 0. (Receiving packet from previous phase + // after packet from new phase was received.) + header.packet_number = kPacketNumber + 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should decrypt and key update count should not change. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterDiscardPreviousOneRttKeys) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + // Process packet N with phase 0. + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+2 with phase 1. + header.packet_number = kPacketNumber + 2; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Discard keys for previous key phase. + framer_.DiscardPreviousOneRttKeys(); + + // Process packet N+1 with phase 0. (Receiving packet from previous phase + // after packet from new phase was received.) + header.packet_number = kPacketNumber + 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should not decrypt and key update count should not change. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdatePacketsOutOfOrder) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + // Process packet N with phase 0. + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+2 with phase 1. + header.packet_number = kPacketNumber + 2; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+1 with phase 1. (Receiving packet from new phase out of + // order.) + header.packet_number = kPacketNumber + 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should decrypt and key update count should not change. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdateWrongKey) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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)); + // Processed valid packet with phase=0, key=1: no key update. + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount()); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 2, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet with phase=1 but key=3, should not process and should not cause key + // update, but next decrypter key should have been created to attempt to + // decode it. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + EXPECT_EQ(1u, framer_.PotentialPeerKeyUpdateAttemptCount()); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet with phase=1 but key=1, should not process and should not cause key + // update. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount()); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet with phase=0 but key=2, should not process and should not cause key + // update. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount()); + + header.packet_number += 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet with phase=0 and key=0, should process and reset + // potential_peer_key_update_attempt_count_. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount()); +} + +TEST_P(QuicFramerTest, KeyUpdateReceivedWhenNotEnabled) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); + ASSERT_TRUE(data != nullptr); + std::unique_ptr<QuicEncryptedPacket> encrypted( + EncryptPacketWithTagAndPhase(*data, 1, true)); + ASSERT_TRUE(encrypted); + + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Received a packet with key phase updated even though framer hasn't had key + // update enabled (SetNextOneRttCrypters never called). Should fail to + // process. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(0u, visitor_.key_update_count()); + EXPECT_EQ(0, visitor_.derive_next_key_count_); + EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdateLocallyInitiated) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests)); + // Key update count should be updated, but haven't received packet from peer + // with new key phase. + ASSERT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + // Process packet N with phase 1. + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); + ASSERT_TRUE(data != nullptr); + std::unique_ptr<QuicEncryptedPacket> encrypted( + EncryptPacketWithTagAndPhase(*data, 1, true)); + ASSERT_TRUE(encrypted); + + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should decrypt and key update count should not change and + // OnDecryptedFirstPacketInKeyPhase should have been called. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N-1 with phase 0. (Receiving packet from previous phase + // after packet from new phase was received.) + header.packet_number = kPacketNumber - 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should decrypt and key update count should not change. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+1 with phase 0 and key 1. This should not decrypt even + // though it's using the previous key, since the packet number is higher than + // a packet number received using the current key. + header.packet_number = kPacketNumber + 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should not decrypt and key update count should not change. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(2, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); +} + +TEST_P(QuicFramerTest, KeyUpdateLocallyInitiatedReceivedOldPacket) { + if (!framer_.version().UsesTls()) { + // Key update is only used in QUIC+TLS. + return; + } + ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse()); + // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter + // instead of TestDecrypter. + framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); + framer_.SetKeyUpdateSupportForConnection(true); + + EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests)); + // Key update count should be updated, but haven't received packet + // from peer with new key phase. + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); + + QuicPacketHeader header; + header.destination_connection_id = FramerTestConnectionId(); + header.reset_flag = false; + header.version_flag = false; + header.packet_number = kPacketNumber; + + QuicFrames frames = {QuicFrame(QuicPaddingFrame())}; + + // Process packet N with phase 0. (Receiving packet from previous phase + // after locally initiated key update, but before any packet from new phase + // was received.) + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + 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); + // Packet should decrypt and key update count should not change and + // OnDecryptedFirstPacketInKeyPhase should not have been called since the + // packet was from the previous key phase. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+1 with phase 1. + header.packet_number = kPacketNumber + 1; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 1, true); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should decrypt and key update count should not change, but + // OnDecryptedFirstPacketInKeyPhase should have been called. + EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(1, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); + + // Process packet N+2 with phase 0 and key 1. This should not decrypt even + // though it's using the previous key, since the packet number is higher than + // a packet number received using the current key. + header.packet_number = kPacketNumber + 2; + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); + data = BuildDataPacket(header, frames); + ASSERT_TRUE(data != nullptr); + encrypted = EncryptPacketWithTagAndPhase(*data, 0, false); + ASSERT_TRUE(encrypted); + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + // Packet should not decrypt and key update count should not change. + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(2, visitor_.derive_next_key_count_); + EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); +} + } // namespace } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h index 0ac98278019..d469a083d9c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque.h @@ -7,13 +7,13 @@ #include <algorithm> +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_interval.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" namespace quic { @@ -260,7 +260,7 @@ class QUIC_NO_EXPORT QuicIntervalDeque { friend class test::QuicIntervalDequePeer; C container_; - quiche::QuicheOptional<std::size_t> cached_index_; + absl::optional<std::size_t> cached_index_; }; template <class T, class C> diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc index f7a84414434..2539f1d1b65 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_interval_deque_test.cc @@ -32,7 +32,7 @@ struct TestIntervalItem { : val(val), interval_start(interval_start), interval_end(interval_end) {} }; -typedef QuicIntervalDeque<TestIntervalItem> QID; +using QID = QuicIntervalDeque<TestIntervalItem>; class QuicIntervalDequeTest : public QuicTest { public: diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h index 28153c19088..7ab06475792 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set.h @@ -67,18 +67,18 @@ namespace quic { template <typename T> class QUIC_NO_EXPORT QuicIntervalSet { public: - typedef QuicInterval<T> value_type; + using value_type = QuicInterval<T>; private: struct QUIC_NO_EXPORT IntervalLess { bool operator()(const value_type& a, const value_type& b) const; }; // TODO(wub): Switch to absl::btree_set when it is available in Chromium. - typedef std::set<value_type, IntervalLess> Set; + using Set = std::set<value_type, IntervalLess>; public: - typedef typename Set::const_iterator const_iterator; - typedef typename Set::const_reverse_iterator const_reverse_iterator; + using const_iterator = typename Set::const_iterator; + using const_reverse_iterator = typename Set::const_reverse_iterator; // Instantiates an empty QuicIntervalSet. QuicIntervalSet() {} @@ -350,9 +350,6 @@ class QUIC_NO_EXPORT QuicIntervalSet { return *this; } - // Swap this QuicIntervalSet with *other. This is a constant-time operation. - void Swap(QuicIntervalSet<T>* other) { intervals_.swap(other->intervals_); } - friend bool operator==(const QuicIntervalSet& a, const QuicIntervalSet& b) { return a.Size() == b.Size() && std::equal(a.begin(), a.end(), b.begin(), NonemptyIntervalEq()); @@ -438,9 +435,6 @@ auto operator<<(std::ostream& out, const QuicIntervalSet<T>& seq) return out; } -template <typename T> -void swap(QuicIntervalSet<T>& x, QuicIntervalSet<T>& y); - //============================================================================== // Implementation details: Clients can stop reading here. @@ -918,11 +912,6 @@ bool QuicIntervalSet<T>::Valid() const { return true; } -template <typename T> -void swap(QuicIntervalSet<T>& x, QuicIntervalSet<T>& y) { - x.Swap(&y); -} - // This comparator orders intervals first by ascending min() and then by // descending max(). Readers who are satisified with that explanation can stop // reading here. The remainder of this comment is for the benefit of future diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc index efa8fe7e960..30d08b8bc1e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_interval_set_test.cc @@ -971,10 +971,10 @@ TEST_F(QuicIntervalSetTest, Swap) { a.Add(300, 400); b.Add(100, 200); b.Add(500, 600); - a.Swap(&b); + std::swap(a, b); EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600)); EXPECT_TRUE(Check(b, 1, 300, 400)); - swap(a, b); + std::swap(a, b); EXPECT_TRUE(Check(a, 1, 300, 400)); EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600)); } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc index 4afd34201c8..8e9317271dc 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc @@ -19,7 +19,7 @@ QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {} // static QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead( - quiche::QuicheStringPiece sni) { + absl::string_view sni) { // The number 52 is the sum of: // - Flags (1 byte) // - Server Connection ID (8 bytes) @@ -85,8 +85,8 @@ SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate( // static QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate( - quiche::QuicheStringPiece sni, - quiche::QuicheStringPiece inner_packet, + absl::string_view sni, + absl::string_view inner_packet, const QuicConnectionId& server_connection_id, QuicTime creation_time, QuicByteCount outer_max_packet_length, diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h index 413829b4be0..7a4ada68b9f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_ #define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -27,8 +27,8 @@ class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator // the contents of the encapsulated packet to |out|. |out| must point to a // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes. static QuicPacketLength Encapsulate( - quiche::QuicheStringPiece sni, - quiche::QuicheStringPiece inner_packet, + absl::string_view sni, + absl::string_view inner_packet, const QuicConnectionId& server_connection_id, QuicTime creation_time, QuicByteCount outer_max_packet_length, @@ -37,7 +37,7 @@ class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator // Returns the number of bytes of minimum overhead caused by Legacy Version // Encapsulation, based on the length of the provided server name |sni|. // The overhead may be higher due to extra padding added. - static QuicByteCount GetMinimumOverhead(quiche::QuicheStringPiece sni); + static QuicByteCount GetMinimumOverhead(absl::string_view sni); // Overrides for QuicPacketCreator::DelegateInterface. QuicPacketBuffer GetPacketBuffer() override; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc index a71b2f44eb5..d765fff3ba6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc @@ -4,11 +4,11 @@ #include "net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -43,7 +43,7 @@ class QuicLegacyVersionEncapsulatorTest ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported(); QuicConnectionId destination_connection_id, source_connection_id; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; std::string detailed_error; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( QuicEncryptedPacket(outer_buffer_, encapsulated_length_), diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h index 40916579fad..fe186dfe872 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h @@ -161,9 +161,8 @@ struct QUIC_EXPORT_PRIVATE BufferedWrite { // QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent); class QUIC_EXPORT_PRIVATE QuicMMsgHdr { public: - typedef std::function< - void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)> - ControlBufferInitializer; + using ControlBufferInitializer = std::function< + void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>; template <typename IteratorT> QuicMMsgHdr(const IteratorT& first, const IteratorT& last, diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h b/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h index 41842f35963..d8218036643 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_one_block_arena.h @@ -44,7 +44,7 @@ class QUIC_EXPORT_PRIVATE QuicOneBlockArena { // Actual storage. // Subtle/annoying: the value '8' must be coded explicitly into the alignment // declaration for MSVC. - QUIC_ALIGNED(8) char storage_[ArenaSize]; + alignas(8) char storage_[ArenaSize]; // Current offset into the storage. uint32_t offset_; }; @@ -57,7 +57,7 @@ template <typename T, typename... Args> QuicArenaScopedPtr<T> QuicOneBlockArena<ArenaSize>::New(Args&&... args) { DCHECK_LT(AlignedSize<T>(), ArenaSize) << "Object is too large for the arena."; - static_assert(QUIC_ALIGN_OF(T) > 1, + static_assert(alignof(T) > 1, "Objects added to the arena must be at least 2B aligned."); if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) { QUIC_BUG << "Ran out of space in QuicOneBlockArena at " << this diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc index 30b911fa839..3db37eda64b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc @@ -11,6 +11,9 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h" @@ -22,16 +25,13 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -134,8 +134,8 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id, fully_pad_crypto_handshake_packets_(true), latched_hard_max_packet_length_(0), max_datagram_frame_size_(0) { - if (close_connection_on_serialization_failure_) { - QUIC_RELOADABLE_FLAG_COUNT(quic_close_connection_on_serialization_failure); + if (let_connection_handle_pings_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_let_connection_handle_pings); } SetMaxPacketLength(kDefaultMaxPacketSize); if (!framer_->version().UsesTls()) { @@ -466,7 +466,7 @@ void QuicPacketCreator::FlushCurrentPacket() { return; } - QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize]; + ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize]; QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer()); if (external_buffer.buffer == nullptr) { @@ -475,24 +475,14 @@ void QuicPacketCreator::FlushCurrentPacket() { } DCHECK_EQ(nullptr, packet_.encrypted_buffer); - const bool success = - SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize); - if (close_connection_on_serialization_failure_ && !success) { + if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize)) { return; } OnSerializedPacket(); } void QuicPacketCreator::OnSerializedPacket() { - if (close_connection_on_serialization_failure_) { - QUIC_BUG_IF(packet_.encrypted_buffer == nullptr); - } else if (packet_.encrypted_buffer == nullptr) { - const std::string error_details = "Failed to SerializePacket."; - QUIC_BUG << error_details; - delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, - error_details); - return; - } + QUIC_BUG_IF(packet_.encrypted_buffer == nullptr); SerializedPacket packet(std::move(packet_)); ClearPacket(); @@ -556,9 +546,7 @@ size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket( return 0; } } - const bool success = - SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len); - if (close_connection_on_serialization_failure_ && !success) { + if (!SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len)) { return 0; } const size_t encrypted_length = packet_.encrypted_length; @@ -590,7 +578,7 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame( << ": " << SerializedPacketFateToString(packet_.fate) << " of " << EncryptionLevelToString(packet_.encryption_level); - QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize]; + ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize]; QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer()); if (packet_buffer.buffer == nullptr) { @@ -604,7 +592,6 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame( size_t length_field_offset = 0; if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) { QUIC_BUG << "AppendPacketHeader failed"; - RecordFailToSerializePacketLocation(kQuicFailToAppendPacketHeaderFastPath); return; } @@ -646,12 +633,10 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame( bool omit_frame_length = !needs_padding; if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) { QUIC_BUG << "AppendTypeByte failed"; - RecordFailToSerializePacketLocation(kQuicFailToAppendTypeFastPath); return; } if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) { QUIC_BUG << "AppendStreamFrame failed"; - RecordFailToSerializePacketLocation(kQuicFailToAppendStreamFrameFastPath); return; } if (needs_padding && @@ -659,14 +644,11 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame( !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) - plaintext_bytes_written)) { QUIC_BUG << "Unable to add padding bytes"; - RecordFailToSerializePacketLocation(kQuicFailToAddPaddingFastPath); return; } if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset, packet_.encryption_level)) { - RecordFailToSerializePacketLocation( - kQuicFailToWriteIetfLongHeaderLengthFastPath); return; } @@ -681,7 +663,6 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame( writer.length(), kMaxOutgoingPacketSize, encrypted_buffer); if (encrypted_length == 0) { QUIC_BUG << "Failed to encrypt packet number " << header.packet_number; - RecordFailToSerializePacketLocation(kQuicFailToEncryptPacketFastPath); return; } // TODO(ianswett): Optimize the storage so RetransmitableFrames can be @@ -764,9 +745,7 @@ bool QuicPacketCreator::AddPaddedSavedFrame( bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, size_t encrypted_buffer_len) { - if (close_connection_on_serialization_failure_ && - packet_.encrypted_buffer != nullptr) { - RecordFailToSerializePacketLocation(kQuicSerializePacketNonEmptyBuffer); + if (packet_.encrypted_buffer != nullptr) { const std::string error_details = "Packet's encrypted buffer is not empty before serialization"; QUIC_BUG << error_details; @@ -774,11 +753,7 @@ bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, error_details); return false; } - const bool use_handler = - GetQuicReloadableFlag( - quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded) || - close_connection_on_serialization_failure_; - ScopedSerializationFailureHandler handler(use_handler ? this : nullptr); + ScopedSerializationFailureHandler handler(this); DCHECK_LT(0u, encrypted_buffer_len); QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0) @@ -810,22 +785,6 @@ bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, << QuicFramesToString(queued_frames_) << " at missing encryption_level " << packet_.encryption_level << " using " << framer_->version(); - switch (packet_.encryption_level) { - case ENCRYPTION_INITIAL: - RecordFailToSerializePacketLocation(kQuicMissingInitialKey); - break; - case ENCRYPTION_HANDSHAKE: - RecordFailToSerializePacketLocation(kQuicMissingHandshakeKey); - break; - case ENCRYPTION_ZERO_RTT: - RecordFailToSerializePacketLocation(kQuicMissingZeroRttKey); - break; - case ENCRYPTION_FORWARD_SECURE: - RecordFailToSerializePacketLocation(kQuicMissingOneRttKey); - break; - default: - break; - } return false; } @@ -844,42 +803,6 @@ bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, << latched_hard_max_packet_length_ << ", max_packet_length_: " << max_packet_length_ << ", header: " << header; - switch (packet_.encryption_level) { - case ENCRYPTION_INITIAL: - if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { - RecordFailToSerializePacketLocation( - kQuicFailToBuildPacketWithPaddingInitial); - } else { - RecordFailToSerializePacketLocation(kQuicFailToBuildPacketInitial); - } - break; - case ENCRYPTION_HANDSHAKE: - if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { - RecordFailToSerializePacketLocation( - kQuicFailToBuildPacketWithPaddingHandshake); - } else { - RecordFailToSerializePacketLocation(kQuicFailToBuildPacketHandshake); - } - break; - case ENCRYPTION_ZERO_RTT: - if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { - RecordFailToSerializePacketLocation( - kQuicFailToBuildPacketWithPaddingZeroRtt); - } else { - RecordFailToSerializePacketLocation(kQuicFailToBuildPacketZeroRtt); - } - break; - case ENCRYPTION_FORWARD_SECURE: - if (QuicUtils::ContainsFrameType(queued_frames_, PADDING_FRAME)) { - RecordFailToSerializePacketLocation( - kQuicFailToBuildPacketWithPaddingOneRtt); - } else { - RecordFailToSerializePacketLocation(kQuicFailToBuildPacketOneRtt); - } - break; - default: - break; - } return false; } @@ -901,29 +824,10 @@ bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, encrypted_buffer_len, encrypted_buffer.buffer); if (encrypted_length == 0) { QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; - switch (packet_.encryption_level) { - case ENCRYPTION_INITIAL: - RecordFailToSerializePacketLocation(kQuicFailToEncryptInitial); - break; - case ENCRYPTION_HANDSHAKE: - RecordFailToSerializePacketLocation(kQuicFailToEncryptHandshake); - break; - case ENCRYPTION_ZERO_RTT: - RecordFailToSerializePacketLocation(kQuicFailToEncryptZeroRtt); - break; - case ENCRYPTION_FORWARD_SECURE: - RecordFailToSerializePacketLocation(kQuicFailToEncryptOneRtt); - break; - default: - break; - } return false; } packet_size_ = 0; - if (!use_handler) { - queued_frames_.clear(); - } packet_.encrypted_buffer = encrypted_buffer.buffer; packet_.encrypted_length = encrypted_length; @@ -932,21 +836,6 @@ bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer, return true; } -std::unique_ptr<QuicEncryptedPacket> -QuicPacketCreator::SerializeVersionNegotiationPacket( - bool ietf_quic, - bool use_length_prefix, - const ParsedQuicVersionVector& supported_versions) { - DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); - std::unique_ptr<QuicEncryptedPacket> encrypted = - QuicFramer::BuildVersionNegotiationPacket( - server_connection_id_, client_connection_id_, ietf_quic, - use_length_prefix, supported_versions); - DCHECK(encrypted); - DCHECK_GE(max_packet_length_, encrypted->length()); - return encrypted; -} - std::unique_ptr<SerializedPacket> QuicPacketCreator::SerializeConnectivityProbingPacket() { QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version())) @@ -1288,22 +1177,23 @@ QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength() return VARIABLE_LENGTH_INTEGER_LENGTH_0; } -quiche::QuicheStringPiece QuicPacketCreator::GetRetryToken() const { +absl::string_view QuicPacketCreator::GetRetryToken() const { if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) && HasIetfLongHeader() && EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) { return retry_token_; } - return quiche::QuicheStringPiece(); + return absl::string_view(); } -void QuicPacketCreator::SetRetryToken(quiche::QuicheStringPiece retry_token) { +void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) { retry_token_ = std::string(retry_token); } bool QuicPacketCreator::ConsumeRetransmittableControlFrame( const QuicFrame& frame) { - QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame)) + QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame) && + (!let_connection_handle_pings_ || frame.type != PING_FRAME)) << "Adding a control frame with no control frame id: " << frame; DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame; MaybeBundleAckOpportunistically(); @@ -1574,7 +1464,7 @@ void QuicPacketCreator::Flush() { FlushCurrentPacket(); SendRemainingPendingPadding(); flusher_attached_ = false; - if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) { + if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) { if (!write_start_packet_number_.IsInitialized()) { QUIC_BUG << "write_start_packet_number is not initialized"; return; @@ -2102,8 +1992,7 @@ QuicPacketCreator::ScopedSerializationFailureHandler:: // Always clear queued_frames_. creator_->queued_frames_.clear(); - if (creator_->close_connection_on_serialization_failure_ && - creator_->packet_.encrypted_buffer == nullptr) { + if (creator_->packet_.encrypted_buffer == nullptr) { const std::string error_details = "Failed to SerializePacket."; QUIC_BUG << error_details; creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, @@ -2119,11 +2008,39 @@ void QuicPacketCreator::set_encryption_level(EncryptionLevel level) { packet_.encryption_level = level; } +void QuicPacketCreator::AddPathChallengeFrame(QuicPathFrameBuffer* payload) { + // Write a PATH_CHALLENGE frame, which has a random 8-byte payload. + random_->RandBytes(payload->data(), payload->size()); + auto path_challenge_frame = new QuicPathChallengeFrame(0, *payload); + QuicFrame frame(path_challenge_frame); + if (AddPaddedFrameWithRetry(frame)) { + return; + } + // Fail silently if the probing packet cannot be written, path validation + // initiator will retry sending automatically. + // TODO(danzh) This will consume retry budget, if it causes performance + // regression, consider to notify the caller about the sending failure and let + // the caller to decide if it worth retrying. + QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now"; + delete path_challenge_frame; +} + bool QuicPacketCreator::AddPathResponseFrame( const QuicPathFrameBuffer& data_buffer) { auto path_response = new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer); QuicFrame frame(path_response); + if (AddPaddedFrameWithRetry(frame)) { + return true; + } + + QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now"; + QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response, 5, 5); + delete path_response; + return false; +} + +bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) { if (HasPendingFrames()) { if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) { // Frame is queued. @@ -2134,14 +2051,12 @@ bool QuicPacketCreator::AddPathResponseFrame( DCHECK(!HasPendingFrames()); if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) { - QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now"; - QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response, 5, 5); - delete path_response; return false; } bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION); QUIC_BUG_IF(!success); return true; } + #undef ENDPOINT // undef for jumbo builds } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h index b025d06f66f..54da59c05f3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h @@ -20,6 +20,8 @@ #include <utility> #include <vector> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_coalesced_packet.h" @@ -27,8 +29,6 @@ #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -231,12 +231,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { bool AddPaddedSavedFrame(const QuicFrame& frame, TransmissionType transmission_type); - // Creates a version negotiation packet which supports |supported_versions|. - std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket( - bool ietf_quic, - bool use_length_prefix, - const ParsedQuicVersionVector& supported_versions); - // Creates a connectivity probing packet for versions prior to version 99. std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket(); @@ -258,6 +252,11 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // Add PATH_RESPONSE to current packet, flush before or afterwards if needed. bool AddPathResponseFrame(const QuicPathFrameBuffer& data_buffer); + // Add PATH_CHALLENGE to current packet, flush before or afterwards if needed. + // This is a best effort adding. It may fail becasue of delegate state, but + // it's okay because of path validation retry mechanism. + void AddPathChallengeFrame(QuicPathFrameBuffer* payload); + // Returns a dummy packet that is valid but contains no useful information. static SerializedPacket NoPacket(); @@ -322,7 +321,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { void AddPendingPadding(QuicByteCount size); // Sets the retry token to be sent over the wire in IETF Initial packets. - void SetRetryToken(quiche::QuicheStringPiece retry_token); + void SetRetryToken(absl::string_view retry_token); // Consumes retransmittable control |frame|. Returns true if the frame is // successfully consumed. Returns false otherwise. @@ -469,6 +468,10 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // different from the current one, flush all the queue frames first. void SetDefaultPeerAddress(QuicSocketAddress address); + bool let_connection_handle_pings() const { + return let_connection_handle_pings_; + } + private: friend class test::QuicPacketCreatorPeer; @@ -510,7 +513,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // retransmitted to packet_.retransmittable_frames. All frames must fit into // a single packet. Returns true on success, otherwise, returns false. // Fails if |encrypted_buffer| is not large enough for the encrypted packet. - QUIC_MUST_USE_RESULT bool SerializePacket( + ABSL_MUST_USE_RESULT bool SerializePacket( QuicOwnedPacketBuffer encrypted_buffer, size_t encrypted_buffer_len); @@ -569,7 +572,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // Returns the retry token to send over the wire, only sent in // v99 IETF Initial packets. - quiche::QuicheStringPiece GetRetryToken() const; + absl::string_view GetRetryToken() const; // Returns length of the length variable length integer to send over the // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets. @@ -592,6 +595,11 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // Returns true and close connection if it attempts to send unencrypted data. bool AttemptingToSendUnencryptedStreamData(); + // Add the given frame to the current packet with full padding. If the current + // packet doesn't have enough space, flush once and try again. Return false if + // fail to add. + bool AddPaddedFrameWithRetry(const QuicFrame& frame); + // Does not own these delegates or the framer. DelegateInterface* delegate_; DebugDelegate* debug_delegate_; @@ -663,8 +671,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // negotiates this during the handshake. QuicByteCount max_datagram_frame_size_; - const bool close_connection_on_serialization_failure_ = - GetQuicReloadableFlag(quic_close_connection_on_serialization_failure); + const bool let_connection_handle_pings_ = + GetQuicReloadableFlag(quic_let_connection_handle_pings); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc index 4afbf06158a..d76f1985ad6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc @@ -11,6 +11,8 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" @@ -30,9 +32,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" using testing::_; @@ -227,8 +227,7 @@ class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> { producer_.WriteStreamData(stream_id, frame.stream_frame.offset, frame.stream_frame.data_length, &writer); } - EXPECT_EQ(data, - quiche::QuicheStringPiece(buf, frame.stream_frame.data_length)); + EXPECT_EQ(data, absl::string_view(buf, frame.stream_frame.data_length)); EXPECT_EQ(offset, frame.stream_frame.offset); EXPECT_EQ(fin, frame.stream_frame.fin); } @@ -306,7 +305,7 @@ TEST_P(QuicPacketCreatorTest, SerializeFrames) { client_framer_.transport_version(), Perspective::IS_CLIENT); if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) { frames_.push_back(QuicFrame( - QuicStreamFrame(stream_id, false, 0u, quiche::QuicheStringPiece()))); + QuicStreamFrame(stream_id, false, 0u, absl::string_view()))); } SerializedPacket serialized = SerializeAllFrames(frames_); EXPECT_EQ(level, serialized.encryption_level); @@ -580,28 +579,6 @@ TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) { } } -TEST_P(QuicPacketCreatorTest, SerializeVersionNegotiationPacket) { - QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER); - ParsedQuicVersionVector versions; - versions.push_back(test::QuicVersionMax()); - const bool ietf_quic = - VersionHasIetfInvariantHeader(creator_.transport_version()); - const bool has_length_prefix = - GetParam().version.HasLengthPrefixedConnectionIds(); - std::unique_ptr<QuicEncryptedPacket> encrypted( - creator_.SerializeVersionNegotiationPacket(ietf_quic, has_length_prefix, - versions)); - - { - InSequence s; - EXPECT_CALL(framer_visitor_, OnPacket()); - EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); - EXPECT_CALL(framer_visitor_, OnVersionNegotiationPacket(_)); - } - QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_CLIENT); - client_framer_.ProcessPacket(*encrypted); -} - // Test that the path challenge connectivity probing packet is serialized // correctly as a padded PATH CHALLENGE packet. TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) { @@ -640,9 +617,9 @@ TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) { MockRandom randomizer; size_t length = creator_.BuildPaddedPathChallengePacket( - header, buffer.get(), QUICHE_ARRAYSIZE(packet), &payload, &randomizer, + header, buffer.get(), ABSL_ARRAYSIZE(packet), &payload, &randomizer, ENCRYPTION_INITIAL); - EXPECT_EQ(length, QUICHE_ARRAYSIZE(packet)); + EXPECT_EQ(length, ABSL_ARRAYSIZE(packet)); // Payload has the random bytes that were generated. Copy them into packet, // above, before checking that the generated packet is correct. @@ -653,7 +630,7 @@ TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) { quiche::test::CompareCharArraysWithHexError( "constructed packet", data.data(), data.length(), - reinterpret_cast<char*>(packet), QUICHE_ARRAYSIZE(packet)); + reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet)); } TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) { @@ -711,13 +688,13 @@ TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) { // clang-format on unsigned char* p = packet; - size_t packet_size = QUICHE_ARRAYSIZE(packet); + size_t packet_size = ABSL_ARRAYSIZE(packet); if (creator_.version().HasIetfQuicFrames()) { p = packet99; - packet_size = QUICHE_ARRAYSIZE(packet99); + packet_size = ABSL_ARRAYSIZE(packet99); } else if (creator_.version().HasIetfInvariantHeader()) { p = packet46; - packet_size = QUICHE_ARRAYSIZE(packet46); + packet_size = ABSL_ARRAYSIZE(packet46); } std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]); @@ -772,15 +749,15 @@ TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponseUnpadded) { QuicCircularDeque<QuicPathFrameBuffer> payloads; payloads.push_back(payload0); size_t length = creator_.BuildPathResponsePacket( - header, buffer.get(), QUICHE_ARRAYSIZE(packet), payloads, + header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads, /*is_padded=*/false, ENCRYPTION_INITIAL); - EXPECT_EQ(length, QUICHE_ARRAYSIZE(packet)); + EXPECT_EQ(length, ABSL_ARRAYSIZE(packet)); QuicPacket data(creator_.transport_version(), buffer.release(), length, true, header); quiche::test::CompareCharArraysWithHexError( "constructed packet", data.data(), data.length(), - reinterpret_cast<char*>(packet), QUICHE_ARRAYSIZE(packet)); + reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet)); } TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) { @@ -819,15 +796,15 @@ TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) { QuicCircularDeque<QuicPathFrameBuffer> payloads; payloads.push_back(payload0); size_t length = creator_.BuildPathResponsePacket( - header, buffer.get(), QUICHE_ARRAYSIZE(packet), payloads, + header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads, /*is_padded=*/true, ENCRYPTION_INITIAL); - EXPECT_EQ(length, QUICHE_ARRAYSIZE(packet)); + EXPECT_EQ(length, ABSL_ARRAYSIZE(packet)); QuicPacket data(creator_.transport_version(), buffer.release(), length, true, header); quiche::test::CompareCharArraysWithHexError( "constructed packet", data.data(), data.length(), - reinterpret_cast<char*>(packet), QUICHE_ARRAYSIZE(packet)); + reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet)); } TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) { @@ -871,15 +848,15 @@ TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) { payloads.push_back(payload1); payloads.push_back(payload2); size_t length = creator_.BuildPathResponsePacket( - header, buffer.get(), QUICHE_ARRAYSIZE(packet), payloads, + header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads, /*is_padded=*/false, ENCRYPTION_INITIAL); - EXPECT_EQ(length, QUICHE_ARRAYSIZE(packet)); + EXPECT_EQ(length, ABSL_ARRAYSIZE(packet)); QuicPacket data(creator_.transport_version(), buffer.release(), length, true, header); quiche::test::CompareCharArraysWithHexError( "constructed packet", data.data(), data.length(), - reinterpret_cast<char*>(packet), QUICHE_ARRAYSIZE(packet)); + reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet)); } TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) { @@ -925,15 +902,15 @@ TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) { payloads.push_back(payload1); payloads.push_back(payload2); size_t length = creator_.BuildPathResponsePacket( - header, buffer.get(), QUICHE_ARRAYSIZE(packet), payloads, + header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads, /*is_padded=*/true, ENCRYPTION_INITIAL); - EXPECT_EQ(length, QUICHE_ARRAYSIZE(packet)); + EXPECT_EQ(length, ABSL_ARRAYSIZE(packet)); QuicPacket data(creator_.transport_version(), buffer.release(), length, true, header); quiche::test::CompareCharArraysWithHexError( "constructed packet", data.data(), data.length(), - reinterpret_cast<char*>(packet), QUICHE_ARRAYSIZE(packet)); + reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet)); } TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) { @@ -1296,7 +1273,7 @@ TEST_P(QuicPacketCreatorTest, SerializeFrame) { if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { QuicStreamFrame stream_frame( QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), - /*fin=*/false, 0u, quiche::QuicheStringPiece()); + /*fin=*/false, 0u, absl::string_view()); frames_.push_back(QuicFrame(stream_frame)); } else { producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); @@ -1333,7 +1310,7 @@ TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) { if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { QuicStreamFrame stream_frame( QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), - /*fin=*/false, 0u, quiche::QuicheStringPiece()); + /*fin=*/false, 0u, absl::string_view()); frames_.push_back(QuicFrame(stream_frame)); } else { producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); @@ -1556,7 +1533,7 @@ TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) { creator_.set_encryption_level(ENCRYPTION_INITIAL); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), - /*fin=*/false, 0u, quiche::QuicheStringPiece()); + /*fin=*/false, 0u, absl::string_view()); EXPECT_QUIC_BUG( creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), "Cannot send stream data with level: ENCRYPTION_INITIAL"); @@ -1571,7 +1548,7 @@ TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) { creator_.set_encryption_level(ENCRYPTION_HANDSHAKE); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), - /*fin=*/false, 0u, quiche::QuicheStringPiece()); + /*fin=*/false, 0u, absl::string_view()); EXPECT_QUIC_BUG( creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), "Cannot send stream data with level: ENCRYPTION_HANDSHAKE"); @@ -1598,9 +1575,8 @@ TEST_P(QuicPacketCreatorTest, ChloTooLarge) { message_data = framer.ConstructHandshakeMessage(message); struct iovec iov; - MakeIOVector( - quiche::QuicheStringPiece(message_data->data(), message_data->length()), - &iov); + MakeIOVector(absl::string_view(message_data->data(), message_data->length()), + &iov); QuicFrame frame; EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _)); EXPECT_QUIC_BUG( @@ -1677,7 +1653,7 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) { .WillRepeatedly( Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); // Send stream frame of size kStreamFramePayloadSize. - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize), &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, NOT_RETRANSMISSION, &frame); @@ -1685,8 +1661,7 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) { // 1 byte padding is sent. EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes()); // Send stream frame of size kStreamFramePayloadSize + 1. - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize + 1), - &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize + 1), &iov_); creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, 0u, kStreamFramePayloadSize, false, false, NOT_RETRANSMISSION, &frame); @@ -1798,7 +1773,7 @@ TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) { creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize); } std::string message_data(kDefaultMaxPacketSize, 'a'); - quiche::QuicheStringPiece message_buffer(message_data); + absl::string_view message_buffer(message_data); QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); // Test all possible encryption levels of message frames. for (EncryptionLevel level : @@ -1809,10 +1784,9 @@ TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) { message_size <= creator_.GetCurrentLargestMessagePayload(); ++message_size) { QuicMessageFrame* frame = new QuicMessageFrame( - 0, MakeSpan( - &allocator_, - quiche::QuicheStringPiece(message_buffer.data(), message_size), - &storage)); + 0, MakeSpan(&allocator_, + absl::string_view(message_buffer.data(), message_size), + &storage)); EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION)); EXPECT_TRUE(creator_.HasPendingFrames()); @@ -1938,7 +1912,7 @@ TEST_P(QuicPacketCreatorTest, PacketTransmissionType) { client_framer_.transport_version(), Perspective::IS_CLIENT); QuicFrame stream_frame(QuicStreamFrame(stream_id, /*fin=*/false, 0u, - quiche::QuicheStringPiece())); + absl::string_view())); ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type)); QuicFrame padding_frame{QuicPaddingFrame()}; @@ -1979,7 +1953,7 @@ TEST_P(QuicPacketCreatorTest, RetryToken) { if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { QuicStreamFrame stream_frame( QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), - /*fin=*/false, 0u, quiche::QuicheStringPiece()); + /*fin=*/false, 0u, absl::string_view()); frames_.push_back(QuicFrame(stream_frame)); } else { producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); @@ -2146,8 +2120,8 @@ TEST_P(QuicPacketCreatorTest, SerializeCoalescedPacket) { QuicAckFrame ack_frame(InitAckFrame(1)); frames_.push_back(QuicFrame(&ack_frame)); if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) { - frames_.push_back(QuicFrame( - QuicStreamFrame(1, false, 0u, quiche::QuicheStringPiece()))); + frames_.push_back( + QuicFrame(QuicStreamFrame(1, false, 0u, absl::string_view()))); } SerializedPacket serialized = SerializeAllFrames(frames_); EXPECT_EQ(level, serialized.encryption_level); @@ -2420,7 +2394,7 @@ class MultiplePacketsTestPacketCreator : public QuicPacketCreator { } size_t ConsumeCryptoData(EncryptionLevel level, - quiche::QuicheStringPiece data, + absl::string_view data, QuicStreamOffset offset) { producer_->SaveCryptoData(level, offset, data); if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, @@ -3576,7 +3550,7 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, ConnectionCloseFrameLargerThanPacketSize) { delegate_.SetCanWriteAnything(); char buf[2000] = {}; - quiche::QuicheStringPiece error_details(buf, 2000); + absl::string_view error_details(buf, 2000); const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR; QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame( @@ -3616,7 +3590,7 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillOnce( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize), &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); creator_.Flush(); @@ -3659,7 +3633,7 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize), &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); creator_.Flush(); @@ -3714,11 +3688,11 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, EXPECT_CALL(delegate_, OnSerializedPacket(_)) .WillRepeatedly( Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize), &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); QuicConsumedData consumed = creator_.ConsumeData( kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - MakeIOVector(quiche::QuicheStringPiece(buf, kStreamFramePayloadSize), &iov_); + MakeIOVector(absl::string_view(buf, kStreamFramePayloadSize), &iov_); consumed = creator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc index 33340423eaf..2902f998b6e 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/core/quic_packet_reader.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_process_packet_interface.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" @@ -13,7 +14,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h index 86eaa0ee9ad..6edf1f1dd29 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_reader.h @@ -7,11 +7,11 @@ #ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_ #define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_ +#include "absl/base/optimization.h" #include "net/third_party/quiche/src/quic/core/quic_clock.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_process_packet_interface.h" #include "net/third_party/quiche/src/quic/core/quic_udp_socket.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" @@ -51,10 +51,10 @@ class QUIC_EXPORT_PRIVATE QuicPacketReader { bool prefer_v6_ip); struct QUIC_EXPORT_PRIVATE ReadBuffer { - QUIC_CACHELINE_ALIGNED char + ABSL_CACHELINE_ALIGNED char control_buffer[kDefaultUdpPacketControlBufferSize]; // For ancillary // data. - QUIC_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize]; + ABSL_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize]; }; QuicUdpSocketApi socket_api_; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc index f54cf00d081..3d6228e6847 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packets.cc @@ -6,6 +6,8 @@ #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -14,7 +16,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -185,7 +186,7 @@ QuicPacketHeader::QuicPacketHeader() long_packet_type(INITIAL), possible_stateless_reset_token(0), retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0), - retry_token(quiche::QuicheStringPiece()), + retry_token(absl::string_view()), length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0), remaining_packet_length(0) {} @@ -263,8 +264,8 @@ std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) { } if (header.nonce != nullptr) { os << ", diversification_nonce: " - << quiche::QuicheTextUtils::HexEncode(quiche::QuicheStringPiece( - header.nonce->data(), header.nonce->size())); + << absl::BytesToHexString( + absl::string_view(header.nonce->data(), header.nonce->size())); } os << ", packet_number: " << header.packet_number << " }\n"; return os; @@ -276,7 +277,7 @@ QuicData::QuicData(const char* buffer, size_t length) QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer) : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {} -QuicData::QuicData(quiche::QuicheStringPiece packet_data) +QuicData::QuicData(absl::string_view packet_data) : buffer_(packet_data.data()), length_(packet_data.length()), owns_buffer_(false) {} @@ -335,7 +336,7 @@ QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, bool owns_buffer) : QuicData(buffer, length, owns_buffer) {} -QuicEncryptedPacket::QuicEncryptedPacket(quiche::QuicheStringPiece data) +QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data) : QuicData(data) {} std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const { @@ -426,9 +427,9 @@ std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) { return os; } -quiche::QuicheStringPiece QuicPacket::AssociatedData( +absl::string_view QuicPacket::AssociatedData( QuicTransportVersion version) const { - return quiche::QuicheStringPiece( + return absl::string_view( data(), GetStartOfEncryptedData(version, destination_connection_id_length_, source_connection_id_length_, includes_version_, @@ -437,14 +438,13 @@ quiche::QuicheStringPiece QuicPacket::AssociatedData( retry_token_length_, length_length_)); } -quiche::QuicheStringPiece QuicPacket::Plaintext( - QuicTransportVersion version) const { +absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const { const size_t start_of_encrypted_data = GetStartOfEncryptedData( version, destination_connection_id_length_, source_connection_id_length_, includes_version_, includes_diversification_nonce_, packet_number_length_, retry_token_length_length_, retry_token_length_, length_length_); - return quiche::QuicheStringPiece(data() + start_of_encrypted_data, - length() - start_of_encrypted_data); + return absl::string_view(data() + start_of_encrypted_data, + length() - start_of_encrypted_data); } SerializedPacket::SerializedPacket(QuicPacketNumber packet_number, diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packets.h b/chromium/net/third_party/quiche/src/quic/core/quic_packets.h index e9c811c6737..8cf7305a84f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_packets.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_packets.h @@ -14,6 +14,7 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h" #include "net/third_party/quiche/src/quic/core/quic_bandwidth.h" @@ -25,7 +26,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -160,7 +160,7 @@ struct QUIC_EXPORT_PRIVATE QuicPacketHeader { // carried only by v99 IETF Initial packets. QuicVariableLengthIntegerLength retry_token_length_length; // Retry token, carried only by v99 IETF Initial packets. - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; // Length of the length variable length integer field, // carried only by v99 IETF Initial, 0-RTT and Handshake packets. QuicVariableLengthIntegerLength length_length; @@ -211,15 +211,15 @@ class QUIC_EXPORT_PRIVATE QuicData { // Creates a QuicData from a buffer and length, // optionally taking ownership of the buffer. QuicData(const char* buffer, size_t length, bool owns_buffer); - // Creates a QuicData from a quiche::QuicheStringPiece. Does not own the + // Creates a QuicData from a absl::string_view. Does not own the // buffer. - QuicData(quiche::QuicheStringPiece data); + QuicData(absl::string_view data); QuicData(const QuicData&) = delete; QuicData& operator=(const QuicData&) = delete; virtual ~QuicData(); - quiche::QuicheStringPiece AsStringPiece() const { - return quiche::QuicheStringPiece(data(), length()); + absl::string_view AsStringPiece() const { + return absl::string_view(data(), length()); } const char* data() const { return buffer_; } @@ -252,8 +252,8 @@ class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { QuicPacket(const QuicPacket&) = delete; QuicPacket& operator=(const QuicPacket&) = delete; - quiche::QuicheStringPiece AssociatedData(QuicTransportVersion version) const; - quiche::QuicheStringPiece Plaintext(QuicTransportVersion version) const; + absl::string_view AssociatedData(QuicTransportVersion version) const; + absl::string_view Plaintext(QuicTransportVersion version) const; char* mutable_data() { return buffer_; } @@ -277,9 +277,9 @@ class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData { // Creates a QuicEncryptedPacket from a buffer and length, // optionally taking ownership of the buffer. QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer); - // Creates a QuicEncryptedPacket from a quiche::QuicheStringPiece. + // Creates a QuicEncryptedPacket from a absl::string_view. // Does not own the buffer. - QuicEncryptedPacket(quiche::QuicheStringPiece data); + QuicEncryptedPacket(absl::string_view data); QuicEncryptedPacket(const QuicEncryptedPacket&) = delete; QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc new file mode 100644 index 00000000000..5d5e7206d54 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.cc @@ -0,0 +1,128 @@ +// Copyright (c) 2020 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 "net/third_party/quiche/src/quic/core/quic_path_validator.h" + +#include "net/third_party/quiche/src/quic/core/quic_constants.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" + +namespace quic { + +class RetryAlarmDelegate : public QuicAlarm::Delegate { + public: + explicit RetryAlarmDelegate(QuicPathValidator* path_validator) + : path_validator_(path_validator) {} + RetryAlarmDelegate(const RetryAlarmDelegate&) = delete; + RetryAlarmDelegate& operator=(const RetryAlarmDelegate&) = delete; + + void OnAlarm() override { path_validator_->OnRetryTimeout(); } + + private: + QuicPathValidator* path_validator_; +}; + +std::ostream& operator<<(std::ostream& os, + const QuicPathValidationContext& context) { + return os << " from " << context.self_address_ << " to " + << context.peer_address_; +} + +QuicPathValidator::QuicPathValidator(QuicAlarmFactory* alarm_factory, + QuicOneBlockArena<1024>* arena, + SendDelegate* send_delegate, + QuicRandom* random) + : send_delegate_(send_delegate), + random_(random), + retry_timer_( + alarm_factory->CreateAlarm(arena->New<RetryAlarmDelegate>(this), + arena)), + retry_count_(0u) {} + +void QuicPathValidator::OnPathResponse(const QuicPathFrameBuffer& probing_data, + QuicSocketAddress self_address) { + if (!HasPendingPathValidation()) { + return; + } + + QUIC_DVLOG(1) << "Match PATH_RESPONSE received on " << self_address; + QUIC_BUG_IF(!path_context_->self_address().IsInitialized()) + << "Self address should have been known by now"; + if (self_address != path_context_->self_address()) { + QUIC_DVLOG(1) << "Expect the response to be received on " + << path_context_->self_address(); + return; + } + // This iterates at most 3 times. + if (std::find(probing_data_.begin(), probing_data_.end(), probing_data) != + probing_data_.end()) { + result_delegate_->OnPathValidationSuccess(std::move(path_context_)); + ResetPathValidation(); + } +} + +void QuicPathValidator::StartValidingPath( + std::unique_ptr<QuicPathValidationContext> context, + std::unique_ptr<ResultDelegate> result_delegate) { + CancelPathValidation(); + DCHECK_NE(nullptr, context); + QUIC_DLOG(INFO) << "Start validating path " << *context + << " via writer: " << context->WriterToUse(); + + path_context_ = std::move(context); + result_delegate_ = std::move(result_delegate); + SendPathChallengeAndSetAlarm(); +} + +void QuicPathValidator::ResetPathValidation() { + path_context_ = nullptr; + result_delegate_ = nullptr; + retry_timer_->Cancel(); + retry_count_ = 0; +} + +void QuicPathValidator::CancelPathValidation() { + if (path_context_ == nullptr) { + return; + } + QUIC_DVLOG(1) << "Cancel validation on path" << *path_context_; + ResetPathValidation(); +} + +bool QuicPathValidator::HasPendingPathValidation() const { + return path_context_ != nullptr; +} + +const QuicPathFrameBuffer& QuicPathValidator::GeneratePathChallengePayload() { + probing_data_.push_back(QuicPathFrameBuffer()); + random_->RandBytes(probing_data_.back().data(), sizeof(QuicPathFrameBuffer)); + return probing_data_.back(); +} + +void QuicPathValidator::OnRetryTimeout() { + ++retry_count_; + if (retry_count_ > kMaxRetryTimes) { + result_delegate_->OnPathValidationFailure(std::move(path_context_)); + CancelPathValidation(); + return; + } + QUIC_DVLOG(1) << "Send another PATH_CHALLENGE on path " << *path_context_; + SendPathChallengeAndSetAlarm(); +} + +void QuicPathValidator::SendPathChallengeAndSetAlarm() { + bool should_continue = send_delegate_->SendPathChallenge( + GeneratePathChallengePayload(), path_context_->self_address(), + path_context_->peer_address(), path_context_->WriterToUse()); + + if (!should_continue) { + // The delegate doesn't want to continue the path validation. + CancelPathValidation(); + return; + } + retry_timer_->Set(send_delegate_->GetRetryTimeout( + path_context_->peer_address(), path_context_->WriterToUse())); +} + +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h new file mode 100644 index 00000000000..8cfa81d733a --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator.h @@ -0,0 +1,135 @@ +// Copyright (c) 2020 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_QUIC_PATH_VALIDATOR_H_ +#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_ + +#include <ostream> + +#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" +#include "net/third_party/quiche/src/quic/core/quic_alarm.h" +#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" +#include "net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h" +#include "net/third_party/quiche/src/quic/core/quic_clock.h" +#include "net/third_party/quiche/src/quic/core/quic_one_block_arena.h" +#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" +#include "net/quic/platform/impl/quic_export_impl.h" + +namespace quic { + +namespace test { +class QuicPathValidatorPeer; +} + +class QuicConnection; + +// Interface to provide the information of the path to be validated. +class QUIC_EXPORT_PRIVATE QuicPathValidationContext { + public: + QuicPathValidationContext(const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address) + : self_address_(self_address), peer_address_(peer_address) {} + + virtual ~QuicPathValidationContext() = default; + + virtual QuicPacketWriter* WriterToUse() = 0; + + const QuicSocketAddress& self_address() const { return self_address_; } + const QuicSocketAddress& peer_address() const { return peer_address_; } + + private: + QUIC_EXPORT_PRIVATE friend std::ostream& operator<<( + std::ostream& os, + const QuicPathValidationContext& context); + + QuicSocketAddress self_address_; + QuicSocketAddress peer_address_; +}; + +// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before +// declaring a path validation failure. +class QUIC_EXPORT_PRIVATE QuicPathValidator { + public: + static const uint16_t kMaxRetryTimes = 2; + + // Used to write PATH_CHALLENGE on the path to be validated and to get retry + // timeout. + class QUIC_EXPORT_PRIVATE SendDelegate { + public: + virtual ~SendDelegate() = default; + + // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given + // path information. Return false if the delegate doesn't want to continue + // the validation. + virtual bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer, + const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + QuicPacketWriter* writer) = 0; + // Return the time to retry sending PATH_CHALLENGE again based on given peer + // address and writer. + virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address, + QuicPacketWriter* writer) const = 0; + }; + + // Handles the validation result. + class QUIC_EXPORT_PRIVATE ResultDelegate { + public: + virtual ~ResultDelegate() = default; + + virtual void OnPathValidationSuccess( + std::unique_ptr<QuicPathValidationContext> context) = 0; + + virtual void OnPathValidationFailure( + std::unique_ptr<QuicPathValidationContext> context) = 0; + }; + + QuicPathValidator(QuicAlarmFactory* alarm_factory, + QuicConnectionArena* arena, + SendDelegate* delegate, + QuicRandom* random); + + // Send PATH_CHALLENGE and start the retry timer. + void StartValidingPath(std::unique_ptr<QuicPathValidationContext> context, + std::unique_ptr<ResultDelegate> result_delegate); + + // Called when a PATH_RESPONSE frame has been received. Matches the received + // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE + // frames and the self address on which it was sent. + void OnPathResponse(const QuicPathFrameBuffer& probing_data, + QuicSocketAddress self_address); + + // Cancel the retry timer and reset the path and result delegate. + void CancelPathValidation(); + + bool HasPendingPathValidation() const; + + // Send another PATH_CHALLENGE on the same path. After retrying + // |kMaxRetryTimes| times, fail the current path validation. + void OnRetryTimeout(); + + private: + friend class test::QuicPathValidatorPeer; + + // Return the payload to be used in the next PATH_CHALLENGE frame. + const QuicPathFrameBuffer& GeneratePathChallengePayload(); + + void SendPathChallengeAndSetAlarm(); + + void ResetPathValidation(); + + // Has at most 3 entries due to validation timeout. + QuicInlinedVector<QuicPathFrameBuffer, 3> probing_data_; + SendDelegate* send_delegate_; + QuicRandom* random_; + std::unique_ptr<QuicPathValidationContext> path_context_; + std::unique_ptr<ResultDelegate> result_delegate_; + QuicArenaScopedPtr<QuicAlarm> retry_timer_; + size_t retry_count_; +}; + +} // namespace quic + +#endif // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_ diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc new file mode 100644 index 00000000000..656292eb149 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/quic_path_validator_test.cc @@ -0,0 +1,242 @@ +// Copyright (c) 2020 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 "net/third_party/quiche/src/quic/core/quic_path_validator.h" + +#include <memory> + +#include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h" +#include "net/third_party/quiche/src/quic/core/quic_constants.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" +#include "net/third_party/quiche/src/quic/test_tools/mock_random.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h" + +using testing::_; +using testing::Invoke; +using testing::Return; + +namespace quic { +namespace test { + +class MockSendDelegate : public QuicPathValidator::SendDelegate { + public: + // Send a PATH_CHALLENGE frame using given path information and populate + // |data_buffer| with the frame payload. Return true if the validator should + // move forward in validation, i.e. arm the retry timer. + MOCK_METHOD(bool, + SendPathChallenge, + (const QuicPathFrameBuffer&, + const QuicSocketAddress&, + const QuicSocketAddress&, + QuicPacketWriter*), + (override)); + + MOCK_METHOD(QuicTime, + GetRetryTimeout, + (const QuicSocketAddress&, QuicPacketWriter*), + (const override)); +}; + +class QuicPathValidatorTest : public QuicTest { + public: + QuicPathValidatorTest() + : path_validator_(&alarm_factory_, &arena_, &send_delegate_, &random_), + context_(new MockQuicPathValidationContext(self_address_, + peer_address_, + &writer_)), + result_delegate_(new MockQuicPathValidationResultDelegate()) { + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); + ON_CALL(send_delegate_, GetRetryTimeout(_, _)) + .WillByDefault( + Return(clock_.ApproximateNow() + + 3 * QuicTime::Delta::FromMilliseconds(kInitialRttMs))); + } + + protected: + quic::test::MockAlarmFactory alarm_factory_; + MockSendDelegate send_delegate_; + MockRandom random_; + MockClock clock_; + QuicConnectionArena arena_; + QuicPathValidator path_validator_; + QuicSocketAddress self_address_{QuicIpAddress::Any4(), 443}; + QuicSocketAddress peer_address_{QuicIpAddress::Loopback4(), 443}; + MockPacketWriter writer_; + MockQuicPathValidationContext* context_; + MockQuicPathValidationResultDelegate* result_delegate_; +}; + +TEST_F(QuicPathValidatorTest, PathValidationSuccessOnFirstRound) { + QuicPathFrameBuffer challenge_data; + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + memcpy(challenge_data.data(), payload.data(), payload.size()); + return true; + })); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + EXPECT_TRUE(path_validator_.HasPendingPathValidation()); + EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_)) + .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) { + EXPECT_EQ(context.get(), context_); + })); + path_validator_.OnPathResponse(challenge_data, self_address_); + EXPECT_FALSE(path_validator_.HasPendingPathValidation()); +} + +TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) { + QuicPathFrameBuffer challenge_data; + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .WillOnce(Invoke([&](const QuicPathFrameBuffer payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + memcpy(challenge_data.data(), payload.data(), payload.size()); + return true; + })); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + + // Reception of a PATH_RESPONSE on a different self address should be ignored. + const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321); + EXPECT_NE(kAlternativeSelfAddress, self_address_); + path_validator_.OnPathResponse(challenge_data, kAlternativeSelfAddress); + + EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_)) + .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) { + EXPECT_EQ(context->self_address(), self_address_); + })); + path_validator_.OnPathResponse(challenge_data, self_address_); +} + +TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) { + QuicPathFrameBuffer challenge_data; + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + // Store up the 1st PATH_CHALLANGE payload. + memcpy(challenge_data.data(), payload.data(), payload.size()); + return true; + })) + .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + EXPECT_NE(payload, challenge_data); + return true; + })); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)) + .Times(2u); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs)); + random_.ChangeValue(); + alarm_factory_.FireAlarm( + QuicPathValidatorPeer::retry_timer(&path_validator_)); + + EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_)); + // Respond to the 1st PATH_CHALLENGE should complete the validation. + path_validator_.OnPathResponse(challenge_data, self_address_); + EXPECT_FALSE(path_validator_.HasPendingPathValidation()); +} + +TEST_F(QuicPathValidatorTest, RespondToRetryChallenge) { + QuicPathFrameBuffer challenge_data; + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + memcpy(challenge_data.data(), payload.data(), payload.size()); + return true; + })) + .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload, + const QuicSocketAddress&, const QuicSocketAddress&, + QuicPacketWriter*) { + EXPECT_NE(challenge_data, payload); + memcpy(challenge_data.data(), payload.data(), payload.size()); + return true; + })); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)) + .Times(2u); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs)); + random_.ChangeValue(); + alarm_factory_.FireAlarm( + QuicPathValidatorPeer::retry_timer(&path_validator_)); + + // Respond to the 2nd PATH_CHALLENGE should complete the validation. + EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_)); + path_validator_.OnPathResponse(challenge_data, self_address_); + EXPECT_FALSE(path_validator_.HasPendingPathValidation()); +} + +TEST_F(QuicPathValidatorTest, ValidationTimeOut) { + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .Times(3u) + .WillRepeatedly(Return(true)); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)) + .Times(3u); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + + QuicPathFrameBuffer challenge_data; + memset(challenge_data.data(), 'a', challenge_data.size()); + // Reception of a PATH_RESPONSE with different payload should be ignored. + path_validator_.OnPathResponse(challenge_data, self_address_); + + // Retry 3 times. The 3rd time should fail the validation. + EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_)) + .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) { + EXPECT_EQ(context_, context.get()); + })); + for (size_t i = 0; i <= QuicPathValidator::kMaxRetryTimes; ++i) { + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs)); + alarm_factory_.FireAlarm( + QuicPathValidatorPeer::retry_timer(&path_validator_)); + } +} + +TEST_F(QuicPathValidatorTest, SendPathChallengeError) { + EXPECT_CALL(send_delegate_, + SendPathChallenge(_, self_address_, peer_address_, &writer_)) + .WillOnce(Invoke([&](const QuicPathFrameBuffer&, const QuicSocketAddress&, + const QuicSocketAddress&, QuicPacketWriter*) { + // Abandon this validation in the call stack shouldn't cause crash and + // should cancel the alarm. + path_validator_.CancelPathValidation(); + return false; + })); + EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_)) + .Times(0u); + path_validator_.StartValidingPath( + std::unique_ptr<QuicPathValidationContext>(context_), + std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_)); + EXPECT_FALSE(path_validator_.HasPendingPathValidation()); + EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet()); +} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h new file mode 100644 index 00000000000..b9d0a2d68a3 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/quic_protocol_flags_list.h @@ -0,0 +1,246 @@ +// Copyright (c) 2020 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. + +// NOLINT(build/header_guard) +// This file intentionally does not have header guards, it's intended to be +// included multiple times, each time with a different definition of +// QUIC_PROTOCOL_FLAG. + +#if defined(QUIC_PROTOCOL_FLAG) + +QUIC_PROTOCOL_FLAG( + bool, + quic_allow_chlo_buffering, + true, + "If true, allows packets to be buffered in anticipation of a " + "future CHLO, and allow CHLO packets to be buffered until next " + "iteration of the event loop.") + +QUIC_PROTOCOL_FLAG(bool, + quic_disable_pacing_for_perf_tests, + false, + "If true, disable pacing in QUIC") + +QUIC_PROTOCOL_FLAG(bool, + quic_enforce_single_packet_chlo, + true, + "If true, enforce that QUIC CHLOs fit in one packet") + +// Currently, this number is quite conservative. At a hypothetical 1000 qps, +// this means that the longest time-wait list we should see is: +// 200 seconds * 1000 qps = 200000. +// Of course, there are usually many queries per QUIC connection, so we allow a +// factor of 3 leeway. +QUIC_PROTOCOL_FLAG(int64_t, + quic_time_wait_list_max_connections, + 600000, + "Maximum number of connections on the time-wait list. " + "A negative value implies no configured limit.") + +QUIC_PROTOCOL_FLAG(int64_t, + quic_time_wait_list_seconds, + 200, + "Time period for which a given connection_id should live in " + "the time-wait state.") + +QUIC_PROTOCOL_FLAG(double, + quic_bbr_cwnd_gain, + 2.0f, + "Congestion window gain for QUIC BBR during PROBE_BW phase.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_buffered_data_threshold, + 8 * 1024, + "If buffered data in QUIC stream is less than this " + "threshold, buffers all provided data or asks upper layer for more data") + +QUIC_PROTOCOL_FLAG( + uint64_t, + quic_send_buffer_max_data_slice_size, + 4 * 1024, + "Max size of data slice in bytes for QUIC stream send buffer.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_lumpy_pacing_size, + 2, + "Number of packets that the pacing sender allows in bursts during " + "pacing. This flag is ignored if a flow's estimated bandwidth is " + "lower than 1200 kbps.") + +QUIC_PROTOCOL_FLAG( + double, + quic_lumpy_pacing_cwnd_fraction, + 0.25f, + "Congestion window fraction that the pacing sender allows in bursts " + "during pacing.") + +QUIC_PROTOCOL_FLAG(int32_t, + quic_max_pace_time_into_future_ms, + 10, + "Max time that QUIC can pace packets into the future in ms.") + +QUIC_PROTOCOL_FLAG( + double, + quic_pace_time_into_future_srtt_fraction, + 0.125f, // One-eighth smoothed RTT + "Smoothed RTT fraction that a connection can pace packets into the future.") + +QUIC_PROTOCOL_FLAG(bool, + quic_export_write_path_stats_at_server, + false, + "If true, export detailed write path statistics at server.") + +QUIC_PROTOCOL_FLAG(bool, + quic_disable_version_negotiation_grease_randomness, + false, + "If true, use predictable version negotiation versions.") + +QUIC_PROTOCOL_FLAG(bool, + quic_enable_http3_grease_randomness, + true, + "If true, use random greased settings and frames.") + +QUIC_PROTOCOL_FLAG(int64_t, + quic_max_tracked_packet_count, + 10000, + "Maximum number of tracked packets.") + +QUIC_PROTOCOL_FLAG( + bool, + quic_client_convert_http_header_name_to_lowercase, + true, + "If true, HTTP request header names sent from QuicSpdyClientBase(and " + "descendents) will be automatically converted to lower case.") + +QUIC_PROTOCOL_FLAG( + bool, + quic_enable_http3_server_push, + false, + "If true, server push will be allowed in QUIC versions that use HTTP/3.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_probe_bw_base_duration_ms, + 2000, + "The default minimum duration for BBRv2-native probes, in milliseconds.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_probe_bw_max_rand_duration_ms, + 1000, + "The default upper bound of the random amount of BBRv2-native " + "probes, in milliseconds.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_probe_rtt_period_ms, + 10000, + "The default period for entering PROBE_RTT, in milliseconds.") + +QUIC_PROTOCOL_FLAG( + double, + quic_bbr2_default_loss_threshold, + 0.02, + "The default loss threshold for QUIC BBRv2, should be a value " + "between 0 and 1.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_startup_full_loss_count, + 8, + "The default minimum number of loss marking events to exit STARTUP.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_probe_bw_full_loss_count, + 2, + "The default minimum number of loss marking events to exit PROBE_UP phase.") + +QUIC_PROTOCOL_FLAG( + double, + quic_bbr2_default_inflight_hi_headroom, + 0.15, + "The default fraction of unutilized headroom to try to leave in path " + "upon high loss.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_bbr2_default_initial_ack_height_filter_window, + 10, + "The default initial value of the max ack height filter's window length.") + +QUIC_PROTOCOL_FLAG( + double, + quic_ack_aggregation_bandwidth_threshold, + 1.0, + "If the bandwidth during ack aggregation is smaller than (estimated " + "bandwidth * this flag), consider the current aggregation completed " + "and starts a new one.") + +// TODO(b/153892665): Change the default value of +// quic_anti_amplification_factor back to 3 when cert compression is +// supported. +QUIC_PROTOCOL_FLAG( + int32_t, + quic_anti_amplification_factor, + 5, + 3, + "Anti-amplification factor. Before address validation, server will " + "send no more than factor times bytes received.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_max_buffered_crypto_bytes, + 16 * 1024, // 16 KB + "The maximum amount of CRYPTO frame data that can be buffered.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_max_aggressive_retransmittable_on_wire_ping_count, + 5, + "Maximum number of consecutive pings that can be sent with the " + "aggressive initial retransmittable on the wire timeout if there is " + "no new stream data received. After this limit, the timeout will be " + "doubled each ping until it exceeds the default ping timeout.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_max_retransmittable_on_wire_ping_count, + 1000, + "Maximum number of pings that can be sent with the retransmittable " + "on the wire timeout, over the lifetime of a connection. After this " + "limit, the timeout will be the default ping timeout.") + +QUIC_PROTOCOL_FLAG(int32_t, + quic_max_congestion_window, + 2000, + "The maximum congestion window in packets.") + +QUIC_PROTOCOL_FLAG( + int32_t, + quic_max_streams_window_divisor, + 2, + "The divisor that controls how often MAX_STREAMS frame is sent.") + +QUIC_PROTOCOL_FLAG( + uint64_t, + quic_key_update_confidentiality_limit, + 0, + "If non-zero and key update is allowed, the maximum number of " + "packets sent for each key phase before initiating a key update.") + +QUIC_PROTOCOL_FLAG(bool, + quic_disable_client_tls_zero_rtt, + false, + "If true, QUIC client with TLS will not try 0-RTT.") + +QUIC_PROTOCOL_FLAG(bool, + quic_disable_server_tls_resumption, + false, + "If true, QUIC server will disable TLS resumption by not " + "issuing or processing session tickets.") + +#endif 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 9a84d975fd5..98f450cbf37 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 @@ -26,8 +26,6 @@ namespace { // against an ack loss const size_t kMaxPacketsAfterNewMissing = 4; -// One quarter RTT delay when doing ack decimation. -const float kAckDecimationDelay = 0.25; // One eighth RTT delay when doing ack decimation. const float kShortAckDecimationDelay = 0.125; } // namespace @@ -266,8 +264,11 @@ void QuicReceivedPacketManager::MaybeUpdateAckTimeout( return; } - MaybeUpdateAckTimeoutTo( - now + GetMaxAckDelay(last_received_packet_number, *rtt_stats)); + QuicTime updated_ack_time = + now + GetMaxAckDelay(last_received_packet_number, *rtt_stats); + if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) { + ack_timeout_ = updated_ack_time; + } } void QuicReceivedPacketManager::ResetAckStates() { @@ -277,12 +278,6 @@ void QuicReceivedPacketManager::ResetAckStates() { last_sent_largest_acked_ = LargestAcked(ack_frame_); } -void QuicReceivedPacketManager::MaybeUpdateAckTimeoutTo(QuicTime time) { - if (!ack_timeout_.IsInitialized() || ack_timeout_ > time) { - ack_timeout_ = time; - } -} - bool QuicReceivedPacketManager::HasMissingPackets() const { if (ack_frame_.packets.Empty()) { return false; 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 4dc25828378..592faa14baa 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 @@ -5,13 +5,18 @@ #include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h" #include <algorithm> +#include <cstddef> #include <string> #include "net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h" #include "net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h" #include "net/third_party/quiche/src/quic/core/quic_connection_stats.h" +#include "net/third_party/quiche/src/quic/core/quic_constants.h" +#include "net/third_party/quiche/src/quic/core/quic_packet_number.h" +#include "net/third_party/quiche/src/quic/core/quic_transmission_info.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" @@ -140,6 +145,16 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { peer_max_ack_delay_ = QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs()); } + if (GetQuicReloadableFlag(quic_can_send_ack_frequency) && + perspective == Perspective::IS_SERVER) { + if (config.HasReceivedMinAckDelayMs()) { + peer_min_ack_delay_ = + QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs()); + } + if (config.HasClientSentConnectionOption(kAFF1, perspective)) { + use_smoothed_rtt_in_ack_delay_ = true; + } + } if (config.HasClientSentConnectionOption(kMAD0, perspective)) { rtt_stats_.set_ignore_max_ack_delay(true); } @@ -462,17 +477,40 @@ void QuicSentPacketManager::MaybeInvokeCongestionEvent( } void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() { - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); - for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - if (it->encryption_level == ENCRYPTION_ZERO_RTT) { - if (it->in_flight) { - // Remove 0-RTT packets and packets of the wrong version from flight, - // because neither can be processed by the peer. - unacked_packets_.RemoveFromInFlight(&*it); + if (unacked_packets_.use_circular_deque()) { + if (unacked_packets_.empty()) { + return; + } + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) { + if (transmission_info->in_flight) { + // Remove 0-RTT packets and packets of the wrong version from flight, + // because neither can be processed by the peer. + unacked_packets_.RemoveFromInFlight(transmission_info); + } + if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) { + MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION); + } } - if (unacked_packets_.HasRetransmittableFrames(*it)) { - MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION); + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin(); + it != unacked_packets_.end(); ++it, ++packet_number) { + if (it->encryption_level == ENCRYPTION_ZERO_RTT) { + if (it->in_flight) { + // Remove 0-RTT packets and packets of the wrong version from + // flight, because neither can be processed by the peer. + unacked_packets_.RemoveFromInFlight(&*it); + } + if (unacked_packets_.HasRetransmittableFrames(*it)) { + MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION); + } } } } @@ -593,6 +631,11 @@ void QuicSentPacketManager::MarkForRetransmission( HandleRetransmission(transmission_type, transmission_info); + // Get the latest transmission_info here as it can be invalidated after + // HandleRetransmission adding new sent packets into unacked_packets_. + transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + // Update packet state according to transmission type. transmission_info->state = QuicUtils::RetransmissionTypeToPacketState(transmission_type); @@ -700,6 +743,32 @@ void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number, info->state = ACKED; } +bool QuicSentPacketManager::CanSendAckFrequency() const { + return !peer_min_ack_delay_.IsInfinite() && handshake_finished_; +} + +QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame() + const { + QuicAckFrequencyFrame frame; + if (!CanSendAckFrequency()) { + QUIC_BUG << "New AckFrequencyFrame is created while it shouldn't."; + return frame; + } + + QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3); + frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck; + auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt() + : rtt_stats_.MinOrInitialRtt(); + frame.max_ack_delay = rtt * kAckDecimationDelay; + frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_); + // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to + // 5 ms on the client side. + frame.max_ack_delay = + std::max(frame.max_ack_delay, + QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs)); + return frame; +} + bool QuicSentPacketManager::OnPacketSent( SerializedPacket* mutable_packet, QuicTime sent_time, @@ -810,19 +879,43 @@ void QuicSentPacketManager::RetransmitCryptoPackets() { DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); ++consecutive_crypto_retransmission_count_; bool packet_retransmitted = false; - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); std::vector<QuicPacketNumber> crypto_retransmissions; - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - // Only retransmit frames which are in flight, and therefore have been sent. - if (!it->in_flight || it->state != OUTSTANDING || - !it->has_crypto_handshake || - !unacked_packets_.HasRetransmittableFrames(*it)) { - continue; + if (unacked_packets_.use_circular_deque()) { + if (!unacked_packets_.empty()) { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + // Only retransmit frames which are in flight, and therefore have been + // sent. + if (!transmission_info->in_flight || + transmission_info->state != OUTSTANDING || + !transmission_info->has_crypto_handshake || + !unacked_packets_.HasRetransmittableFrames(*transmission_info)) { + continue; + } + packet_retransmitted = true; + crypto_retransmissions.push_back(packet_number); + ++pending_timer_transmission_count_; + } + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it, ++packet_number) { + // Only retransmit frames which are in flight, and therefore have been + // sent. + if (!it->in_flight || it->state != OUTSTANDING || + !it->has_crypto_handshake || + !unacked_packets_.HasRetransmittableFrames(*it)) { + continue; + } + packet_retransmitted = true; + crypto_retransmissions.push_back(packet_number); + ++pending_timer_transmission_count_; } - packet_retransmitted = true; - crypto_retransmissions.push_back(packet_number); - ++pending_timer_transmission_count_; } DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; for (QuicPacketNumber retransmission : crypto_retransmissions) { @@ -842,16 +935,38 @@ bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { } bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) { - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - // Only retransmit frames which are in flight, and therefore have been sent. - if (!it->in_flight || it->state != OUTSTANDING || - !unacked_packets_.HasRetransmittableFrames(*it)) { - continue; + if (unacked_packets_.use_circular_deque()) { + if (!unacked_packets_.empty()) { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + // Only retransmit frames which are in flight, and therefore have been + // sent. + if (!transmission_info->in_flight || + transmission_info->state != OUTSTANDING || + !unacked_packets_.HasRetransmittableFrames(*transmission_info)) { + continue; + } + MarkForRetransmission(packet_number, type); + return true; + } + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it, ++packet_number) { + // Only retransmit frames which are in flight, and therefore have been + // sent. + if (!it->in_flight || it->state != OUTSTANDING || + !unacked_packets_.HasRetransmittableFrames(*it)) { + continue; + } + MarkForRetransmission(packet_number, type); + return true; } - MarkForRetransmission(packet_number, type); - return true; } QUIC_DVLOG(1) << "No retransmittable packets, so RetransmitOldestPacket failed."; @@ -863,16 +978,35 @@ void QuicSentPacketManager::RetransmitRtoPackets() { QUIC_BUG_IF(pending_timer_transmission_count_ > 0) << "Retransmissions already queued:" << pending_timer_transmission_count_; // Mark two packets for retransmission. - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); std::vector<QuicPacketNumber> retransmissions; - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - if (it->state == OUTSTANDING && - unacked_packets_.HasRetransmittableFrames(*it) && - pending_timer_transmission_count_ < max_rto_packets_) { - DCHECK(it->in_flight); - retransmissions.push_back(packet_number); - ++pending_timer_transmission_count_; + if (unacked_packets_.use_circular_deque()) { + if (!unacked_packets_.empty()) { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + if (transmission_info->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*transmission_info) && + pending_timer_transmission_count_ < max_rto_packets_) { + DCHECK(transmission_info->in_flight); + retransmissions.push_back(packet_number); + ++pending_timer_transmission_count_; + } + } + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it, ++packet_number) { + if (it->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*it) && + pending_timer_transmission_count_ < max_rto_packets_) { + DCHECK(it->in_flight); + retransmissions.push_back(packet_number); + ++pending_timer_transmission_count_; + } } } if (pending_timer_transmission_count_ > 0) { @@ -908,19 +1042,42 @@ void QuicSentPacketManager::MaybeSendProbePackets() { return; } } - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); std::vector<QuicPacketNumber> probing_packets; - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - if (it->state == OUTSTANDING && - unacked_packets_.HasRetransmittableFrames(*it) && - (!supports_multiple_packet_number_spaces() || - unacked_packets_.GetPacketNumberSpace(it->encryption_level) == - packet_number_space)) { - DCHECK(it->in_flight); - probing_packets.push_back(packet_number); - if (probing_packets.size() == pending_timer_transmission_count_) { - break; + if (unacked_packets_.use_circular_deque()) { + if (!unacked_packets_.empty()) { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + if (transmission_info->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*transmission_info) && + (!supports_multiple_packet_number_spaces() || + unacked_packets_.GetPacketNumberSpace( + transmission_info->encryption_level) == packet_number_space)) { + DCHECK(transmission_info->in_flight); + probing_packets.push_back(packet_number); + if (probing_packets.size() == pending_timer_transmission_count_) { + break; + } + } + } + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it, ++packet_number) { + if (it->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*it) && + (!supports_multiple_packet_number_spaces() || + unacked_packets_.GetPacketNumberSpace(it->encryption_level) == + packet_number_space)) { + DCHECK(it->in_flight); + probing_packets.push_back(packet_number); + if (probing_packets.size() == pending_timer_transmission_count_) { + break; + } } } } @@ -976,21 +1133,48 @@ void QuicSentPacketManager::RetransmitDataOfSpaceIfAny( // No in flight data of space. return; } - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - if (it->state == OUTSTANDING && - unacked_packets_.HasRetransmittableFrames(*it) && - unacked_packets_.GetPacketNumberSpace(it->encryption_level) == space) { - DCHECK(it->in_flight); - if (GetQuicReloadableFlag(quic_fix_pto_pending_timer_count) && - pending_timer_transmission_count_ == 0) { - QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pto_pending_timer_count); - pending_timer_transmission_count_ = 1; - } - MarkForRetransmission(packet_number, PTO_RETRANSMISSION); + if (unacked_packets_.use_circular_deque()) { + if (unacked_packets_.empty()) { return; } + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + QuicPacketNumber largest_sent_packet = + unacked_packets_.largest_sent_packet(); + for (; packet_number <= largest_sent_packet; ++packet_number) { + QuicTransmissionInfo* transmission_info = + unacked_packets_.GetMutableTransmissionInfo(packet_number); + if (transmission_info->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*transmission_info) && + unacked_packets_.GetPacketNumberSpace( + transmission_info->encryption_level) == space) { + DCHECK(transmission_info->in_flight); + if (GetQuicReloadableFlag(quic_fix_pto_pending_timer_count) && + pending_timer_transmission_count_ == 0) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pto_pending_timer_count); + pending_timer_transmission_count_ = 1; + } + MarkForRetransmission(packet_number, PTO_RETRANSMISSION); + return; + } + } + } else { + QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it, ++packet_number) { + if (it->state == OUTSTANDING && + unacked_packets_.HasRetransmittableFrames(*it) && + unacked_packets_.GetPacketNumberSpace(it->encryption_level) == + space) { + DCHECK(it->in_flight); + if (GetQuicReloadableFlag(quic_fix_pto_pending_timer_count) && + pending_timer_transmission_count_ == 0) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pto_pending_timer_count); + pending_timer_transmission_count_ = 1; + } + MarkForRetransmission(packet_number, PTO_RETRANSMISSION); + return; + } + } } } @@ -1535,11 +1719,6 @@ void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) { QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs); QuicTime::Delta max_rtt = QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs); - if (GetQuicReloadableFlag(quic_cap_large_client_initial_rtt)) { - // TODO(fayang): change the value of kMaxInitialRoundTripTimeUs when - // deprecating quic_cap_large_client_initial_rtt. - max_rtt = QuicTime::Delta::FromSeconds(1); - } rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt))); } 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 6e36da9f6b5..df18f2a22c1 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 @@ -22,6 +22,7 @@ #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h" +#include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_transmission_info.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h" @@ -124,6 +125,10 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { virtual void SetFromConfig(const QuicConfig& config); + void ReserveUnackedPacketsInitialCapacity(int initial_capacity) { + unacked_packets_.ReserveInitialCapacity(initial_capacity); + } + void ApplyConnectionOptions(const QuicTagVector& connection_options); // Pass the CachedNetworkParameters to the send algorithm. @@ -197,6 +202,10 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { HasRetransmittableData has_retransmittable_data, bool measure_rtt); + bool CanSendAckFrequency() const; + + QuicAckFrequencyFrame GetUpdatedAckFrequencyFrame() const; + // Called when the retransmission timer expires and returns the retransmission // mode. RetransmissionTimeoutMode OnRetransmissionTimeout(); @@ -442,6 +451,11 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); } + // Gets the earliest in flight packet sent time to calculate PTO. Also + // updates |packet_number_space| if a PTO timer should be armed. + QuicTime GetEarliestPacketSentTimeForPto( + PacketNumberSpace* packet_number_space) const; + bool give_sent_packet_to_debug_visitor_after_sent() const { return give_sent_packet_to_debug_visitor_after_sent_; } @@ -504,7 +518,8 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { // Request that |packet_number| be retransmitted after the other pending // retransmissions. Does not add it to the retransmissions if it's already - // a pending retransmission. + // a pending retransmission. Do not reuse iterator of the underlying + // unacked_packets_ after calling this function as it can be invalidated. void MarkForRetransmission(QuicPacketNumber packet_number, TransmissionType transmission_type); @@ -540,11 +555,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { // timeout. bool ShouldAddMaxAckDelay(PacketNumberSpace space) const; - // Gets the earliest in flight packet sent time to calculate PTO. Also - // updates |packet_number_space| if a PTO timer should be armed. - QuicTime GetEarliestPacketSentTimeForPto( - PacketNumberSpace* packet_number_space) const; - // Returns true if application data should be used to arm PTO. Only used when // multiple packet number space is enabled. bool ShouldArmPtoForApplicationData() const; @@ -650,6 +660,13 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { // negotiation or subsequently by AckFrequencyFrame. QuicTime::Delta peer_max_ack_delay_; + // Peer sends min_ack_delay in TransportParameter to advertise its support for + // AckFrequencyFrame. + QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite(); + + // Use smoothed RTT for computing max_ack_delay in AckFrequency frame. + bool use_smoothed_rtt_in_ack_delay_ = false; + // The history of outstanding max_ack_delays sent to peer. Outstanding means // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or // an unacked AckFrequencyFrame after that. 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 c186f65099b..3975809ac09 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 @@ -7,16 +7,17 @@ #include <memory> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::AnyNumber; @@ -68,7 +69,7 @@ class QuicSentPacketManagerTest : public QuicTest { kDefaultLength, HAS_RETRANSMITTABLE_DATA)); SerializedPacket packet(CreatePacket(packet_number, false)); packet.retransmittable_frames.push_back( - QuicFrame(QuicStreamFrame(1, false, 0, quiche::QuicheStringPiece()))); + QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view()))); packet.has_crypto_handshake = IS_HANDSHAKE; manager_.OnPacketSent(&packet, clock_.Now(), HANDSHAKE_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, true); @@ -252,8 +253,8 @@ class QuicSentPacketManagerTest : public QuicTest { PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength, false, false); if (retransmittable) { - packet.retransmittable_frames.push_back(QuicFrame( - QuicStreamFrame(kStreamId, false, 0, quiche::QuicheStringPiece()))); + packet.retransmittable_frames.push_back( + QuicFrame(QuicStreamFrame(kStreamId, false, 0, absl::string_view()))); } return packet; } @@ -299,7 +300,7 @@ class QuicSentPacketManagerTest : public QuicTest { kDefaultLength, HAS_RETRANSMITTABLE_DATA)); SerializedPacket packet(CreatePacket(packet_number, false)); packet.retransmittable_frames.push_back( - QuicFrame(QuicStreamFrame(1, false, 0, quiche::QuicheStringPiece()))); + QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view()))); packet.has_crypto_handshake = IS_HANDSHAKE; manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, true); @@ -360,10 +361,10 @@ TEST_F(QuicSentPacketManagerTest, IsUnacked) { SendDataPacket(1); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); uint64_t retransmittable[] = {1}; VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); } TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) { @@ -372,7 +373,7 @@ TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) { EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2)); uint64_t unacked[] = {1, 2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); std::vector<uint64_t> retransmittable = {1, 2}; VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size()); } @@ -392,7 +393,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); // Packet 1 is unacked, pending, but not retransmittable. uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); EXPECT_TRUE(manager_.HasInFlightPackets()); VerifyRetransmittablePackets(nullptr, 0); } @@ -415,7 +416,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); uint64_t unacked[] = {2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); // We do not know packet 2 is a spurious retransmission until it gets acked. VerifyRetransmittablePackets(nullptr, 0); EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted); @@ -430,7 +431,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted); } @@ -452,7 +453,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); // 2 remains unacked, but no packets have retransmittable data. uint64_t unacked[] = {2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); EXPECT_TRUE(manager_.HasInFlightPackets()); VerifyRetransmittablePackets(nullptr, 0); // Ack 2 causes 2 be considered as spurious retransmission. @@ -519,7 +520,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) { ENCRYPTION_INITIAL)); uint64_t unacked[] = {2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); EXPECT_FALSE(manager_.HasInFlightPackets()); VerifyRetransmittablePackets(nullptr, 0); @@ -551,7 +552,7 @@ TEST_F(QuicSentPacketManagerTest, // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT. uint64_t unacked[] = {2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); EXPECT_FALSE(manager_.HasInFlightPackets()); VerifyRetransmittablePackets(nullptr, 0); @@ -588,7 +589,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { // 2 and 3 remain unacked, but no packets have retransmittable data. uint64_t unacked[] = {2, 3}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); EXPECT_TRUE(manager_.HasInFlightPackets()); VerifyRetransmittablePackets(nullptr, 0); @@ -599,7 +600,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { .WillOnce(Return(false)) .WillRepeatedly(Return(true)); uint64_t acked[] = {3, 4}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5)); @@ -609,7 +610,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { ENCRYPTION_INITIAL)); uint64_t unacked2[] = {2}; - VerifyUnackedPackets(unacked2, QUICHE_ARRAYSIZE(unacked2)); + VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2)); EXPECT_TRUE(manager_.HasInFlightPackets()); SendDataPacket(5); @@ -630,7 +631,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { ENCRYPTION_INITIAL)); uint64_t unacked3[] = {2}; - VerifyUnackedPackets(unacked3, QUICHE_ARRAYSIZE(unacked3)); + VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3)); EXPECT_FALSE(manager_.HasInFlightPackets()); // Spurious retransmission is detected when packet 3 gets acked. We cannot // know packet 2 is a spurious until it gets acked. @@ -679,7 +680,7 @@ TEST_F(QuicSentPacketManagerTest, AckOriginalTransmission) { // Ack 3, which causes SpuriousRetransmitDetected to be called. { uint64_t acked[] = {3}; - ExpectAcksAndLosses(false, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(false, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _)); EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, QuicPacketNumber(3), @@ -725,7 +726,7 @@ TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) { // Now ack the ack and expect an RTT update. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::FromMilliseconds(5), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -738,7 +739,7 @@ TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) { // Now ack the ack and expect only an RTT update. uint64_t acked2[] = {3}; - ExpectAcksAndLosses(true, acked2, QUICHE_ARRAYSIZE(acked2), nullptr, 0); + ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4)); @@ -885,8 +886,8 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) { SendDataPacket(5); uint64_t acked[] = {4, 5}; uint64_t lost[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), lost, - QUICHE_ARRAYSIZE(lost)); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost, + ABSL_ARRAYSIZE(lost)); // Frames in all packets are acked. EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); // Notify session that stream frame in packets 1 and 2 get lost although @@ -1021,8 +1022,8 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) { // Crypto packets remain in flight, so any that aren't acked will be lost. uint64_t acked[] = {3, 4, 5, 8, 9}; uint64_t lost[] = {1, 2, 6}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), lost, - QUICHE_ARRAYSIZE(lost)); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost, + ABSL_ARRAYSIZE(lost)); EXPECT_CALL(notifier_, OnFrameLost(_)).Times(3); EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false)); manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(), @@ -1054,7 +1055,7 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) { // Now ack the second crypto packet, and ensure the first gets removed, but // the third does not. uint64_t acked[] = {2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false)); EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), @@ -1066,7 +1067,7 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) { EXPECT_FALSE(manager_.HasUnackedCryptoPackets()); uint64_t unacked[] = {1, 3}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); } TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) { @@ -1113,14 +1114,14 @@ TEST_F(QuicSentPacketManagerTest, manager_.NeuterUnencryptedPackets(); EXPECT_FALSE(manager_.HasUnackedCryptoPackets()); uint64_t unacked[] = {1, 2, 3}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); EXPECT_FALSE(manager_.HasUnackedCryptoPackets()); EXPECT_FALSE(manager_.HasInFlightPackets()); // Ensure both packets get discarded when packet 2 is acked. uint64_t acked[] = {3}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4)); @@ -1609,7 +1610,7 @@ TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) { // Ack a packet before the first RTO and ensure the RTO timeout returns to the // original value and OnRetransmissionTimeout is not called or reverted. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -2309,8 +2310,8 @@ TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) { // Ack [5, 7), [10, 12), [15, 17). uint64_t acked1[] = {5, 6, 10, 11, 15, 16}; uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13}; - ExpectAcksAndLosses(true, acked1, QUICHE_ARRAYSIZE(acked1), lost1, - QUICHE_ARRAYSIZE(lost1)); + ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1, + ABSL_ARRAYSIZE(lost1)); EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber()); manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(), clock_.Now()); @@ -2325,7 +2326,7 @@ TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) { // Ack [4, 8), [9, 13), [14, 21). uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20}; - ExpectAcksAndLosses(true, acked2, QUICHE_ARRAYSIZE(acked2), nullptr, 0); + ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21)); @@ -2344,8 +2345,8 @@ TEST_F(QuicSentPacketManagerTest, TolerateReneging) { // Ack [5, 7), [10, 12), [15, 17). uint64_t acked1[] = {5, 6, 10, 11, 15, 16}; uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13}; - ExpectAcksAndLosses(true, acked1, QUICHE_ARRAYSIZE(acked1), lost1, - QUICHE_ARRAYSIZE(lost1)); + ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1, + ABSL_ARRAYSIZE(lost1)); EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber()); manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(), clock_.Now()); @@ -2358,7 +2359,7 @@ TEST_F(QuicSentPacketManagerTest, TolerateReneging) { // Making sure reneged ACK does not harm. Ack [4, 8), [9, 13). uint64_t acked2[] = {4, 7, 9, 12}; - ExpectAcksAndLosses(true, acked2, QUICHE_ARRAYSIZE(acked2), nullptr, 0); + ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(12), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13)); @@ -2479,7 +2480,7 @@ TEST_F(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) { APPLICATION_DATA)); // Ack all packets. uint64_t acked[] = {4, 6, 7, 8}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9)); @@ -2549,7 +2550,7 @@ TEST_F(QuicSentPacketManagerTest, // Packet 1 gets acked in the wrong packet number space. Since packet 1 has // been acked in the correct packet number space, tolerate it. uint64_t acked[] = {2, 3}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4)); @@ -2591,7 +2592,7 @@ TEST_F(QuicSentPacketManagerTest, PacketInLimbo) { // Received Ack of packets 1, 3 and 4. uint64_t acked[] = {1, 3, 4}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5)); @@ -2604,8 +2605,8 @@ TEST_F(QuicSentPacketManagerTest, PacketInLimbo) { uint64_t loss[] = {2}; // Verify packet 2 is detected lost. EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1); - ExpectAcksAndLosses(true, acked2, QUICHE_ARRAYSIZE(acked2), loss, - QUICHE_ARRAYSIZE(loss)); + ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), loss, + ABSL_ARRAYSIZE(loss)); manager_.OnAckFrameStart(QuicPacketNumber(6), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(7)); @@ -2696,7 +2697,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) { // Received ACK for packets 1 and 2. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -2874,7 +2875,7 @@ TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) { // Received ACK for packets 1 and 2. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -3091,7 +3092,7 @@ TEST_F(QuicSentPacketManagerTest, RtoNotInFlightPacket) { } QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2); // Send SHLO. - QuicStreamFrame crypto_frame(1, false, 0, quiche::QuicheStringPiece()); + QuicStreamFrame crypto_frame(1, false, 0, absl::string_view()); SendCryptoPacket(1); // Send data packet. SendDataPacket(2, ENCRYPTION_FORWARD_SECURE); @@ -3473,7 +3474,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) { // Received ACK for packets 1 and 2. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -3554,7 +3555,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) { // Received ACK for packets 1 and 2. uint64_t acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), clock_.Now()); manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); @@ -4025,7 +4026,7 @@ TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) { // Received ACK for HANDSHAKE packets. uint64_t acked[] = {2, 3, 4}; - ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0); + ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0); clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90)); manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(), clock_.Now()); @@ -4419,6 +4420,62 @@ TEST_F(QuicSentPacketManagerTest, ClearDataInMessageFrameAfterPacketSent) { EXPECT_EQ(message_frame->message_length, 0); } +TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) { + SetQuicReloadableFlag(quic_can_send_ack_frequency, true); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); + QuicConfig config; + QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1); + manager_.SetFromConfig(config); + manager_.SetHandshakeConfirmed(); + + // Set up RTTs. + auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); + rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero()); + // Make sure srtt and min_rtt are different. + rtt_stats->UpdateRtt( + QuicTime::Delta::FromMilliseconds(160), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24)); + + auto frame = manager_.GetUpdatedAckFrequencyFrame(); + EXPECT_EQ(frame.max_ack_delay, + std::max(rtt_stats->min_rtt() * 0.25, + QuicTime::Delta::FromMilliseconds(1u))); + EXPECT_EQ(frame.packet_tolerance, 10u); +} + +TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) { + SetQuicReloadableFlag(quic_can_send_ack_frequency, true); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); + QuicConfig config; + QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1); + QuicTagVector quic_tag_vector; + quic_tag_vector.push_back(kAFF1); // SRTT enabling tag. + QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector); + manager_.SetFromConfig(config); + manager_.SetHandshakeConfirmed(); + + // Set up RTTs. + auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); + rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero()); + // Make sure srtt and min_rtt are different. + rtt_stats->UpdateRtt( + QuicTime::Delta::FromMilliseconds(160), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24)); + + auto frame = manager_.GetUpdatedAckFrequencyFrame(); + EXPECT_EQ(frame.max_ack_delay, + std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25, + QuicTime::Delta::FromMilliseconds(1u))); +} + } // namespace } // namespace test } // namespace quic 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 4737902ef2c..6b4c5170f12 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 @@ -8,6 +8,8 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_flow_controller.h" @@ -23,7 +25,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" #include "net/third_party/quiche/src/quic/platform/api/quic_stack_trace.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using spdy::SpdyPriority; @@ -65,14 +66,14 @@ QuicSession::QuicSession( connection->transport_version(), kDefaultMaxStreamsPerConnection, config_.GetMaxBidirectionalStreamsToSend()), - v99_streamid_manager_(perspective(), - connection->version(), - this, - 0, - num_expected_unidirectional_static_streams, - config_.GetMaxBidirectionalStreamsToSend(), - config_.GetMaxUnidirectionalStreamsToSend() + - num_expected_unidirectional_static_streams), + ietf_streamid_manager_(perspective(), + connection->version(), + this, + 0, + num_expected_unidirectional_static_streams, + config_.GetMaxBidirectionalStreamsToSend(), + config_.GetMaxUnidirectionalStreamsToSend() + + num_expected_unidirectional_static_streams), num_draining_streams_(0), num_outgoing_draining_streams_(0), num_static_streams_(0), @@ -137,6 +138,11 @@ void QuicSession::Initialize() { connection_->OnSuccessfulVersionNegotiation(); } + if (GetQuicReloadableFlag(quic_key_update_supported) && + GetMutableCryptoStream()->KeyUpdateSupportedLocally()) { + config_.SetKeyUpdateSupportedLocally(); + } + if (QuicVersionUsesCryptoFrames(transport_version())) { return; } @@ -276,6 +282,15 @@ void QuicSession::OnHandshakePacketSent() { GetMutableCryptoStream()->OnHandshakePacketSent(); } +std::unique_ptr<QuicDecrypter> +QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter(); +} + +std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() { + return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter(); +} + void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) { DCHECK(VersionUsesHttp3(transport_version())); QuicStreamId stream_id = frame.stream_id; @@ -343,7 +358,7 @@ void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) { transport_goaway_received_ = true; } -void QuicSession::OnMessageReceived(quiche::QuicheStringPiece message) { +void QuicSession::OnMessageReceived(absl::string_view message) { QUIC_DVLOG(1) << ENDPOINT << "Received message, length: " << message.length() << ", " << message; } @@ -634,9 +649,16 @@ bool QuicSession::WillingAndAbleToWrite() const { // 3) If the crypto or headers streams are blocked, or // 4) connection is not flow control blocked and there are write blocked // streams. - if (QuicVersionUsesCryptoFrames(transport_version()) && - HasPendingHandshake()) { - return true; + if (QuicVersionUsesCryptoFrames(transport_version())) { + if (HasPendingHandshake()) { + return true; + } + if (GetQuicReloadableFlag(quic_fix_willing_and_able_to_write2)) { + QUIC_RELOADABLE_FLAG_COUNT(quic_fix_willing_and_able_to_write2); + if (!IsEncryptionEstablished()) { + return false; + } + } } if (control_frame_manager_.WillingToWrite() || !streams_with_pending_retransmission_.empty()) { @@ -705,9 +727,10 @@ QuicConsumedData QuicSession::WritevData( QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) { + absl::optional<EncryptionLevel> level) { DCHECK(connection_->connected()) << ENDPOINT << "Try to write stream data when connection is closed."; + DCHECK(!use_write_or_buffer_data_at_level_ || level.has_value()); if (!IsEncryptionEstablished() && !QuicUtils::IsCryptoStreamId(transport_version(), id)) { // Do not let streams write without encryption. The calling stream will end @@ -726,9 +749,14 @@ QuicConsumedData QuicSession::WritevData( SetTransmissionType(type); const auto current_level = connection()->encryption_level(); - if (level.has_value()) { - connection()->SetDefaultEncryptionLevel(level.value()); + if (!use_encryption_level_context()) { + if (level.has_value()) { + connection()->SetDefaultEncryptionLevel(level.value()); + } } + QuicConnection::ScopedEncryptionLevelContext context( + use_encryption_level_context() ? connection() : nullptr, + use_encryption_level_context() ? level.value() : NUM_ENCRYPTION_LEVELS); QuicConsumedData data = connection_->SendStreamData(id, write_length, offset, state); @@ -738,8 +766,11 @@ QuicConsumedData QuicSession::WritevData( } // Restore the encryption level. - if (level.has_value()) { - connection()->SetDefaultEncryptionLevel(current_level); + if (!use_encryption_level_context()) { + // Restore the encryption level. + if (level.has_value()) { + connection()->SetDefaultEncryptionLevel(current_level); + } } return data; @@ -763,11 +794,17 @@ size_t QuicSession::SendCryptoData(EncryptionLevel level, } SetTransmissionType(type); const auto current_level = connection()->encryption_level(); - connection_->SetDefaultEncryptionLevel(level); + if (!use_encryption_level_context()) { + connection_->SetDefaultEncryptionLevel(level); + } + QuicConnection::ScopedEncryptionLevelContext context( + use_encryption_level_context() ? connection() : nullptr, level); const auto bytes_consumed = connection_->SendCryptoData(level, write_length, offset); - // Restores encryption level. - connection_->SetDefaultEncryptionLevel(current_level); + if (!use_encryption_level_context()) { + // Restores encryption level. + connection_->SetDefaultEncryptionLevel(current_level); + } return bytes_consumed; } @@ -782,7 +819,19 @@ bool QuicSession::WriteControlFrame(const QuicFrame& frame, TransmissionType type) { DCHECK(connection()->connected()) << ENDPOINT << "Try to write control frames when connection is closed."; + if (connection_->encrypted_control_frames()) { + QUIC_RELOADABLE_FLAG_COUNT(quic_encrypted_control_frames); + if (!IsEncryptionEstablished()) { + QUIC_BUG << ENDPOINT << "Tried to send control frame " << frame + << " before encryption is established."; + return false; + } + } SetTransmissionType(type); + QuicConnection::ScopedEncryptionLevelContext context( + use_encryption_level_context() ? connection() : nullptr, + use_encryption_level_context() ? GetEncryptionLevelToSendApplicationData() + : NUM_ENCRYPTION_LEVELS); return connection_->SendControlFrame(frame); } @@ -790,15 +839,26 @@ void QuicSession::SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written, bool send_rst_only) { - if (connection()->connected()) { - QuicConnection::ScopedPacketFlusher flusher(connection()); - MaybeSendRstStreamFrame(id, error, bytes_written); - if (!send_rst_only) { - MaybeSendStopSendingFrame(id, error); - } + DCHECK(!split_up_send_rst()); + if (!connection()->connected()) { + return; + } - connection_->OnStreamReset(id, error); + QuicConnection::ScopedPacketFlusher flusher(connection()); + if (!VersionHasIetfQuicFrames(transport_version()) || + QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id), + version()) != READ_UNIDIRECTIONAL) { + control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written); + } + if (!send_rst_only) { + if (VersionHasIetfQuicFrames(transport_version()) && + QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id), + version()) != WRITE_UNIDIRECTIONAL) { + control_frame_manager_.WriteOrBufferStopSending(error, id); + } } + + connection_->OnStreamReset(id, error); } void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) { @@ -815,23 +875,37 @@ void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) { return; } - SendRstStream(id, error, 0, /*send_rst_only = */ false); + if (split_up_send_rst()) { + QuicConnection::ScopedPacketFlusher flusher(connection()); + MaybeSendStopSendingFrame(id, error); + MaybeSendRstStreamFrame(id, error, 0); + } else { + SendRstStream(id, error, 0, /*send_rst_only = */ false); + } } void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written) { - DCHECK(connection()->connected()); + DCHECK(split_up_send_rst()); + if (!connection()->connected()) { + return; + } if (!VersionHasIetfQuicFrames(transport_version()) || QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id), version()) != READ_UNIDIRECTIONAL) { control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written); } + + connection_->OnStreamReset(id, error); } void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id, QuicRstStreamErrorCode error) { - DCHECK(connection()->connected()); + DCHECK(split_up_send_rst()); + if (!connection()->connected()) { + return; + } if (VersionHasIetfQuicFrames(transport_version()) && QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id), version()) != WRITE_UNIDIRECTIONAL) { @@ -841,14 +915,25 @@ void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id, void QuicSession::SendGoAway(QuicErrorCode error_code, const std::string& reason) { - // GOAWAY frame is not supported in v99. + // GOAWAY frame is not supported in IETF QUIC. DCHECK(!VersionHasIetfQuicFrames(transport_version())); if (transport_goaway_sent_) { return; } transport_goaway_sent_ = true; - control_frame_manager_.WriteOrBufferGoAway( - error_code, stream_id_manager_.largest_peer_created_stream_id(), reason); + if (GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + DCHECK_EQ(perspective(), Perspective::IS_SERVER); + QUIC_RELOADABLE_FLAG_COUNT_N(quic_goaway_with_max_stream_id, 2, 2); + control_frame_manager_.WriteOrBufferGoAway( + error_code, + QuicUtils::GetMaxClientInitiatedBidirectionalStreamId( + transport_version()), + reason); + } else { + control_frame_manager_.WriteOrBufferGoAway( + error_code, stream_id_manager_.largest_peer_created_stream_id(), + reason); + } } void QuicSession::SendBlocked(QuicStreamId id) { @@ -942,7 +1027,7 @@ void QuicSession::OnStreamClosed(QuicStreamId stream_id) { if (IsIncomingStream(stream_id)) { // Stream Id manager is only interested in peer initiated stream IDs. if (VersionHasIetfQuicFrames(transport_version())) { - v99_streamid_manager_.OnStreamClosed(stream_id); + ietf_streamid_manager_.OnStreamClosed(stream_id); } return; } @@ -956,7 +1041,7 @@ void QuicSession::ClosePendingStream(QuicStreamId stream_id) { DCHECK(VersionHasIetfQuicFrames(transport_version())); pending_stream_map_.erase(stream_id); if (connection_->connected()) { - v99_streamid_manager_.OnStreamClosed(stream_id); + ietf_streamid_manager_.OnStreamClosed(stream_id); } } @@ -991,7 +1076,7 @@ void QuicSession::OnFinalByteOffsetReceived( } if (IsIncomingStream(stream_id)) { if (VersionHasIetfQuicFrames(transport_version())) { - v99_streamid_manager_.OnStreamClosed(stream_id); + ietf_streamid_manager_.OnStreamClosed(stream_id); } } else if (!VersionHasIetfQuicFrames(transport_version())) { OnCanCreateNewOutgoingStream(false); @@ -1038,14 +1123,14 @@ void QuicSession::OnConfigNegotiated() { } if (was_zero_rtt_rejected_ && max_streams < - v99_streamid_manager_.outgoing_bidirectional_stream_count()) { + ietf_streamid_manager_.outgoing_bidirectional_stream_count()) { connection_->CloseConnection( QUIC_ZERO_RTT_UNRETRANSMITTABLE, quiche::QuicheStrCat( "Server rejected 0-RTT, aborting because new bidirectional " "initial stream limit ", max_streams, " is less than current open streams: ", - v99_streamid_manager_.outgoing_bidirectional_stream_count()), + ietf_streamid_manager_.outgoing_bidirectional_stream_count()), ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return; } @@ -1054,7 +1139,7 @@ void QuicSession::OnConfigNegotiated() { << max_streams; if (perspective_ == Perspective::IS_CLIENT && max_streams < - v99_streamid_manager_.max_outgoing_bidirectional_streams()) { + ietf_streamid_manager_.max_outgoing_bidirectional_streams()) { connection_->CloseConnection( was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, @@ -1064,11 +1149,11 @@ void QuicSession::OnConfigNegotiated() { : "", "new bidirectional limit ", max_streams, " decreases the current limit: ", - v99_streamid_manager_.max_outgoing_bidirectional_streams()), + ietf_streamid_manager_.max_outgoing_bidirectional_streams()), ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return; } - if (v99_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( + if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( max_streams)) { OnCanCreateNewOutgoingStream(/*unidirectional = */ false); } @@ -1080,20 +1165,20 @@ void QuicSession::OnConfigNegotiated() { if (was_zero_rtt_rejected_ && max_streams < - v99_streamid_manager_.outgoing_unidirectional_stream_count()) { + ietf_streamid_manager_.outgoing_unidirectional_stream_count()) { connection_->CloseConnection( QUIC_ZERO_RTT_UNRETRANSMITTABLE, quiche::QuicheStrCat( "Server rejected 0-RTT, aborting because new unidirectional " "initial stream limit ", max_streams, " is less than current open streams: ", - v99_streamid_manager_.outgoing_unidirectional_stream_count()), + ietf_streamid_manager_.outgoing_unidirectional_stream_count()), ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return; } if (max_streams < - v99_streamid_manager_.max_outgoing_unidirectional_streams()) { + ietf_streamid_manager_.max_outgoing_unidirectional_streams()) { connection_->CloseConnection( was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, @@ -1103,14 +1188,14 @@ void QuicSession::OnConfigNegotiated() { : "", "new unidirectional limit ", max_streams, " decreases the current limit: ", - v99_streamid_manager_.max_outgoing_unidirectional_streams()), + ietf_streamid_manager_.max_outgoing_unidirectional_streams()), ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return; } QUIC_DVLOG(1) << ENDPOINT << "Setting Unidirectional outgoing_max_streams_ to " << max_streams; - if (v99_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( + if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( max_streams)) { OnCanCreateNewOutgoingStream(/*unidirectional = */ true); } @@ -1179,9 +1264,9 @@ void QuicSession::OnConfigNegotiated() { } if (VersionHasIetfQuicFrames(transport_version())) { - v99_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( + ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( config_.GetMaxBidirectionalStreamsToSend()); - v99_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( + ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( config_.GetMaxUnidirectionalStreamsToSend()); } else { // A small number of additional incoming streams beyond the limit should be @@ -1635,6 +1720,16 @@ QuicErrorCode QuicSession::ProcessTransportParameters( error_details); } +void QuicSession::OnHandshakeCallbackDone() { + if (!connection_->connected()) { + return; + } + + if (!connection()->is_processing_packet()) { + connection()->MaybeProcessUndecryptablePackets(); + } +} + void QuicSession::OnCryptoHandshakeMessageSent( const CryptoHandshakeMessage& /*message*/) {} @@ -1693,14 +1788,14 @@ void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) { QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetNextOutgoingBidirectionalStreamId(); + return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId(); } return stream_id_manager_.GetNextOutgoingStreamId(); } QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetNextOutgoingUnidirectionalStreamId(); + return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId(); } return stream_id_manager_.GetNextOutgoingStreamId(); } @@ -1715,11 +1810,11 @@ bool QuicSession::CanOpenNextOutgoingBidirectionalStream() { return false; } } else { - if (!v99_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) { + if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) { if (is_configured_) { // Send STREAM_BLOCKED after config negotiated. control_frame_manager_.WriteOrBufferStreamsBlocked( - v99_streamid_manager_.max_outgoing_bidirectional_streams(), + ietf_streamid_manager_.max_outgoing_bidirectional_streams(), /*unidirectional=*/false); } return false; @@ -1739,13 +1834,13 @@ bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() { if (!VersionHasIetfQuicFrames(transport_version())) { return stream_id_manager_.CanOpenNextOutgoingStream(); } - if (v99_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) { + if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) { return true; } if (is_configured_) { // Send STREAM_BLOCKED after config negotiated. control_frame_manager_.WriteOrBufferStreamsBlocked( - v99_streamid_manager_.max_outgoing_unidirectional_streams(), + ietf_streamid_manager_.max_outgoing_unidirectional_streams(), /*unidirectional=*/true); } return false; @@ -1754,7 +1849,7 @@ bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() { QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams() const { DCHECK(VersionHasIetfQuicFrames(transport_version())); - return v99_streamid_manager_.advertised_max_incoming_bidirectional_streams(); + return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams(); } QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) { @@ -1800,7 +1895,7 @@ void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) { DCHECK(QuicContainsKey(stream_map_, stream_id)); QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining"; if (VersionHasIetfQuicFrames(transport_version())) { - v99_streamid_manager_.OnStreamClosed(stream_id); + ietf_streamid_manager_.OnStreamClosed(stream_id); } else { stream_id_manager_.OnStreamClosed( /*is_incoming=*/IsIncomingStream(stream_id)); @@ -1816,7 +1911,7 @@ bool QuicSession::MaybeIncreaseLargestPeerStreamId( const QuicStreamId stream_id) { if (VersionHasIetfQuicFrames(transport_version())) { std::string error_details; - if (v99_streamid_manager_.MaybeIncreaseLargestPeerStreamId( + if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId( stream_id, &error_details)) { return true; } @@ -1871,7 +1966,7 @@ QuicStreamId QuicSession::GetLargestPeerCreatedStreamId( bool unidirectional) const { // This method is only used in IETF QUIC. DCHECK(VersionHasIetfQuicFrames(transport_version())); - return v99_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional); + return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional); } void QuicSession::DeleteConnection() { @@ -1901,7 +1996,7 @@ bool QuicSession::IsClosedStream(QuicStreamId id) { } if (VersionHasIetfQuicFrames(transport_version())) { - return !v99_streamid_manager_.IsAvailableStream(id); + return !ietf_streamid_manager_.IsAvailableStream(id); } return !stream_id_manager_.IsAvailableStream(id); @@ -1964,6 +2059,10 @@ void QuicSession::SendPing() { control_frame_manager_.WritePing(); } +void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) { + control_frame_manager_.WriteOrBufferAckFrequency(frame); +} + bool QuicSession::IsConnectionFlowControlBlocked() const { return flow_controller_.IsBlocked(); } @@ -1983,14 +2082,14 @@ bool QuicSession::IsStreamFlowControlBlocked() { size_t QuicSession::MaxAvailableBidirectionalStreams() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams(); + return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams(); } return stream_id_manager_.MaxAvailableStreams(); } size_t QuicSession::MaxAvailableUnidirectionalStreams() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams(); + return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams(); } return stream_id_manager_.MaxAvailableStreams(); } @@ -2002,7 +2101,7 @@ bool QuicSession::IsIncomingStream(QuicStreamId id) const { return stream_id_manager_.IsIncomingStream(id); } -void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) { +void QuicSession::MaybeCloseZombieStream(QuicStreamId id) { auto it = stream_map_.find(id); if (it == stream_map_.end()) { return; @@ -2303,6 +2402,10 @@ MessageResult QuicSession::SendMessage(QuicMemSliceSpan message, bool flush) { if (!IsEncryptionEstablished()) { return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0}; } + QuicConnection::ScopedEncryptionLevelContext context( + use_encryption_level_context() ? connection() : nullptr, + use_encryption_level_context() ? GetEncryptionLevelToSendApplicationData() + : NUM_ENCRYPTION_LEVELS); MessageStatus result = connection_->SendMessage(last_message_id_ + 1, message, flush); if (result == MESSAGE_STATUS_SUCCESS) { @@ -2340,14 +2443,14 @@ void QuicSession::SendStopSending(QuicRstStreamErrorCode code, QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.next_outgoing_bidirectional_stream_id(); + return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id(); } return stream_id_manager_.next_outgoing_stream_id(); } QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.next_outgoing_unidirectional_stream_id(); + return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id(); } return stream_id_manager_.next_outgoing_stream_id(); } @@ -2355,9 +2458,9 @@ QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const { bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) { const bool allow_new_streams = frame.unidirectional - ? v99_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( + ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( frame.stream_count) - : v99_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( + : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( frame.stream_count); if (allow_new_streams) { OnCanCreateNewOutgoingStream(frame.unidirectional); @@ -2368,7 +2471,7 @@ bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) { bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) { std::string error_details; - if (v99_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) { + if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) { return true; } connection_->CloseConnection( @@ -2379,25 +2482,25 @@ bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) { size_t QuicSession::max_open_incoming_bidirectional_streams() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams(); + return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams(); } return stream_id_manager_.max_open_incoming_streams(); } size_t QuicSession::max_open_incoming_unidirectional_streams() const { if (VersionHasIetfQuicFrames(transport_version())) { - return v99_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams(); + return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams(); } return stream_id_manager_.max_open_incoming_streams(); } -std::vector<quiche::QuicheStringPiece>::const_iterator QuicSession::SelectAlpn( - const std::vector<quiche::QuicheStringPiece>& alpns) const { +std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn( + const std::vector<absl::string_view>& alpns) const { const std::string alpn = AlpnForVersion(connection()->version()); return std::find(alpns.cbegin(), alpns.cend(), alpn); } -void QuicSession::OnAlpnSelected(quiche::QuicheStringPiece alpn) { +void QuicSession::OnAlpnSelected(absl::string_view alpn) { QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ") << "ALPN selected: " << alpn; @@ -2433,5 +2536,9 @@ void QuicSession::PerformActionOnActiveStreams( } } +EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const { + return connection_->framer().GetEncryptionLevelToSendApplicationData(); +} + #undef ENDPOINT // undef for jumbo builds } // namespace quic 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 f5e01f85157..e454892ac5c 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 @@ -14,6 +14,9 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h" #include "net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" @@ -32,9 +35,8 @@ #include "net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -98,7 +100,7 @@ class QUIC_EXPORT_PRIVATE QuicSession void OnCryptoFrame(const QuicCryptoFrame& frame) override; void OnRstStream(const QuicRstStreamFrame& frame) override; void OnGoAway(const QuicGoAwayFrame& frame) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; void OnHandshakeDoneReceived() override; void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; void OnBlockedFrame(const QuicBlockedFrame& frame) override; @@ -122,6 +124,7 @@ class QUIC_EXPORT_PRIVATE QuicSession // Adds a connection level WINDOW_UPDATE frame. void OnAckNeedsRetransmittableFrame() override; void SendPing() override; + void SendAckFrequency(const QuicAckFrequencyFrame& frame) override; bool WillingAndAbleToWrite() const override; std::string GetStreamsInfoForLogging() const override; void OnPathDegrading() override; @@ -134,6 +137,11 @@ class QUIC_EXPORT_PRIVATE QuicSession void OnPacketDecrypted(EncryptionLevel level) override; void OnOneRttPacketAcknowledged() override; void OnHandshakePacketSent() override; + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override; + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; + void BeforeConnectionCloseSent() override {} // QuicStreamFrameDataProducer WriteStreamDataResult WriteStreamData(QuicStreamId id, @@ -213,6 +221,8 @@ class QUIC_EXPORT_PRIVATE QuicSession // Called by stream to send RST_STREAM (and STOP_SENDING in IETF QUIC). // if |send_rst_only|, STOP_SENDING will not be sent for IETF QUIC. + // TODO(b/170233449): Delete this method when flag quic_split_up_send_rst_2 is + // deprecated. virtual void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written, @@ -267,6 +277,7 @@ class QUIC_EXPORT_PRIVATE QuicSession QuicErrorCode ProcessTransportParameters(const TransportParameters& params, bool is_resumption, std::string* error_details) override; + void OnHandshakeCallbackDone() override; // Implement StreamDelegateInterface. void OnStreamError(QuicErrorCode error_code, @@ -288,13 +299,12 @@ class QUIC_EXPORT_PRIVATE QuicSession // indicating if the fin bit was consumed. This does not indicate the data // has been sent on the wire: it may have been turned into a packet and queued // if the socket was unexpectedly blocked. - QuicConsumedData WritevData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) override; + QuicConsumedData WritevData(QuicStreamId id, + size_t write_length, + QuicStreamOffset offset, + StreamSendingState state, + TransmissionType type, + absl::optional<EncryptionLevel> level) override; size_t SendCryptoData(EncryptionLevel level, size_t write_length, @@ -330,6 +340,8 @@ class QUIC_EXPORT_PRIVATE QuicSession return connection_->connection_id(); } + bool split_up_send_rst() const { return split_up_send_rst_; } + // Returns the number of currently open streams, excluding static streams, and // never counting unfinished streams. size_t GetNumActiveStreams() const; @@ -340,11 +352,8 @@ class QUIC_EXPORT_PRIVATE QuicSession // WINDOW_UPDATE arrives. virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id); - // Called when stream |id| is done waiting for acks either because all data - // gets acked or is not interested in data being acked (which happens when - // a stream is reset because of an error). - // TODO(b/136274541): rename to CloseZombieStreams. - void OnStreamDoneWaitingForAcks(QuicStreamId id); + // Called to close zombie stream |id|. + void MaybeCloseZombieStream(QuicStreamId id); // Returns true if there is pending handshake data in the crypto stream. // TODO(ianswett): Make this private or remove. @@ -452,12 +461,12 @@ class QUIC_EXPORT_PRIVATE QuicSession // Provided a list of ALPNs offered by the client, selects an ALPN from the // list, or alpns.end() if none of the ALPNs are acceptable. - virtual std::vector<quiche::QuicheStringPiece>::const_iterator SelectAlpn( - const std::vector<quiche::QuicheStringPiece>& alpns) const; + virtual std::vector<absl::string_view>::const_iterator SelectAlpn( + const std::vector<absl::string_view>& alpns) const; // Called when the ALPN of the connection is established for a connection that // uses TLS handshake. - virtual void OnAlpnSelected(quiche::QuicheStringPiece alpn); + virtual void OnAlpnSelected(absl::string_view alpn); // Called on clients by the crypto handshaker to provide application state // necessary for sending application data in 0-RTT. The state provided here is @@ -474,7 +483,20 @@ class QUIC_EXPORT_PRIVATE QuicSession return true; } - const quiche::QuicheOptional<std::string> user_agent_id() const { + // Does actual work of sending RESET_STREAM, if the stream type allows. + // Also informs the connection so that pending stream frames can be flushed. + virtual void MaybeSendRstStreamFrame(QuicStreamId id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written); + + // Sends a STOP_SENDING frame if the stream type allows. + virtual void MaybeSendStopSendingFrame(QuicStreamId id, + QuicRstStreamErrorCode error); + + // Returns the encryption level to send application data. + EncryptionLevel GetEncryptionLevelToSendApplicationData() const; + + const absl::optional<std::string> user_agent_id() const { return user_agent_id_; } @@ -491,6 +513,15 @@ class QUIC_EXPORT_PRIVATE QuicSession return liveness_testing_in_progress_; } + bool use_write_or_buffer_data_at_level() const { + return use_write_or_buffer_data_at_level_; + } + + bool use_encryption_level_context() const { + return connection_->use_encryption_level_context() && + use_write_or_buffer_data_at_level_; + } + protected: using StreamMap = QuicHashMap<QuicStreamId, std::unique_ptr<QuicStream>>; @@ -557,9 +588,6 @@ class QUIC_EXPORT_PRIVATE QuicSession StreamMap& stream_map() { return stream_map_; } - // TODO(b/136274541): remove this getter and only expose GetNumActiveStreams() - size_t stream_map_size() const { return stream_map_.size(); } - size_t pending_streams_size() const { return pending_stream_map_.size(); } ClosedStreams* closed_streams() { return &closed_streams_; } @@ -618,6 +646,8 @@ class QUIC_EXPORT_PRIVATE QuicSession return num_outgoing_draining_streams_; } + size_t num_draining_streams() const { return num_draining_streams_; } + // Processes the stream type information of |pending| depending on // different kinds of sessions' own rules. Returns true if the pending stream // is converted into a normal stream. @@ -717,14 +747,6 @@ class QUIC_EXPORT_PRIVATE QuicSession // stream. void PendingStreamOnRstStream(const QuicRstStreamFrame& frame); - // Does actual work of sending RESET_STREAM, if the stream type allows. - void MaybeSendRstStreamFrame(QuicStreamId id, - QuicRstStreamErrorCode error, - QuicStreamOffset bytes_written); - - // Sends a STOP_SENDING frame if the stream type allows. - void MaybeSendStopSendingFrame(QuicStreamId id, QuicRstStreamErrorCode error); - // Keep track of highest received byte offset of locally closed streams, while // waiting for a definitive final highest offset from the peer. QuicHashMap<QuicStreamId, QuicStreamOffset> @@ -761,7 +783,7 @@ class QUIC_EXPORT_PRIVATE QuicSession LegacyQuicStreamIdManager stream_id_manager_; // Manages stream IDs for version99/IETF QUIC - UberQuicStreamIdManager v99_streamid_manager_; + UberQuicStreamIdManager ietf_streamid_manager_; // A counter for streams which have sent and received FIN but waiting for // application to consume data. @@ -818,7 +840,7 @@ class QUIC_EXPORT_PRIVATE QuicSession // list may be a superset of the connection framer's supported versions. ParsedQuicVersionVector supported_versions_; - quiche::QuicheOptional<std::string> user_agent_id_; + absl::optional<std::string> user_agent_id_; // If true, write_blocked_streams_ uses HTTP2 (tree-style) priority write // scheduler. @@ -837,6 +859,12 @@ class QUIC_EXPORT_PRIVATE QuicSession // This indicates a liveness testing is in progress, and push back the // creation of new outgoing bidirectional streams. bool liveness_testing_in_progress_; + + const bool split_up_send_rst_ = + GetQuicReloadableFlag(quic_split_up_send_rst_2); + + const bool use_write_or_buffer_data_at_level_ = + GetQuicReloadableFlag(quic_use_write_or_buffer_data_at_level); }; } // namespace quic 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 e5b6cff3a03..06225086ed7 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 @@ -9,6 +9,9 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" @@ -37,10 +40,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using spdy::kV3HighestPriority; using spdy::SpdyPriority; @@ -70,6 +70,13 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker { params_->cipher_suite = 1; } + void EstablishZeroRttEncryption() { + encryption_established_ = true; + session()->connection()->SetEncrypter( + ENCRYPTION_ZERO_RTT, + std::make_unique<NullEncrypter>(session()->perspective())); + } + void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override { encryption_established_ = true; one_rtt_keys_available_ = true; @@ -104,6 +111,9 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker { session()->config()->ProcessPeerHello(msg, CLIENT, &error_details); } EXPECT_THAT(error, IsQuicNoError()); + session()->OnNewEncryptionKeyAvailable( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(session()->perspective())); session()->OnConfigNegotiated(); if (session()->connection()->version().handshake_protocol == PROTOCOL_TLS1_3) { @@ -140,6 +150,15 @@ 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, + (), + (override)); + MOCK_METHOD(std::unique_ptr<QuicEncrypter>, + CreateCurrentOneRttEncrypter, + (), + (override)); MOCK_METHOD(void, OnCanWrite, (), (override)); bool HasPendingCryptoRetransmission() const override { return false; } @@ -198,6 +217,8 @@ 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, @@ -293,13 +314,12 @@ class TestSession : public QuicSession { return GetNumActiveStreams() > 0; } - QuicConsumedData WritevData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) override { + QuicConsumedData WritevData(QuicStreamId id, + size_t write_length, + QuicStreamOffset offset, + StreamSendingState state, + TransmissionType type, + absl::optional<EncryptionLevel> level) override { bool fin = state != NO_FIN; QuicConsumedData consumed(write_length, fin); if (!writev_consumes_all_data_) { @@ -330,7 +350,8 @@ class TestSession : public QuicSession { MakeIOVector("not empty", &iov); QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9); QuicConsumedData consumed = - WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, QUICHE_NULLOPT); + WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, + GetEncryptionLevelToSendApplicationData()); QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed( consumed.bytes_consumed); return consumed; @@ -347,7 +368,7 @@ class TestSession : public QuicSession { QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) { DCHECK(writev_consumes_all_data_); return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION, - QUICHE_NULLOPT); + GetEncryptionLevelToSendApplicationData()); } bool UsesPendingStreams() const override { return uses_pending_streams_; } @@ -477,6 +498,16 @@ class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> { closed_streams_.insert(id); } + void CompleteHandshake() { + CryptoHandshakeMessage msg; + if (connection_->version().HasHandshakeDone() && + connection_->perspective() == Perspective::IS_SERVER) { + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&ClearControlFrame)); + } + session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); + } + QuicTransportVersion transport_version() const { return connection_->transport_version(); } @@ -620,12 +651,7 @@ TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) { TEST_P(QuicSessionTestServer, OneRttKeysAvailable) { EXPECT_FALSE(session_.OneRttKeysAvailable()); - CryptoHandshakeMessage message; - if (connection_->version().HasHandshakeDone()) { - EXPECT_CALL(*connection_, SendControlFrame(_)); - } - connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - session_.GetMutableCryptoStream()->OnHandshakeMessage(message); + CompleteHandshake(); EXPECT_TRUE(session_.OneRttKeysAvailable()); } @@ -697,6 +723,7 @@ TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) { } TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id()); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -710,6 +737,7 @@ TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) { } TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream(); EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id()); TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream(); @@ -723,6 +751,7 @@ TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) { } TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) { + CompleteHandshake(); QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0); QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1); session_.GetOrCreateStream(stream_id1); @@ -743,6 +772,7 @@ TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) { } TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) { + CompleteHandshake(); QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0); QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1); session_.GetOrCreateStream(stream_id1); @@ -905,6 +935,7 @@ TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) { } TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); QuicStreamId closed_stream_id = stream2->id(); // Close the stream. @@ -918,6 +949,7 @@ TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) { } TEST_P(QuicSessionTestServer, OnCanWrite) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -1142,15 +1174,9 @@ TEST_P(QuicSessionTestServer, RoundRobinScheduling) { TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { // Encryption needs to be established before data can be sent. - if (connection_->version().HasHandshakeDone()) { - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(&ClearControlFrame)); - } - CryptoHandshakeMessage msg; + CompleteHandshake(); MockPacketWriter* writer = static_cast<MockPacketWriter*>( QuicConnectionPeer::GetWriter(session_.connection())); - connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); // Drive congestion control manually. MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; @@ -1189,6 +1215,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { } TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); InSequence s; @@ -1236,6 +1263,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) { } TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) { + CompleteHandshake(); // Drive congestion control manually in order to ensure that // application-limited signaling is handled correctly. MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; @@ -1263,6 +1291,7 @@ TEST_P(QuicSessionTestServer, SendStreamsBlocked) { if (!VersionHasIetfQuicFrames(transport_version())) { return; } + CompleteHandshake(); for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) { ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream()); session_.GetNextOutgoingBidirectionalStreamId(); @@ -1348,6 +1377,7 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) { } TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); TestStream* stream4 = session_.CreateOutgoingBidirectionalStream(); @@ -1417,6 +1447,7 @@ TEST_P(QuicSessionTestServer, SendGoAway) { // In IETF QUIC, GOAWAY lives up in the HTTP layer. return; } + CompleteHandshake(); connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); MockPacketWriter* writer = static_cast<MockPacketWriter*>( QuicConnectionPeer::GetWriter(session_.connection())); @@ -1438,6 +1469,7 @@ TEST_P(QuicSessionTestServer, SendGoAway) { } TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) { + CompleteHandshake(); if (VersionHasIetfQuicFrames(transport_version())) { // In IETF QUIC, GOAWAY lives up in the HTTP layer. return; @@ -1539,12 +1571,7 @@ TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbes) { TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) { EXPECT_EQ(kInitialIdleTimeoutSecs + 3, QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); - if (connection_->version().HasHandshakeDone()) { - EXPECT_CALL(*connection_, SendControlFrame(_)); - } - CryptoHandshakeMessage msg; - connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); + CompleteHandshake(); EXPECT_EQ(kMaximumIdleTimeoutSecs + 3, QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); } @@ -1561,8 +1588,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) { /*is_static*/ true, BIDIRECTIONAL); QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream)); // Send two bytes of payload. - QuicStreamFrame data1(headers_stream_id, true, 0, - quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(headers_stream_id, true, 0, absl::string_view("HT")); EXPECT_CALL(*connection_, CloseConnection( QUIC_INVALID_STREAM_ID, "Attempt to close a static stream", @@ -1574,7 +1600,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) { // Send two bytes of payload. QuicStreamFrame data1( QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); EXPECT_CALL(*connection_, CloseConnection( QUIC_INVALID_STREAM_ID, "Received data for an invalid stream", @@ -1607,6 +1633,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { // Ensure that Writev consumes all the data it is given (simulate no socket // blocking). session_.set_writev_consumes_all_data(true); + session_.GetMutableCryptoStream()->EstablishZeroRttEncryption(); // Create a stream, and send enough data to make it flow control blocked. TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); @@ -1622,8 +1649,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { // Now complete the crypto handshake, resulting in an increased flow control // send window. - CryptoHandshakeMessage msg; - session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); + CompleteHandshake(); EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id())); // Stream is now unblocked. EXPECT_FALSE(stream2->IsFlowControlBlocked()); @@ -1632,7 +1658,8 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { } TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { - if (QuicVersionUsesCryptoFrames(GetParam().transport_version)) { + if (QuicVersionUsesCryptoFrames(GetParam().transport_version) || + connection_->encrypted_control_frames()) { // QUIC version 47 onwards uses CRYPTO frames for the handshake, so this // test doesn't make sense for those versions since CRYPTO frames aren't // flow controlled. @@ -1657,7 +1684,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { QuicConfig config; CryptoHandshakeMessage crypto_message; config.ToHandshakeMessage(&crypto_message, transport_version()); - crypto_stream->SendHandshakeMessage(crypto_message); + crypto_stream->SendHandshakeMessage(crypto_message, ENCRYPTION_INITIAL); char buf[1000]; QuicDataWriter writer(1000, buf, quiche::NETWORK_BYTE_ORDER); crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer); @@ -1670,8 +1697,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { // Now complete the crypto handshake, resulting in an increased flow control // send window. - CryptoHandshakeMessage msg; - session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); + CompleteHandshake(); EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked( &session_, QuicUtils::GetCryptoStreamId(connection_->transport_version()))); @@ -1682,6 +1708,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { } TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) { + CompleteHandshake(); // Test that when we receive an out of order stream RST we correctly adjust // our connection level flow control receive window. // On close, the stream should mark as consumed all bytes between the highest @@ -1711,6 +1738,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) { } TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) { + CompleteHandshake(); // Test the situation where we receive a FIN on a stream, and before we fully // consume all the data from the sequencer buffer we locally RST the stream. // The bytes between highest consumed byte, and the final byte offset that we @@ -1737,6 +1765,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) { } TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) { + CompleteHandshake(); // Test that when we RST the stream (and tear down stream state), and then // receive a FIN from the peer, we correctly adjust our connection level flow // control receive window. @@ -1763,7 +1792,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) { const QuicStreamOffset kByteOffset = 5678; std::string body = "hello"; QuicStreamFrame frame(stream->id(), true, kByteOffset, - quiche::QuicheStringPiece(body)); + absl::string_view(body)); session_.OnStreamFrame(frame); QuicStreamOffset total_stream_bytes_sent_by_peer = @@ -1776,6 +1805,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) { } TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) { + CompleteHandshake(); // Test that when we RST the stream (and tear down stream state), and then // receive a RST from the peer, we correctly adjust our connection level flow // control receive window. @@ -1841,6 +1871,7 @@ TEST_P(QuicSessionTestServer, CustomFlowControlWindow) { } TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) { + CompleteHandshake(); // Test that if we receive a stream RST with a highest byte offset that // violates flow control, that we close the connection. const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; @@ -1853,8 +1884,7 @@ TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) { EXPECT_CALL(*connection_, SendControlFrame(_)); EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); stream->Reset(QUIC_STREAM_CANCELLED); - QuicStreamFrame frame(stream->id(), true, kLargeOffset, - quiche::QuicheStringPiece()); + QuicStreamFrame frame(stream->id(), true, kLargeOffset, absl::string_view()); session_.OnStreamFrame(frame); // Check that RST results in connection close. @@ -1864,6 +1894,7 @@ TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) { } TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) { + CompleteHandshake(); // If a buggy/malicious peer creates too many streams that are not ended // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the // connection is closed. @@ -1881,7 +1912,7 @@ TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) { // FIN or a RST_STREAM from the client. for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += QuicUtils::StreamIdDelta(connection_->transport_version())) { - QuicStreamFrame data1(i, false, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(i, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); CloseStream(i); } @@ -1898,8 +1929,7 @@ TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) { .Times(1); } // Create one more data streams to exceed limit of open stream. - QuicStreamFrame data1(kFinalStreamId, false, 0, - quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); } @@ -1907,9 +1937,10 @@ TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) { // Verify that a draining stream (which has received a FIN but not consumed // it) does not count against the open quota (because it is closed from the // protocol point of view). + CompleteHandshake(); TestStream* stream = session_.CreateOutgoingBidirectionalStream(); QuicStreamId stream_id = stream->id(); - QuicStreamFrame data1(stream_id, true, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1); session_.StreamDraining(stream_id, /*unidirectional=*/false); @@ -1920,11 +1951,11 @@ TEST_P(QuicSessionTestServer, NoPendingStreams) { QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( transport_version(), Perspective::IS_CLIENT); - QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_EQ(1, session_.num_incoming_streams_created()); - QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data2); EXPECT_EQ(1, session_.num_incoming_streams_created()); } @@ -1937,12 +1968,12 @@ TEST_P(QuicSessionTestServer, PendingStreams) { QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( transport_version(), Perspective::IS_CLIENT); - QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id)); EXPECT_EQ(0, session_.num_incoming_streams_created()); - QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data2); EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id)); EXPECT_EQ(1, session_.num_incoming_streams_created()); @@ -1956,7 +1987,7 @@ TEST_P(QuicSessionTestServer, RstPendingStreams) { QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( transport_version(), Perspective::IS_CLIENT); - QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id)); EXPECT_EQ(0, session_.num_incoming_streams_created()); @@ -1969,7 +2000,7 @@ TEST_P(QuicSessionTestServer, RstPendingStreams) { EXPECT_EQ(0, session_.num_incoming_streams_created()); EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); - QuicStreamFrame data2(stream_id, false, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT")); session_.OnStreamFrame(data2); EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id)); EXPECT_EQ(0, session_.num_incoming_streams_created()); @@ -2000,7 +2031,7 @@ TEST_P(QuicSessionTestServer, PendingStreamOnWindowUpdate) { session_.set_uses_pending_streams(true); QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId( transport_version(), Perspective::IS_CLIENT); - QuicStreamFrame data1(stream_id, true, 10, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id)); EXPECT_EQ(0, session_.num_incoming_streams_created()); @@ -2018,6 +2049,7 @@ TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) { // Verify that a draining stream (which has received a FIN but not consumed // it) does not count against the open quota (because it is closed from the // protocol point of view). + CompleteHandshake(); if (VersionHasIetfQuicFrames(transport_version())) { // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are // not enough streams to create the next one. @@ -2040,7 +2072,7 @@ TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) { GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1); for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += QuicUtils::StreamIdDelta(connection_->transport_version())) { - QuicStreamFrame data1(i, true, 0, quiche::QuicheStringPiece("HT")); + QuicStreamFrame data1(i, true, 0, absl::string_view("HT")); session_.OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); session_.StreamDraining(i, /*unidirectional=*/false); @@ -2174,6 +2206,7 @@ TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) { } TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) { + CompleteHandshake(); // Verify that an incoming FIN is recorded in a stream object even if the read // side has been closed. This prevents an entry from being made in // locally_closed_streams_highest_offset_ (which will never be deleted). @@ -2184,7 +2217,7 @@ TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) { QuicStreamPeer::CloseReadSide(stream); // Receive a stream data frame with FIN. - QuicStreamFrame frame(stream_id, true, 0, quiche::QuicheStringPiece()); + QuicStreamFrame frame(stream_id, true, 0, absl::string_view()); session_.OnStreamFrame(frame); EXPECT_TRUE(stream->fin_received()); @@ -2217,7 +2250,7 @@ TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) { QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1), /* fin = */ false, /* offset = */ 0, - quiche::QuicheStringPiece("foo")); + absl::string_view("foo")); session_.OnStreamFrame(frame); } @@ -2232,6 +2265,30 @@ TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) { ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame()); } +TEST_P(QuicSessionTestClient, KeyUpdateFlagNotSet) { + SetQuicReloadableFlag(quic_key_update_supported, false); + EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally()) + .Times(0); + session_.Initialize(); + EXPECT_FALSE(session_.config()->KeyUpdateSupportedLocally()); +} + +TEST_P(QuicSessionTestClient, KeyUpdateNotSupportedLocallyAndFlagSet) { + SetQuicReloadableFlag(quic_key_update_supported, true); + EXPECT_CALL(*session_.GetMutableCryptoStream(), KeyUpdateSupportedLocally()) + .WillOnce(Return(false)); + session_.Initialize(); + EXPECT_FALSE(session_.config()->KeyUpdateSupportedLocally()); +} + +TEST_P(QuicSessionTestClient, KeyUpdateSupportedLocallyAndFlagSet) { + SetQuicReloadableFlag(quic_key_update_supported, true); + 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()); @@ -2255,6 +2312,7 @@ TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) { } TEST_P(QuicSessionTestServer, ZombieStreams) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); QuicStreamPeer::SetStreamBytesWritten(3, stream2); EXPECT_TRUE(stream2->IsWaitingForAcks()); @@ -2262,12 +2320,13 @@ TEST_P(QuicSessionTestServer, ZombieStreams) { CloseStream(stream2->id()); ASSERT_EQ(1u, session_.closed_streams()->size()); EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id()); - session_.OnStreamDoneWaitingForAcks(stream2->id()); + session_.MaybeCloseZombieStream(stream2->id()); EXPECT_EQ(1u, session_.closed_streams()->size()); EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id()); } TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) { + CompleteHandshake(); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); QuicStreamPeer::SetStreamBytesWritten(3, stream2); EXPECT_TRUE(stream2->IsWaitingForAcks()); @@ -2287,6 +2346,7 @@ TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) { // Regression test of b/71548958. TEST_P(QuicSessionTestServer, TestZombieStreams) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); @@ -2342,6 +2402,7 @@ TEST_P(QuicSessionTestServer, TestZombieStreams) { } TEST_P(QuicSessionTestServer, OnStreamFrameLost) { + CompleteHandshake(); InSequence s; // Drive congestion control manually. @@ -2418,6 +2479,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameLost) { } TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) { + CompleteHandshake(); InSequence s; TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); @@ -2457,6 +2519,7 @@ TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) { } TEST_P(QuicSessionTestServer, RetransmitFrames) { + CompleteHandshake(); MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); InSequence s; @@ -2493,6 +2556,7 @@ TEST_P(QuicSessionTestServer, RetransmitFrames) { // Regression test of b/110082001. TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) { + CompleteHandshake(); // This test mimics the scenario when a dynamic stream retransmits lost data // and causes connection close. TestStream* stream = session_.CreateOutgoingBidirectionalStream(); @@ -2531,16 +2595,10 @@ TEST_P(QuicSessionTestServer, SendMessage) { MakeSpan(connection_->helper()->GetStreamSendBufferAllocator(), "", &storage))); - // Finish handshake. - if (connection_->version().HasHandshakeDone()) { - EXPECT_CALL(*connection_, SendControlFrame(_)); - } - CryptoHandshakeMessage handshake_message; - connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); - session_.GetMutableCryptoStream()->OnHandshakeMessage(handshake_message); + CompleteHandshake(); EXPECT_TRUE(session_.OneRttKeysAvailable()); - quiche::QuicheStringPiece message; + absl::string_view message; EXPECT_CALL(*connection_, SendMessage(1, _, false)) .WillOnce(Return(MESSAGE_STATUS_SUCCESS)); EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1), @@ -2578,6 +2636,7 @@ TEST_P(QuicSessionTestServer, SendMessage) { // Regression test of b/115323618. TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) { + CompleteHandshake(); session_.set_writev_consumes_all_data(true); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); std::string body(100, '.'); @@ -2607,6 +2666,7 @@ TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) { } TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) { + CompleteHandshake(); EXPECT_FALSE( QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet()); @@ -2712,8 +2772,8 @@ TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) { .Times(1); char data[1024]; std::vector<std::pair<char*, size_t>> buffers; - buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data))); - buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data))); + buffers.push_back(std::make_pair(data, ABSL_ARRAYSIZE(data))); + buffers.push_back(std::make_pair(data, ABSL_ARRAYSIZE(data))); QuicTestMemSliceVector vector(buffers); stream4->WriteMemSlices(vector.span(), false); } @@ -2731,7 +2791,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) { return; } QuicStreamId bidirectional_stream_id = StreamCountToId( - QuicSessionPeer::v99_streamid_manager(&session_) + QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_bidirectional_streams() - 1, Perspective::IS_CLIENT, @@ -2743,7 +2803,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) { session_.OnStreamFrame(bidirectional_stream_frame); QuicStreamId unidirectional_stream_id = StreamCountToId( - QuicSessionPeer::v99_streamid_manager(&session_) + QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_unidirectional_streams() - 1, Perspective::IS_CLIENT, @@ -2761,7 +2821,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) { return; } QuicStreamId bidirectional_stream_id = - StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_) + StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_bidirectional_streams(), Perspective::IS_CLIENT, /*bidirectional=*/true); QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0, @@ -2770,7 +2830,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) { session_.OnStreamFrame(bidirectional_stream_frame); QuicStreamId unidirectional_stream_id = - StreamCountToId(QuicSessionPeer::v99_streamid_manager(&session_) + StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_unidirectional_streams(), Perspective::IS_CLIENT, /*bidirectional=*/false); QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false, @@ -2787,7 +2847,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) { } QuicStreamId bidirectional_stream_id = StreamCountToId( - QuicSessionPeer::v99_streamid_manager(&session_) + QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_bidirectional_streams() + 1, Perspective::IS_CLIENT, /*bidirectional=*/true); @@ -2800,7 +2860,7 @@ TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) { session_.OnStreamFrame(bidirectional_stream_frame); QuicStreamId unidirectional_stream_id = StreamCountToId( - QuicSessionPeer::v99_streamid_manager(&session_) + QuicSessionPeer::ietf_streamid_manager(&session_) ->advertised_max_incoming_unidirectional_streams() + 1, Perspective::IS_CLIENT, /*bidirectional=*/false); @@ -2879,7 +2939,7 @@ TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) { if (!VersionHasIetfQuicFrames(transport_version())) { return; } - + CompleteHandshake(); TestStream* stream = session_.CreateOutgoingBidirectionalStream(); QuicStreamId stream_id = stream->id(); CloseStream(stream_id); @@ -2906,6 +2966,7 @@ TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) { // If a STOP_SENDING is received for a peer initiated stream, the new stream // will be created. TEST_P(QuicSessionTestServer, OnStopSendingNewStream) { + CompleteHandshake(); if (!VersionHasIetfQuicFrames(transport_version())) { return; } @@ -2925,6 +2986,7 @@ TEST_P(QuicSessionTestServer, OnStopSendingNewStream) { // For a valid stream, ensure that all works TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) { + CompleteHandshake(); if (!VersionHasIetfQuicFrames(transport_version())) { // Applicable only to IETF QUIC return; @@ -2990,6 +3052,7 @@ TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) { } TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) { + CompleteHandshake(); if (!VersionHasIetfQuicFrames(transport_version())) { return; } @@ -3000,24 +3063,21 @@ TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) { .Times(1) .WillOnce(Invoke(&ClearControlFrame)); EXPECT_CALL(*connection_, OnStreamReset(read_only, _)); - session_.SendRstStream(read_only, QUIC_STREAM_CANCELLED, 0, - /*send_rst_only = */ false); + session_.ResetStream(read_only, QUIC_STREAM_CANCELLED); QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0); EXPECT_CALL(*connection_, SendControlFrame(_)) .Times(1) .WillOnce(Invoke(&ClearControlFrame)); EXPECT_CALL(*connection_, OnStreamReset(write_only, _)); - session_.SendRstStream(write_only, QUIC_STREAM_CANCELLED, 0, - /*send_rst_only = */ false); + session_.ResetStream(write_only, QUIC_STREAM_CANCELLED); QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0); EXPECT_CALL(*connection_, SendControlFrame(_)) .Times(2) .WillRepeatedly(Invoke(&ClearControlFrame)); EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _)); - session_.SendRstStream(bidirectional, QUIC_STREAM_CANCELLED, 0, - /*send_rst_only = */ false); + session_.ResetStream(bidirectional, QUIC_STREAM_CANCELLED); } TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) { @@ -3043,7 +3103,7 @@ TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) { QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1), /* fin = */ false, /* offset = */ 0, - quiche::QuicheStringPiece("foo")); + absl::string_view("foo")); session_.OnStreamFrame(frame); } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc index cbfe04f7d86..4f3c3fe26b3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_socket_address_coder_test.cc @@ -6,8 +6,8 @@ #include <string> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -111,7 +111,7 @@ TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) { {"::1", 65534}, }; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_case); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(test_case); i++) { QuicIpAddress ip; ASSERT_TRUE(ip.FromString(test_case[i].ip_literal)); QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port)); 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 d973549e555..aaef261106b 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 @@ -7,6 +7,8 @@ #include <limits> #include <string> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_flow_controller.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" @@ -16,11 +18,8 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" -using quiche::QuicheOptional; using spdy::SpdyPriority; namespace quic { @@ -109,6 +108,9 @@ QuicByteCount GetReceivedFlowControlWindow(QuicSession* session, // static const SpdyPriority QuicStream::kDefaultPriority; +// static +const int QuicStream::kDefaultUrgency; + PendingStream::PendingStream(QuicStreamId id, QuicSession* session) : id_(id), stream_delegate_(session), @@ -281,7 +283,7 @@ QuicStream::QuicStream(PendingStream* pending, namespace { -QuicheOptional<QuicFlowController> FlowController(QuicStreamId id, +absl::optional<QuicFlowController> FlowController(QuicStreamId id, QuicSession* session, StreamType type) { if (type == CRYPTO) { @@ -289,7 +291,7 @@ QuicheOptional<QuicFlowController> FlowController(QuicStreamId id, // it is using crypto frames instead of stream frames. The QuicCryptoStream // doesn't have any flow control in that case, so we don't create a // QuicFlowController for it. - return QuicheOptional<QuicFlowController>(); + return absl::nullopt; } return QuicFlowController( session, id, @@ -324,7 +326,7 @@ QuicStream::QuicStream(QuicStreamId id, StreamType type, uint64_t stream_bytes_read, bool fin_received, - QuicheOptional<QuicFlowController> flow_controller, + absl::optional<QuicFlowController> flow_controller, QuicFlowController* connection_flow_controller) : sequencer_(std::move(sequencer)), id_(id), @@ -343,6 +345,7 @@ QuicStream::QuicStream(QuicStreamId id, fin_received_(fin_received), rst_sent_(false), rst_received_(false), + stop_sending_sent_(false), flow_controller_(std::move(flow_controller)), connection_flow_controller_(connection_flow_controller), stream_contributes_to_connection_flow_control_(true), @@ -388,16 +391,6 @@ QuicStream::~QuicStream() { } } -// static -int QuicStream::DefaultUrgency() { - if (GetQuicReloadableFlag(quic_http3_new_default_urgency_value)) { - QUIC_RELOADABLE_FLAG_COUNT(quic_http3_new_default_urgency_value); - return 3; - } else { - return 1; - } -} - void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) { DCHECK_EQ(frame.stream_id, id_); @@ -505,10 +498,15 @@ bool QuicStream::OnStopSending(QuicRstStreamErrorCode code) { stream_error_ = code; - session()->SendRstStream(id(), code, stream_bytes_written(), - /*send_rst_only = */ true); - rst_sent_ = true; - CloseWriteSide(); + if (session()->split_up_send_rst()) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_split_up_send_rst_2, 1, 3); + MaybeSendRstStream(code); + } else { + session()->SendRstStream(id(), code, stream_bytes_written(), + /*send_rst_only = */ true); + rst_sent_ = true; + CloseWriteSide(); + } return true; } @@ -594,15 +592,24 @@ void QuicStream::SetFinSent() { void QuicStream::Reset(QuicRstStreamErrorCode error) { stream_error_ = error; - session()->SendRstStream(id(), error, stream_bytes_written(), - /*send_rst_only = */ false); - rst_sent_ = true; + if (session()->split_up_send_rst()) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_split_up_send_rst_2, 2, 3); + QuicConnection::ScopedPacketFlusher flusher(session()->connection()); + MaybeSendStopSending(error); + MaybeSendRstStream(error); + } else { + session()->SendRstStream(id(), error, stream_bytes_written(), + /*send_rst_only = */ false); + rst_sent_ = true; + } if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) { - session()->OnStreamDoneWaitingForAcks(id_); + session()->MaybeCloseZombieStream(id_); return; } - CloseReadSide(); - CloseWriteSide(); + if (!session()->split_up_send_rst()) { + CloseReadSide(); + CloseWriteSide(); + } } void QuicStream::OnUnrecoverableError(QuicErrorCode error, @@ -623,9 +630,26 @@ void QuicStream::SetPriority(const spdy::SpdyStreamPrecedence& precedence) { } void QuicStream::WriteOrBufferData( - quiche::QuicheStringPiece data, + absl::string_view data, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { + if (session()->use_write_or_buffer_data_at_level()) { + QUIC_BUG_IF(QuicUtils::IsCryptoStreamId(transport_version(), id_)) + << ENDPOINT + << "WriteOrBufferData is used to send application data, use " + "WriteOrBufferDataAtLevel to send crypto data."; + return WriteOrBufferDataAtLevel( + data, fin, session()->GetEncryptionLevelToSendApplicationData(), + ack_listener); + } + return WriteOrBufferDataInner(data, fin, absl::nullopt, ack_listener); +} + +void QuicStream::WriteOrBufferDataInner( + absl::string_view data, + bool fin, + absl::optional<EncryptionLevel> level, + QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { if (data.empty() && !fin) { QUIC_BUG << "data.empty() && !fin"; return; @@ -665,10 +689,20 @@ void QuicStream::WriteOrBufferData( } if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) { // Write data if there is no buffered data before. - WriteBufferedData(); + WriteBufferedData(level); } } +void QuicStream::WriteOrBufferDataAtLevel( + absl::string_view data, + bool fin, + EncryptionLevel level, + QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { + DCHECK(session()->use_write_or_buffer_data_at_level()); + QUIC_RELOADABLE_FLAG_COUNT(quic_use_write_or_buffer_data_at_level); + return WriteOrBufferDataInner(data, fin, level, ack_listener); +} + void QuicStream::OnCanWrite() { if (HasDeadlinePassed()) { OnDeadlinePassed(); @@ -688,7 +722,11 @@ void QuicStream::OnCanWrite() { return; } if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) { - WriteBufferedData(); + absl::optional<EncryptionLevel> send_level = absl::nullopt; + if (session()->use_write_or_buffer_data_at_level()) { + send_level = session()->GetEncryptionLevelToSendApplicationData(); + } + WriteBufferedData(send_level); } if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) { // Notify upper layer to write new data when buffered data size is below @@ -766,7 +804,11 @@ QuicConsumedData QuicStream::WriteMemSlices(QuicMemSliceSpan span, bool fin) { if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) { // Write data if there is no buffered data before. - WriteBufferedData(); + absl::optional<EncryptionLevel> send_level = absl::nullopt; + if (session()->use_write_or_buffer_data_at_level()) { + send_level = session()->GetEncryptionLevelToSendApplicationData(); + } + WriteBufferedData(send_level); } return consumed_data; @@ -813,6 +855,44 @@ void QuicStream::CloseWriteSide() { } } +void QuicStream::MaybeSendStopSending(QuicRstStreamErrorCode error) { + DCHECK(session()->split_up_send_rst()); + if (stop_sending_sent_) { + return; + } + + if (!session()->version().UsesHttp3() && error != QUIC_STREAM_NO_ERROR) { + // In gQUIC, RST with error closes both read and write side. + return; + } + + if (session()->version().UsesHttp3()) { + session()->MaybeSendStopSendingFrame(id(), error); + } else { + DCHECK_EQ(QUIC_STREAM_NO_ERROR, error); + session()->MaybeSendRstStreamFrame(id(), QUIC_STREAM_NO_ERROR, + stream_bytes_written()); + } + stop_sending_sent_ = true; + CloseReadSide(); +} + +void QuicStream::MaybeSendRstStream(QuicRstStreamErrorCode error) { + DCHECK(session()->split_up_send_rst()); + if (rst_sent_) { + return; + } + + if (!session()->version().UsesHttp3()) { + QUIC_BUG_IF(error == QUIC_STREAM_NO_ERROR); + stop_sending_sent_ = true; + CloseReadSide(); + } + session()->MaybeSendRstStreamFrame(id(), error, stream_bytes_written()); + rst_sent_ = true; + CloseWriteSide(); +} + bool QuicStream::HasBufferedData() const { DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written()); return send_buffer_.stream_offset() > stream_bytes_written(); @@ -835,14 +915,25 @@ void QuicStream::OnClose() { DCHECK(read_side_closed_ && write_side_closed_); if (!fin_sent_ && !rst_sent_) { - // For flow control accounting, tell the peer how many bytes have been - // written on this stream before termination. Done here if needed, using a - // RST_STREAM frame. - QUIC_DLOG(INFO) << ENDPOINT << "Sending RST_STREAM in OnClose: " << id(); - session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, - stream_bytes_written(), /*send_rst_only = */ false); - session_->OnStreamDoneWaitingForAcks(id_); - rst_sent_ = true; + if (!session()->split_up_send_rst()) { + // For flow control accounting, tell the peer how many bytes have been + // written on this stream before termination. Done here if needed, using a + // RST_STREAM frame. + QUIC_DLOG(INFO) << ENDPOINT << "Sending RST_STREAM in OnClose: " << id(); + session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, + stream_bytes_written(), + /*send_rst_only = */ false); + session_->MaybeCloseZombieStream(id_); + rst_sent_ = true; + } else { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_split_up_send_rst_2, 3, 3); + QUIC_BUG_IF(session()->connection()->connected() && + session()->version().UsesHttp3()) + << "The stream should've already sent RST in response to " + "STOP_SENDING"; + MaybeSendRstStream(QUIC_RST_ACKNOWLEDGEMENT); + session_->MaybeCloseZombieStream(id_); + } } if (!flow_controller_.has_value() || @@ -1019,7 +1110,7 @@ bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset, fin_lost_ = false; } if (!IsWaitingForAcks() && read_side_closed_ && write_side_closed_) { - session_->OnStreamDoneWaitingForAcks(id_); + session_->MaybeCloseZombieStream(id_); } return new_data_acked; } @@ -1064,6 +1155,10 @@ bool QuicStream::RetransmitStreamData(QuicStreamOffset offset, if (retransmission.Empty() && !retransmit_fin) { return true; } + absl::optional<EncryptionLevel> send_level = absl::nullopt; + if (session()->use_write_or_buffer_data_at_level()) { + send_level = session()->GetEncryptionLevelToSendApplicationData(); + } QuicConsumedData consumed(0, false); for (const auto& interval : retransmission) { QuicStreamOffset retransmission_offset = interval.min(); @@ -1073,7 +1168,7 @@ bool QuicStream::RetransmitStreamData(QuicStreamOffset offset, stream_bytes_written()); consumed = stream_delegate_->WritevData( id_, retransmission_length, retransmission_offset, - can_bundle_fin ? FIN : NO_FIN, type, QUICHE_NULLOPT); + can_bundle_fin ? FIN : NO_FIN, type, send_level); QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " is forced to retransmit stream data [" << retransmission_offset << ", " @@ -1095,7 +1190,7 @@ bool QuicStream::RetransmitStreamData(QuicStreamOffset offset, QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " retransmits fin only frame."; consumed = stream_delegate_->WritevData(id_, 0, stream_bytes_written(), FIN, - type, QUICHE_NULLOPT); + type, send_level); if (!consumed.fin_consumed) { return false; } @@ -1121,7 +1216,7 @@ bool QuicStream::WriteStreamData(QuicStreamOffset offset, return send_buffer_.WriteStreamData(offset, data_length, writer); } -void QuicStream::WriteBufferedData() { +void QuicStream::WriteBufferedData(absl::optional<EncryptionLevel> level) { DCHECK(!write_side_closed_ && (HasBufferedData() || fin_buffered_)); if (session_->ShouldYield(id())) { @@ -1173,7 +1268,7 @@ void QuicStream::WriteBufferedData() { } QuicConsumedData consumed_data = stream_delegate_->WritevData(id(), write_length, stream_bytes_written(), - state, NOT_RETRANSMISSION, QUICHE_NULLOPT); + state, NOT_RETRANSMISSION, level); OnStreamDataConsumed(consumed_data.bytes_consumed); @@ -1244,12 +1339,15 @@ void QuicStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) { void QuicStream::WritePendingRetransmission() { while (HasPendingRetransmission()) { QuicConsumedData consumed(0, false); + absl::optional<EncryptionLevel> send_level = absl::nullopt; + if (session()->use_write_or_buffer_data_at_level()) { + send_level = session()->GetEncryptionLevelToSendApplicationData(); + } if (!send_buffer_.HasPendingRetransmission()) { QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " retransmits fin only frame."; - consumed = - stream_delegate_->WritevData(id_, 0, stream_bytes_written(), FIN, - LOSS_RETRANSMISSION, QUICHE_NULLOPT); + consumed = stream_delegate_->WritevData( + id_, 0, stream_bytes_written(), FIN, LOSS_RETRANSMISSION, send_level); fin_lost_ = !consumed.fin_consumed; if (fin_lost_) { // Connection is write blocked. @@ -1264,7 +1362,7 @@ void QuicStream::WritePendingRetransmission() { (pending.offset + pending.length == stream_bytes_written()); consumed = stream_delegate_->WritevData( id_, pending.length, pending.offset, can_bundle_fin ? FIN : NO_FIN, - LOSS_RETRANSMISSION, QUICHE_NULLOPT); + LOSS_RETRANSMISSION, send_level); QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " tries to retransmit stream data [" << pending.offset << ", " << pending.offset + pending.length @@ -1341,7 +1439,7 @@ void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) { spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority( const QuicSession* session) { if (VersionUsesHttp3(session->transport_version())) { - return spdy::SpdyStreamPrecedence(DefaultUrgency()); + return spdy::SpdyStreamPrecedence(kDefaultUrgency); } if (session->use_http2_priority_write_scheduler()) { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream.h index f0a5a714a21..50fc5e1a182 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream.h @@ -22,6 +22,8 @@ #include <list> #include <string> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_flow_controller.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h" @@ -32,8 +34,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" namespace quic { @@ -142,9 +142,7 @@ class QUIC_EXPORT_PRIVATE QuicStream // Default priority for IETF QUIC, defined by the priority extension at // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html#urgency. - // TODO(bnc): Remove this method and reinstate static const int - // kDefaultUrgency member when removing quic_http3_new_default_urgency_value. - static int DefaultUrgency(); + static const int kDefaultUrgency = 3; // QuicStreamSequencer::StreamInterface implementation. QuicStreamId id() const override { return id_; } @@ -206,6 +204,7 @@ class QUIC_EXPORT_PRIVATE QuicStream return sequencer_.ignore_read_data() || read_side_closed_; } bool write_side_closed() const { return write_side_closed_; } + bool read_side_closed() const { return read_side_closed_; } bool IsZombie() const { return read_side_closed_ && write_side_closed_ && IsWaitingForAcks(); @@ -274,15 +273,23 @@ class QUIC_EXPORT_PRIVATE QuicStream // stop sending stream-level flow-control updates when this end sends FIN. virtual void StopReading(); - // Sends as much of 'data' to the connection as the connection will consume, - // and then buffers any remaining data in queued_data_. - // If fin is true: if it is immediately passed on to the session, - // write_side_closed() becomes true, otherwise fin_buffered_ becomes true. + // Sends as much of |data| to the connection on the application encryption + // level as the connection will consume, and then buffers any remaining data + // in the send buffer. If fin is true: if it is immediately passed on to the + // session, write_side_closed() becomes true, otherwise fin_buffered_ becomes + // true. void WriteOrBufferData( - quiche::QuicheStringPiece data, + absl::string_view data, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); + // Sends |data| to connection with specified |level|. + void WriteOrBufferDataAtLevel( + absl::string_view data, + bool fin, + EncryptionLevel level, + QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); + // Adds random padding after the fin is consumed for this stream. void AddRandomPaddingAfterFin(); @@ -402,6 +409,12 @@ class QUIC_EXPORT_PRIVATE QuicStream // empty. void SetFinSent(); + // Send STOP_SENDING if it hasn't been sent yet. + void MaybeSendStopSending(QuicRstStreamErrorCode error); + + // Send RESET_STREAM if it hasn't been sent yet. + void MaybeSendRstStream(QuicRstStreamErrorCode error); + // Close the write side of the socket. Further writes will fail. // Can be called by the subclass or internally. // Does not send a FIN. May cause the stream to be closed. @@ -439,7 +452,7 @@ class QUIC_EXPORT_PRIVATE QuicStream StreamType type, uint64_t stream_bytes_read, bool fin_received, - quiche::QuicheOptional<QuicFlowController> flow_controller, + absl::optional<QuicFlowController> flow_controller, QuicFlowController* connection_flow_controller); // Calls MaybeSendBlocked on the stream's flow controller and the connection @@ -448,9 +461,10 @@ class QUIC_EXPORT_PRIVATE QuicStream // controller, marks this stream as connection-level write blocked. void MaybeSendBlocked(); - // Write buffered data in send buffer. TODO(fayang): Consider combine - // WriteOrBufferData, Writev and WriteBufferedData. - void WriteBufferedData(); + // Write buffered data in send buffer. + // TODO(fayang): Change absl::optional<EncryptionLevel> to EncryptionLevel + // when deprecating quic_use_write_or_buffer_data_at_level. + void WriteBufferedData(absl::optional<EncryptionLevel> level); // Close the read side of the stream. May cause the stream to be closed. void CloseReadSide(); @@ -458,6 +472,14 @@ class QUIC_EXPORT_PRIVATE QuicStream // Called when bytes are sent to the peer. void AddBytesSent(QuicByteCount bytes); + // TODO(fayang): Inline this function when deprecating + // quic_use_write_or_buffer_data_at_level. + void WriteOrBufferDataInner( + absl::string_view data, + bool fin, + absl::optional<EncryptionLevel> level, + QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); + // Returns true if deadline_ has passed. bool HasDeadlinePassed() const; @@ -508,7 +530,10 @@ class QUIC_EXPORT_PRIVATE QuicStream // True if this stream has received a RST_STREAM frame. bool rst_received_; - quiche::QuicheOptional<QuicFlowController> flow_controller_; + // True if the stream has sent STOP_SENDING to the session. + bool stop_sending_sent_; + + absl::optional<QuicFlowController> flow_controller_; // The connection level flow controller. Not owned. QuicFlowController* connection_flow_controller_; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc index 6232887d678..0d5471e2aee 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_send_buffer_test.cc @@ -6,6 +6,7 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -15,13 +16,12 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { namespace { -struct iovec MakeIovec(quiche::QuicheStringPiece data) { +struct iovec MakeIovec(absl::string_view data) { struct iovec iov = {const_cast<char*>(data.data()), static_cast<size_t>(data.size())}; return iov; @@ -36,8 +36,8 @@ class QuicStreamSendBufferTest : public QuicTest { std::string data1(1536, 'a'); std::string data2 = std::string(256, 'b') + std::string(256, 'c'); struct iovec iov[2]; - iov[0] = MakeIovec(quiche::QuicheStringPiece(data1)); - iov[1] = MakeIovec(quiche::QuicheStringPiece(data2)); + iov[0] = MakeIovec(absl::string_view(data1)); + iov[1] = MakeIovec(absl::string_view(data2)); QuicUniqueBufferPtr buffer1 = MakeUniqueBuffer(&allocator_, 1024); memset(buffer1.get(), 'c', 1024); @@ -88,23 +88,23 @@ TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) { std::string copy4(768, 'd'); ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer)); - EXPECT_EQ(copy1, quiche::QuicheStringPiece(buf, 1024)); + EXPECT_EQ(copy1, absl::string_view(buf, 1024)); ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer)); - EXPECT_EQ(copy2, quiche::QuicheStringPiece(buf + 1024, 1024)); + EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024)); ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer)); - EXPECT_EQ(copy3, quiche::QuicheStringPiece(buf + 2048, 1024)); + EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024)); ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer)); - EXPECT_EQ(copy4, quiche::QuicheStringPiece(buf + 3072, 768)); + EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768)); // Test data piece across boundries. QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER); std::string copy5 = std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c'); ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2)); - EXPECT_EQ(copy5, quiche::QuicheStringPiece(buf, 1024)); + EXPECT_EQ(copy5, absl::string_view(buf, 1024)); ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2)); std::string copy6 = std::string(572, 'c') + std::string(452, 'd'); - EXPECT_EQ(copy6, quiche::QuicheStringPiece(buf + 1024, 1024)); + EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024)); // Invalid data copy. QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER); @@ -129,21 +129,20 @@ TEST_F(QuicStreamSendBufferTest, // Write more than one slice. EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_)); ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer)); - EXPECT_EQ(copy1, quiche::QuicheStringPiece(buf, 1024)); + EXPECT_EQ(copy1, absl::string_view(buf, 1024)); EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_)); // Retransmit the first frame and also send new data. ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer)); - EXPECT_EQ(copy1 + copy2, quiche::QuicheStringPiece(buf + 1024, 2048)); + EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048)); // Write new data. EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_)); ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer)); - EXPECT_EQ(std::string(50, 'c'), - quiche::QuicheStringPiece(buf + 1024 + 2048, 50)); + EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50)); EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_)); ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer)); - EXPECT_EQ(copy3, quiche::QuicheStringPiece(buf + 1024 + 2048 + 50, 1124)); + EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124)); EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_)); } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc index 0dfc8f7c103..7d1c237bb40 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer.cc @@ -10,6 +10,7 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_clock.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -65,8 +65,8 @@ void QuicStreamSequencer::OnFrameData(QuicStreamOffset byte_offset, size_t bytes_written; std::string error_details; QuicErrorCode result = buffered_frames_.OnStreamData( - byte_offset, quiche::QuicheStringPiece(data_buffer, data_len), - &bytes_written, &error_details); + byte_offset, absl::string_view(data_buffer, data_len), &bytes_written, + &error_details); if (result != QUIC_NO_ERROR) { std::string details = quiche::QuicheStrCat("Stream ", stream_->id(), ": ", QuicErrorCodeToString(result), diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc index 8a26521a4da..6f399381a4d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.cc @@ -4,8 +4,12 @@ #include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h" +#include <algorithm> +#include <cstddef> +#include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_interval.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" @@ -13,7 +17,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace { @@ -28,13 +31,24 @@ size_t CalculateBlockCount(size_t max_capacity_bytes) { // arrives. const size_t kMaxNumDataIntervalsAllowed = 2 * kMaxPacketGap; +// Number of blocks allocated initially. +constexpr size_t kInitialBlockCount = 8u; + +// How fast block pointers container grow in size. +// Choose 4 to reduce the amount of reallocation. +constexpr int kBlocksGrowthFactor = 4; + } // namespace QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes) : max_buffer_capacity_bytes_(max_capacity_bytes), - blocks_count_(CalculateBlockCount(max_capacity_bytes)), + max_blocks_count_(CalculateBlockCount(max_capacity_bytes)), + current_blocks_count_(0u), total_bytes_read_(0), blocks_(nullptr) { + if (allocate_blocks_on_demand_) { + DCHECK_GE(max_blocks_count_, kInitialBlockCount); + } Clear(); } @@ -44,7 +58,9 @@ QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() { void QuicStreamSequencerBuffer::Clear() { if (blocks_ != nullptr) { - for (size_t i = 0; i < blocks_count_; ++i) { + size_t blocks_to_clear = + allocate_blocks_on_demand_ ? current_blocks_count_ : max_blocks_count_; + for (size_t i = 0; i < blocks_to_clear; ++i) { if (blocks_[i] != nullptr) { RetireBlock(i); } @@ -66,9 +82,38 @@ bool QuicStreamSequencerBuffer::RetireBlock(size_t index) { return true; } +void QuicStreamSequencerBuffer::MaybeAddMoreBlocks(size_t next_expected_byte) { + if (current_blocks_count_ == max_blocks_count_) { + return; + } + size_t last_byte = next_expected_byte - 1; + size_t num_of_blocks_needed; + // As long as last_byte does not wrap around, its index plus one blocks are + // needed. Otherwise, block_count_ blocks are needed. + if (last_byte < max_buffer_capacity_bytes_) { + num_of_blocks_needed = + std::max(GetBlockIndex(last_byte) + 1, kInitialBlockCount); + } else { + num_of_blocks_needed = max_blocks_count_; + } + if (current_blocks_count_ >= num_of_blocks_needed) { + return; + } + size_t new_block_count = kBlocksGrowthFactor * current_blocks_count_; + new_block_count = std::min(std::max(new_block_count, num_of_blocks_needed), + max_blocks_count_); + auto new_blocks = std::make_unique<BufferBlock*[]>(new_block_count); + if (blocks_ != nullptr) { + memcpy(new_blocks.get(), blocks_.get(), + current_blocks_count_ * sizeof(BufferBlock*)); + } + blocks_ = std::move(new_blocks); + current_blocks_count_ = new_block_count; +} + QuicErrorCode QuicStreamSequencerBuffer::OnStreamData( QuicStreamOffset starting_offset, - quiche::QuicheStringPiece data, + absl::string_view data, size_t* const bytes_buffered, std::string* error_details) { *bytes_buffered = 0; @@ -83,6 +128,12 @@ QuicErrorCode QuicStreamSequencerBuffer::OnStreamData( *error_details = "Received data beyond available range."; return QUIC_INTERNAL_ERROR; } + if (allocate_blocks_on_demand_) { + QUIC_RELOADABLE_FLAG_COUNT( + quic_allocate_stream_sequencer_buffer_blocks_on_demand); + MaybeAddMoreBlocks(starting_offset + size); + } + if (bytes_received_.Empty() || starting_offset >= bytes_received_.rbegin()->max() || bytes_received_.IsDisjoint(QuicInterval<QuicStreamOffset>( @@ -135,7 +186,7 @@ QuicErrorCode QuicStreamSequencerBuffer::OnStreamData( } bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset, - quiche::QuicheStringPiece data, + absl::string_view data, size_t* bytes_copy, std::string* error_details) { *bytes_copy = 0; @@ -150,7 +201,9 @@ bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset, while (source_remaining > 0) { const size_t write_block_num = GetBlockIndex(offset); const size_t write_block_offset = GetInBlockOffset(offset); - DCHECK_GT(blocks_count_, write_block_num); + size_t current_blocks_count = + allocate_blocks_on_demand_ ? current_blocks_count_ : max_blocks_count_; + DCHECK_GT(current_blocks_count, write_block_num); size_t block_capacity = GetBlockCapacity(write_block_num); size_t bytes_avail = block_capacity - write_block_offset; @@ -161,19 +214,21 @@ bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset, bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset; } - if (blocks_ == nullptr) { - blocks_.reset(new BufferBlock*[blocks_count_]()); - for (size_t i = 0; i < blocks_count_; ++i) { - blocks_[i] = nullptr; + if (!allocate_blocks_on_demand_) { + if (blocks_ == nullptr) { + blocks_.reset(new BufferBlock*[max_blocks_count_]()); + for (size_t i = 0; i < max_blocks_count_; ++i) { + blocks_[i] = nullptr; + } } } - if (write_block_num >= blocks_count_) { + if (write_block_num >= current_blocks_count) { *error_details = quiche::QuicheStrCat( "QuicStreamSequencerBuffer error: OnStreamData() exceed array bounds." "write offset = ", offset, " write_block_num = ", write_block_num, - " blocks_count_ = ", blocks_count_); + " current_blocks_count_ = ", current_blocks_count); return false; } if (blocks_ == nullptr) { @@ -307,14 +362,14 @@ int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov, // before gap is met or |iov| is filled. For these blocks, one whole block is // a region. int iov_used = 1; - size_t block_idx = (start_block_idx + iov_used) % blocks_count_; + size_t block_idx = (start_block_idx + iov_used) % max_blocks_count_; while (block_idx != end_block_idx && iov_used < iov_len) { DCHECK(nullptr != blocks_[block_idx]); iov[iov_used].iov_base = blocks_[block_idx]->buffer; iov[iov_used].iov_len = GetBlockCapacity(block_idx); QUIC_DVLOG(1) << "Got block with index: " << block_idx; ++iov_used; - block_idx = (start_block_idx + iov_used) % blocks_count_; + block_idx = (start_block_idx + iov_used) % max_blocks_count_; } // Deal with last block if |iov| can hold more. @@ -397,6 +452,7 @@ size_t QuicStreamSequencerBuffer::FlushBufferedFrames() { void QuicStreamSequencerBuffer::ReleaseWholeBuffer() { Clear(); + current_blocks_count_ = 0; blocks_.reset(nullptr); } @@ -472,7 +528,7 @@ bool QuicStreamSequencerBuffer::Empty() const { } size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const { - if ((block_index + 1) == blocks_count_) { + if ((block_index + 1) == max_blocks_count_) { size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes; if (result == 0) { // whole block result = kBlockSizeBytes; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h index 0ad984117de..674e3d91dfb 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h @@ -28,11 +28,11 @@ // Expected Use: // QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024); // std::string source(1024, 'a'); -// quiche::QuicheStringPiece string_piece(source.data(), source.size()); +// absl::string_view string_piece(source.data(), source.size()); // size_t written = 0; // buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written); // source = std::string{800, 'b'}; -// quiche::QuicheStringPiece string_piece1(source.data(), 800); +// absl::string_view string_piece1(source.data(), 800); // // Try to write to [1, 801), but should fail due to overlapping, // // res should be QUIC_INVALID_STREAM_DATA // auto res = buffer.OnStreamData(1, string_piece1, &written)); @@ -64,12 +64,12 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_interval_set.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_iovec.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -107,7 +107,7 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer { // successfully buffered, returns QUIC_NO_ERROR and stores the number of // bytes buffered in |bytes_buffered|. Returns an error otherwise. QuicErrorCode OnStreamData(QuicStreamOffset offset, - quiche::QuicheStringPiece data, + absl::string_view data, size_t* bytes_buffered, std::string* error_details); @@ -168,7 +168,7 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer { // Copies |data| to blocks_, sets |bytes_copy|. Returns true if the copy is // successful. Otherwise, sets |error_details| and returns false. bool CopyStreamData(QuicStreamOffset offset, - quiche::QuicheStringPiece data, + absl::string_view data, size_t* bytes_copy, std::string* error_details); @@ -212,17 +212,29 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer { // Return all received frames as a string. std::string ReceivedFramesDebugString() const; + // Resize blocks_ if more blocks are needed to accomodate bytes before + // next_expected_byte. + void MaybeAddMoreBlocks(size_t next_expected_byte); + // The maximum total capacity of this buffer in byte, as constructed. size_t max_buffer_capacity_bytes_; - // How many blocks this buffer would need when it reaches full capacity. - size_t blocks_count_; + // Number of blocks this buffer would have when it reaches full capacity, + // i.e., maximal number of blocks in blocks_. + size_t max_blocks_count_; + + // Number of blocks this buffer currently has. + size_t current_blocks_count_; // Number of bytes read out of buffer. QuicStreamOffset total_bytes_read_; + // Whether size of blocks_ grows on demand. + bool allocate_blocks_on_demand_ = GetQuicReloadableFlag( + quic_allocate_stream_sequencer_buffer_blocks_on_demand); + // An ordered, variable-length list of blocks, with the length limited - // such that the number of blocks never exceeds blocks_count_. + // such that the number of blocks never exceeds max_blocks_count_. // Each list entry can hold up to kBlockSizeBytes bytes. std::unique_ptr<BufferBlock*[]> blocks_; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc index 7341983d4a5..0ad7244ea35 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer_test.cc @@ -11,20 +11,20 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { -quiche::QuicheStringPiece IovecToStringPiece(iovec iov) { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(iov.iov_base), - iov.iov_len); +absl::string_view IovecToStringPiece(iovec iov) { + return absl::string_view(reinterpret_cast<const char*>(iov.iov_base), + iov.iov_len); } char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) { @@ -52,7 +52,7 @@ const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap; static const size_t kBlockSizeBytes = QuicStreamSequencerBuffer::kBlockSizeBytes; -typedef QuicStreamSequencerBuffer::BufferBlock BufferBlock; +using BufferBlock = QuicStreamSequencerBuffer::BufferBlock; namespace { @@ -72,10 +72,10 @@ class QuicStreamSequencerBufferTest : public QuicTest { helper_ = std::make_unique<QuicStreamSequencerBufferPeer>((buffer_.get())); } - // Use 2.5 here to make sure the buffer has more than one block and its end - // doesn't align with the end of a block in order to test all the offset - // calculation. - size_t max_capacity_bytes_ = 2.5 * kBlockSizeBytes; + // Use 8.5 here to make sure that the buffer has more than + // QuicStreamSequencerBuffer::kInitialBlockCount block and its end doesn't + // align with the end of a block in order to test all the offset calculation. + size_t max_capacity_bytes_ = 8.5 * kBlockSizeBytes; std::unique_ptr<QuicStreamSequencerBuffer> buffer_; std::unique_ptr<QuicStreamSequencerBufferPeer> helper_; @@ -86,18 +86,18 @@ class QuicStreamSequencerBufferTest : public QuicTest { TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) { ResetMaxCapacityBytes(16 * 1024 * 1024); // 16MB EXPECT_EQ(2 * 1024u, // 16MB / 8KB = 2K - helper_->block_count()); + helper_->max_blocks_count()); EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity()); EXPECT_TRUE(helper_->CheckInitialState()); } TEST_F(QuicStreamSequencerBufferTest, InitializationWithDifferentSizes) { - const size_t kCapacity = 2 * QuicStreamSequencerBuffer::kBlockSizeBytes; + const size_t kCapacity = 16 * QuicStreamSequencerBuffer::kBlockSizeBytes; ResetMaxCapacityBytes(kCapacity); EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity()); EXPECT_TRUE(helper_->CheckInitialState()); - const size_t kCapacity1 = 8 * QuicStreamSequencerBuffer::kBlockSizeBytes; + const size_t kCapacity1 = 32 * QuicStreamSequencerBuffer::kBlockSizeBytes; ResetMaxCapacityBytes(kCapacity1); EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity()); EXPECT_TRUE(helper_->CheckInitialState()); @@ -159,8 +159,8 @@ TEST_F(QuicStreamSequencerBufferTest, Move) { TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInvalidSource) { // Pass in an invalid source, expects to return error. - quiche::QuicheStringPiece source; - source = quiche::QuicheStringPiece(nullptr, 1024); + absl::string_view source; + source = absl::string_view(nullptr, 1024); EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_), IsError(QUIC_STREAM_SEQUENCER_INVALID_STATE)); EXPECT_EQ(0u, error_details_.find(quiche::QuicheStrCat( @@ -320,7 +320,7 @@ TEST_F(QuicStreamSequencerBufferTest, Readv100Bytes) { QUIC_LOG(ERROR) << error_details_; EXPECT_EQ(100u, read); EXPECT_EQ(100u, buffer_->BytesConsumed()); - EXPECT_EQ(source, quiche::QuicheStringPiece(dest, read)); + EXPECT_EQ(source, absl::string_view(dest, read)); // The first block should be released as its data has been read out. EXPECT_EQ(nullptr, helper_->GetBlock(0)); EXPECT_TRUE(helper_->CheckBufferInvariants()); @@ -399,7 +399,7 @@ TEST_F(QuicStreamSequencerBufferTest, // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes, // max_capacity_bytes_ + 512 + 1). But last bytes exceeds current capacity. source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b'); - EXPECT_THAT(buffer_->OnStreamData(2 * kBlockSizeBytes, source, &written_, + EXPECT_THAT(buffer_->OnStreamData(8 * kBlockSizeBytes, source, &written_, &error_details_), IsError(QUIC_INTERNAL_ERROR)); EXPECT_TRUE(helper_->CheckBufferInvariants()); @@ -523,15 +523,15 @@ TEST_F(QuicStreamSequencerBufferTest, TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsWithMultipleIOVsAcrossEnd) { - // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024) + // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024) // and then append 1024 + 512 bytes. - std::string source(2.5 * kBlockSizeBytes - 1024, 'a'); + std::string source(8.5 * kBlockSizeBytes - 1024, 'a'); buffer_->OnStreamData(0, source, &written_, &error_details_); char dest[1024]; helper_->Read(dest, 1024); // Write across the end. source = std::string(1024 + 512, 'b'); - buffer_->OnStreamData(2.5 * kBlockSizeBytes - 1024, source, &written_, + buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_, &error_details_); // Use short iovec's. iovec iovs[2]; @@ -540,11 +540,11 @@ TEST_F(QuicStreamSequencerBufferTest, EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len); EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len); // Use long iovec's and wrap the end of buffer. - iovec iovs1[5]; - EXPECT_EQ(4, buffer_->GetReadableRegions(iovs1, 5)); - EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[2].iov_len); - EXPECT_EQ(512u, iovs1[3].iov_len); - EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[3])); + iovec iovs1[11]; + EXPECT_EQ(10, buffer_->GetReadableRegions(iovs1, 11)); + EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[8].iov_len); + EXPECT_EQ(512u, iovs1[9].iov_len); + EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[9])); } TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionEmpty) { @@ -610,8 +610,7 @@ TEST_F(QuicStreamSequencerBufferTest, PeekSingleBlock) { // Peek at a different offset. EXPECT_TRUE(buffer_->PeekRegion(100, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source).substr(100), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source).substr(100), IovecToStringPiece(iov)); // Peeking at or after FirstMissingByte() returns false. EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes, &iov)); @@ -638,15 +637,15 @@ TEST_F(QuicStreamSequencerBufferTest, PeekTwoWritesInSingleBlock) { // Peek with an offset inside the first write. const QuicStreamOffset offset1 = 500; EXPECT_TRUE(buffer_->PeekRegion(offset1, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source1).substr(offset1), + EXPECT_EQ(absl::string_view(source1).substr(offset1), IovecToStringPiece(iov).substr(0, length1 - offset1)); - EXPECT_EQ(quiche::QuicheStringPiece(source2), + EXPECT_EQ(absl::string_view(source2), IovecToStringPiece(iov).substr(length1 - offset1)); // Peek with an offset inside the second write. const QuicStreamOffset offset2 = 1500; EXPECT_TRUE(buffer_->PeekRegion(offset2, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source2).substr(offset2 - length1), + EXPECT_EQ(absl::string_view(source2).substr(offset2 - length1), IovecToStringPiece(iov)); // Peeking at or after FirstMissingByte() returns false. @@ -671,19 +670,16 @@ TEST_F(QuicStreamSequencerBufferTest, PeekBufferWithMultipleBlocks) { EXPECT_TRUE(buffer_->PeekRegion(0, &iov)); EXPECT_EQ(kBlockSizeBytes, iov.iov_len); EXPECT_EQ(source1, IovecToStringPiece(iov).substr(0, length1)); - EXPECT_EQ( - quiche::QuicheStringPiece(source2).substr(0, kBlockSizeBytes - length1), - IovecToStringPiece(iov).substr(length1)); + EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1), + IovecToStringPiece(iov).substr(length1)); EXPECT_TRUE(buffer_->PeekRegion(length1, &iov)); - EXPECT_EQ( - quiche::QuicheStringPiece(source2).substr(0, kBlockSizeBytes - length1), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1), + IovecToStringPiece(iov)); EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov)); - EXPECT_EQ( - quiche::QuicheStringPiece(source2).substr(kBlockSizeBytes - length1), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source2).substr(kBlockSizeBytes - length1), + IovecToStringPiece(iov)); // Peeking at or after FirstMissingByte() returns false. EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov)); @@ -706,12 +702,10 @@ TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) { EXPECT_FALSE(buffer_->PeekRegion(512, &iov)); EXPECT_TRUE(buffer_->PeekRegion(1024, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source1).substr(1024), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source1).substr(1024), IovecToStringPiece(iov)); EXPECT_TRUE(buffer_->PeekRegion(1500, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source1).substr(1500), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source1).substr(1500), IovecToStringPiece(iov)); // Consume rest of block. EXPECT_TRUE(buffer_->MarkConsumed(kBlockSizeBytes - 1024)); @@ -725,8 +719,7 @@ TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) { EXPECT_EQ(source2, IovecToStringPiece(iov)); EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes + 128, &iov)); - EXPECT_EQ(quiche::QuicheStringPiece(source2).substr(128), - IovecToStringPiece(iov)); + EXPECT_EQ(absl::string_view(source2).substr(128), IovecToStringPiece(iov)); // Peeking into consumed data still fails. EXPECT_FALSE(buffer_->PeekRegion(0, &iov)); @@ -802,20 +795,20 @@ TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossBlock) { } TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) { - // Write into [0, 2.5 * kBlockSizeBytes - 1024) and then read out [0, 1024) + // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024) // and then append 1024 + 512 bytes. - std::string source(2.5 * kBlockSizeBytes - 1024, 'a'); + std::string source(8.5 * kBlockSizeBytes - 1024, 'a'); buffer_->OnStreamData(0, source, &written_, &error_details_); char dest[1024]; helper_->Read(dest, 1024); source = std::string(1024 + 512, 'b'); - buffer_->OnStreamData(2.5 * kBlockSizeBytes - 1024, source, &written_, + buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_, &error_details_); EXPECT_EQ(1024u, buffer_->BytesConsumed()); - // Consume to the end of 2nd block. - buffer_->MarkConsumed(2 * kBlockSizeBytes - 1024); - EXPECT_EQ(2 * kBlockSizeBytes, buffer_->BytesConsumed()); + // Consume to the end of 8th block. + buffer_->MarkConsumed(8 * kBlockSizeBytes - 1024); + EXPECT_EQ(8 * kBlockSizeBytes, buffer_->BytesConsumed()); // Consume across the physical end of buffer buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500); EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed()); @@ -828,7 +821,7 @@ TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) { } TEST_F(QuicStreamSequencerBufferTest, FlushBufferedFrames) { - // Write into [0, 2.5 * kBlockSizeBytes - 1024) and then read out [0, 1024). + // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024). std::string source(max_capacity_bytes_ - 1024, 'a'); buffer_->OnStreamData(0, source, &written_, &error_details_); char dest[1024]; @@ -871,12 +864,12 @@ TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) { class QuicStreamSequencerBufferRandomIOTest : public QuicStreamSequencerBufferTest { public: - typedef std::pair<QuicStreamOffset, size_t> OffsetSizePair; + using OffsetSizePair = std::pair<QuicStreamOffset, size_t>; void SetUp() override { // Test against a larger capacity then above tests. Also make sure the last // block is partially available to use. - max_capacity_bytes_ = 6.25 * kBlockSizeBytes; + max_capacity_bytes_ = 8.25 * kBlockSizeBytes; // Stream to be buffered should be larger than the capacity to test wrap // around. bytes_to_buffer_ = 2 * max_capacity_bytes_; @@ -933,7 +926,7 @@ class QuicStreamSequencerBufferRandomIOTest for (size_t i = 0; i < num_to_write; ++i) { write_buf[i] = (offset + i) % 256; } - quiche::QuicheStringPiece string_piece_w(write_buf.get(), num_to_write); + absl::string_view string_piece_w(write_buf.get(), num_to_write); auto result = buffer_->OnStreamData(offset, string_piece_w, &written_, &error_details_); if (result == QUIC_NO_ERROR) { @@ -1097,6 +1090,50 @@ TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) { EXPECT_LE(bytes_to_buffer_, total_bytes_written_); } +TEST_F(QuicStreamSequencerBufferTest, GrowBlockSizeOnDemand) { + SetQuicReloadableFlag(quic_allocate_stream_sequencer_buffer_blocks_on_demand, + true); + max_capacity_bytes_ = 1024 * kBlockSizeBytes; + std::string source_of_one_block(kBlockSizeBytes, 'a'); + Initialize(); + + ASSERT_EQ(helper_->current_blocks_count(), 0u); + + // A minimum of 8 blocks are allocated + buffer_->OnStreamData(0, source_of_one_block, &written_, &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 8u); + + // Number of blocks doesn't grow if the data is within the capacity. + buffer_->OnStreamData(kBlockSizeBytes * 7, source_of_one_block, &written_, + &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 8u); + + // Number of blocks grows by a factor of 4 normally. + buffer_->OnStreamData(kBlockSizeBytes * 8, "a", &written_, &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 32u); + + // Number of blocks grow to the demanded size of 140 instead of 128 since + // that's not enough. + buffer_->OnStreamData(kBlockSizeBytes * 139, source_of_one_block, &written_, + &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 140u); + + // Number of blocks grows by a factor of 4 normally. + buffer_->OnStreamData(kBlockSizeBytes * 140, source_of_one_block, &written_, + &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 560u); + + // max_capacity_bytes is reached and number of blocks is capped. + buffer_->OnStreamData(kBlockSizeBytes * 560, source_of_one_block, &written_, + &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 1024u); + + // max_capacity_bytes is reached and number of blocks is capped. + buffer_->OnStreamData(kBlockSizeBytes * 1025, source_of_one_block, &written_, + &error_details_); + ASSERT_EQ(helper_->current_blocks_count(), 1024u); +} + } // anonymous namespace } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc index bdf141267a7..a996ee21d64 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_sequencer_test.cc @@ -11,6 +11,8 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_stream.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" @@ -19,8 +21,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::AnyNumber; @@ -52,7 +52,7 @@ class QuicStreamSequencerTest : public QuicTest { public: void ConsumeData(size_t num_bytes) { char buffer[1024]; - ASSERT_GT(QUICHE_ARRAYSIZE(buffer), num_bytes); + ASSERT_GT(ABSL_ARRAYSIZE(buffer), num_bytes); struct iovec iov; iov.iov_base = buffer; iov.iov_len = num_bytes; @@ -96,7 +96,7 @@ class QuicStreamSequencerTest : public QuicTest { const std::vector<std::string>& expected) { iovec iovecs[5]; size_t num_iovecs = - sequencer.GetReadableRegions(iovecs, QUICHE_ARRAYSIZE(iovecs)); + sequencer.GetReadableRegions(iovecs, ABSL_ARRAYSIZE(iovecs)); return VerifyReadableRegion(sequencer, expected) && VerifyIovecs(sequencer, iovecs, num_iovecs, expected); } @@ -116,7 +116,7 @@ class QuicStreamSequencerTest : public QuicTest { return true; } - bool VerifyIovec(const iovec& iovec, quiche::QuicheStringPiece expected) { + bool VerifyIovec(const iovec& iovec, absl::string_view expected) { if (iovec.iov_len != expected.length()) { QUIC_LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs " << expected.length(); @@ -376,11 +376,11 @@ TEST_F(QuicStreamSequencerTest, MultipleOffsets) { class QuicSequencerRandomTest : public QuicStreamSequencerTest { public: - typedef std::pair<int, std::string> Frame; - typedef std::vector<Frame> FrameList; + using Frame = std::pair<int, std::string>; + using FrameList = std::vector<Frame>; void CreateFrames() { - int payload_size = QUICHE_ARRAYSIZE(kPayload) - 1; + int payload_size = ABSL_ARRAYSIZE(kPayload) - 1; int remaining_payload = payload_size; while (remaining_payload != 0) { int size = std::min(OneToN(6), remaining_payload); @@ -403,10 +403,10 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest { void ReadAvailableData() { // Read all available data - char output[QUICHE_ARRAYSIZE(kPayload) + 1]; + char output[ABSL_ARRAYSIZE(kPayload) + 1]; iovec iov; iov.iov_base = output; - iov.iov_len = QUICHE_ARRAYSIZE(output); + iov.iov_len = ABSL_ARRAYSIZE(output); int bytes_read = sequencer_->Readv(&iov, 1); EXPECT_NE(0, bytes_read); output_.append(output, bytes_read); @@ -442,9 +442,9 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { list_.erase(list_.begin() + index); } - ASSERT_EQ(QUICHE_ARRAYSIZE(kPayload) - 1, output_.size()); + ASSERT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, output_.size()); EXPECT_EQ(kPayload, output_); - EXPECT_EQ(QUICHE_ARRAYSIZE(kPayload) - 1, total_bytes_consumed); + EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed); } TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { @@ -464,7 +464,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { total_bytes_consumed += bytes; })); - while (output_.size() != QUICHE_ARRAYSIZE(kPayload) - 1) { + while (output_.size() != ABSL_ARRAYSIZE(kPayload) - 1) { if (!list_.empty() && OneToN(2) == 1) { // Send data int index = OneToN(list_.size()) - 1; OnFrame(list_[index].first, list_[index].second.data()); @@ -480,7 +480,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { ASSERT_EQ(0, iovs_peeked); ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov)); } - int total_bytes_to_peek = QUICHE_ARRAYSIZE(buffer); + int total_bytes_to_peek = ABSL_ARRAYSIZE(buffer); for (int i = 0; i < iovs_peeked; ++i) { int bytes_to_peek = std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek); @@ -497,7 +497,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { } EXPECT_EQ(std::string(kPayload), output_); EXPECT_EQ(std::string(kPayload), peeked_); - EXPECT_EQ(QUICHE_ARRAYSIZE(kPayload) - 1, total_bytes_consumed); + EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed); } // Same as above, just using a different method for reading. @@ -600,10 +600,10 @@ TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) { // overlapping byte ranges - if they do, we close the connection. QuicStreamId id = 1; - QuicStreamFrame frame1(id, false, 1, quiche::QuicheStringPiece("hello")); + QuicStreamFrame frame1(id, false, 1, absl::string_view("hello")); sequencer_->OnStreamFrame(frame1); - QuicStreamFrame frame2(id, false, 2, quiche::QuicheStringPiece("hello")); + QuicStreamFrame frame2(id, false, 2, absl::string_view("hello")); EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _)) .Times(0); sequencer_->OnStreamFrame(frame2); @@ -635,7 +635,7 @@ TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) { EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); // Received [1498, 1503). - QuicStreamFrame frame3(id, false, 1498, quiche::QuicheStringPiece("hello")); + QuicStreamFrame frame3(id, false, 1498, absl::string_view("hello")); EXPECT_CALL(stream_, OnDataAvailable()); sequencer_->OnStreamFrame(frame3); EXPECT_CALL(stream_, AddBytesConsumed(3)); @@ -644,7 +644,7 @@ TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) { EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); // Received [1000, 1005). - QuicStreamFrame frame4(id, false, 1000, quiche::QuicheStringPiece("hello")); + QuicStreamFrame frame4(id, false, 1000, absl::string_view("hello")); EXPECT_CALL(stream_, OnDataAvailable()).Times(0); sequencer_->OnStreamFrame(frame4); EXPECT_EQ(1503u, sequencer_->NumBytesConsumed()); diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc index f2b5563344b..d241dac9098 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc @@ -8,6 +8,10 @@ #include <string> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" @@ -30,9 +34,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::AnyNumber; @@ -72,6 +73,7 @@ class TestStream : public QuicStream { using QuicStream::CanWriteNewDataAfterData; using QuicStream::CloseWriteSide; using QuicStream::fin_buffered; + using QuicStream::MaybeSendStopSending; using QuicStream::OnClose; using QuicStream::WriteMemSlices; using QuicStream::WriteOrBufferData; @@ -94,7 +96,9 @@ class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> { connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_); session_->Initialize(); - + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow( session_->config(), kMinimumFlowControlSendWindow); QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional( @@ -112,8 +116,15 @@ class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> { // session_ now owns stream_. session_->ActivateStream(QuicWrapUnique(stream_)); // Ignore resetting when session_ is terminated. - EXPECT_CALL(*session_, SendRstStream(kTestStreamId, _, _, _)) - .Times(AnyNumber()); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(kTestStreamId, _, _, _)) + .Times(AnyNumber()); + } else { + EXPECT_CALL(*session_, MaybeSendStopSendingFrame(kTestStreamId, _)) + .Times(AnyNumber()); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)) + .Times(AnyNumber()); + } write_blocked_list_ = QuicSessionPeer::GetWriteBlockedStreams(session_.get()); } @@ -132,7 +143,7 @@ class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> { QuicStreamOffset /*offset*/, StreamSendingState /*state*/, TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) { + absl::optional<EncryptionLevel> /*level*/) { session_->ResetStream(id, QUIC_STREAM_CANCELLED); return QuicConsumedData(1, false); } @@ -295,8 +306,7 @@ TEST_P(QuicStreamTest, NoBlockingIfNoDataOrFin) { // Write no data and no fin. If we consume nothing we should not be write // blocked. EXPECT_QUIC_BUG( - stream_->WriteOrBufferData(quiche::QuicheStringPiece(), false, nullptr), - ""); + stream_->WriteOrBufferData(absl::string_view(), false, nullptr), ""); EXPECT_FALSE(HasWriteBlockedStreams()); } @@ -308,10 +318,9 @@ TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), false, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr); EXPECT_TRUE(session_->HasUnackedStreamData()); ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); EXPECT_EQ(1u, stream_->BufferedDataBytes()); @@ -327,10 +336,9 @@ TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr); EXPECT_TRUE(session_->HasUnackedStreamData()); ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); } @@ -342,7 +350,7 @@ TEST_P(QuicStreamTest, BlockIfSoloFinNotConsumed) { // as the fin was not consumed. EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(Return(QuicConsumedData(0, false))); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(), true, nullptr); + stream_->WriteOrBufferData(absl::string_view(), true, nullptr); ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); } @@ -354,8 +362,7 @@ TEST_P(QuicStreamTest, CloseOnPartialWrite) { // crash with an unknown stream. EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError)); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), false, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr); ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams()); } @@ -375,7 +382,7 @@ TEST_P(QuicStreamTest, WriteOrBufferData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); stream_->WriteOrBufferData(kData1, false, nullptr); @@ -391,8 +398,7 @@ TEST_P(QuicStreamTest, WriteOrBufferData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1, - NO_FIN, NOT_RETRANSMISSION, - QUICHE_NULLOPT); + NO_FIN, NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_CALL(*stream_, OnCanWriteNewData()); stream_->OnCanWrite(); @@ -402,8 +408,7 @@ TEST_P(QuicStreamTest, WriteOrBufferData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2, - NO_FIN, NOT_RETRANSMISSION, - QUICHE_NULLOPT); + NO_FIN, NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_CALL(*stream_, OnCanWriteNewData()); stream_->OnCanWrite(); @@ -427,13 +432,21 @@ TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) { TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) { Initialize(); - QuicStreamPeer::CloseReadSide(stream_); - stream_->CloseWriteSide(); - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); + QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(), + QUIC_STREAM_CANCELLED, 1234); + stream_->OnStreamReset(rst_frame); + if (VersionHasIetfQuicFrames(session_->transport_version())) { + // Create and inject a STOP SENDING frame to complete the close + // of the stream. This is only needed for version 99/IETF QUIC. + QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(), + QUIC_STREAM_CANCELLED); + session_->OnStopSendingFrame(stop_sending); + } + EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); EXPECT_THAT(stream_->connection_error(), IsQuicNoError()); stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, ConnectionCloseSource::FROM_SELF); - EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); + EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED)); EXPECT_THAT(stream_->connection_error(), IsQuicNoError()); } @@ -450,18 +463,29 @@ TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), false, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 1), false, nullptr); EXPECT_TRUE(session_->HasUnackedStreamData()); EXPECT_FALSE(fin_sent()); EXPECT_FALSE(rst_sent()); // Now close the stream, and expect that we send a RST. - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)); - QuicStreamPeer::CloseReadSide(stream_); - stream_->CloseWriteSide(); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(kTestStreamId, _, _, _)); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)); + } + QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(), + QUIC_STREAM_CANCELLED, 1234); + stream_->OnStreamReset(rst_frame); + if (VersionHasIetfQuicFrames(session_->transport_version())) { + // Create and inject a STOP SENDING frame to complete the close + // of the stream. This is only needed for version 99/IETF QUIC. + QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(), + QUIC_STREAM_CANCELLED); + session_->OnStopSendingFrame(stop_sending); + } EXPECT_FALSE(session_->HasUnackedStreamData()); EXPECT_FALSE(fin_sent()); EXPECT_TRUE(rst_sent()); @@ -480,10 +504,9 @@ TEST_P(QuicStreamTest, RstNotSentIfFinSent) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 1u, 0u, FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), true, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 1), true, nullptr); EXPECT_TRUE(fin_sent()); EXPECT_FALSE(rst_sent()); @@ -505,8 +528,12 @@ TEST_P(QuicStreamTest, OnlySendOneRst) { EXPECT_FALSE(rst_sent()); // Reset the stream. - const int expected_resets = 1; - EXPECT_CALL(*session_, SendRstStream(_, _, _, _)).Times(expected_resets); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(kTestStreamId, _, _, _)).Times(1); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)) + .Times(1); + } stream_->Reset(QUIC_STREAM_CANCELLED); EXPECT_FALSE(fin_sent()); EXPECT_TRUE(rst_sent()); @@ -597,9 +624,9 @@ TEST_P(QuicStreamTest, StopReadingSendsFlowControl) { EXPECT_CALL(*connection_, CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)) .Times(0); - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&ClearControlFrame)); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); std::string data(1000, 'x'); for (QuicStreamOffset offset = 0; @@ -647,8 +674,6 @@ TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) { CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); stream_->OnStreamReset(rst_frame); EXPECT_TRUE(stream_->HasReceivedFinalOffset()); - QuicStreamPeer::CloseReadSide(stream_); - stream_->CloseWriteSide(); } TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) { @@ -673,7 +698,7 @@ TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) { current_connection_flow_control_offset); QuicStreamFrame zero_length_stream_frame_with_fin( stream_->id(), /*fin=*/true, kByteOffsetExceedingFlowControlWindow, - quiche::QuicheStringPiece()); + absl::string_view()); EXPECT_EQ(0, zero_length_stream_frame_with_fin.data_length); EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0); @@ -744,10 +769,9 @@ TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr); EXPECT_TRUE(stream_->write_side_closed()); EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get())); @@ -762,10 +786,9 @@ TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) { EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); - stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true, - nullptr); + stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr); EXPECT_TRUE(stream_->write_side_closed()); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -920,22 +943,35 @@ TEST_P(QuicStreamTest, CancelStream) { EXPECT_TRUE(session_->HasUnackedStreamData()); EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size()); // Cancel stream. - stream_->Reset(QUIC_STREAM_NO_ERROR); + if (session_->split_up_send_rst()) { + stream_->MaybeSendStopSending(QUIC_STREAM_NO_ERROR); + } else { + stream_->Reset(QUIC_STREAM_NO_ERROR); + } // stream still waits for acks as the error code is QUIC_STREAM_NO_ERROR, and // data is going to be retransmitted. EXPECT_TRUE(stream_->IsWaitingForAcks()); EXPECT_TRUE(session_->HasUnackedStreamData()); EXPECT_CALL(*connection_, OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED)); - EXPECT_CALL(*connection_, SendControlFrame(_)) + EXPECT_CALL(*session_, WriteControlFrame(_, _)) .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&ClearControlFrame)); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 9, _)) - .WillOnce(InvokeWithoutArgs([this]() { - session_->ReallySendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, - stream_->stream_bytes_written(), false); - })); + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 9, _)) + .WillOnce(InvokeWithoutArgs([this]() { + session_->ReallySendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, + stream_->stream_bytes_written(), false); + })); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)) + .WillOnce(InvokeWithoutArgs([this]() { + session_->ReallyMaybeSendRstStreamFrame( + stream_->id(), QUIC_STREAM_CANCELLED, + stream_->stream_bytes_written()); + })); + } stream_->Reset(QUIC_STREAM_CANCELLED); EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size()); @@ -966,8 +1002,14 @@ TEST_P(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) { // RST_STREAM received. QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 9); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9, _)); + + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9, _)); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame( + stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9)); + } stream_->OnStreamReset(rst_frame); EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size()); // Stream stops waiting for acks as it does not finish sending and rst is @@ -1010,8 +1052,14 @@ TEST_P(QuicStreamTest, ConnectionClosed) { stream_->WriteOrBufferData(kData1, false, nullptr); EXPECT_TRUE(stream_->IsWaitingForAcks()); EXPECT_TRUE(session_->HasUnackedStreamData()); - EXPECT_CALL(*session_, - SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9, _)); + } else { + EXPECT_CALL(*session_, MaybeSendRstStreamFrame( + stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9)); + } + QuicConnectionPeer::SetConnectionClose(connection_); stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, ConnectionCloseSource::FROM_SELF); EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size()); @@ -1039,7 +1087,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); stream_->WriteOrBufferData(data, false, nullptr); stream_->WriteOrBufferData(data, false, nullptr); @@ -1052,7 +1100,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); // Buffered data size > threshold, do not ask upper layer for more data. EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0); @@ -1067,7 +1115,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this, data_to_write]() { return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); // Buffered data size < threshold, ask upper layer for more data. EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1); @@ -1117,7 +1165,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this, data_to_write]() { return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1); @@ -1169,8 +1217,8 @@ TEST_P(QuicStreamTest, WriteMemSlices) { Initialize(); char data[1024]; std::vector<std::pair<char*, size_t>> buffers; - buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data))); - buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data))); + buffers.push_back(std::make_pair(data, ABSL_ARRAYSIZE(data))); + buffers.push_back(std::make_pair(data, ABSL_ARRAYSIZE(data))); QuicTestMemSliceVector vector1(buffers); QuicTestMemSliceVector vector2(buffers); QuicMemSliceSpan span1 = vector1.span(); @@ -1179,13 +1227,13 @@ TEST_P(QuicStreamTest, WriteMemSlices) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); // There is no buffered data before, all data should be consumed. QuicConsumedData consumed = stream_->WriteMemSlices(span1, false); EXPECT_EQ(2048u, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); - EXPECT_EQ(2 * QUICHE_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes()); + EXPECT_EQ(2 * ABSL_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes()); EXPECT_FALSE(stream_->fin_buffered()); EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0); @@ -1193,16 +1241,16 @@ TEST_P(QuicStreamTest, WriteMemSlices) { consumed = stream_->WriteMemSlices(span2, true); EXPECT_EQ(0u, consumed.bytes_consumed); EXPECT_FALSE(consumed.fin_consumed); - EXPECT_EQ(2 * QUICHE_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes()); + EXPECT_EQ(2 * ABSL_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes()); EXPECT_FALSE(stream_->fin_buffered()); QuicByteCount data_to_write = - 2 * QUICHE_ARRAYSIZE(data) - 100 - + 2 * ABSL_ARRAYSIZE(data) - 100 - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1; EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this, data_to_write]() { return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1); stream_->OnCanWrite(); @@ -1214,7 +1262,7 @@ TEST_P(QuicStreamTest, WriteMemSlices) { consumed = stream_->WriteMemSlices(span2, true); EXPECT_EQ(2048u, consumed.bytes_consumed); EXPECT_TRUE(consumed.fin_consumed); - EXPECT_EQ(2 * QUICHE_ARRAYSIZE(data) + + EXPECT_EQ(2 * ABSL_ARRAYSIZE(data) + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1, stream_->BufferedDataBytes()); EXPECT_TRUE(stream_->fin_buffered()); @@ -1233,13 +1281,13 @@ TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) { QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_); char data[5]; std::vector<std::pair<char*, size_t>> buffers; - buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data))); + buffers.push_back(std::make_pair(data, ABSL_ARRAYSIZE(data))); QuicTestMemSliceVector vector1(buffers); QuicMemSliceSpan span1 = vector1.span(); EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); // There is no buffered data before, all data should be consumed. QuicConsumedData consumed = stream_->WriteMemSlices(span1, false); @@ -1377,7 +1425,7 @@ TEST_P(QuicStreamTest, OnStreamFrameLost) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 9u, 18u, FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); stream_->OnCanWrite(); EXPECT_FALSE(stream_->HasPendingRetransmission()); @@ -1407,7 +1455,7 @@ TEST_P(QuicStreamTest, CannotBundleLostFin) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillOnce(Return(QuicConsumedData(0, true))); @@ -1430,8 +1478,8 @@ TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) { EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData)); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); std::string data(1024, '.'); stream->WriteOrBufferData(data, false, nullptr); EXPECT_FALSE(HasWriteBlockedStreams()); @@ -1464,8 +1512,8 @@ TEST_P(QuicStreamTest, std::string data(100, '.'); EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData)); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); stream->WriteOrBufferData(data, false, nullptr); EXPECT_FALSE(HasWriteBlockedStreams()); @@ -1496,7 +1544,7 @@ TEST_P(QuicStreamTest, RetransmitStreamData) { EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _)) .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN, - NOT_RETRANSMISSION, QUICHE_NULLOPT); + NOT_RETRANSMISSION, absl::nullopt); })); EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION)); @@ -1535,8 +1583,19 @@ TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) { connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); // Verify stream gets reset because TTL expires. - EXPECT_CALL(*session_, SendRstStream(_, QUIC_STREAM_TTL_EXPIRED, _, _)) - .Times(1); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(_, QUIC_STREAM_TTL_EXPIRED, _, _)) + .Times(1); + } else { + if (session_->version().UsesHttp3()) { + EXPECT_CALL(*session_, + MaybeSendStopSendingFrame(_, QUIC_STREAM_TTL_EXPIRED)) + .Times(1); + } + EXPECT_CALL(*session_, + MaybeSendRstStreamFrame(_, QUIC_STREAM_TTL_EXPIRED, _)) + .Times(1); + } stream_->OnCanWrite(); } @@ -1554,8 +1613,19 @@ TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) { connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); // Verify stream gets reset because TTL expires. - EXPECT_CALL(*session_, SendRstStream(_, QUIC_STREAM_TTL_EXPIRED, _, _)) - .Times(1); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, SendRstStream(_, QUIC_STREAM_TTL_EXPIRED, _, _)) + .Times(1); + } else { + if (session_->version().UsesHttp3()) { + EXPECT_CALL(*session_, + MaybeSendStopSendingFrame(_, QUIC_STREAM_TTL_EXPIRED)) + .Times(1); + } + EXPECT_CALL(*session_, + MaybeSendRstStreamFrame(_, QUIC_STREAM_TTL_EXPIRED, _)) + .Times(1); + } stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION); } 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 d6c2f6c25de..5b38a8b3a78 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 @@ -7,9 +7,11 @@ #include <algorithm> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_split.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -43,10 +45,10 @@ std::string QuicTagToString(QuicTag tag) { bool ascii = true; const QuicTag orig_tag = tag; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(chars); i++) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) { chars[i] = static_cast<char>(tag); if ((chars[i] == 0 || chars[i] == '\xff') && - i == QUICHE_ARRAYSIZE(chars) - 1) { + i == ABSL_ARRAYSIZE(chars) - 1) { chars[i] = ' '; } if (!isprint(static_cast<unsigned char>(chars[i]))) { @@ -60,8 +62,8 @@ std::string QuicTagToString(QuicTag tag) { return std::string(chars, sizeof(chars)); } - return quiche::QuicheTextUtils::HexEncode( - reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)); + return absl::BytesToHexString(absl::string_view( + reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag))); } uint32_t MakeQuicTag(char a, char b, char c, char d) { @@ -74,11 +76,11 @@ bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) { tag_vector.end(); } -QuicTag ParseQuicTag(quiche::QuicheStringPiece tag_string) { +QuicTag ParseQuicTag(absl::string_view tag_string) { quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string); std::string tag_bytes; if (tag_string.length() == 8) { - tag_bytes = quiche::QuicheTextUtils::HexDecode(tag_string); + tag_bytes = absl::HexStringToBytes(tag_string); tag_string = tag_bytes; } QuicTag tag = 0; @@ -92,13 +94,13 @@ QuicTag ParseQuicTag(quiche::QuicheStringPiece tag_string) { return tag; } -QuicTagVector ParseQuicTagVector(quiche::QuicheStringPiece tags_string) { +QuicTagVector ParseQuicTagVector(absl::string_view tags_string) { QuicTagVector tag_vector; quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string); if (!tags_string.empty()) { - std::vector<quiche::QuicheStringPiece> tag_strings = - quiche::QuicheTextUtils::Split(tags_string, ','); - for (quiche::QuicheStringPiece tag_string : tag_strings) { + std::vector<absl::string_view> tag_strings = + absl::StrSplit(tags_string, ','); + for (absl::string_view tag_string : tag_strings) { tag_vector.push_back(ParseQuicTag(tag_string)); } } 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 7ba6cfc5f39..606d89d16ad 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 @@ -9,8 +9,8 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -22,9 +22,9 @@ namespace quic { // Tags will often be referred to by their ASCII equivalent, e.g. EXMP. This is // just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII // string E X M P). -typedef uint32_t QuicTag; -typedef std::map<QuicTag, std::string> QuicTagValueMap; -typedef std::vector<QuicTag> QuicTagVector; +using QuicTag = uint32_t; +using QuicTagValueMap = std::map<QuicTag, std::string>; +using QuicTagVector = std::vector<QuicTag>; // MakeQuicTag returns a value given the four bytes. For example: // MakeQuicTag('C', 'H', 'L', 'O'); @@ -53,12 +53,12 @@ QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag); // corresponding QuicTag. Note that tags that are less than four characters // long are right-padded with zeroes. Tags that contain non-ASCII characters // are represented as 8-character-long hexadecimal strings. -QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(quiche::QuicheStringPiece tag_string); +QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(absl::string_view tag_string); // Utility function that converts a string of the form "ABCD,EFGH" to a vector // of the form {kABCD,kEFGH}. Note the caveats on ParseQuicTag. QUIC_EXPORT_PRIVATE QuicTagVector -ParseQuicTagVector(quiche::QuicheStringPiece tags_string); +ParseQuicTagVector(absl::string_view tags_string); } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc index a09caac5ee2..769a9c5c43f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.cc @@ -9,6 +9,7 @@ #include <memory> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -239,7 +239,7 @@ void QuicTimeWaitListManager::SendVersionNegotiationPacket( << (ietf_quic ? "" : "!") << "ietf_quic, " << (use_length_prefix ? "" : "!") << "use_length_prefix:" << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( + << quiche::QuicheTextUtils::HexDump(absl::string_view( version_packet->data(), version_packet->length())); SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address, std::move(version_packet)), @@ -263,9 +263,9 @@ void QuicTimeWaitListManager::SendPublicReset( BuildIetfStatelessResetPacket(connection_id); QUIC_DVLOG(2) << "Dispatcher sending IETF reset packet for " << connection_id << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( - ietf_reset_packet->data(), - ietf_reset_packet->length())); + << quiche::QuicheTextUtils::HexDump( + absl::string_view(ietf_reset_packet->data(), + ietf_reset_packet->length())); SendOrQueuePacket( std::make_unique<QueuedPacket>(self_address, peer_address, std::move(ietf_reset_packet)), @@ -283,7 +283,7 @@ void QuicTimeWaitListManager::SendPublicReset( std::unique_ptr<QuicEncryptedPacket> reset_packet = BuildPublicReset(packet); QUIC_DVLOG(2) << "Dispatcher sending reset packet for " << connection_id << std::endl - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( + << quiche::QuicheTextUtils::HexDump(absl::string_view( reset_packet->data(), reset_packet->length())); SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address, std::move(reset_packet)), diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h index 6fd2041e8cb..d1286919ed5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h @@ -275,10 +275,9 @@ class QUIC_NO_EXPORT QuicTimeWaitListManager }; // QuicLinkedHashMap allows lookup by ConnectionId and traversal in add order. - typedef QuicLinkedHashMap<QuicConnectionId, - ConnectionIdData, - QuicConnectionIdHash> - ConnectionIdMap; + using ConnectionIdMap = QuicLinkedHashMap<QuicConnectionId, + ConnectionIdData, + QuicConnectionIdHash>; ConnectionIdMap connection_id_map_; // Pending termination packets that need to be sent out to the peer when we diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc b/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc index bf352f363ad..7ac7b7bd29d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc @@ -7,7 +7,7 @@ #include <string> #include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc index 02b34b57a14..3d33c998d27 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.cc @@ -7,9 +7,9 @@ namespace quic { QuicTransmissionInfo::QuicTransmissionInfo() - : encryption_level(ENCRYPTION_INITIAL), + : sent_time(QuicTime::Zero()), bytes_sent(0), - sent_time(QuicTime::Zero()), + encryption_level(ENCRYPTION_INITIAL), transmission_type(NOT_RETRANSMISSION), in_flight(false), state(OUTSTANDING), @@ -22,9 +22,9 @@ QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level, QuicPacketLength bytes_sent, bool has_crypto_handshake, bool has_ack_frequency) - : encryption_level(level), + : sent_time(sent_time), bytes_sent(bytes_sent), - sent_time(sent_time), + encryption_level(level), transmission_type(transmission_type), in_flight(false), state(OUTSTANDING), diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h index acc5667e9fd..61d1ad028cb 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_transmission_info.h @@ -33,9 +33,9 @@ struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo { ~QuicTransmissionInfo(); QuicFrames retransmittable_frames; - EncryptionLevel encryption_level; - QuicPacketLength bytes_sent; QuicTime sent_time; + QuicPacketLength bytes_sent; + EncryptionLevel encryption_level; // Reason why this packet was transmitted. TransmissionType transmission_type; // In flight packets have not been abandoned or lost. diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_types.cc b/chromium/net/third_party/quiche/src/quic/core/quic_types.cc index 4027ffa60ee..9eb0a2752c8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_types.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_types.cc @@ -363,6 +363,29 @@ std::ostream& operator<<(std::ostream& os, AddressChangeType type) { return os; } +std::string KeyUpdateReasonString(KeyUpdateReason reason) { +#define RETURN_REASON_LITERAL(x) \ + case KeyUpdateReason::x: \ + return #x + switch (reason) { + RETURN_REASON_LITERAL(kInvalid); + RETURN_REASON_LITERAL(kRemote); + RETURN_REASON_LITERAL(kLocalForTests); + RETURN_REASON_LITERAL(kLocalForInteropRunner); + RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit); + RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride); + default: + return quiche::QuicheStrCat("Unknown(", static_cast<int>(reason), ")"); + break; + } +#undef RETURN_REASON_LITERAL +} + +std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) { + os << KeyUpdateReasonString(reason); + return os; +} + #undef RETURN_STRING_LITERAL // undef for jumbo builds } // namespace quic 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 13307bb9d6f..5152a158055 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 @@ -602,8 +602,8 @@ QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString( QuicLongHeaderType type); enum QuicPacketHeaderTypeFlags : uint8_t { - // Bit 2: Reserved for experimentation for short header. - FLAGS_EXPERIMENTATION_BIT = 1 << 2, + // Bit 2: Key phase bit for IETF QUIC short header packets. + FLAGS_KEY_PHASE_BIT = 1 << 2, // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this // bit to 0, allowing to distinguish Google QUIC packets from short header // packets. @@ -798,6 +798,22 @@ struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer { } }; +// These values must remain stable as they are uploaded to UMA histograms. +enum class KeyUpdateReason { + kInvalid = 0, + kRemote = 1, + kLocalForTests = 2, + kLocalForInteropRunner = 3, + kLocalAeadConfidentialityLimit = 4, + kLocalKeyUpdateLimitOverride = 5, + kMaxValue = kLocalKeyUpdateLimitOverride, +}; + +QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, + const KeyUpdateReason reason); + +QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason); + } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_ diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc index 3e377cfa21b..852a0df2dc2 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc @@ -4,10 +4,12 @@ #include "net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h" +#include <cstddef> #include <limits> #include <type_traits> #include "net/third_party/quiche/src/quic/core/quic_connection_stats.h" +#include "net/third_party/quiche/src/quic/core/quic_packet_number.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" @@ -120,11 +122,21 @@ QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective) {QuicTime::Zero()}}, last_crypto_packet_sent_time_(QuicTime::Zero()), session_notifier_(nullptr), - supports_multiple_packet_number_spaces_(false) {} + supports_multiple_packet_number_spaces_(false) { + if (use_circular_deque_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_use_circular_deque_for_unacked_packets); + } +} QuicUnackedPacketMap::~QuicUnackedPacketMap() { - for (QuicTransmissionInfo& transmission_info : unacked_packets_) { - DeleteFrames(&(transmission_info.retransmittable_frames)); + if (use_circular_deque_) { + for (QuicTransmissionInfo& transmission_info : unacked_packets_) { + DeleteFrames(&(transmission_info.retransmittable_frames)); + } + } else { + for (QuicTransmissionInfo& transmission_info : unacked_packets_deque_) { + DeleteFrames(&(transmission_info.retransmittable_frames)); + } } } @@ -140,10 +152,10 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet, largest_sent_packet_ >= packet_number) << "largest_sent_packet_: " << largest_sent_packet_ << ", packet_number: " << packet_number; - DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size()); - while (least_unacked_ + unacked_packets_.size() < packet_number) { - unacked_packets_.push_back(QuicTransmissionInfo()); - unacked_packets_.back().state = NEVER_SENT; + DCHECK_GE(packet_number, least_unacked_ + unacked_packets_size()); + while (least_unacked_ + unacked_packets_size() < packet_number) { + unacked_packets_push_back(QuicTransmissionInfo()); + unacked_packets_back().state = NEVER_SENT; } const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE; @@ -170,7 +182,7 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet, last_inflight_packet_sent_time_ = sent_time; last_inflight_packets_sent_time_[packet_number_space] = sent_time; } - unacked_packets_.push_back(info); + unacked_packets_push_back(info); // Swap the retransmittable frames to avoid allocations. // TODO(ianswett): Could use emplace_back when Chromium can. if (has_crypto_handshake) { @@ -178,16 +190,16 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet, } mutable_packet->retransmittable_frames.swap( - unacked_packets_.back().retransmittable_frames); + unacked_packets_back().retransmittable_frames); } void QuicUnackedPacketMap::RemoveObsoletePackets() { - while (!unacked_packets_.empty()) { - if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) { + while (!unacked_packets_empty()) { + if (!IsPacketUseless(least_unacked_, unacked_packets_front())) { break; } - DeleteFrames(&unacked_packets_.front().retransmittable_frames); - unacked_packets_.pop_front(); + DeleteFrames(&unacked_packets_front().retransmittable_frames); + unacked_packets_pop_front(); ++least_unacked_; } } @@ -195,9 +207,9 @@ void QuicUnackedPacketMap::RemoveObsoletePackets() { bool QuicUnackedPacketMap::HasRetransmittableFrames( QuicPacketNumber packet_number) const { DCHECK_GE(packet_number, least_unacked_); - DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); + DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size()); return HasRetransmittableFrames( - unacked_packets_[packet_number - least_unacked_]); + unacked_packets_at(packet_number - least_unacked_)); } bool QuicUnackedPacketMap::HasRetransmittableFrames( @@ -223,9 +235,9 @@ void QuicUnackedPacketMap::RemoveRetransmittability( void QuicUnackedPacketMap::RemoveRetransmittability( QuicPacketNumber packet_number) { DCHECK_GE(packet_number, least_unacked_); - DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); + DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size()); QuicTransmissionInfo* info = - &unacked_packets_[packet_number - least_unacked_]; + &unacked_packets_at(packet_number - least_unacked_); RemoveRetransmittability(info); } @@ -275,11 +287,11 @@ bool QuicUnackedPacketMap::IsPacketUseless( bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const { if (packet_number < least_unacked_ || - packet_number >= least_unacked_ + unacked_packets_.size()) { + packet_number >= least_unacked_ + unacked_packets_size()) { return false; } return !IsPacketUseless(packet_number, - unacked_packets_[packet_number - least_unacked_]); + unacked_packets_at(packet_number - least_unacked_)); } void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) { @@ -313,9 +325,9 @@ void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) { void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) { DCHECK_GE(packet_number, least_unacked_); - DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); + DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size()); QuicTransmissionInfo* info = - &unacked_packets_[packet_number - least_unacked_]; + &unacked_packets_at(packet_number - least_unacked_); RemoveFromInFlight(info); } @@ -323,8 +335,8 @@ QuicInlinedVector<QuicPacketNumber, 2> QuicUnackedPacketMap::NeuterUnencryptedPackets() { QuicInlinedVector<QuicPacketNumber, 2> neutered_packets; QuicPacketNumber packet_number = GetLeastUnacked(); - for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { + for (QuicUnackedPacketMap::iterator it = begin(); it != end(); + ++it, ++packet_number) { if (!it->retransmittable_frames.empty() && it->encryption_level == ENCRYPTION_INITIAL) { QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number; @@ -350,8 +362,8 @@ QuicInlinedVector<QuicPacketNumber, 2> QuicUnackedPacketMap::NeuterHandshakePackets() { QuicInlinedVector<QuicPacketNumber, 2> neutered_packets; QuicPacketNumber packet_number = GetLeastUnacked(); - for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { + for (QuicUnackedPacketMap::iterator it = begin(); it != end(); + ++it, ++packet_number) { if (!it->retransmittable_frames.empty() && GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) { QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number; @@ -375,12 +387,12 @@ bool QuicUnackedPacketMap::HasInFlightPackets() const { const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( QuicPacketNumber packet_number) const { - return unacked_packets_[packet_number - least_unacked_]; + return unacked_packets_at(packet_number - least_unacked_); } QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo( QuicPacketNumber packet_number) { - return &unacked_packets_[packet_number - least_unacked_]; + return &unacked_packets_at(packet_number - least_unacked_); } QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const { @@ -394,8 +406,7 @@ QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const { size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const { size_t unacked_packet_count = 0; QuicPacketNumber packet_number = least_unacked_; - for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); - ++it, ++packet_number) { + for (auto it = begin(); it != end(); ++it, ++packet_number) { if (!IsPacketUseless(packet_number, *it)) { ++unacked_packet_count; } @@ -408,8 +419,7 @@ bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const { return true; } size_t num_in_flight = 0; - for (auto it = unacked_packets_.rbegin(); it != unacked_packets_.rend(); - ++it) { + for (auto it = rbegin(); it != rend(); ++it) { if (it->in_flight) { ++num_in_flight; } @@ -425,8 +435,7 @@ bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { } bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { - for (auto it = unacked_packets_.rbegin(); it != unacked_packets_.rend(); - ++it) { + for (auto it = rbegin(); it != rend(); ++it) { if (it->in_flight && HasRetransmittableFrames(*it)) { return true; } @@ -584,7 +593,7 @@ QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace( const QuicTransmissionInfo* QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const { DCHECK(HasInFlightPackets()); - for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); ++it) { + for (auto it = begin(); it != end(); ++it) { if (it->in_flight) { return &(*it); } @@ -598,7 +607,7 @@ QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace( PacketNumberSpace packet_number_space) const { // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent // time works. - for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); ++it) { + for (auto it = begin(); it != end(); ++it) { if (it->in_flight && GetPacketNumberSpace(it->encryption_level) == packet_number_space) { return &(*it); @@ -628,7 +637,7 @@ int32_t QuicUnackedPacketMap::GetLastPacketContent() const { return -1; } int32_t content = 0; - const QuicTransmissionInfo& last_packet = unacked_packets_.back(); + const QuicTransmissionInfo& last_packet = unacked_packets_back(); for (const auto& frame : last_packet.retransmittable_frames) { content |= GetFrameTypeBitfield(frame.type); } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h index 595f435e0fc..45413510a28 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h @@ -6,12 +6,15 @@ #define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_ #include <cstddef> +#include <cstdint> #include <deque> +#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_transmission_info.h" #include "net/third_party/quiche/src/quic/core/session_notifier_interface.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" namespace quic { @@ -90,7 +93,9 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap { bool HasUnackedRetransmittableFrames() const; // Returns true if there are no packets present in the unacked packet map. - bool empty() const { return unacked_packets_.empty(); } + bool empty() const { return unacked_packets_empty(); } + + bool use_circular_deque() const { return use_circular_deque_; } // Returns the largest packet number that has been sent. QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; } @@ -110,20 +115,83 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap { // been acked by the peer. If there are no unacked packets, returns 0. QuicPacketNumber GetLeastUnacked() const; - // This can not be a QuicCircularDeque since pointers into this are - // assumed to be stable. - typedef std::deque<QuicTransmissionInfo> UnackedPacketMap; - - typedef UnackedPacketMap::const_iterator const_iterator; - typedef UnackedPacketMap::const_reverse_iterator const_reverse_iterator; - typedef UnackedPacketMap::iterator iterator; - - const_iterator begin() const { return unacked_packets_.begin(); } - const_iterator end() const { return unacked_packets_.end(); } - const_reverse_iterator rbegin() const { return unacked_packets_.rbegin(); } - const_reverse_iterator rend() const { return unacked_packets_.rend(); } - iterator begin() { return unacked_packets_.begin(); } - iterator end() { return unacked_packets_.end(); } + template <typename Itr1, typename Itr2> + class QUIC_EXPORT_PRIVATE IteratorWrapper { + public: + explicit IteratorWrapper(Itr1 itr1) { + itr_.template emplace<0>(std::move(itr1)); + } + explicit IteratorWrapper(Itr2 itr2) { + itr_.template emplace<1>(std::move(itr2)); + } + + auto& operator*() const { + return absl::visit( + [](const auto& itr) -> auto& { return *itr; }, itr_); + } + + auto* operator->() const { + return absl::visit([](const auto& itr) { return &*itr; }, itr_); + } + + IteratorWrapper& operator++() { + absl::visit([](auto& itr) { ++itr; }, itr_); + return *this; + } + + IteratorWrapper& operator+=(int difference) { + absl::visit([difference](auto& itr) { itr += difference; }, itr_); + return *this; + } + + IteratorWrapper operator++(int) { + return absl::visit([](auto& itr) { IteratorWrapper(itr++); }, itr_); + } + + bool operator!=(const IteratorWrapper& other) const { + return itr_ != other.itr_; + } + + private: + absl::variant<Itr1, Itr2> itr_; + }; + + using const_iterator = + IteratorWrapper<std::deque<QuicTransmissionInfo>::const_iterator, + QuicCircularDeque<QuicTransmissionInfo>::const_iterator>; + using const_reverse_iterator = IteratorWrapper< + std::deque<QuicTransmissionInfo>::const_reverse_iterator, + QuicCircularDeque<QuicTransmissionInfo>::const_reverse_iterator>; + using iterator = + IteratorWrapper<std::deque<QuicTransmissionInfo>::iterator, + QuicCircularDeque<QuicTransmissionInfo>::iterator>; + + const_iterator begin() const { + return use_circular_deque_ ? const_iterator(unacked_packets_.begin()) + : const_iterator(unacked_packets_deque_.begin()); + } + const_iterator end() const { + return use_circular_deque_ ? const_iterator(unacked_packets_.end()) + : const_iterator(unacked_packets_deque_.end()); + } + const_reverse_iterator rbegin() const { + return use_circular_deque_ + ? const_reverse_iterator(unacked_packets_.rbegin()) + : const_reverse_iterator(unacked_packets_deque_.rbegin()); + } + const_reverse_iterator rend() const { + return use_circular_deque_ + ? const_reverse_iterator(unacked_packets_.rend()) + : const_reverse_iterator(unacked_packets_deque_.rend()); + } + iterator begin() { + return use_circular_deque_ ? iterator(unacked_packets_.begin()) + : iterator(unacked_packets_deque_.begin()); + } + iterator end() { + return use_circular_deque_ ? iterator(unacked_packets_.end()) + : iterator(unacked_packets_deque_.end()); + } // Returns true if there are unacked packets that are in flight. bool HasInFlightPackets() const; @@ -244,9 +312,73 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap { return supports_multiple_packet_number_spaces_; } + void ReserveInitialCapacity(size_t initial_capacity) { + if (use_circular_deque_) { + unacked_packets_.reserve(initial_capacity); + } + } + private: friend class test::QuicUnackedPacketMapPeer; + // TODO(haoyuewang) Remove these methods when deprecate + // quic_use_circular_deque_for_unacked_packets flag. + size_t unacked_packets_size() const { + return use_circular_deque_ ? unacked_packets_.size() + : unacked_packets_deque_.size(); + } + + const QuicTransmissionInfo& unacked_packets_at(int index) const { + return use_circular_deque_ ? unacked_packets_[index] + : unacked_packets_deque_[index]; + } + + QuicTransmissionInfo& unacked_packets_at(int index) { + return use_circular_deque_ ? unacked_packets_[index] + : unacked_packets_deque_[index]; + } + + const QuicTransmissionInfo& unacked_packets_front() const { + return use_circular_deque_ ? unacked_packets_.front() + : unacked_packets_deque_.front(); + } + + QuicTransmissionInfo& unacked_packets_front() { + return use_circular_deque_ ? unacked_packets_.front() + : unacked_packets_deque_.front(); + } + + const QuicTransmissionInfo& unacked_packets_back() const { + return use_circular_deque_ ? unacked_packets_.back() + : unacked_packets_deque_.back(); + } + + QuicTransmissionInfo& unacked_packets_back() { + return use_circular_deque_ ? unacked_packets_.back() + : unacked_packets_deque_.back(); + } + + void unacked_packets_push_back(QuicTransmissionInfo info) { + if (use_circular_deque_) { + unacked_packets_.push_back(std::move(info)); + } else { + unacked_packets_deque_.push_back(std::move(info)); + } + } + + void unacked_packets_pop_front() { + if (use_circular_deque_) { + unacked_packets_.pop_front(); + } else { + unacked_packets_deque_.pop_front(); + } + } + + bool unacked_packets_empty() const { + return use_circular_deque_ ? unacked_packets_.empty() + : unacked_packets_deque_.empty(); + } + // Returns true if packet may be useful for an RTT measurement. bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number, const QuicTransmissionInfo& info) const; @@ -286,7 +418,12 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap { // If the old packet is acked before the new packet, then the old entry will // be removed from the map and the new entry's retransmittable frames will be // set to nullptr. - UnackedPacketMap unacked_packets_; + QuicCircularDeque<QuicTransmissionInfo> unacked_packets_; + std::deque<QuicTransmissionInfo> unacked_packets_deque_; + + const bool use_circular_deque_ = + GetQuicReloadableFlag(quic_use_circular_deque_for_unacked_packets); + // The packet at the 0th index of unacked_packets_. QuicPacketNumber least_unacked_; diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc index 96ba08acb35..02821083e31 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map_test.cc @@ -3,15 +3,17 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h" +#include <cstddef> #include <limits> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" +#include "net/third_party/quiche/src/quic/core/quic_packet_number.h" #include "net/third_party/quiche/src/quic/core/quic_transmission_info.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" using testing::_; using testing::Return; @@ -84,8 +86,8 @@ class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> { .in_flight); } size_t in_flight_count = 0; - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it) { + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it) { if (it->in_flight) { ++in_flight_count; } @@ -111,8 +113,8 @@ class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> { void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) { unacked_packets_.RemoveObsoletePackets(); size_t num_retransmittable_packets = 0; - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it) { + for (auto it = unacked_packets_.begin(); it != unacked_packets_.end(); + ++it) { if (unacked_packets_.HasRetransmittableFrames(*it)) { ++num_retransmittable_packets; } @@ -174,7 +176,7 @@ TEST_P(QuicUnackedPacketMapTest, RttOnly) { true); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyInFlightPackets(nullptr, 0); VerifyRetransmittablePackets(nullptr, 0); @@ -190,18 +192,18 @@ TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) { unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyRetransmittablePackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyRetransmittablePackets(unacked, ABSL_ARRAYSIZE(unacked)); unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1)); @@ -216,15 +218,15 @@ TEST_P(QuicUnackedPacketMapTest, StopRetransmission) { unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); uint64_t retransmittable[] = {1}; VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); } @@ -234,16 +236,16 @@ TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) { unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true); uint64_t unacked[] = {1}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); uint64_t retransmittable[] = {1}; VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); } TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) { @@ -254,14 +256,14 @@ TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) { RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION); uint64_t unacked[] = {1, 2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); std::vector<uint64_t> retransmittable = {1, 2}; VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size()); EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); } @@ -274,26 +276,26 @@ TEST_P(QuicUnackedPacketMapTest, RetransmittedPacket) { RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION); uint64_t unacked[] = {1, 2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); std::vector<uint64_t> retransmittable = {1, 2}; VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size()); EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2)); - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2)); uint64_t unacked2[] = {1}; - VerifyUnackedPackets(unacked2, QUICHE_ARRAYSIZE(unacked2)); - VerifyInFlightPackets(unacked2, QUICHE_ARRAYSIZE(unacked2)); + VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2)); + VerifyInFlightPackets(unacked2, ABSL_ARRAYSIZE(unacked2)); VerifyRetransmittablePackets(nullptr, 0); unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1)); @@ -312,11 +314,11 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) { true); uint64_t unacked[] = {1, 2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); uint64_t retransmittable[] = {1, 2}; VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); // Early retransmit 1 as 3 and send new data as 4. unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2)); @@ -329,9 +331,9 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) { true); uint64_t unacked2[] = {1, 3, 4}; - VerifyUnackedPackets(unacked2, QUICHE_ARRAYSIZE(unacked2)); + VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2)); uint64_t pending2[] = {3, 4}; - VerifyInFlightPackets(pending2, QUICHE_ARRAYSIZE(pending2)); + VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2)); std::vector<uint64_t> retransmittable2 = {1, 3, 4}; VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size()); @@ -349,7 +351,7 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) { VerifyUnackedPackets(&unacked3[0], unacked3.size()); VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size()); uint64_t pending3[] = {3, 5, 6}; - VerifyInFlightPackets(pending3, QUICHE_ARRAYSIZE(pending3)); + VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3)); // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed. unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6)); @@ -362,13 +364,13 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) { VerifyUnackedPackets(&unacked4[0], unacked4.size()); VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size()); uint64_t pending4[] = {3, 5, 7}; - VerifyInFlightPackets(pending4, QUICHE_ARRAYSIZE(pending4)); + VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4)); // Remove the older two transmissions from in flight. unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3)); unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5)); uint64_t pending5[] = {7}; - VerifyInFlightPackets(pending5, QUICHE_ARRAYSIZE(pending5)); + VerifyInFlightPackets(pending5, ABSL_ARRAYSIZE(pending5)); } TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) { @@ -381,11 +383,11 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) { true); uint64_t unacked[] = {1, 2}; - VerifyUnackedPackets(unacked, QUICHE_ARRAYSIZE(unacked)); - VerifyInFlightPackets(unacked, QUICHE_ARRAYSIZE(unacked)); + VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked)); + VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked)); uint64_t retransmittable[] = {1, 2}; VerifyRetransmittablePackets(retransmittable, - QUICHE_ARRAYSIZE(retransmittable)); + ABSL_ARRAYSIZE(retransmittable)); // Early retransmit 1 as 3. unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2)); @@ -395,9 +397,9 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) { RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION); uint64_t unacked2[] = {1, 3}; - VerifyUnackedPackets(unacked2, QUICHE_ARRAYSIZE(unacked2)); + VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2)); uint64_t pending2[] = {3}; - VerifyInFlightPackets(pending2, QUICHE_ARRAYSIZE(pending2)); + VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2)); std::vector<uint64_t> retransmittable2 = {1, 3}; VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size()); @@ -408,9 +410,9 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) { true); uint64_t unacked3[] = {1, 3, 4, 5}; - VerifyUnackedPackets(unacked3, QUICHE_ARRAYSIZE(unacked3)); + VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3)); uint64_t pending3[] = {3, 4, 5}; - VerifyInFlightPackets(pending3, QUICHE_ARRAYSIZE(pending3)); + VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3)); std::vector<uint64_t> retransmittable3 = {1, 3, 4, 5}; VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size()); @@ -425,7 +427,7 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) { std::vector<uint64_t> unacked4 = {4, 6}; VerifyUnackedPackets(&unacked4[0], unacked4.size()); uint64_t pending4[] = {6}; - VerifyInFlightPackets(pending4, QUICHE_ARRAYSIZE(pending4)); + VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4)); std::vector<uint64_t> retransmittable4 = {4, 6}; VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size()); } @@ -655,6 +657,18 @@ TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) { EXPECT_FALSE(unacked_packets_.GetLastPacketContent() & (1 << ACK_FRAME)); } +TEST_P(QuicUnackedPacketMapTest, ReserveInitialCapacityTest) { + SetQuicReloadableFlag(quic_use_circular_deque_for_unacked_packets, true); + QuicUnackedPacketMap unacked_packets(GetParam()); + ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 0u); + unacked_packets.ReserveInitialCapacity(16); + QuicStreamId stream_id(1); + SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id)); + unacked_packets.AddSentPacket(&packet, TransmissionType::NOT_RETRANSMISSION, + now_, true, true); + ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 16u); +} + } // namespace } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc b/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc index b6619d4398e..3322fedd906 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_utils.cc @@ -9,19 +9,19 @@ #include <cstring> #include <string> +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_prefetch.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace { @@ -36,8 +36,7 @@ namespace { #endif #ifdef QUIC_UTIL_HAS_UINT128 -QuicUint128 IncrementalHashFast(QuicUint128 uhash, - quiche::QuicheStringPiece data) { +QuicUint128 IncrementalHashFast(QuicUint128 uhash, absl::string_view data) { // This code ends up faster than the naive implementation for 2 reasons: // 1. QuicUint128 is sufficiently complicated that the compiler // cannot transform the multiplication by kPrime into a shift-multiply-add; @@ -60,8 +59,7 @@ QuicUint128 IncrementalHashFast(QuicUint128 uhash, #ifndef QUIC_UTIL_HAS_UINT128 // Slow implementation of IncrementalHash. In practice, only used by Chromium. -QuicUint128 IncrementalHashSlow(QuicUint128 hash, - quiche::QuicheStringPiece data) { +QuicUint128 IncrementalHashSlow(QuicUint128 hash, absl::string_view data) { // kPrime = 309485009821345068724781371 static const QuicUint128 kPrime = MakeQuicUint128(16777216, 315); const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data()); @@ -73,7 +71,7 @@ QuicUint128 IncrementalHashSlow(QuicUint128 hash, } #endif -QuicUint128 IncrementalHash(QuicUint128 hash, quiche::QuicheStringPiece data) { +QuicUint128 IncrementalHash(QuicUint128 hash, absl::string_view data) { #ifdef QUIC_UTIL_HAS_UINT128 return IncrementalHashFast(hash, data); #else @@ -84,7 +82,7 @@ QuicUint128 IncrementalHash(QuicUint128 hash, quiche::QuicheStringPiece data) { } // namespace // static -uint64_t QuicUtils::FNV1a_64_Hash(quiche::QuicheStringPiece data) { +uint64_t QuicUtils::FNV1a_64_Hash(absl::string_view data) { static const uint64_t kOffset = UINT64_C(14695981039346656037); static const uint64_t kPrime = UINT64_C(1099511628211); @@ -101,21 +99,20 @@ uint64_t QuicUtils::FNV1a_64_Hash(quiche::QuicheStringPiece data) { } // static -QuicUint128 QuicUtils::FNV1a_128_Hash(quiche::QuicheStringPiece data) { - return FNV1a_128_Hash_Three(data, quiche::QuicheStringPiece(), - quiche::QuicheStringPiece()); +QuicUint128 QuicUtils::FNV1a_128_Hash(absl::string_view data) { + return FNV1a_128_Hash_Three(data, absl::string_view(), absl::string_view()); } // static -QuicUint128 QuicUtils::FNV1a_128_Hash_Two(quiche::QuicheStringPiece data1, - quiche::QuicheStringPiece data2) { - return FNV1a_128_Hash_Three(data1, data2, quiche::QuicheStringPiece()); +QuicUint128 QuicUtils::FNV1a_128_Hash_Two(absl::string_view data1, + absl::string_view data2) { + return FNV1a_128_Hash_Three(data1, data2, absl::string_view()); } // static -QuicUint128 QuicUtils::FNV1a_128_Hash_Three(quiche::QuicheStringPiece data1, - quiche::QuicheStringPiece data2, - quiche::QuicheStringPiece data3) { +QuicUint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1, + absl::string_view data2, + absl::string_view data3) { // The two constants are defined as part of the hash algorithm. // see http://www.isthe.com/chongo/tech/comp/fnv/ // kOffset = 144066263297769815596495629667062367629 @@ -268,7 +265,7 @@ void QuicUtils::CopyToBuffer(const struct iovec* iov, // it to the hardware prefetcher after that. QuicPrefetchT0(next_base); if (iov[iovnum + 1].iov_len >= 64) { - QuicPrefetchT0(next_base + QUIC_CACHELINE_SIZE); + QuicPrefetchT0(next_base + ABSL_CACHELINE_SIZE); } } @@ -287,7 +284,7 @@ void QuicUtils::CopyToBuffer(const struct iovec* iov, } // static -struct iovec QuicUtils::MakeIovec(quiche::QuicheStringPiece data) { +struct iovec QuicUtils::MakeIovec(absl::string_view data) { struct iovec iov = {const_cast<char*>(data.data()), static_cast<size_t>(data.size())}; return iov; @@ -497,6 +494,18 @@ QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId( } // static +QuicStreamId QuicUtils::GetMaxClientInitiatedBidirectionalStreamId( + QuicTransportVersion version) { + if (VersionHasIetfQuicFrames(version)) { + // Client initiated bidirectional streams have stream IDs divisible by 4. + return std::numeric_limits<QuicStreamId>::max() - 3; + } + + // Client initiated bidirectional streams have odd stream IDs. + return std::numeric_limits<QuicStreamId>::max(); +} + +// static QuicConnectionId QuicUtils::CreateReplacementConnectionId( const QuicConnectionId& connection_id) { return CreateReplacementConnectionId(connection_id, @@ -511,7 +520,7 @@ QuicConnectionId QuicUtils::CreateReplacementConnectionId( return EmptyQuicConnectionId(); } const uint64_t connection_id_hash64 = FNV1a_64_Hash( - quiche::QuicheStringPiece(connection_id.data(), connection_id.length())); + absl::string_view(connection_id.data(), connection_id.length())); if (expected_connection_id_length <= sizeof(uint64_t)) { return QuicConnectionId( reinterpret_cast<const char*>(&connection_id_hash64), @@ -519,7 +528,7 @@ QuicConnectionId QuicUtils::CreateReplacementConnectionId( } char new_connection_id_data[255] = {}; const QuicUint128 connection_id_hash128 = FNV1a_128_Hash( - quiche::QuicheStringPiece(connection_id.data(), connection_id.length())); + absl::string_view(connection_id.data(), connection_id.length())); static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <= sizeof(new_connection_id_data), "bad size"); @@ -566,7 +575,7 @@ QuicConnectionId QuicUtils::CreateZeroConnectionId( if (!VersionAllowsVariableLengthConnectionIds(version)) { char connection_id_bytes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; return QuicConnectionId(static_cast<char*>(connection_id_bytes), - QUICHE_ARRAYSIZE(connection_id_bytes)); + ABSL_ARRAYSIZE(connection_id_bytes)); } return EmptyQuicConnectionId(); } @@ -615,7 +624,7 @@ bool QuicUtils::IsConnectionIdValidForVersion( QuicUint128 QuicUtils::GenerateStatelessResetToken( QuicConnectionId connection_id) { return FNV1a_128_Hash( - quiche::QuicheStringPiece(connection_id.data(), connection_id.length())); + absl::string_view(connection_id.data(), connection_id.length())); } // static diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils.h b/chromium/net/third_party/quiche/src/quic/core/quic_utils.h index 05c7124194a..c1a19a830e4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_utils.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_utils.h @@ -11,6 +11,7 @@ #include <string> #include <type_traits> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" @@ -21,7 +22,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_iovec.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -31,22 +31,22 @@ class QUIC_EXPORT_PRIVATE QuicUtils { // Returns the 64 bit FNV1a hash of the data. See // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param - static uint64_t FNV1a_64_Hash(quiche::QuicheStringPiece data); + static uint64_t FNV1a_64_Hash(absl::string_view data); // Returns the 128 bit FNV1a hash of the data. See // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param - static QuicUint128 FNV1a_128_Hash(quiche::QuicheStringPiece data); + static QuicUint128 FNV1a_128_Hash(absl::string_view data); // Returns the 128 bit FNV1a hash of the two sequences of data. See // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param - static QuicUint128 FNV1a_128_Hash_Two(quiche::QuicheStringPiece data1, - quiche::QuicheStringPiece data2); + static QuicUint128 FNV1a_128_Hash_Two(absl::string_view data1, + absl::string_view data2); // Returns the 128 bit FNV1a hash of the three sequences of data. See // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param - static QuicUint128 FNV1a_128_Hash_Three(quiche::QuicheStringPiece data1, - quiche::QuicheStringPiece data2, - quiche::QuicheStringPiece data3); + static QuicUint128 FNV1a_128_Hash_Three(absl::string_view data1, + absl::string_view data2, + absl::string_view data3); // SerializeUint128 writes the first 96 bits of |v| in little-endian form // to |out|. @@ -80,7 +80,7 @@ class QUIC_EXPORT_PRIVATE QuicUtils { char* buffer); // Creates an iovec pointing to the same data as |data|. - static struct iovec MakeIovec(quiche::QuicheStringPiece data); + static struct iovec MakeIovec(absl::string_view data); // Returns the opposite Perspective of the |perspective| passed in. static constexpr Perspective InvertPerspective(Perspective perspective) { @@ -170,6 +170,10 @@ class QUIC_EXPORT_PRIVATE QuicUtils { QuicTransportVersion version, Perspective perspective); + // Returns the largest possible client initiated bidirectional stream ID. + static QuicStreamId GetMaxClientInitiatedBidirectionalStreamId( + QuicTransportVersion version); + // Generates a connection ID of length |expected_connection_id_length| // derived from |connection_id|. // This is guaranteed to be deterministic (calling this method with two diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc index 041cd9856a1..efcdb7e4293 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc @@ -6,12 +6,12 @@ #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -100,7 +100,7 @@ TEST_F(QuicUtilsTest, ReferenceTest) { data[i] = i % 255; } EXPECT_EQ(IncrementalHashReference(data.data(), data.size()), - QuicUtils::FNV1a_128_Hash(quiche::QuicheStringPiece( + QuicUtils::FNV1a_128_Hash(absl::string_view( reinterpret_cast<const char*>(data.data()), data.size()))); } @@ -257,10 +257,10 @@ TEST_F(QuicUtilsTest, RandomConnectionId) { QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(&random); EXPECT_EQ(connection_id.length(), sizeof(uint64_t)); char connection_id_bytes[sizeof(uint64_t)]; - random.RandBytes(connection_id_bytes, QUICHE_ARRAYSIZE(connection_id_bytes)); + random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes)); EXPECT_EQ(connection_id, QuicConnectionId(static_cast<char*>(connection_id_bytes), - QUICHE_ARRAYSIZE(connection_id_bytes))); + ABSL_ARRAYSIZE(connection_id_bytes))); EXPECT_NE(connection_id, EmptyQuicConnectionId()); EXPECT_NE(connection_id, TestConnectionId()); EXPECT_NE(connection_id, TestConnectionId(1)); @@ -276,10 +276,10 @@ TEST_F(QuicUtilsTest, RandomConnectionIdVariableLength) { QuicUtils::CreateRandomConnectionId(connection_id_length, &random); EXPECT_EQ(connection_id.length(), connection_id_length); char connection_id_bytes[connection_id_length]; - random.RandBytes(connection_id_bytes, QUICHE_ARRAYSIZE(connection_id_bytes)); + random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes)); EXPECT_EQ(connection_id, QuicConnectionId(static_cast<char*>(connection_id_bytes), - QUICHE_ARRAYSIZE(connection_id_bytes))); + ABSL_ARRAYSIZE(connection_id_bytes))); EXPECT_NE(connection_id, EmptyQuicConnectionId()); EXPECT_NE(connection_id, TestConnectionId()); EXPECT_NE(connection_id, TestConnectionId(1)); 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 7cf6a1d8c24..9ca86f960de 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 @@ -6,10 +6,10 @@ #include <algorithm> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { 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 c91ad99d4af..487471f0e19 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 @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/core/quic_version_manager.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" using ::testing::ElementsAre; 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 d3f707bdda7..6bda82be251 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 @@ -6,6 +6,9 @@ #include <string> +#include "absl/base/macros.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_tag.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -13,10 +16,9 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace { @@ -328,14 +330,12 @@ ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) { return UnsupportedQuicVersion(); } -ParsedQuicVersion ParseQuicVersionString( - quiche::QuicheStringPiece version_string) { +ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) { if (version_string.empty()) { return UnsupportedQuicVersion(); } int quic_version_number = 0; - if (quiche::QuicheTextUtils::StringToInt(version_string, - &quic_version_number) && + if (absl::SimpleAtoi(version_string, &quic_version_number) && quic_version_number > 0) { QuicTransportVersion transport_version = static_cast<QuicTransportVersion>(quic_version_number); @@ -374,11 +374,11 @@ ParsedQuicVersion ParseQuicVersionString( } ParsedQuicVersionVector ParseQuicVersionVectorString( - quiche::QuicheStringPiece versions_string) { + absl::string_view versions_string) { ParsedQuicVersionVector versions; - std::vector<quiche::QuicheStringPiece> version_strings = - quiche::QuicheTextUtils::Split(versions_string, ','); - for (quiche::QuicheStringPiece version_string : version_strings) { + std::vector<absl::string_view> version_strings = + absl::StrSplit(versions_string, ','); + for (absl::string_view version_string : version_strings) { quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace( &version_string); ParsedQuicVersion version = ParseQuicVersionString(version_string); @@ -664,6 +664,9 @@ std::string AlpnForVersion(ParsedQuicVersion parsed_version) { void QuicVersionInitializeSupportForIetfDraft() { // Enable necessary flags. SetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2, true); + SetQuicReloadableFlag(quic_key_update_supported, true); + SetQuicReloadableFlag(quic_send_version_negotiation_for_short_connection_ids, + true); } void QuicEnableVersion(const ParsedQuicVersion& version) { 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 77b33594f79..c29b715f288 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 @@ -26,10 +26,10 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_tag.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -198,6 +198,7 @@ QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid( return transport_version == QUIC_VERSION_UNSUPPORTED; case PROTOCOL_QUIC_CRYPTO: return transport_version != QUIC_VERSION_UNSUPPORTED && + transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION && transport_version != QUIC_VERSION_51 && transport_version != QUIC_VERSION_IETF_DRAFT_27 && transport_version != QUIC_VERSION_IETF_DRAFT_29; @@ -281,7 +282,7 @@ struct QUIC_EXPORT_PRIVATE ParsedQuicVersion { } static constexpr ParsedQuicVersion ReservedForNegotiation() { - return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, + return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_RESERVED_FOR_NEGOTIATION); } @@ -496,13 +497,13 @@ ParseQuicVersionLabel(QuicVersionLabel version_label); // ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also // supports parsing numbers such as "46". QUIC_EXPORT_PRIVATE ParsedQuicVersion -ParseQuicVersionString(quiche::QuicheStringPiece version_string); +ParseQuicVersionString(absl::string_view version_string); // Parses a comma-separated list of QUIC version strings. Supports parsing by // label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions. // For example: "h3-29,Q050,46". QUIC_EXPORT_PRIVATE ParsedQuicVersionVector -ParseQuicVersionVectorString(quiche::QuicheStringPiece versions_string); +ParseQuicVersionVectorString(absl::string_view versions_string); // Constructs a QuicVersionLabel from the provided ParsedQuicVersion. QUIC_EXPORT_PRIVATE QuicVersionLabel 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 fa32de3f9b8..452f3f8e345 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 @@ -4,12 +4,12 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mock_log.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -332,16 +332,16 @@ TEST_F(QuicVersionsTest, CreateQuicVersionLabel) { CreateQuicVersionLabel(ParsedQuicVersion::T050())); // Make sure the negotiation reserved version is in the IETF reserved space. - EXPECT_EQ(MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a) & 0x0f0f0f0f, - CreateQuicVersionLabel(ParsedQuicVersion( - PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_RESERVED_FOR_NEGOTIATION)) & - 0x0f0f0f0f); + EXPECT_EQ( + MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a) & 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( - PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_RESERVED_FOR_NEGOTIATION))); + EXPECT_EQ( + MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a), + CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation())); } TEST_F(QuicVersionsTest, QuicVersionLabelToString) { @@ -371,7 +371,7 @@ TEST_F(QuicVersionsTest, QuicVersionToString) { QuicTransportVersion single_version[] = {QUIC_VERSION_43}; QuicTransportVersionVector versions_vector; - for (size_t i = 0; i < QUICHE_ARRAYSIZE(single_version); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) { versions_vector.push_back(single_version[i]); } EXPECT_EQ("QUIC_VERSION_43", @@ -380,7 +380,7 @@ TEST_F(QuicVersionsTest, QuicVersionToString) { QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED, QUIC_VERSION_43}; versions_vector.clear(); - for (size_t i = 0; i < QUICHE_ARRAYSIZE(multiple_versions); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) { versions_vector.push_back(multiple_versions[i]); } EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc index b3602a6618a..eba6a2936b3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc +++ b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.cc @@ -149,17 +149,8 @@ void QuicWriteBlockedList::UpdateBytesForStream(QuicStreamId stream_id, if (batch_write_stream_id_[last_priority_popped_] == stream_id) { // If this was the last data stream popped by PopFront, update the // bytes remaining in its batch write. - if (fix_bytes_left_for_batch_write_) { - QUIC_RELOADABLE_FLAG_COUNT(quic_fix_bytes_left_for_batch_write); - // TODO(fayang): change this static_cast to static_cast<uint32_t> when - // deprecating quic_fix_bytes_left_for_batch_write. - bytes_left_for_batch_write_[last_priority_popped_] -= - std::min(bytes_left_for_batch_write_[last_priority_popped_], - static_cast<int32_t>(bytes)); - } else { - bytes_left_for_batch_write_[last_priority_popped_] -= - static_cast<int32_t>(bytes); - } + bytes_left_for_batch_write_[last_priority_popped_] -= + std::min(bytes_left_for_batch_write_[last_priority_popped_], bytes); } } diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h index 08f70b39515..930157b5197 100644 --- a/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h +++ b/chromium/net/third_party/quiche/src/quic/core/quic_write_blocked_list.h @@ -27,7 +27,7 @@ namespace quic { // Crypto stream > Headers stream > Data streams by requested priority. class QUIC_EXPORT_PRIVATE QuicWriteBlockedList { private: - typedef spdy::WriteScheduler<QuicStreamId> QuicPriorityWriteScheduler; + using QuicPriorityWriteScheduler = spdy::WriteScheduler<QuicStreamId>; public: explicit QuicWriteBlockedList(QuicTransportVersion version); @@ -104,9 +104,7 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList { // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given // priority. This is decremented with each write the stream does until it is // done with its batch write. - // TODO(fayang): switch this to uint32_t when deprecating - // quic_fix_bytes_left_for_batch_write. - int32_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1]; + size_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1]; // Tracks the last priority popped for UpdateBytesForStream. spdy::SpdyPriority last_priority_popped_; @@ -120,7 +118,7 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList { }; // Optimized for the typical case of 2 static streams per session. - typedef QuicInlinedVector<StreamIdBlockedPair, 2> StreamsVector; + using StreamsVector = QuicInlinedVector<StreamIdBlockedPair, 2>; StreamsVector::const_iterator begin() const { return streams_.cbegin(); } @@ -156,9 +154,6 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList { StaticStreamCollection static_stream_collection_; spdy::WriteSchedulerType scheduler_type_; - - const bool fix_bytes_left_for_batch_write_ = - GetQuicReloadableFlag(quic_fix_bytes_left_for_batch_write); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h b/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h index 9f271475939..dc932999f2c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h +++ b/chromium/net/third_party/quiche/src/quic/core/stream_delegate_interface.h @@ -6,8 +6,8 @@ #define QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_ #include <cstddef> +#include "absl/types/optional.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" namespace quic { @@ -26,13 +26,15 @@ class QUIC_EXPORT_PRIVATE StreamDelegateInterface { // Called when the stream needs to write data. If |level| is present, the data // will be written at the specified |level|. The data will be written // at specified transmission |type|. + // TODO(fayang): Change absl::optional<EncryptionLevel> to EncryptionLevel + // when deprecating quic_use_write_or_buffer_data_at_level. virtual QuicConsumedData WritevData( QuicStreamId id, size_t write_length, QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) = 0; + absl::optional<EncryptionLevel> level) = 0; // Called to write crypto data. virtual size_t SendCryptoData(EncryptionLevel level, size_t write_length, diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc index 7c10d2c8e0b..06ed1c8a4da 100644 --- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc +++ b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.cc @@ -6,6 +6,7 @@ #include <cstring> #include <memory> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -280,14 +280,14 @@ void TlsChloExtractor::HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello) { if (rv == 1) { QuicDataReader alpns_reader(reinterpret_cast<const char*>(alpn_data), alpn_len); - quiche::QuicheStringPiece alpns_payload; + absl::string_view alpns_payload; if (!alpns_reader.ReadStringPiece16(&alpns_payload)) { HandleUnrecoverableError("Failed to read alpns_payload"); return; } QuicDataReader alpns_payload_reader(alpns_payload); while (!alpns_payload_reader.IsDoneReading()) { - quiche::QuicheStringPiece alpn_payload; + absl::string_view alpn_payload; if (!alpns_payload_reader.ReadStringPiece8(&alpn_payload)) { HandleUnrecoverableError("Failed to read alpn_payload"); return; diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h index b50d2e236ab..718e5fa09eb 100644 --- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h +++ b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h @@ -67,10 +67,9 @@ class QUIC_NO_EXPORT TlsChloExtractor const QuicVersionNegotiationPacket& /*packet*/) override {} void OnRetryPacket(QuicConnectionId /*original_connection_id*/, QuicConnectionId /*new_connection_id*/, - quiche::QuicheStringPiece /*retry_token*/, - quiche::QuicheStringPiece /*retry_integrity_tag*/, - quiche::QuicheStringPiece /*retry_without_tag*/) override { - } + absl::string_view /*retry_token*/, + absl::string_view /*retry_integrity_tag*/, + absl::string_view /*retry_without_tag*/) override {} bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override; bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override { return true; @@ -161,6 +160,15 @@ class QUIC_NO_EXPORT TlsChloExtractor } void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} + void OnDecryptedFirstPacketInKeyPhase() override {} + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + return nullptr; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } // Methods from QuicStreamSequencer::StreamInterface. void OnDataAvailable() override; diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc index 955e58c0ee6..db926b422c2 100644 --- a/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc @@ -31,7 +31,7 @@ class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> { QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet); std::string detailed_error; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( *packet, /*expected_destination_connection_id_length=*/0, &packet_info.form, &packet_info.long_packet_type, @@ -128,7 +128,7 @@ TEST_P(TlsChloExtractorTest, MoveAssignmentBetweenPackets) { QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]); std::string detailed_error; bool retry_token_present; - quiche::QuicheStringPiece retry_token; + absl::string_view retry_token; const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( *packets_[0], /*expected_destination_connection_id_length=*/0, &packet_info.form, &packet_info.long_packet_type, 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 ba3f9d4de4a..6ea06b83b3c 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 @@ -7,6 +7,7 @@ #include <cstring> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" @@ -15,40 +16,10 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { -TlsClientHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( - TlsClientHandshaker* parent) - : parent_(parent) {} - -TlsClientHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {} - -void TlsClientHandshaker::ProofVerifierCallbackImpl::Run( - bool ok, - const std::string& /*error_details*/, - std::unique_ptr<ProofVerifyDetails>* details) { - if (parent_ == nullptr) { - return; - } - - parent_->verify_details_ = std::move(*details); - parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid; - parent_->state_ = STATE_HANDSHAKE_RUNNING; - parent_->proof_verify_callback_ = nullptr; - if (parent_->verify_details_) { - parent_->proof_handler_->OnProofVerifyDetailsAvailable( - *parent_->verify_details_); - } - parent_->AdvanceHandshake(); -} - -void TlsClientHandshaker::ProofVerifierCallbackImpl::Cancel() { - parent_ = nullptr; -} - TlsClientHandshaker::TlsClientHandshaker( const QuicServerId& server_id, QuicCryptoStream* stream, @@ -70,15 +41,9 @@ TlsClientHandshaker::TlsClientHandshaker( has_application_state_(has_application_state), tls_connection_(crypto_config->ssl_ctx(), this) {} -TlsClientHandshaker::~TlsClientHandshaker() { - if (proof_verify_callback_) { - proof_verify_callback_->Cancel(); - } -} +TlsClientHandshaker::~TlsClientHandshaker() {} bool TlsClientHandshaker::CryptoConnect() { - state_ = STATE_HANDSHAKE_RUNNING; - if (!pre_shared_key_.empty()) { // TODO(b/154162689) add PSK support to QUIC+TLS. std::string error_details = @@ -189,7 +154,7 @@ bool TlsClientHandshaker::SetAlpn() { success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0); if (!success) { QUIC_BUG << "Failed to set ALPN: " - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( + << quiche::QuicheTextUtils::HexDump(absl::string_view( alpn_writer.data(), alpn_writer.length())); return false; } @@ -273,7 +238,7 @@ bool TlsClientHandshaker::ProcessTransportParameters( } session()->OnConfigNegotiated(); - if (state_ == STATE_CONNECTION_CLOSED) { + if (is_connection_closed()) { *error_details = "Session closed the connection when parsing negotiated config."; return false; @@ -286,12 +251,12 @@ int TlsClientHandshaker::num_sent_client_hellos() const { } bool TlsClientHandshaker::IsResumption() const { - QUIC_BUG_IF(!one_rtt_keys_available_); + QUIC_BUG_IF(!one_rtt_keys_available()); return SSL_session_reused(ssl()) == 1; } bool TlsClientHandshaker::EarlyDataAccepted() const { - QUIC_BUG_IF(!one_rtt_keys_available_); + QUIC_BUG_IF(!one_rtt_keys_available()); return SSL_early_data_accepted(ssl()) == 1; } @@ -300,7 +265,7 @@ ssl_early_data_reason_t TlsClientHandshaker::EarlyDataReason() const { } bool TlsClientHandshaker::ReceivedInchoateReject() const { - QUIC_BUG_IF(!one_rtt_keys_available_); + QUIC_BUG_IF(!one_rtt_keys_available()); // REJ messages are a QUIC crypto feature, so TLS always returns false. return false; } @@ -319,7 +284,7 @@ bool TlsClientHandshaker::encryption_established() const { } bool TlsClientHandshaker::one_rtt_keys_available() const { - return one_rtt_keys_available_; + return state_ >= HANDSHAKE_COMPLETE; } const QuicCryptoNegotiatedParameters& @@ -332,16 +297,7 @@ CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() { } HandshakeState TlsClientHandshaker::GetHandshakeState() const { - if (handshake_confirmed_) { - return HANDSHAKE_CONFIRMED; - } - if (one_rtt_keys_available_) { - return HANDSHAKE_COMPLETE; - } - if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) { - return HANDSHAKE_PROCESSED; - } - return HANDSHAKE_START; + return state_; } size_t TlsClientHandshaker::BufferSizeLimitForLevel( @@ -349,6 +305,20 @@ size_t TlsClientHandshaker::BufferSizeLimitForLevel( return TlsHandshaker::BufferSizeLimitForLevel(level); } +bool TlsClientHandshaker::KeyUpdateSupportedLocally() const { + return true; +} + +std::unique_ptr<QuicDecrypter> +TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter(); +} + +std::unique_ptr<QuicEncrypter> +TlsClientHandshaker::CreateCurrentOneRttEncrypter() { + return TlsHandshaker::CreateCurrentOneRttEncrypter(); +} + void TlsClientHandshaker::OnOneRttPacketAcknowledged() { OnHandshakeConfirmed(); } @@ -362,13 +332,13 @@ void TlsClientHandshaker::OnHandshakePacketSent() { handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL); } -void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode /*error*/, - ConnectionCloseSource /*source*/) { - state_ = STATE_CONNECTION_CLOSED; +void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode error, + ConnectionCloseSource source) { + TlsHandshaker::OnConnectionClosed(error, source); } void TlsClientHandshaker::OnHandshakeDoneReceived() { - if (!one_rtt_keys_available_) { + if (!one_rtt_keys_available()) { CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected handshake done received"); return; @@ -380,89 +350,54 @@ void TlsClientHandshaker::SetWriteSecret( EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& write_secret) { - if (state_ == STATE_CONNECTION_CLOSED) { + if (is_connection_closed()) { return; } if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) { encryption_established_ = true; } - const bool postpone_discarding_zero_rtt_keys = - GetQuicReloadableFlag(quic_postpone_discarding_zero_rtt_keys); - if (!postpone_discarding_zero_rtt_keys && - level == ENCRYPTION_FORWARD_SECURE) { - handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT); - } TlsHandshaker::SetWriteSecret(level, cipher, write_secret); - if (postpone_discarding_zero_rtt_keys && level == ENCRYPTION_FORWARD_SECURE) { + if (level == ENCRYPTION_FORWARD_SECURE) { handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT); } } void TlsClientHandshaker::OnHandshakeConfirmed() { - DCHECK(one_rtt_keys_available_); - if (handshake_confirmed_) { + DCHECK(one_rtt_keys_available()); + if (state_ >= HANDSHAKE_CONFIRMED) { return; } - handshake_confirmed_ = true; + state_ = HANDSHAKE_CONFIRMED; handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE); handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE); } -void TlsClientHandshaker::AdvanceHandshake() { - if (state_ == STATE_CONNECTION_CLOSED) { - QUIC_LOG(INFO) - << "TlsClientHandshaker received message after connection closed"; - return; - } - if (state_ == STATE_IDLE) { - CloseConnection(QUIC_HANDSHAKE_FAILED, - "Client observed TLS handshake idle failure"); - return; - } - if (state_ == STATE_HANDSHAKE_COMPLETE) { - int rv = SSL_process_quic_post_handshake(ssl()); - if (rv != 1) { - CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data"); - } - return; - } +QuicAsyncStatus TlsClientHandshaker::VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, + std::unique_ptr<ProofVerifierCallback> callback) { + const uint8_t* ocsp_response_raw; + size_t ocsp_response_len; + SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len); + std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw), + ocsp_response_len); + const uint8_t* sct_list_raw; + size_t sct_list_len; + SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len); + std::string sct_list(reinterpret_cast<const char*>(sct_list_raw), + sct_list_len); - QUIC_LOG(INFO) << "TlsClientHandshaker: continuing handshake"; - int rv = SSL_do_handshake(ssl()); - if (rv == 1) { - FinishHandshake(); - return; - } - int ssl_error = SSL_get_error(ssl(), rv); - bool should_close = true; - if (ssl_error == SSL_ERROR_EARLY_DATA_REJECTED) { - HandleZeroRttReject(); - return; - } - switch (state_) { - case STATE_HANDSHAKE_RUNNING: - should_close = ssl_error != SSL_ERROR_WANT_READ; - break; - case STATE_CERT_VERIFY_PENDING: - should_close = ssl_error != SSL_ERROR_WANT_CERTIFICATE_VERIFY; - break; - default: - should_close = true; - } - if (should_close && state_ != STATE_CONNECTION_CLOSED) { - // TODO(nharper): Surface error details from the error queue when ssl_error - // is SSL_ERROR_SSL. - QUIC_LOG(WARNING) << "SSL_do_handshake failed; closing connection"; - CloseConnection(QUIC_HANDSHAKE_FAILED, - "Client observed TLS handshake failure"); - } + return proof_verifier_->VerifyCertChain( + server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list, + verify_context_.get(), error_details, details, out_alert, + std::move(callback)); } -void TlsClientHandshaker::CloseConnection(QuicErrorCode error, - const std::string& reason_phrase) { - DCHECK(!reason_phrase.empty()); - state_ = STATE_CONNECTION_CLOSED; - stream()->OnUnrecoverableError(error, reason_phrase); +void TlsClientHandshaker::OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) { + proof_handler_->OnProofVerifyDetailsAvailable(verify_details); } void TlsClientHandshaker::FinishHandshake() { @@ -487,7 +422,6 @@ void TlsClientHandshaker::FinishHandshake() { return; } QUIC_LOG(INFO) << "Client: handshake finished"; - state_ = STATE_HANDSHAKE_COMPLETE; std::string error_details; if (!ProcessTransportParameters(&error_details)) { @@ -523,10 +457,26 @@ void TlsClientHandshaker::FinishHandshake() { session()->OnAlpnSelected(received_alpn_string); QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string << "'"; - one_rtt_keys_available_ = true; + state_ = HANDSHAKE_COMPLETE; handshaker_delegate()->OnTlsHandshakeComplete(); } +void TlsClientHandshaker::ProcessPostHandshakeMessage() { + int rv = SSL_process_quic_post_handshake(ssl()); + if (rv != 1) { + CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data"); + } +} + +bool TlsClientHandshaker::ShouldCloseConnectionOnUnexpectedError( + int ssl_error) { + if (ssl_error != SSL_ERROR_EARLY_DATA_REJECTED) { + return true; + } + HandleZeroRttReject(); + return false; +} + void TlsClientHandshaker::HandleZeroRttReject() { QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server"; DCHECK(session_cache_); @@ -538,61 +488,6 @@ void TlsClientHandshaker::HandleZeroRttReject() { AdvanceHandshake(); } -enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) { - if (verify_result_ != ssl_verify_retry || - state_ == STATE_CERT_VERIFY_PENDING) { - enum ssl_verify_result_t result = verify_result_; - verify_result_ = ssl_verify_retry; - return result; - } - const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl()); - if (cert_chain == nullptr) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return ssl_verify_invalid; - } - // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies. - std::vector<std::string> certs; - for (CRYPTO_BUFFER* cert : cert_chain) { - certs.push_back( - std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)), - CRYPTO_BUFFER_len(cert))); - } - const uint8_t* ocsp_response_raw; - size_t ocsp_response_len; - SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len); - std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw), - ocsp_response_len); - const uint8_t* sct_list_raw; - size_t sct_list_len; - SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len); - std::string sct_list(reinterpret_cast<const char*>(sct_list_raw), - sct_list_len); - - ProofVerifierCallbackImpl* proof_verify_callback = - new ProofVerifierCallbackImpl(this); - - QuicAsyncStatus verify_result = proof_verifier_->VerifyCertChain( - server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list, - verify_context_.get(), &cert_verify_error_details_, &verify_details_, - std::unique_ptr<ProofVerifierCallback>(proof_verify_callback)); - switch (verify_result) { - case QUIC_SUCCESS: - if (verify_details_) { - proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_); - } - return ssl_verify_ok; - case QUIC_PENDING: - proof_verify_callback_ = proof_verify_callback; - state_ = STATE_CERT_VERIFY_PENDING; - return ssl_verify_retry; - case QUIC_FAILURE: - default: - QUIC_LOG(INFO) << "Cert chain verification failed: " - << cert_verify_error_details_; - return ssl_verify_invalid; - } -} - void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) { if (!received_transport_params_) { QUIC_BUG << "Transport parameters isn't received"; @@ -616,17 +511,16 @@ void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) { } void TlsClientHandshaker::WriteMessage(EncryptionLevel level, - quiche::QuicheStringPiece data) { - if (level == ENCRYPTION_HANDSHAKE && - state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) { - state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_SENT; + absl::string_view data) { + if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) { + state_ = HANDSHAKE_PROCESSED; } TlsHandshaker::WriteMessage(level, data); } void TlsClientHandshaker::SetServerApplicationStateForResumption( std::unique_ptr<ApplicationState> application_state) { - DCHECK_EQ(STATE_HANDSHAKE_COMPLETE, state_); + DCHECK(one_rtt_keys_available()); received_application_state_ = std::move(application_state); // At least one tls session is cached before application state is received. So // insert now. 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 2a09fb83818..aadfa0bf541 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 @@ -9,8 +9,8 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" -#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" #include "net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" @@ -18,7 +18,6 @@ #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/core/tls_handshaker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -59,6 +58,10 @@ 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; void OnOneRttPacketAcknowledged() override; void OnHandshakePacketSent() override; void OnConnectionClosed(QuicErrorCode error, @@ -69,8 +72,7 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker const std::vector<uint8_t>& write_secret) override; // Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data. - void WriteMessage(EncryptionLevel level, - quiche::QuicheStringPiece data) override; + void WriteMessage(EncryptionLevel level, absl::string_view data) override; void SetServerApplicationStateForResumption( std::unique_ptr<ApplicationState> application_state) override; @@ -83,48 +85,25 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker return &tls_connection_; } - void AdvanceHandshake() override; - void CloseConnection(QuicErrorCode error, - const std::string& reason_phrase) override; + void FinishHandshake() override; + void ProcessPostHandshakeMessage() override; + bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override; + QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, + std::unique_ptr<ProofVerifierCallback> callback) override; + void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) override; // TlsClientConnection::Delegate implementation: - enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override; TlsConnection::Delegate* ConnectionDelegate() override { return this; } private: - // ProofVerifierCallbackImpl handles the result of an asynchronous certificate - // verification operation. - class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl - : public ProofVerifierCallback { - public: - explicit ProofVerifierCallbackImpl(TlsClientHandshaker* parent); - ~ProofVerifierCallbackImpl() override; - - // ProofVerifierCallback interface. - void Run(bool ok, - const std::string& error_details, - std::unique_ptr<ProofVerifyDetails>* details) override; - - // If called, Cancel causes the pending callback to be a no-op. - void Cancel(); - - private: - TlsClientHandshaker* parent_; - }; - - enum State { - STATE_IDLE, - STATE_HANDSHAKE_RUNNING, - STATE_CERT_VERIFY_PENDING, - STATE_ENCRYPTION_HANDSHAKE_DATA_SENT, - STATE_HANDSHAKE_COMPLETE, - STATE_CONNECTION_CLOSED, - } state_ = STATE_IDLE; - bool SetAlpn(); bool SetTransportParameters(); bool ProcessTransportParameters(std::string* error_details); - void FinishHandshake(); void HandleZeroRttReject(); // Called when server completes handshake (i.e., either handshake done is @@ -141,10 +120,10 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker QuicServerId server_id_; // Objects used for verifying the server's certificate chain. - // |proof_verifier_| is owned by the caller of TlsClientHandshaker's - // constructor. + // |proof_verifier_| is owned by the caller of TlsHandshaker's constructor. ProofVerifier* proof_verifier_; std::unique_ptr<ProofVerifyContext> verify_context_; + // Unowned pointer to the proof handler which has the // OnProofVerifyDetailsAvailable callback to use for notifying the result of // certificate verification. @@ -159,17 +138,9 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker // Pre-shared key used during the handshake. std::string pre_shared_key_; - // ProofVerifierCallback used for async certificate verification. This object - // is owned by |proof_verifier_|. - ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr; - std::unique_ptr<ProofVerifyDetails> verify_details_; - enum ssl_verify_result_t verify_result_ = ssl_verify_retry; - std::string cert_verify_error_details_; - + HandshakeState state_ = HANDSHAKE_START; bool encryption_established_ = false; bool initial_keys_dropped_ = false; - bool one_rtt_keys_available_ = false; - bool handshake_confirmed_ = false; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc index 132e6365786..2488426167f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc @@ -6,6 +6,7 @@ #include <string> #include <utility> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" @@ -24,7 +25,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" #include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" using testing::_; @@ -52,7 +52,7 @@ class TestProofVerifier : public ProofVerifier { const uint16_t port, const std::string& server_config, QuicTransportVersion quic_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& certs, const std::string& cert_sct, const std::string& signature, @@ -74,15 +74,16 @@ class TestProofVerifier : public ProofVerifier { const ProofVerifyContext* context, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, std::unique_ptr<ProofVerifierCallback> callback) override { if (!active_) { - return verifier_->VerifyCertChain(hostname, port, certs, ocsp_response, - cert_sct, context, error_details, - details, std::move(callback)); + return verifier_->VerifyCertChain( + hostname, port, certs, ocsp_response, cert_sct, context, + error_details, details, out_alert, std::move(callback)); } pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>( hostname, port, certs, ocsp_response, cert_sct, context, error_details, - details, std::move(callback), verifier_.get())); + details, out_alert, std::move(callback), verifier_.get())); return QUIC_PENDING; } @@ -123,6 +124,7 @@ class TestProofVerifier : public ProofVerifier { const ProofVerifyContext* context, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, std::unique_ptr<ProofVerifierCallback> callback, ProofVerifier* delegate) : hostname_(hostname), @@ -133,6 +135,7 @@ class TestProofVerifier : public ProofVerifier { context_(context), error_details_(error_details), details_(details), + out_alert_(out_alert), callback_(std::move(callback)), delegate_(delegate) {} @@ -143,7 +146,7 @@ class TestProofVerifier : public ProofVerifier { // synchronously. QuicAsyncStatus status = delegate_->VerifyCertChain( hostname_, port_, certs_, ocsp_response_, cert_sct_, context_, - error_details_, details_, + error_details_, details_, out_alert_, std::make_unique<FailingProofVerifierCallback>()); ASSERT_NE(status, QUIC_PENDING); callback_->Run(status == QUIC_SUCCESS, *error_details_, details_); @@ -158,6 +161,7 @@ class TestProofVerifier : public ProofVerifier { const ProofVerifyContext* context_; std::string* error_details_; std::unique_ptr<ProofVerifyDetails>* details_; + uint8_t* out_alert_; std::unique_ptr<ProofVerifierCallback> callback_; ProofVerifier* delegate_; }; @@ -233,10 +237,9 @@ class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> { server_session_.reset(server_session); std::string alpn = AlpnForVersion(connection_->version()); EXPECT_CALL(*server_session_, SelectAlpn(_)) - .WillRepeatedly( - [alpn](const std::vector<quiche::QuicheStringPiece>& alpns) { - return std::find(alpns.cbegin(), alpns.cend(), alpn); - }); + .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) { + return std::find(alpns.cbegin(), alpns.cend(), alpn); + }); } MockQuicConnectionHelper server_helper_; @@ -286,8 +289,8 @@ TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) { 0, 0, 0, // uint24 length }; stream()->crypto_message_parser()->ProcessInput( - quiche::QuicheStringPiece(bogus_handshake_message, - QUICHE_ARRAYSIZE(bogus_handshake_message)), + absl::string_view(bogus_handshake_message, + ABSL_ARRAYSIZE(bogus_handshake_message)), ENCRYPTION_INITIAL); EXPECT_FALSE(stream()->one_rtt_keys_available()); @@ -556,10 +559,9 @@ TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) { InitializeFakeServer(); const std::string kTestAlpn = "An ALPN That Client Did Not Offer"; EXPECT_CALL(*server_session_, SelectAlpn(_)) - .WillOnce( - [kTestAlpn](const std::vector<quiche::QuicheStringPiece>& alpns) { - return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn); - }); + .WillOnce([kTestAlpn](const std::vector<absl::string_view>& alpns) { + return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn); + }); EXPECT_CALL(*server_connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failure (ENCRYPTION_INITIAL) 120: " @@ -634,7 +636,7 @@ TEST_P(TlsClientHandshakerTest, BadTransportParams) { CreateConnection(); stream()->CryptoConnect(); - auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get()); + auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get()); EXPECT_EQ(kDefaultMaxStreamsPerConnection, id_manager->max_outgoing_bidirectional_streams()); QuicConfig config; 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 04fab15201a..bfe35455f2e 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 @@ -4,23 +4,55 @@ #include "net/third_party/quiche/src/quic/core/tls_handshaker.h" +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/crypto.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { +TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( + TlsHandshaker* parent) + : parent_(parent) {} + +TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {} + +void TlsHandshaker::ProofVerifierCallbackImpl::Run( + bool ok, + const std::string& /*error_details*/, + std::unique_ptr<ProofVerifyDetails>* details) { + if (parent_ == nullptr) { + return; + } + + parent_->verify_details_ = std::move(*details); + parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid; + parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ); + parent_->proof_verify_callback_ = nullptr; + if (parent_->verify_details_) { + parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_); + } + parent_->AdvanceHandshake(); +} + +void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { + parent_ = nullptr; +} + TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session) : stream_(stream), handshaker_delegate_(session) {} -TlsHandshaker::~TlsHandshaker() {} +TlsHandshaker::~TlsHandshaker() { + if (proof_verify_callback_) { + proof_verify_callback_->Cancel(); + } +} -bool TlsHandshaker::ProcessInput(quiche::QuicheStringPiece input, +bool TlsHandshaker::ProcessInput(absl::string_view input, EncryptionLevel level) { if (parser_error_ != QUIC_NO_ERROR) { return false; @@ -52,6 +84,50 @@ bool TlsHandshaker::ProcessInput(quiche::QuicheStringPiece input, return true; } +void TlsHandshaker::AdvanceHandshake() { + if (is_connection_closed_) { + return; + } + if (GetHandshakeState() >= HANDSHAKE_COMPLETE) { + ProcessPostHandshakeMessage(); + return; + } + + QUIC_VLOG(1) << "TlsHandshaker: continuing handshake"; + int rv = SSL_do_handshake(ssl()); + if (rv == 1) { + FinishHandshake(); + return; + } + int ssl_error = SSL_get_error(ssl(), rv); + if (ssl_error == expected_ssl_error_) { + return; + } + if (ShouldCloseConnectionOnUnexpectedError(ssl_error) && + !is_connection_closed_) { + QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns " + << ssl_error; + ERR_print_errors_fp(stderr); + CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed"); + } +} + +void TlsHandshaker::CloseConnection(QuicErrorCode error, + const std::string& reason_phrase) { + DCHECK(!reason_phrase.empty()); + stream()->OnUnrecoverableError(error, reason_phrase); + is_connection_closed_ = true; +} + +void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/, + ConnectionCloseSource /*source*/) { + is_connection_closed_ = true; +} + +bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) { + return true; +} + size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const { return SSL_quic_max_handshake_flight_len( ssl(), TlsConnection::BoringEncryptionLevel(level)); @@ -65,12 +141,73 @@ const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) { return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher)); } +enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) { + if (verify_result_ != ssl_verify_retry || + expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) { + enum ssl_verify_result_t result = verify_result_; + verify_result_ = ssl_verify_retry; + *out_alert = cert_verify_tls_alert_; + return result; + } + const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl()); + if (cert_chain == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_verify_invalid; + } + // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies. + std::vector<std::string> certs; + for (CRYPTO_BUFFER* cert : cert_chain) { + certs.push_back( + std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)), + CRYPTO_BUFFER_len(cert))); + } + + ProofVerifierCallbackImpl* proof_verify_callback = + new ProofVerifierCallbackImpl(this); + + cert_verify_tls_alert_ = *out_alert; + QuicAsyncStatus verify_result = VerifyCertChain( + certs, &cert_verify_error_details_, &verify_details_, + &cert_verify_tls_alert_, + std::unique_ptr<ProofVerifierCallback>(proof_verify_callback)); + switch (verify_result) { + case QUIC_SUCCESS: + if (verify_details_) { + OnProofVerifyDetailsAvailable(*verify_details_); + } + return ssl_verify_ok; + case QUIC_PENDING: + proof_verify_callback_ = proof_verify_callback; + set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY); + return ssl_verify_retry; + case QUIC_FAILURE: + default: + *out_alert = cert_verify_tls_alert_; + QUIC_LOG(INFO) << "Cert chain verification failed: " + << cert_verify_error_details_; + return ssl_verify_invalid; + } +} + void TlsHandshaker::SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& write_secret) { + QUIC_DVLOG(1) << "SetWriteSecret level=" << level; std::unique_ptr<QuicEncrypter> encrypter = QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher)); - CryptoUtils::SetKeyAndIV(Prf(cipher), write_secret, encrypter.get()); + const EVP_MD* prf = Prf(cipher); + CryptoUtils::SetKeyAndIV(prf, write_secret, encrypter.get()); + std::vector<uint8_t> header_protection_key = + CryptoUtils::GenerateHeaderProtectionKey(prf, write_secret, + encrypter->GetKeySize()); + encrypter->SetHeaderProtectionKey( + absl::string_view(reinterpret_cast<char*>(header_protection_key.data()), + header_protection_key.size())); + if (level == ENCRYPTION_FORWARD_SECURE) { + DCHECK(latest_write_secret_.empty()); + latest_write_secret_ = write_secret; + one_rtt_write_header_protection_key_ = header_protection_key; + } handshaker_delegate_->OnNewEncryptionKeyAvailable(level, std::move(encrypter)); } @@ -78,17 +215,75 @@ void TlsHandshaker::SetWriteSecret(EncryptionLevel level, bool TlsHandshaker::SetReadSecret(EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& read_secret) { + QUIC_DVLOG(1) << "SetReadSecret level=" << level; std::unique_ptr<QuicDecrypter> decrypter = QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher)); - CryptoUtils::SetKeyAndIV(Prf(cipher), read_secret, decrypter.get()); + const EVP_MD* prf = Prf(cipher); + CryptoUtils::SetKeyAndIV(prf, read_secret, decrypter.get()); + std::vector<uint8_t> header_protection_key = + CryptoUtils::GenerateHeaderProtectionKey(prf, read_secret, + decrypter->GetKeySize()); + decrypter->SetHeaderProtectionKey( + absl::string_view(reinterpret_cast<char*>(header_protection_key.data()), + header_protection_key.size())); + if (level == ENCRYPTION_FORWARD_SECURE) { + DCHECK(latest_read_secret_.empty()); + latest_read_secret_ = read_secret; + one_rtt_read_header_protection_key_ = header_protection_key; + } return handshaker_delegate_->OnNewDecryptionKeyAvailable( level, std::move(decrypter), /*set_alternative_decrypter=*/false, /*latch_once_used=*/false); } +std::unique_ptr<QuicDecrypter> +TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + if (latest_read_secret_.empty() || latest_write_secret_.empty() || + one_rtt_read_header_protection_key_.empty() || + one_rtt_write_header_protection_key_.empty()) { + std::string error_details = "1-RTT secret(s) not set yet."; + QUIC_BUG << error_details; + CloseConnection(QUIC_INTERNAL_ERROR, error_details); + return nullptr; + } + 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_); + + std::unique_ptr<QuicDecrypter> decrypter = + QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher)); + CryptoUtils::SetKeyAndIV(prf, latest_read_secret_, decrypter.get()); + decrypter->SetHeaderProtectionKey(absl::string_view( + reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()), + one_rtt_read_header_protection_key_.size())); + + return decrypter; +} + +std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() { + if (latest_write_secret_.empty() || + one_rtt_write_header_protection_key_.empty()) { + std::string error_details = "1-RTT write secret not set yet."; + QUIC_BUG << error_details; + CloseConnection(QUIC_INTERNAL_ERROR, error_details); + return nullptr; + } + 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()); + encrypter->SetHeaderProtectionKey(absl::string_view( + reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()), + one_rtt_write_header_protection_key_.size())); + return encrypter; +} + void TlsHandshaker::WriteMessage(EncryptionLevel level, - quiche::QuicheStringPiece data) { + absl::string_view data) { stream_->WriteCryptoData(level, data); } diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h index 2b3c9fc20a1..12b27f1b00f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h +++ b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker.h @@ -5,16 +5,17 @@ #ifndef QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_ #define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_ +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/base.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h" +#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/tls_connection.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,8 +37,7 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate, ~TlsHandshaker() override; // From CryptoMessageParser - bool ProcessInput(quiche::QuicheStringPiece input, - EncryptionLevel level) override; + bool ProcessInput(absl::string_view input, EncryptionLevel level) override; size_t InputBytesRemaining() const override { return 0; } QuicErrorCode error() const override { return parser_error_; } const std::string& error_detail() const override { @@ -49,12 +49,61 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate, CryptoMessageParser* crypto_message_parser() { return this; } size_t BufferSizeLimitForLevel(EncryptionLevel level) const; ssl_early_data_reason_t EarlyDataReason() const; + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter(); + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter(); + virtual HandshakeState GetHandshakeState() const = 0; protected: - virtual void AdvanceHandshake() = 0; + // Called when a new message is received on the crypto stream and is available + // for the TLS stack to read. + void AdvanceHandshake(); - virtual void CloseConnection(QuicErrorCode error, - const std::string& reason_phrase) = 0; + void CloseConnection(QuicErrorCode error, const std::string& reason_phrase); + + void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source); + + bool is_connection_closed() const { return is_connection_closed_; } + + // Called when |SSL_do_handshake| returns 1, indicating that the handshake has + // finished. Note that due to 0-RTT, the handshake may "finish" twice; + // |SSL_in_early_data| can be used to determine whether the handshake is truly + // done. + virtual void FinishHandshake() = 0; + + // Called when a handshake message is received after the handshake is + // complete. + virtual void ProcessPostHandshakeMessage() = 0; + + // Called when an unexpected error code is received from |SSL_get_error|. If a + // subclass can expect more than just a single error (as provided by + // |set_expected_ssl_error|), it can override this method to handle that case. + virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error); + + void set_expected_ssl_error(int ssl_error) { + expected_ssl_error_ = ssl_error; + } + int expected_ssl_error() const { return expected_ssl_error_; } + + // Called to verify a cert chain. This is a simple wrapper around + // ProofVerifier or ServerProofVerifier, which optionally gathers additional + // arguments to pass into their VerifyCertChain method. This class retains a + // non-owning pointer to |callback|; the callback must live until this + // function returns QUIC_SUCCESS or QUIC_FAILURE, or until the callback is + // run. + // + // If certificate verification fails, |*out_alert| may be set to a TLS alert + // that will be sent when closing the connection; it defaults to + // certificate_unknown. Implementations of VerifyCertChain may retain the + // |out_alert| pointer while performing an async operation. + virtual QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, + std::unique_ptr<ProofVerifierCallback> callback) = 0; + // Called when certificate verification is completed. + virtual void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) = 0; // Returns the PRF used by the cipher suite negotiated in the TLS handshake. const EVP_MD* Prf(const SSL_CIPHER* cipher); @@ -68,6 +117,8 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate, return handshaker_delegate_; } + enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override; + // SetWriteSecret provides the encryption secret used to encrypt messages at // encryption level |level|. The secret provided here is the one from the TLS // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake @@ -88,8 +139,7 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate, // WriteMessage is called when there is |data| from the TLS stack ready for // the QUIC stack to write in a crypto frame. The data must be transmitted at // encryption level |level|. - void WriteMessage(EncryptionLevel level, - quiche::QuicheStringPiece data) override; + void WriteMessage(EncryptionLevel level, absl::string_view data) override; // FlushFlight is called to signal that the current flight of // messages have all been written (via calls to WriteMessage) and can be @@ -101,11 +151,53 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate, void SendAlert(EncryptionLevel level, uint8_t desc) override; private: + // ProofVerifierCallbackImpl handles the result of an asynchronous certificate + // verification operation. + class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl + : public ProofVerifierCallback { + public: + explicit ProofVerifierCallbackImpl(TlsHandshaker* parent); + ~ProofVerifierCallbackImpl() override; + + // ProofVerifierCallback interface. + void Run(bool ok, + const std::string& error_details, + std::unique_ptr<ProofVerifyDetails>* details) override; + + // If called, Cancel causes the pending callback to be a no-op. + void Cancel(); + + private: + // Non-owning pointer to the TlsHandshaker responsible for this callback. + // |parent_| must be valid for the life of this callback or until |Cancel| + // is called. + TlsHandshaker* parent_; + }; + + // ProofVerifierCallback used for async certificate verification. Ownership of + // this object is transferred to |VerifyCertChain|; + ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr; + std::unique_ptr<ProofVerifyDetails> verify_details_; + enum ssl_verify_result_t verify_result_ = ssl_verify_retry; + uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN; + std::string cert_verify_error_details_; + + int expected_ssl_error_ = SSL_ERROR_WANT_READ; + bool is_connection_closed_ = false; + QuicCryptoStream* stream_; HandshakerDelegateInterface* handshaker_delegate_; QuicErrorCode parser_error_ = QUIC_NO_ERROR; std::string parser_error_detail_; + + // The most recently derived 1-RTT read and write secrets, which are updated + // on each key update. + std::vector<uint8_t> latest_read_secret_; + std::vector<uint8_t> latest_write_secret_; + // 1-RTT header protection keys, which are not changed during key update. + std::vector<uint8_t> one_rtt_read_header_protection_key_; + std::vector<uint8_t> one_rtt_write_header_protection_key_; }; } // namespace quic 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 a8f926ea457..e0fe84d9c52 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 @@ -7,14 +7,16 @@ #include <memory> #include <string> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -34,11 +36,11 @@ void TlsServerHandshaker::SignatureCallback::Run( handshaker_->cert_verify_sig_ = std::move(signature); handshaker_->proof_source_details_ = std::move(details); } - State last_state = handshaker_->state_; - handshaker_->state_ = STATE_SIGNATURE_COMPLETE; + int last_expected_ssl_error = handshaker_->expected_ssl_error(); + handshaker_->set_expected_ssl_error(SSL_ERROR_WANT_READ); handshaker_->signature_callback_ = nullptr; - if (last_state == STATE_SIGNATURE_PENDING) { - handshaker_->AdvanceHandshake(); + if (last_expected_ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { + handshaker_->AdvanceHandshakeFromCallback(); } } @@ -67,8 +69,8 @@ void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) { // pending), TlsServerHandshaker is not actively processing handshake // messages. We need to have it resume processing handshake messages by // calling AdvanceHandshake. - if (handshaker_->state_ == STATE_TICKET_DECRYPTION_PENDING) { - handshaker_->AdvanceHandshake(); + if (handshaker_->expected_ssl_error() == SSL_ERROR_PENDING_TICKET) { + handshaker_->AdvanceHandshakeFromCallback(); } // The TicketDecrypter took ownership of this callback when Decrypt was // called. Once the callback returns, it will be deleted. Remove the @@ -96,6 +98,10 @@ TlsServerHandshaker::TlsServerHandshaker( // Configure the SSL to be a server. SSL_set_accept_state(ssl()); + + if (GetQuicFlag(FLAGS_quic_disable_server_tls_resumption)) { + SSL_set_options(ssl(), SSL_OP_NO_TICKET); + } } TlsServerHandshaker::~TlsServerHandshaker() { @@ -150,9 +156,8 @@ void TlsServerHandshaker::SetPreviousCachedNetworkParams( CachedNetworkParameters /*cached_network_params*/) {} void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) { - if (level == ENCRYPTION_HANDSHAKE && - state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) { - state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED; + if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) { + state_ = HANDSHAKE_PROCESSED; handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL); handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL); } @@ -170,9 +175,9 @@ const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const { return proof_source_details_.get(); } -void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode /*error*/, - ConnectionCloseSource /*source*/) { - state_ = STATE_CONNECTION_CLOSED; +void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode error, + ConnectionCloseSource source) { + TlsHandshaker::OnConnectionClosed(error, source); } ssl_early_data_reason_t TlsServerHandshaker::EarlyDataReason() const { @@ -184,7 +189,7 @@ bool TlsServerHandshaker::encryption_established() const { } bool TlsServerHandshaker::one_rtt_keys_available() const { - return one_rtt_keys_available_; + return state_ == HANDSHAKE_CONFIRMED; } const QuicCryptoNegotiatedParameters& @@ -197,13 +202,7 @@ CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() { } HandshakeState TlsServerHandshaker::GetHandshakeState() const { - if (one_rtt_keys_available_) { - return HANDSHAKE_CONFIRMED; - } - if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) { - return HANDSHAKE_PROCESSED; - } - return HANDSHAKE_START; + return state_; } void TlsServerHandshaker::SetServerApplicationStateForResumption( @@ -216,54 +215,31 @@ size_t TlsServerHandshaker::BufferSizeLimitForLevel( return TlsHandshaker::BufferSizeLimitForLevel(level); } -void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {} - -void TlsServerHandshaker::AdvanceHandshake() { - if (state_ == STATE_CONNECTION_CLOSED) { - QUIC_LOG(INFO) << "TlsServerHandshaker received handshake message after " - "connection was closed"; - return; - } - if (state_ == STATE_HANDSHAKE_COMPLETE) { - // TODO(nharper): Handle post-handshake messages. - return; - } +bool TlsServerHandshaker::KeyUpdateSupportedLocally() const { + return true; +} - int rv = SSL_do_handshake(ssl()); - if (rv == 1) { - FinishHandshake(); - return; - } +std::unique_ptr<QuicDecrypter> +TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() { + return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter(); +} - int ssl_error = SSL_get_error(ssl(), rv); - bool should_close = true; - switch (state_) { - case STATE_LISTENING: - case STATE_SIGNATURE_COMPLETE: - should_close = ssl_error != SSL_ERROR_WANT_READ; - break; - case STATE_SIGNATURE_PENDING: - should_close = ssl_error != SSL_ERROR_WANT_PRIVATE_KEY_OPERATION; - break; - case STATE_TICKET_DECRYPTION_PENDING: - should_close = ssl_error != SSL_ERROR_PENDING_TICKET; - break; - default: - should_close = true; - } - if (should_close && state_ != STATE_CONNECTION_CLOSED) { - QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns " - << ssl_error << ", state_ = " << state_; - ERR_print_errors_fp(stderr); - CloseConnection(QUIC_HANDSHAKE_FAILED, - "Server observed TLS handshake failure"); - } +std::unique_ptr<QuicEncrypter> +TlsServerHandshaker::CreateCurrentOneRttEncrypter() { + return TlsHandshaker::CreateCurrentOneRttEncrypter(); } -void TlsServerHandshaker::CloseConnection(QuicErrorCode error, - const std::string& reason_phrase) { - state_ = STATE_CONNECTION_CLOSED; - stream()->OnUnrecoverableError(error, reason_phrase); +void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {} + +void TlsServerHandshaker::AdvanceHandshakeFromCallback() { + AdvanceHandshake(); + if (GetQuicReloadableFlag( + quic_process_undecryptable_packets_after_async_decrypt_callback) && + !is_connection_closed()) { + QUIC_RELOADABLE_FLAG_COUNT( + quic_process_undecryptable_packets_after_async_decrypt_callback); + handshaker_delegate()->OnHandshakeCallbackDone(); + } } bool TlsServerHandshaker::ProcessTransportParameters( @@ -368,7 +344,7 @@ void TlsServerHandshaker::SetWriteSecret( EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& write_secret) { - if (state_ == STATE_CONNECTION_CLOSED) { + if (is_connection_closed()) { return; } if (level == ENCRYPTION_FORWARD_SECURE) { @@ -409,8 +385,7 @@ void TlsServerHandshaker::FinishHandshake() { QUIC_DLOG(INFO) << "Server: handshake finished. Early data reason " << reason_code << " (" << CryptoUtils::EarlyDataReasonToString(reason_code) << ")"; - state_ = STATE_HANDSHAKE_COMPLETE; - one_rtt_keys_available_ = true; + state_ = HANDSHAKE_CONFIRMED; handshaker_delegate()->OnTlsHandshakeComplete(); handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE); @@ -418,29 +393,42 @@ void TlsServerHandshaker::FinishHandshake() { handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_ZERO_RTT); } +QuicAsyncStatus TlsServerHandshaker::VerifyCertChain( + const std::vector<std::string>& /*certs*/, + std::string* /*error_details*/, + std::unique_ptr<ProofVerifyDetails>* /*details*/, + uint8_t* /*out_alert*/, + std::unique_ptr<ProofVerifierCallback> /*callback*/) { + QUIC_BUG << "Client certificates are not yet supported on the server"; + return QUIC_FAILURE; +} + +void TlsServerHandshaker::OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& /*verify_details*/) {} + ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign( uint8_t* out, size_t* out_len, size_t max_out, uint16_t sig_alg, - quiche::QuicheStringPiece in) { + absl::string_view in) { signature_callback_ = new SignatureCallback(this); proof_source_->ComputeTlsSignature( session()->connection()->self_address(), session()->connection()->peer_address(), hostname_, sig_alg, in, std::unique_ptr<SignatureCallback>(signature_callback_)); - if (state_ == STATE_SIGNATURE_COMPLETE) { - return PrivateKeyComplete(out, out_len, max_out); + if (signature_callback_) { + set_expected_ssl_error(SSL_ERROR_WANT_PRIVATE_KEY_OPERATION); + return ssl_private_key_retry; } - state_ = STATE_SIGNATURE_PENDING; - return ssl_private_key_retry; + return PrivateKeyComplete(out, out_len, max_out); } ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete( uint8_t* out, size_t* out_len, size_t max_out) { - if (state_ == STATE_SIGNATURE_PENDING) { + if (expected_ssl_error() == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) { return ssl_private_key_retry; } if (cert_verify_sig_.size() > max_out || cert_verify_sig_.empty()) { @@ -461,7 +449,7 @@ size_t TlsServerHandshaker::SessionTicketMaxOverhead() { int TlsServerHandshaker::SessionTicketSeal(uint8_t* out, size_t* out_len, size_t max_out_len, - quiche::QuicheStringPiece in) { + absl::string_view in) { DCHECK(proof_source_->GetTicketCrypter()); std::vector<uint8_t> ticket = proof_source_->GetTicketCrypter()->Encrypt(in); if (max_out_len < ticket.size()) { @@ -480,7 +468,7 @@ ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen( uint8_t* out, size_t* out_len, size_t max_out_len, - quiche::QuicheStringPiece in) { + absl::string_view in) { DCHECK(proof_source_->GetTicketCrypter()); if (!ticket_decryption_callback_) { @@ -497,12 +485,12 @@ ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen( // and when the callback is complete this function will be run again to // return the result. if (ticket_decryption_callback_) { - state_ = STATE_TICKET_DECRYPTION_PENDING; + set_expected_ssl_error(SSL_ERROR_PENDING_TICKET); return ssl_ticket_aead_retry; } } ticket_decryption_callback_ = nullptr; - state_ = STATE_LISTENING; + set_expected_ssl_error(SSL_ERROR_WANT_READ); if (decrypted_session_ticket_.empty()) { QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket"; // Ticket decryption failed. Ignore the ticket. @@ -586,7 +574,7 @@ int TlsServerHandshaker::SelectAlpn(const uint8_t** out, CBS all_alpns; CBS_init(&all_alpns, in, in_len); - std::vector<quiche::QuicheStringPiece> alpns; + std::vector<absl::string_view> alpns; while (CBS_len(&all_alpns) > 0) { CBS alpn; if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) { 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 063e5ca827b..4d12bf3ce27 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 @@ -7,6 +7,7 @@ #include <string> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/pool.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/core/tls_handshaker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -66,6 +66,10 @@ 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; void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& write_secret) override; @@ -82,11 +86,21 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker virtual void ProcessAdditionalTransportParameters( const TransportParameters& /*params*/) {} - // Called when a new message is received on the crypto stream and is available - // for the TLS stack to read. - void AdvanceHandshake() override; - void CloseConnection(QuicErrorCode error, - const std::string& reason_phrase) override; + // Called when a potentially async operation is done and the done callback + // needs to advance the handshake. + void AdvanceHandshakeFromCallback(); + + // TlsHandshaker implementation: + void FinishHandshake() override; + void ProcessPostHandshakeMessage() override {} + QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, + std::unique_ptr<ProofVerifierCallback> callback) override; + void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) override; // TlsServerConnection::Delegate implementation: int SelectCertificate(int* out_alert) override; @@ -94,12 +108,11 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker uint8_t* out_len, const uint8_t* in, unsigned in_len) override; - ssl_private_key_result_t PrivateKeySign( - uint8_t* out, - size_t* out_len, - size_t max_out, - uint16_t sig_alg, - quiche::QuicheStringPiece in) override; + ssl_private_key_result_t PrivateKeySign(uint8_t* out, + size_t* out_len, + size_t max_out, + uint16_t sig_alg, + absl::string_view in) override; ssl_private_key_result_t PrivateKeyComplete(uint8_t* out, size_t* out_len, size_t max_out) override; @@ -107,12 +120,11 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker int SessionTicketSeal(uint8_t* out, size_t* out_len, size_t max_out_len, - quiche::QuicheStringPiece in) override; - ssl_ticket_aead_result_t SessionTicketOpen( - uint8_t* out, - size_t* out_len, - size_t max_out_len, - quiche::QuicheStringPiece in) override; + absl::string_view in) override; + ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out, + size_t* out_len, + size_t max_out_len, + absl::string_view in) override; TlsConnection::Delegate* ConnectionDelegate() override { return this; } private: @@ -144,26 +156,9 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker TlsServerHandshaker* handshaker_; }; - enum State { - STATE_LISTENING, - STATE_TICKET_DECRYPTION_PENDING, - STATE_SIGNATURE_PENDING, - STATE_SIGNATURE_COMPLETE, - STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED, - STATE_HANDSHAKE_COMPLETE, - STATE_CONNECTION_CLOSED, - }; - - // Called when the TLS handshake is complete. - void FinishHandshake(); - - void CloseConnection(const std::string& reason_phrase); - bool SetTransportParameters(); bool ProcessTransportParameters(std::string* error_details); - State state_ = STATE_LISTENING; - ProofSource* proof_source_; SignatureCallback* signature_callback_ = nullptr; @@ -190,8 +185,8 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker // Pre-shared key used during the handshake. std::string pre_shared_key_; + HandshakeState state_ = HANDSHAKE_START; bool encryption_established_ = false; - bool one_rtt_keys_available_ = false; bool valid_alpn_received_ = false; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> crypto_negotiated_params_; 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 295af9d6ee7..7411ba2027f 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 @@ -6,6 +6,8 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" @@ -22,8 +24,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" #include "net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { class QuicConnection; @@ -42,14 +42,39 @@ namespace { const char kServerHostname[] = "test.example.com"; const uint16_t kServerPort = 443; -class TlsServerHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> { +struct TestParams { + ParsedQuicVersion version; + bool disable_resumption; +}; + +// Used by ::testing::PrintToStringParamName(). +std::string PrintToString(const TestParams& p) { + return quiche::QuicheStrCat( + ParsedQuicVersionToString(p.version), "_", + (p.disable_resumption ? "ResumptionDisabled" : "ResumptionEnabled")); +} + +// Constructs test permutations. +std::vector<TestParams> GetTestParams() { + std::vector<TestParams> params; + for (const auto& version : AllSupportedVersionsWithTls()) { + for (bool disable_resumption : {false, true}) { + params.push_back(TestParams{version, disable_resumption}); + } + } + return params; +} + +class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> { public: TlsServerHandshakerTest() : server_compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), server_id_(kServerHostname, kServerPort, false), - supported_versions_({GetParam()}) { + supported_versions_({GetParam().version}) { SetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2, true); + SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, + GetParam().disable_resumption); client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>( crypto_test_utils::ProofVerifierForTesting(), std::make_unique<test::SimpleSessionCache>()); @@ -101,7 +126,7 @@ class TlsServerHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> { .Times(testing::AnyNumber()); EXPECT_CALL(*server_session_, SelectAlpn(_)) .WillRepeatedly( - [this](const std::vector<quiche::QuicheStringPiece>& alpns) { + [this](const std::vector<absl::string_view>& alpns) { return std::find( alpns.cbegin(), alpns.cend(), AlpnForVersion(server_session_->connection()->version())); @@ -228,7 +253,7 @@ class TlsServerHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> { INSTANTIATE_TEST_SUITE_P(TlsServerHandshakerTests, TlsServerHandshakerTest, - ::testing::ValuesIn(AllSupportedVersionsWithTls()), + ::testing::ValuesIn(GetTestParams()), ::testing::PrintToStringParamName()); TEST_P(TlsServerHandshakerTest, NotInitiallyConected) { @@ -295,8 +320,8 @@ TEST_P(TlsServerHandshakerTest, ConnectionClosedOnTlsError) { 0, 0, 0, // uint24 length }; server_stream()->crypto_message_parser()->ProcessInput( - quiche::QuicheStringPiece(bogus_handshake_message, - QUICHE_ARRAYSIZE(bogus_handshake_message)), + absl::string_view(bogus_handshake_message, + ABSL_ARRAYSIZE(bogus_handshake_message)), ENCRYPTION_INITIAL); EXPECT_FALSE(server_stream()->one_rtt_keys_available()); @@ -330,15 +355,13 @@ TEST_P(TlsServerHandshakerTest, CustomALPNNegotiation) { EXPECT_CALL(*client_session_, GetAlpnsToOffer()) .WillRepeatedly(Return(kTestAlpns)); EXPECT_CALL(*server_session_, SelectAlpn(_)) - .WillOnce([kTestAlpn, kTestAlpns]( - const std::vector<quiche::QuicheStringPiece>& alpns) { - EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns)); - return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn); - }); - EXPECT_CALL(*client_session_, - OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn))); - EXPECT_CALL(*server_session_, - OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn))); + .WillOnce( + [kTestAlpn, kTestAlpns](const std::vector<absl::string_view>& alpns) { + EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns)); + return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn); + }); + EXPECT_CALL(*client_session_, OnAlpnSelected(absl::string_view(kTestAlpn))); + EXPECT_CALL(*server_session_, OnAlpnSelected(absl::string_view(kTestAlpn))); CompleteCryptoHandshake(); ExpectHandshakeSuccessful(); @@ -371,9 +394,10 @@ TEST_P(TlsServerHandshakerTest, Resumption) { InitializeFakeClient(); CompleteCryptoHandshake(); ExpectHandshakeSuccessful(); - EXPECT_TRUE(client_stream()->IsResumption()); - EXPECT_TRUE(server_stream()->IsResumption()); - EXPECT_TRUE(server_stream()->ResumptionAttempted()); + EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption); + EXPECT_NE(server_stream()->IsResumption(), GetParam().disable_resumption); + EXPECT_NE(server_stream()->ResumptionAttempted(), + GetParam().disable_resumption); } TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) { @@ -388,6 +412,10 @@ TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) { InitializeFakeClient(); AdvanceHandshakeWithFakeClient(); + if (GetParam().disable_resumption) { + ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 0u); + return; + } // Test that the DecryptCallback will be run asynchronously, and then run it. ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u); ticket_crypter_->RunPendingCallback(0); @@ -400,6 +428,10 @@ TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) { } TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) { + if (GetParam().disable_resumption) { + return; + } + // Do the first handshake InitializeFakeClient(); CompleteCryptoHandshake(); @@ -417,6 +449,10 @@ TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) { } TEST_P(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) { + if (GetParam().disable_resumption) { + return; + } + // Do the first handshake InitializeFakeClient(); CompleteCryptoHandshake(); @@ -471,8 +507,8 @@ TEST_P(TlsServerHandshakerTest, ZeroRttResumption) { InitializeFakeClient(); CompleteCryptoHandshake(); ExpectHandshakeSuccessful(); - EXPECT_TRUE(client_stream()->IsResumption()); - EXPECT_TRUE(server_stream()->IsZeroRtt()); + EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption); + EXPECT_NE(server_stream()->IsZeroRtt(), GetParam().disable_resumption); } TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) { @@ -495,7 +531,7 @@ TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) { InitializeFakeClient(); CompleteCryptoHandshake(); ExpectHandshakeSuccessful(); - EXPECT_TRUE(client_stream()->IsResumption()); + EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption); EXPECT_FALSE(server_stream()->IsZeroRtt()); } 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 7b2b32f894f..025da645341 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 @@ -98,9 +98,15 @@ void UberReceivedPacketManager::ResetAckStates( } received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)] .ResetAckStates(); + if (encryption_level == ENCRYPTION_INITIAL) { + // After one Initial ACK is sent, the others should be sent 'immediately'. + received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay( + kAlarmGranularity); + } } -void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport() { +void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport( + Perspective perspective) { if (supports_multiple_packet_number_spaces_) { QUIC_BUG << "Multiple packet number spaces has already been enabled"; return; @@ -112,8 +118,15 @@ void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport() { } // In IETF QUIC, the peer is expected to acknowledge packets in Initial and // Handshake packets with minimal delay. - received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay( - kAlarmGranularity); + if (!GetQuicReloadableFlag(quic_delay_initial_ack) || + perspective == Perspective::IS_CLIENT) { + // Delay the first server ACK, because server ACKs are padded to + // full size and count towards the amplification limit. + received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay( + kAlarmGranularity); + } else { + QUIC_RELOADABLE_FLAG_COUNT(quic_delay_initial_ack); + } received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay( kAlarmGranularity); diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h index 17b5e268063..a9f177592b6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h +++ b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager.h @@ -54,7 +54,7 @@ class QUIC_EXPORT_PRIVATE UberReceivedPacketManager { void ResetAckStates(EncryptionLevel encryption_level); // Called to enable multiple packet number support. - void EnableMultiplePacketNumberSpacesSupport(); + void EnableMultiplePacketNumberSpacesSupport(Perspective perspective); // Returns true if ACK frame has been updated since GetUpdatedAckFrame was // last called. diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc index b7063d2fede..3a1531bcfa8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/uber_received_packet_manager_test.cc @@ -439,7 +439,7 @@ TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) { TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBeforeMultiplePacketNumberSpaces) { - manager_->EnableMultiplePacketNumberSpacesSupport(); + manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_CLIENT); EXPECT_FALSE( manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized()); EXPECT_FALSE( @@ -469,10 +469,42 @@ TEST_F(UberReceivedPacketManagerTest, } TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) { - manager_->EnableMultiplePacketNumberSpacesSupport(); + manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER); EXPECT_FALSE(HasPendingAck()); EXPECT_FALSE(manager_->IsAckFrameUpdated()); + RecordPacketReceipt(ENCRYPTION_INITIAL, 3); + EXPECT_TRUE(manager_->IsAckFrameUpdated()); + MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 3); + EXPECT_TRUE(HasPendingAck()); + // Delayed ack is scheduled. + if (GetQuicReloadableFlag(quic_delay_initial_ack)) { + CheckAckTimeout(clock_.ApproximateNow() + + QuicTime::Delta::FromMilliseconds(25)); + // Send delayed handshake data ACK. + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(25)); + } else { + CheckAckTimeout(clock_.ApproximateNow() + + QuicTime::Delta::FromMilliseconds(1)); + // Send delayed handshake data ACK. + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); + } + CheckAckTimeout(clock_.ApproximateNow()); + EXPECT_FALSE(HasPendingAck()); + + // Second delayed ack should have a shorter delay. + RecordPacketReceipt(ENCRYPTION_INITIAL, 4); + EXPECT_TRUE(manager_->IsAckFrameUpdated()); + MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 4); + EXPECT_TRUE(HasPendingAck()); + // Delayed ack is scheduled. + CheckAckTimeout(clock_.ApproximateNow() + + QuicTime::Delta::FromMilliseconds(1)); + // Send delayed handshake data ACK. + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); + CheckAckTimeout(clock_.ApproximateNow()); + EXPECT_FALSE(HasPendingAck()); + RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3); EXPECT_TRUE(manager_->IsAckFrameUpdated()); MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3); 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 8bdeef5dc35..0e44092876b 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 @@ -9,6 +9,7 @@ #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/masque/masque_client_tools.h" #include "net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h" @@ -21,7 +22,6 @@ #include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h" #include "net/third_party/quiche/src/quic/tools/quic_url.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" DEFINE_QUIC_COMMAND_LINE_FLAG(bool, diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc index 3db36f3769a..4baf4ad26f0 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.cc @@ -23,7 +23,7 @@ MasqueClientSession::MasqueClientSession( owner_(owner), compression_engine_(this) {} -void MasqueClientSession::OnMessageReceived(quiche::QuicheStringPiece message) { +void MasqueClientSession::OnMessageReceived(absl::string_view message) { QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length(); QuicConnectionId client_connection_id, server_connection_id; @@ -46,7 +46,7 @@ void MasqueClientSession::OnMessageReceived(quiche::QuicheStringPiece message) { EncapsulatedClientSession* encapsulated_client_session = connection_id_registration->second; encapsulated_client_session->ProcessPacket( - quiche::QuicheStringPiece(packet.data(), packet.size()), server_address); + absl::string_view(packet.data(), packet.size()), server_address); QUIC_DVLOG(1) << "Sent " << packet.size() << " bytes to connection for " << client_connection_id; @@ -63,7 +63,7 @@ void MasqueClientSession::OnMessageLost(QuicMessageId message_id) { void MasqueClientSession::SendPacket(QuicConnectionId client_connection_id, QuicConnectionId server_connection_id, - quiche::QuicheStringPiece packet, + absl::string_view packet, const QuicSocketAddress& server_address) { compression_engine_.CompressAndSendPacket( packet, client_connection_id, server_connection_id, server_address); diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h index fee24c908ee..38fa929a591 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_client_session.h @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_ #define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quiche/src/quic/masque/masque_compression_engine.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -37,7 +37,7 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession { virtual ~EncapsulatedClientSession() {} // Process packet that was just decapsulated. - virtual void ProcessPacket(quiche::QuicheStringPiece packet, + virtual void ProcessPacket(absl::string_view packet, QuicSocketAddress server_address) = 0; }; @@ -58,7 +58,7 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession { MasqueClientSession& operator=(const MasqueClientSession&) = delete; // From QuicSession. - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; void OnMessageAcked(QuicMessageId message_id, QuicTime receive_timestamp) override; @@ -68,7 +68,7 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession { // Send encapsulated packet. void SendPacket(QuicConnectionId client_connection_id, QuicConnectionId server_connection_id, - quiche::QuicheStringPiece packet, + absl::string_view packet, const QuicSocketAddress& server_address); // Register encapsulated client. This allows clients that are encapsulated diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc index 7b96abe9758..e59204a9344 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_client_tools.cc @@ -69,7 +69,7 @@ bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client, const std::string body = ""; // Construct a GET or POST request for supplied URL. - spdy::SpdyHeaderBlock header_block; + spdy::Http2HeaderBlock header_block; header_block[":method"] = "GET"; header_block[":scheme"] = url.scheme(); header_block[":authority"] = url.HostPort(); diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc index dbc4580c892..008e2b8bf01 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.cc @@ -6,6 +6,7 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" @@ -14,7 +15,6 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -213,7 +213,7 @@ bool MasqueCompressionEngine::WriteCompressedPacketToSlice( return false; } } - quiche::QuicheStringPiece packet_payload = reader->ReadRemainingPayload(); + absl::string_view packet_payload = reader->ReadRemainingPayload(); if (!writer->WriteStringPiece(packet_payload)) { QUIC_BUG << "Failed to write packet_payload"; return false; @@ -222,7 +222,7 @@ bool MasqueCompressionEngine::WriteCompressedPacketToSlice( } void MasqueCompressionEngine::CompressAndSendPacket( - quiche::QuicheStringPiece packet, + absl::string_view packet, QuicConnectionId client_connection_id, QuicConnectionId server_connection_id, const QuicSocketAddress& server_address) { @@ -452,7 +452,7 @@ bool MasqueCompressionEngine::WriteDecompressedPacket( return false; } } - quiche::QuicheStringPiece payload = reader->ReadRemainingPayload(); + absl::string_view payload = reader->ReadRemainingPayload(); if (!writer.WriteStringPiece(payload)) { QUIC_BUG << "Failed to write payload"; return false; @@ -461,7 +461,7 @@ bool MasqueCompressionEngine::WriteDecompressedPacket( } bool MasqueCompressionEngine::DecompressDatagram( - quiche::QuicheStringPiece datagram, + absl::string_view datagram, QuicConnectionId* client_connection_id, QuicConnectionId* server_connection_id, QuicSocketAddress* server_address, @@ -514,8 +514,8 @@ bool MasqueCompressionEngine::DecompressDatagram( QUIC_DVLOG(2) << "Decompressed client " << context.client_connection_id << " server " << context.server_connection_id << "\n" - << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece( - packet->data(), packet->size())); + << quiche::QuicheTextUtils::HexDump( + absl::string_view(packet->data(), packet->size())); return true; } diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h index 5ab88bd9d7e..6eb7a444f64 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_compression_engine.h @@ -5,13 +5,13 @@ #ifndef QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_ #define QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -47,7 +47,7 @@ class QUIC_NO_EXPORT MasqueCompressionEngine { // hand off the uncompressed packet to an encapsulated session that will treat // it as having come from the provided |server_address|. // The connection IDs are the one used by the encapsulated |packet|. - void CompressAndSendPacket(quiche::QuicheStringPiece packet, + void CompressAndSendPacket(absl::string_view packet, QuicConnectionId client_connection_id, QuicConnectionId server_connection_id, const QuicSocketAddress& server_address); @@ -58,7 +58,7 @@ class QUIC_NO_EXPORT MasqueCompressionEngine { // |server_address| will be filled with the |server_address| passed to // CompressAndSendPacket. |version_present| will contain whether the // encapsulated |packet| contains a Version field. - bool DecompressDatagram(quiche::QuicheStringPiece datagram, + bool DecompressDatagram(absl::string_view datagram, QuicConnectionId* client_connection_id, QuicConnectionId* server_connection_id, QuicSocketAddress* server_address, diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc index ff9d2cf4081..bc3b3beef7f 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.cc @@ -28,15 +28,16 @@ MasqueDispatcher::MasqueDispatcher( std::unique_ptr<QuicSession> MasqueDispatcher::CreateQuicSession( QuicConnectionId connection_id, - const QuicSocketAddress& /*self_address*/, + const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece /*alpn*/, + absl::string_view /*alpn*/, const ParsedQuicVersion& version) { // The MasqueServerSession takes ownership of |connection| below. - QuicConnection* connection = new QuicConnection( - connection_id, peer_address, helper(), alarm_factory(), writer(), - /*owns_writer=*/false, Perspective::IS_SERVER, - ParsedQuicVersionVector{version}); + QuicConnection* connection = + new QuicConnection(connection_id, self_address, peer_address, helper(), + alarm_factory(), writer(), + /*owns_writer=*/false, Perspective::IS_SERVER, + ParsedQuicVersionVector{version}); auto session = std::make_unique<MasqueServerSession>( config(), GetSupportedVersions(), connection, this, this, diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h index e663b1cb89e..9ba52ef913d 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_dispatcher.h @@ -36,7 +36,7 @@ class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher, QuicConnectionId connection_id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const ParsedQuicVersion& version) override; bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info) override; diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc index 818ff76c8dc..628e7c83b36 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.cc @@ -23,7 +23,7 @@ MasqueEncapsulatedClientSession::MasqueEncapsulatedClientSession( masque_client_session_(masque_client_session) {} void MasqueEncapsulatedClientSession::ProcessPacket( - quiche::QuicheStringPiece packet, + absl::string_view packet, QuicSocketAddress server_address) { QuicTime now = connection()->clock()->ApproximateNow(); QuicReceivedPacket received_packet(packet.data(), packet.length(), now); diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h index 75ccc1f58ec..11e96011d96 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h @@ -42,7 +42,7 @@ class QUIC_NO_EXPORT MasqueEncapsulatedClientSession const MasqueEncapsulatedClientSession&) = delete; // From MasqueClientSession::EncapsulatedClientSession. - void ProcessPacket(quiche::QuicheStringPiece packet, + void ProcessPacket(absl::string_view packet, QuicSocketAddress server_address) override; // From QuicSession. diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc index 1f3986284ac..934a8e53ae3 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc @@ -27,7 +27,7 @@ class MasquePacketWriter : public QuicPacketWriter { DCHECK(peer_address.IsInitialized()); QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len << " bytes to " << peer_address; - quiche::QuicheStringPiece packet(buffer, buf_len); + absl::string_view packet(buffer, buf_len); client_->masque_client()->masque_client_session()->SendPacket( client_->session()->connection()->client_connection_id(), client_->session()->connection()->connection_id(), packet, diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc index 24cbaa6a75d..3b7c2011331 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_epoll_client.cc @@ -82,7 +82,7 @@ std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create( std::string body = "foo"; // Construct a GET or POST request for supplied URL. - spdy::SpdyHeaderBlock header_block; + spdy::Http2HeaderBlock header_block; header_block[":method"] = "POST"; header_block[":scheme"] = "https"; header_block[":authority"] = masque_client->authority_; @@ -115,7 +115,7 @@ void MasqueEpollClient::UnregisterClientConnectionId( std::string body(client_connection_id.data(), client_connection_id.length()); // Construct a GET or POST request for supplied URL. - spdy::SpdyHeaderBlock header_block; + spdy::Http2HeaderBlock header_block; header_block[":method"] = "POST"; header_block[":scheme"] = "https"; header_block[":authority"] = authority_; diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc index a3c2b9725d0..fc2fdc08c41 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/masque/masque_server_backend.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -28,7 +28,7 @@ MasqueServerBackend::MasqueServerBackend(const std::string& server_authority, } bool MasqueServerBackend::MaybeHandleMasqueRequest( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) { auto path_pair = request_headers.find(":path"); @@ -40,9 +40,9 @@ bool MasqueServerBackend::MaybeHandleMasqueRequest( // This request is missing required headers. return false; } - quiche::QuicheStringPiece path = path_pair->second; - quiche::QuicheStringPiece scheme = scheme_pair->second; - quiche::QuicheStringPiece method = method_pair->second; + absl::string_view path = path_pair->second; + absl::string_view scheme = scheme_pair->second; + absl::string_view method = method_pair->second; if (scheme != "https" || method != "POST" || request_body.empty()) { // MASQUE requests MUST be a non-empty https POST. return false; @@ -60,7 +60,7 @@ bool MasqueServerBackend::MaybeHandleMasqueRequest( // Cannot enforce missing authority. return false; } - quiche::QuicheStringPiece authority = authority_pair->second; + absl::string_view authority = authority_pair->second; if (server_authority_ != authority) { // This request does not match server_authority. return false; @@ -100,7 +100,7 @@ bool MasqueServerBackend::MaybeHandleMasqueRequest( } void MasqueServerBackend::FetchResponseFromBackend( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) { if (MaybeHandleMasqueRequest(request_headers, request_body, diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h index 481d90dde48..52260b72fbd 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_server_backend.h @@ -20,7 +20,7 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend { public: virtual std::unique_ptr<QuicBackendResponse> HandleMasqueRequest( const std::string& masque_path, - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) = 0; virtual ~BackendClient() = default; @@ -35,7 +35,7 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend { // From QuicMemoryCacheBackend. void FetchResponseFromBackend( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) override; @@ -52,7 +52,7 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend { private: // Handle MASQUE request. bool MaybeHandleMasqueRequest( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler); diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc index e884e416702..e6ca1f3c6d5 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.cc @@ -30,7 +30,7 @@ MasqueServerSession::MasqueServerSession( masque_server_backend_->RegisterBackendClient(connection_id(), this); } -void MasqueServerSession::OnMessageReceived(quiche::QuicheStringPiece message) { +void MasqueServerSession::OnMessageReceived(absl::string_view message) { QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length(); QuicConnectionId client_connection_id, server_connection_id; @@ -81,7 +81,7 @@ void MasqueServerSession::OnConnectionClosed( std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest( const std::string& masque_path, - const spdy::SpdyHeaderBlock& /*request_headers*/, + const spdy::Http2HeaderBlock& /*request_headers*/, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* /*request_handler*/) { QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request"; @@ -107,7 +107,7 @@ std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest( // TODO(dschinazi) implement binary protocol sent in response body. const std::string response_body = ""; - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = "200"; auto response = std::make_unique<QuicBackendResponse>(); response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE); diff --git a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h index bc70f5e49f5..63cadcd0aca 100644 --- a/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h +++ b/chromium/net/third_party/quiche/src/quic/masque/masque_server_session.h @@ -48,7 +48,7 @@ class QUIC_NO_EXPORT MasqueServerSession MasqueServerSession& operator=(const MasqueServerSession&) = delete; // From QuicSession. - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; void OnMessageAcked(QuicMessageId message_id, QuicTime receive_timestamp) override; void OnMessageLost(QuicMessageId message_id) override; @@ -58,7 +58,7 @@ class QUIC_NO_EXPORT MasqueServerSession // From MasqueServerBackend::BackendClient. std::unique_ptr<QuicBackendResponse> HandleMasqueRequest( const std::string& masque_path, - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* request_handler) override; diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_aligned.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_aligned.h deleted file mode 100644 index ecfa649f31c..00000000000 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_aligned.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 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_PLATFORM_API_QUIC_ALIGNED_H_ -#define QUICHE_QUIC_PLATFORM_API_QUIC_ALIGNED_H_ - -#include "net/quic/platform/impl/quic_aligned_impl.h" - -#define QUIC_ALIGN_OF QUIC_ALIGN_OF_IMPL -#define QUIC_ALIGNED(X) QUIC_ALIGNED_IMPL(X) -#define QUIC_CACHELINE_ALIGNED QUIC_CACHELINE_ALIGNED_IMPL -#define QUIC_CACHELINE_SIZE QUIC_CACHELINE_SIZE_IMPL - -#endif // QUICHE_QUIC_PLATFORM_API_QUIC_ALIGNED_H_ diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h index a680dd6e00d..b2a5bc22b62 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h @@ -5,17 +5,16 @@ #ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CERT_UTILS_H_ #define QUICHE_QUIC_PLATFORM_API_QUIC_CERT_UTILS_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/quic/platform/impl/quic_cert_utils_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { class QUIC_EXPORT_PRIVATE QuicCertUtils { public: - static bool ExtractSubjectNameFromDERCert( - quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece* subject_out) { + static bool ExtractSubjectNameFromDERCert(absl::string_view cert, + absl::string_view* subject_out) { return QuicCertUtilsImpl::ExtractSubjectNameFromDERCert(cert, subject_out); } }; diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h deleted file mode 100644 index 499b61abf74..00000000000 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2018 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_PLATFORM_API_QUIC_FALLTHROUGH_H_ -#define QUICHE_QUIC_PLATFORM_API_QUIC_FALLTHROUGH_H_ - -#include "net/quic/platform/impl/quic_fallthrough_impl.h" - -#define QUIC_FALLTHROUGH_INTENDED QUIC_FALLTHROUGH_INTENDED_IMPL - -#endif // QUICHE_QUIC_PLATFORM_API_QUIC_FALLTHROUGH_H_ diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.cc index 40dea3ed1ca..a9901e14d86 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_file_utils.h" +#include "absl/strings/string_view.h" #include "net/quic/platform/impl/quic_file_utils_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -16,8 +16,7 @@ std::vector<std::string> ReadFileContents(const std::string& dirname) { } // Reads the contents of |filename| as a string into |contents|. -void ReadFileContents(quiche::QuicheStringPiece filename, - std::string* contents) { +void ReadFileContents(absl::string_view filename, std::string* contents) { ReadFileContentsImpl(filename, contents); } diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.h index 8191e0a5ace..6142feb3f95 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_file_utils.h @@ -8,8 +8,8 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -18,7 +18,7 @@ QUIC_EXPORT_PRIVATE std::vector<std::string> ReadFileContents( const std::string& dirname); // Reads the contents of |filename| as a string into |contents|. -QUIC_EXPORT_PRIVATE void ReadFileContents(quiche::QuicheStringPiece filename, +QUIC_EXPORT_PRIVATE void ReadFileContents(absl::string_view filename, std::string* contents); } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc index 5a0ccc09ccb..d13339c4ca8 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.cc @@ -3,18 +3,17 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { // static -bool QuicHostnameUtils::IsValidSNI(quiche::QuicheStringPiece sni) { +bool QuicHostnameUtils::IsValidSNI(absl::string_view sni) { return QuicHostnameUtilsImpl::IsValidSNI(sni); } // static -std::string QuicHostnameUtils::NormalizeHostname( - quiche::QuicheStringPiece hostname) { +std::string QuicHostnameUtils::NormalizeHostname(absl::string_view hostname) { return QuicHostnameUtilsImpl::NormalizeHostname(hostname); } diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h index 6a04044b714..a3c902ef55b 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h @@ -7,9 +7,9 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/quic/platform/impl/quic_hostname_utils_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -21,12 +21,12 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtils { // (1) disallow IP addresses; // (2) check that the hostname contains valid characters only; and // (3) contains at least one dot. - static bool IsValidSNI(quiche::QuicheStringPiece sni); + static bool IsValidSNI(absl::string_view sni); // Canonicalizes the specified hostname. This involves a wide variety of // transformations, including lowercasing, removing trailing dots and IDNA // conversion. - static std::string NormalizeHostname(quiche::QuicheStringPiece hostname); + static std::string NormalizeHostname(absl::string_view hostname); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc index eba97c4cae5..d1808fb0b3c 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_hostname_utils_test.cc @@ -6,8 +6,8 @@ #include <string> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -78,7 +78,7 @@ TEST_F(QuicHostnameUtilsTest, NormalizeHostname) { }; // clang-format on - for (size_t i = 0; i < QUICHE_ARRAYSIZE(tests); ++i) { + for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); ++i) { EXPECT_EQ(std::string(tests[i].expected), QuicHostnameUtils::NormalizeHostname(tests[i].input)); } diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_macros.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_macros.h deleted file mode 100644 index 7edeb6aa953..00000000000 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_macros.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2019 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_PLATFORM_API_QUIC_MACROS_H_ -#define QUICHE_QUIC_PLATFORM_API_QUIC_MACROS_H_ - -#include "net/quic/platform/impl/quic_macros_impl.h" - -#define QUIC_MUST_USE_RESULT QUIC_MUST_USE_RESULT_IMPL -#define QUIC_UNUSED QUIC_UNUSED_IMPL -#define QUIC_CONST_INIT QUIC_CONST_INIT_IMPL - -#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MACROS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h index a1e0bd07433..741ecb19411 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h @@ -5,9 +5,9 @@ #ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_SPAN_H_ #define QUICHE_QUIC_PLATFORM_API_QUIC_MEM_SLICE_SPAN_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/quic/platform/impl/quic_mem_slice_span_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -39,8 +39,8 @@ class QUIC_EXPORT_PRIVATE QuicMemSliceSpan { } // Return data of the span at |index| by the form of a - // quiche::QuicheStringPiece. - quiche::QuicheStringPiece GetData(int index) { return impl_.GetData(index); } + // absl::string_view. + absl::string_view GetData(int index) { return impl_.GetData(index); } // Return the total length of the data inside the span. QuicByteCount total_length() { return impl_.total_length(); } diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h index 685be0a75bd..b1ddf6e069a 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_port_utils.h @@ -5,22 +5,18 @@ #ifndef QUICHE_QUIC_PLATFORM_API_QUIC_PORT_UTILS_H_ #define QUICHE_QUIC_PLATFORM_API_QUIC_PORT_UTILS_H_ -#include "net/quic/platform/impl/quic_port_utils_impl.h" - namespace quic { // Returns a UDP port that is currently unused. Check-fails if none are // available. May return 0 in which case the bind() call will cause the OS // to use an unused port. inline int QuicPickServerPortForTestsOrDie() { - return QuicPickServerPortForTestsOrDieImpl(); + return 0; } // Indicates that a specified port previously returned by // QuicPickServerPortForTestsOrDie is no longer used. -inline void QuicRecyclePort(int port) { - return QuicRecyclePortImpl(port); -} +inline void QuicRecyclePort(int /*port*/) {} } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_string_utils_test.cc b/chromium/net/third_party/quiche/src/quic/platform/api/quic_string_utils_test.cc index 4f65b7d119b..e23b6ff4697 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_string_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_string_utils_test.cc @@ -6,9 +6,9 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -21,14 +21,14 @@ TEST(QuicStringUtilsTest, QuicheStrCat) { // Single string-like argument. const char kFoo[] = "foo"; const std::string string_foo(kFoo); - const quiche::QuicheStringPiece stringpiece_foo(string_foo); + const absl::string_view stringpiece_foo(string_foo); EXPECT_EQ("foo", quiche::QuicheStrCat(kFoo)); EXPECT_EQ("foo", quiche::QuicheStrCat(string_foo)); EXPECT_EQ("foo", quiche::QuicheStrCat(stringpiece_foo)); // Two string-like arguments. const char kBar[] = "bar"; - const quiche::QuicheStringPiece stringpiece_bar(kBar); + const absl::string_view stringpiece_bar(kBar); const std::string string_bar(kBar); EXPECT_EQ("foobar", quiche::QuicheStrCat(kFoo, kBar)); EXPECT_EQ("foobar", quiche::QuicheStrCat(kFoo, string_bar)); @@ -81,7 +81,7 @@ TEST(QuicStringUtilsTest, QuicStrAppend) { // Single string-like argument. const char kFoo[] = "foo"; const std::string string_foo(kFoo); - const quiche::QuicheStringPiece stringpiece_foo(string_foo); + const absl::string_view stringpiece_foo(string_foo); QuicStrAppend(&output, kFoo); EXPECT_EQ("foo", output); QuicStrAppend(&output, string_foo); @@ -97,7 +97,7 @@ TEST(QuicStringUtilsTest, QuicStrAppend) { // Two string-like arguments. const char kBar[] = "bar"; - const quiche::QuicheStringPiece stringpiece_bar(kBar); + const absl::string_view stringpiece_bar(kBar); const std::string string_bar(kBar); QuicStrAppend(&output, kFoo, kBar); EXPECT_EQ("foobar", output); diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h index 24998761832..f925db65985 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_test_output.h @@ -5,22 +5,21 @@ #ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_ #define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_ +#include "absl/strings/string_view.h" #include "net/quic/platform/impl/quic_test_output_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { // Save |data| into ${QUIC_TEST_OUTPUT_DIR}/filename. If a file with the same // path already exists, overwrite it. -inline void QuicSaveTestOutput(quiche::QuicheStringPiece filename, - quiche::QuicheStringPiece data) { +inline void QuicSaveTestOutput(absl::string_view filename, + absl::string_view data) { QuicSaveTestOutputImpl(filename, data); } // Load the content of ${QUIC_TEST_OUTPUT_DIR}/filename into |*data|. // Return whether it is successfully loaded. -inline bool QuicLoadTestOutput(quiche::QuicheStringPiece filename, - std::string* data) { +inline bool QuicLoadTestOutput(absl::string_view filename, std::string* data) { return QuicLoadTestOutputImpl(filename, data); } @@ -31,8 +30,8 @@ inline bool QuicLoadTestOutput(quiche::QuicheStringPiece filename, // The |identifier| is a human-readable identifier that will be combined with // the name of the unit test and a timestamp. |data| is the serialized // quic_trace.Trace protobuf that is being recorded into the file. -inline void QuicRecordTrace(quiche::QuicheStringPiece identifier, - quiche::QuicheStringPiece data) { +inline void QuicRecordTrace(absl::string_view identifier, + absl::string_view data) { QuicRecordTraceImpl(identifier, data); } diff --git a/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h b/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h index 0df0c4050be..96ce96864a2 100644 --- a/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h +++ b/chromium/net/third_party/quiche/src/quic/platform/api/quic_testvalue.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_ #define QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_ +#include "absl/strings/string_view.h" #include "net/quic/platform/impl/quic_testvalue_impl.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -16,7 +16,7 @@ namespace quic { // // Note that this method does nothing in Chromium. template <class T> -void AdjustTestValue(quiche::QuicheStringPiece label, T* var) { +void AdjustTestValue(absl::string_view label, T* var) { AdjustTestValueImpl(label, var); } diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc index c6dd96d6b6c..a16b2fa61ca 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.cc @@ -6,13 +6,13 @@ #include <netinet/ip6.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" #include "net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace { @@ -128,7 +128,7 @@ bool IcmpReachable::OnEvent(int fd) { } QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump( - quiche::QuicheStringPiece(buffer, size)); + absl::string_view(buffer, size)); auto* header = reinterpret_cast<const icmp6_hdr*>(&buffer); QuicWriterMutexLock mu(&header_lock_); @@ -168,7 +168,7 @@ int64 /* allow-non-std-int */ IcmpReachable::OnAlarm() { icmp_header_.icmp6_seq++; CreateIcmpPacket(src_.sin6_addr, dst_.sin6_addr, icmp_header_, "", - [this](quiche::QuicheStringPiece packet) { + [this](absl::string_view packet) { QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(packet); ssize_t size = kernel_->sendto( @@ -185,8 +185,7 @@ int64 /* allow-non-std-int */ IcmpReachable::OnAlarm() { return absl::ToUnixMicros(absl::Now() + timeout_); } -quiche::QuicheStringPiece IcmpReachable::StatusName( - IcmpReachable::Status status) { +absl::string_view IcmpReachable::StatusName(IcmpReachable::Status status) { switch (status) { case REACHABLE: return "REACHABLE"; diff --git a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h index f58efd08242..a3bc0900ead 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable.h @@ -7,11 +7,11 @@ #include <netinet/icmp6.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" #include "net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h" #include "net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -80,7 +80,7 @@ class IcmpReachable : public IcmpReachableInterface { int64 /* allow-non-std-int */ OnAlarm() QUIC_LOCKS_EXCLUDED(header_lock_) override; - static quiche::QuicheStringPiece StatusName(Status status); + static absl::string_view StatusName(Status status); private: class EpollCallback : public QuicEpollCallbackInterface { diff --git a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h index 3170b7ed4b1..c5ec95bd2c7 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_client.h @@ -5,9 +5,9 @@ #ifndef QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_ #define QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/qbone/qbone_client_interface.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -15,7 +15,7 @@ class MockQboneClient : public QboneClientInterface { public: MOCK_METHOD(void, ProcessPacketFromNetwork, - (quiche::QuicheStringPiece packet), + (absl::string_view packet), (override)); }; diff --git a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h index 0781e7f6b4d..d398ba57d6c 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/mock_qbone_server_session.h @@ -27,14 +27,8 @@ class MockQboneServerSession : public QboneServerSession { MOCK_METHOD(bool, SendClientRequest, (const QboneClientRequest&), (override)); - MOCK_METHOD(void, - ProcessPacketFromNetwork, - (quiche::QuicheStringPiece), - (override)); - MOCK_METHOD(void, - ProcessPacketFromPeer, - (quiche::QuicheStringPiece), - (override)); + MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override)); + MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override)); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc index e64dbbaf8f4..68d15010675 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.cc @@ -6,9 +6,9 @@ #include <netinet/ip6.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace { @@ -36,12 +36,11 @@ struct IPv6PseudoHeader { } // namespace -void CreateIcmpPacket( - in6_addr src, - in6_addr dst, - const icmp6_hdr& icmp_header, - quiche::QuicheStringPiece body, - const std::function<void(quiche::QuicheStringPiece)>& cb) { +void CreateIcmpPacket(in6_addr src, + in6_addr dst, + const icmp6_hdr& icmp_header, + absl::string_view body, + const std::function<void(absl::string_view)>& cb) { const size_t body_size = std::min(body.size(), kICMPv6BodyMaxSize); const size_t payload_size = kICMPv6HeaderSize + body_size; @@ -82,7 +81,7 @@ void CreateIcmpPacket( const char* packet = reinterpret_cast<char*>(&icmp_packet); const size_t packet_size = offsetof(ICMPv6Packet, body) + body_size; - cb(quiche::QuicheStringPiece(packet, packet_size)); + cb(absl::string_view(packet, packet_size)); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h index a76267968fc..ca3fc436832 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h @@ -10,8 +10,8 @@ #include <functional> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -21,8 +21,8 @@ namespace quic { void CreateIcmpPacket(in6_addr src, in6_addr dst, const icmp6_hdr& icmp_header, - quiche::QuicheStringPiece body, - const std::function<void(quiche::QuicheStringPiece)>& cb); + absl::string_view body, + const std::function<void(absl::string_view)>& cb); } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc index 30fbe21ecbc..08623e1ce5d 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/icmp_packet_test.cc @@ -8,8 +8,8 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -85,12 +85,12 @@ TEST(IcmpPacketTest, CreatedPacketMatchesReference) { icmp_header.icmp6_id = 0x82cb; icmp_header.icmp6_seq = 0x0100; - quiche::QuicheStringPiece message_body = quiche::QuicheStringPiece( + absl::string_view message_body = absl::string_view( reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56); - quiche::QuicheStringPiece expected_packet = quiche::QuicheStringPiece( + absl::string_view expected_packet = absl::string_view( reinterpret_cast<const char*>(kReferenceICMPPacket), 104); CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body, - [&expected_packet](quiche::QuicheStringPiece packet) { + [&expected_packet](absl::string_view packet) { QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet); ASSERT_EQ(packet, expected_packet); }); @@ -114,12 +114,12 @@ TEST(IcmpPacketTest, NonZeroChecksumIsIgnored) { // Set the checksum to a bogus value icmp_header.icmp6_cksum = 0x1234; - quiche::QuicheStringPiece message_body = quiche::QuicheStringPiece( + absl::string_view message_body = absl::string_view( reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56); - quiche::QuicheStringPiece expected_packet = quiche::QuicheStringPiece( + absl::string_view expected_packet = absl::string_view( reinterpret_cast<const char*>(kReferenceICMPPacket), 104); CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body, - [&expected_packet](quiche::QuicheStringPiece packet) { + [&expected_packet](absl::string_view packet) { QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet); ASSERT_EQ(packet, expected_packet); }); diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc index 04198d0cf7d..cb9f4a1ab04 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/ip_range.cc @@ -4,7 +4,7 @@ #include "net/third_party/quiche/src/quic/qbone/platform/ip_range.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc index 719551d1e00..d19c28b5fda 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/netlink.cc @@ -7,8 +7,8 @@ #include <linux/fib_rules.h> #include <utility> +#include "absl/base/attributes.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/quic/platform/impl/quic_ip_address_impl.h" @@ -259,7 +259,7 @@ class LocalAddressParser : public NetlinkParserInterface { switch (interface_address->ifa_family) { case AF_INET: - QUIC_FALLTHROUGH_INTENDED; + ABSL_FALLTHROUGH_INTENDED; case AF_INET6: // QuicIpAddress knows how to parse ip from raw bytes as long as they // are in network byte order. diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc index 6da9faa749e..1b0103e3336 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.cc @@ -6,10 +6,10 @@ #include <netinet/ip6.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { namespace { @@ -30,9 +30,8 @@ struct TCPv6PseudoHeader { } // namespace -void CreateTcpResetPacket( - quiche::QuicheStringPiece original_packet, - const std::function<void(quiche::QuicheStringPiece)>& cb) { +void CreateTcpResetPacket(absl::string_view original_packet, + const std::function<void(absl::string_view)>& cb) { // By the time this method is called, original_packet should be fairly // strongly validated. However, it's better to be more paranoid than not, so // here are a bunch of very obvious checks. @@ -121,7 +120,7 @@ void CreateTcpResetPacket( const char* packet = reinterpret_cast<char*>(&tcp_packet); - cb(quiche::QuicheStringPiece(packet, sizeof(tcp_packet))); + cb(absl::string_view(packet, sizeof(tcp_packet))); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h index bb1364b41be..2038fab09ec 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h @@ -10,16 +10,15 @@ #include <functional> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { // Creates an TCPv6 RST packet, returning a packed string representation of the // packet to |cb|. -void CreateTcpResetPacket( - quiche::QuicheStringPiece original_packet, - const std::function<void(quiche::QuicheStringPiece)>& cb); +void CreateTcpResetPacket(absl::string_view original_packet, + const std::function<void(absl::string_view)>& cb); } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc index 84645c8a209..a1431952199 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/platform/tcp_packet_test.cc @@ -8,8 +8,8 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -102,17 +102,16 @@ constexpr uint8_t kReferenceTCPRSTPacket[] = { } // namespace TEST(TcpPacketTest, CreatedPacketMatchesReference) { - quiche::QuicheStringPiece syn = quiche::QuicheStringPiece( - reinterpret_cast<const char*>(kReferenceTCPSYNPacket), - sizeof(kReferenceTCPSYNPacket)); - quiche::QuicheStringPiece expected_packet = quiche::QuicheStringPiece( - reinterpret_cast<const char*>(kReferenceTCPRSTPacket), - sizeof(kReferenceTCPRSTPacket)); - CreateTcpResetPacket( - syn, [&expected_packet](quiche::QuicheStringPiece packet) { - QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet); - ASSERT_EQ(packet, expected_packet); - }); + absl::string_view syn = + absl::string_view(reinterpret_cast<const char*>(kReferenceTCPSYNPacket), + sizeof(kReferenceTCPSYNPacket)); + absl::string_view expected_packet = + absl::string_view(reinterpret_cast<const char*>(kReferenceTCPRSTPacket), + sizeof(kReferenceTCPRSTPacket)); + CreateTcpResetPacket(syn, [&expected_packet](absl::string_view packet) { + QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet); + ASSERT_EQ(packet, expected_packet); + }); } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc index a2ba1175ab4..44aec9c27f0 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.cc @@ -6,12 +6,12 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h" #include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h" #include "net/third_party/quiche/src/quic/qbone/qbone_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace { @@ -58,7 +58,7 @@ QboneClientSession* QboneClient::qbone_session() { return static_cast<QboneClientSession*>(QuicClientBase::session()); } -void QboneClient::ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) { +void QboneClient::ProcessPacketFromNetwork(absl::string_view packet) { qbone_session()->ProcessPacketFromNetwork(packet); } diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h index 209511023d9..7fbba4b7b44 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client.h @@ -5,12 +5,12 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_H_ #define QUICHE_QUIC_QBONE_QBONE_CLIENT_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/qbone/qbone_client_interface.h" #include "net/third_party/quiche/src/quic/qbone/qbone_client_session.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h" #include "net/third_party/quiche/src/quic/tools/quic_client_base.h" #include "net/third_party/quiche/src/quic/tools/quic_client_epoll_network_helper.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { // A QboneClient encapsulates connecting to a server via an epoll server @@ -34,7 +34,7 @@ class QboneClient : public QuicClientBase, public QboneClientInterface { // From QboneClientInterface. Accepts a given packet from the network and // sends the packet down to the QBONE connection. - void ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) override; + void ProcessPacketFromNetwork(absl::string_view packet) override; bool EarlyDataAccepted() override; bool ReceivedInchoateReject() override; diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h index aec3a8fac89..8b31cceb65d 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_interface.h @@ -7,7 +7,7 @@ #include <cstdint> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { @@ -17,7 +17,7 @@ class QboneClientInterface { virtual ~QboneClientInterface() {} // Accepts a given packet from the network and sends the packet down to the // QBONE connection. - virtual void ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) = 0; + virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0; }; } // namespace quic 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 f375e0a403d..4697fcccc52 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 @@ -6,9 +6,9 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/qbone/qbone_constants.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -77,13 +77,11 @@ bool QboneClientSession::SendServerRequest(const QboneServerRequest& request) { return control_stream_->SendRequest(request); } -void QboneClientSession::ProcessPacketFromNetwork( - quiche::QuicheStringPiece packet) { +void QboneClientSession::ProcessPacketFromNetwork(absl::string_view packet) { SendPacketToPeer(packet); } -void QboneClientSession::ProcessPacketFromPeer( - quiche::QuicheStringPiece packet) { +void QboneClientSession::ProcessPacketFromPeer(absl::string_view packet) { writer_->WritePacketToNetwork(packet.data(), packet.size()); } @@ -94,7 +92,7 @@ void QboneClientSession::OnProofVerifyDetailsAvailable( const ProofVerifyDetails& verify_details) {} bool QboneClientSession::HasActiveRequests() const { - return (stream_map_size() - num_static_streams() - num_zombie_streams()) > 0; + return GetNumActiveStreams() + num_draining_streams() > 0; } } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h index 4eeb7b171f7..f3cd0202ba2 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.h @@ -5,13 +5,13 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_ #define QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/qbone/qbone_control.pb.h" #include "net/third_party/quiche/src/quic/qbone/qbone_control_stream.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h" #include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -55,8 +55,8 @@ class QUIC_EXPORT_PRIVATE QboneClientSession bool SendServerRequest(const QboneServerRequest& request); - void ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) override; - void ProcessPacketFromPeer(quiche::QuicheStringPiece packet) override; + void ProcessPacketFromNetwork(absl::string_view packet) override; + void ProcessPacketFromPeer(absl::string_view packet) override; // Returns true if there are active requests on this session. bool HasActiveRequests() const; diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc index cfe6c46abfd..98b1a2e59ba 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc @@ -6,6 +6,7 @@ #include "net/third_party/quiche/src/quic/qbone/qbone_client.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" #include "net/third_party/quiche/src/quic/core/quic_default_packet_writer.h" #include "net/third_party/quiche/src/quic/core/quic_dispatcher.h" @@ -26,7 +27,6 @@ #include "net/third_party/quiche/src/quic/test_tools/server_thread.h" #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_server.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -123,13 +123,13 @@ class QuicQboneDispatcher : public QuicDispatcher { std::unique_ptr<QuicSession> CreateQuicSession( QuicConnectionId id, - const QuicSocketAddress& /*self_address*/, + const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const quic::ParsedQuicVersion& version) override { CHECK_EQ(alpn, "qbone"); QuicConnection* connection = new QuicConnection( - id, peer_address, helper(), alarm_factory(), writer(), + id, self_address, peer_address, helper(), alarm_factory(), writer(), /* owns_writer= */ false, Perspective::IS_SERVER, ParsedQuicVersionVector{version}); // The connection owning wrapper owns the connection created. @@ -232,6 +232,8 @@ TEST_P(QboneClientTest, SendDataFromClient) { QuicPickServerPortForTestsOrDie()); ServerThread server_thread(server, server_address); server_thread.Initialize(); + server_address = + QuicSocketAddress(server_address.host(), server_thread.GetPort()); server_thread.Start(); QuicEpollServer epoll_server; 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 0b453a7a954..04f074c30a7 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 @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/qbone/qbone_control_stream.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/qbone/qbone_constants.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -59,8 +59,8 @@ bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) { uint16_t size = tmp.size(); char size_str[kRequestSizeBytes]; memcpy(size_str, &size, kRequestSizeBytes); - WriteOrBufferData(quiche::QuicheStringPiece(size_str, kRequestSizeBytes), - false, nullptr); + WriteOrBufferData(absl::string_view(size_str, kRequestSizeBytes), false, + nullptr); WriteOrBufferData(tmp, false, nullptr); return true; } diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc index ef78efaef73..5fbf63dfc2d 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.cc @@ -6,13 +6,13 @@ #include <cstring> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h" #include "net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h" #include "net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace { @@ -51,12 +51,11 @@ QbonePacketProcessor::StatsInterface::~StatsInterface() {} QbonePacketProcessor::Filter::~Filter() {} QbonePacketProcessor::ProcessingResult -QbonePacketProcessor::Filter::FilterPacket( - Direction direction, - quiche::QuicheStringPiece full_packet, - quiche::QuicheStringPiece payload, - icmp6_hdr* icmp_header, - OutputInterface* output) { +QbonePacketProcessor::Filter::FilterPacket(Direction direction, + absl::string_view full_packet, + absl::string_view payload, + icmp6_hdr* icmp_header, + OutputInterface* output) { return ProcessingResult::OK; } @@ -128,8 +127,7 @@ QbonePacketProcessor::ProcessIPv6HeaderAndFilter(std::string* packet, result = filter_->FilterPacket( direction, *packet, - quiche::QuicheStringPiece(*transport_data, - packet->size() - header_size), + absl::string_view(*transport_data, packet->size() - header_size), icmp_header, output_); } @@ -237,32 +235,29 @@ QbonePacketProcessor::ProcessingResult QbonePacketProcessor::ProcessIPv6Header( return ProcessingResult::OK; } -void QbonePacketProcessor::SendIcmpResponse( - icmp6_hdr* icmp_header, - quiche::QuicheStringPiece original_packet, - Direction original_direction) { +void QbonePacketProcessor::SendIcmpResponse(icmp6_hdr* icmp_header, + absl::string_view original_packet, + Direction original_direction) { in6_addr dst; // TODO(b/70339814): ensure this is actually a unicast address. memcpy(dst.s6_addr, &original_packet[8], kIPv6AddressSize); - CreateIcmpPacket( - self_ip_, dst, *icmp_header, original_packet, - [this, original_direction](quiche::QuicheStringPiece packet) { - SendResponse(original_direction, packet); - }); + CreateIcmpPacket(self_ip_, dst, *icmp_header, original_packet, + [this, original_direction](absl::string_view packet) { + SendResponse(original_direction, packet); + }); } -void QbonePacketProcessor::SendTcpReset( - quiche::QuicheStringPiece original_packet, - Direction original_direction) { - CreateTcpResetPacket(original_packet, [this, original_direction]( - quiche::QuicheStringPiece packet) { - SendResponse(original_direction, packet); - }); +void QbonePacketProcessor::SendTcpReset(absl::string_view original_packet, + Direction original_direction) { + CreateTcpResetPacket(original_packet, + [this, original_direction](absl::string_view packet) { + SendResponse(original_direction, packet); + }); } void QbonePacketProcessor::SendResponse(Direction original_direction, - quiche::QuicheStringPiece packet) { + absl::string_view packet) { switch (original_direction) { case Direction::FROM_OFF_NETWORK: output_->SendPacketToClient(packet); diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h index 130770d3c67..bb5e8163f04 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h @@ -8,9 +8,9 @@ #include <netinet/icmp6.h> #include <netinet/ip6.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -52,8 +52,8 @@ class QbonePacketProcessor { public: virtual ~OutputInterface(); - virtual void SendPacketToClient(quiche::QuicheStringPiece packet) = 0; - virtual void SendPacketToNetwork(quiche::QuicheStringPiece packet) = 0; + virtual void SendPacketToClient(absl::string_view packet) = 0; + virtual void SendPacketToNetwork(absl::string_view packet) = 0; }; class StatsInterface { @@ -94,8 +94,8 @@ class QbonePacketProcessor { // Note that |output| should not be used except in the DEFER case, as the // processor will perform the necessary writes itself. virtual ProcessingResult FilterPacket(Direction direction, - quiche::QuicheStringPiece full_packet, - quiche::QuicheStringPiece payload, + absl::string_view full_packet, + absl::string_view payload, icmp6_hdr* icmp_header, OutputInterface* output); @@ -104,19 +104,17 @@ class QbonePacketProcessor { // for filtering from the |ipv6_header| argument. All of those assume that // the header is of valid size, which is true for everything passed into // FilterPacket(). - inline uint8_t TransportProtocolFromHeader( - quiche::QuicheStringPiece ipv6_header) { + inline uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) { return ipv6_header[6]; } - inline QuicIpAddress SourceIpFromHeader( - quiche::QuicheStringPiece ipv6_header) { + inline QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) { QuicIpAddress address; address.FromPackedString(&ipv6_header[8], QuicIpAddress::kIPv6AddressSize); return address; } inline QuicIpAddress DestinationIpFromHeader( - quiche::QuicheStringPiece ipv6_header) { + absl::string_view ipv6_header) { QuicIpAddress address; address.FromPackedString(&ipv6_header[24], QuicIpAddress::kIPv6AddressSize); @@ -167,10 +165,10 @@ class QbonePacketProcessor { icmp6_hdr* icmp_header); void SendIcmpResponse(icmp6_hdr* icmp_header, - quiche::QuicheStringPiece original_packet, + absl::string_view original_packet, Direction original_direction); - void SendTcpReset(quiche::QuicheStringPiece original_packet, + void SendTcpReset(absl::string_view original_packet, Direction original_direction); inline bool IsValid() const { return client_ip_ != kInvalidIpAddress; } @@ -194,8 +192,7 @@ class QbonePacketProcessor { char** transport_data, icmp6_hdr* icmp_header); - void SendResponse(Direction original_direction, - quiche::QuicheStringPiece packet); + void SendResponse(Direction original_direction, absl::string_view packet); }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc index 2820a7a1f70..569df911229 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test.cc @@ -6,9 +6,9 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace { @@ -101,15 +101,15 @@ static const char kReferenceClientSubnetPacketData[] = { // clang-format on -static const quiche::QuicheStringPiece kReferenceClientPacket( +static const absl::string_view kReferenceClientPacket( kReferenceClientPacketData, arraysize(kReferenceClientPacketData)); -static const quiche::QuicheStringPiece kReferenceNetworkPacket( +static const absl::string_view kReferenceNetworkPacket( kReferenceNetworkPacketData, arraysize(kReferenceNetworkPacketData)); -static const quiche::QuicheStringPiece kReferenceClientSubnetPacket( +static const absl::string_view kReferenceClientSubnetPacket( kReferenceClientSubnetPacketData, arraysize(kReferenceClientSubnetPacketData)); @@ -128,8 +128,8 @@ class MockPacketFilter : public QbonePacketProcessor::Filter { MOCK_METHOD(ProcessingResult, FilterPacket, (Direction, - quiche::QuicheStringPiece, - quiche::QuicheStringPiece, + absl::string_view, + absl::string_view, icmp6_hdr*, OutputInterface*), (override)); @@ -147,12 +147,12 @@ class QbonePacketProcessorTest : public QuicTest { &stats_); } - void SendPacketFromClient(quiche::QuicheStringPiece packet) { + void SendPacketFromClient(absl::string_view packet) { std::string packet_buffer(packet.data(), packet.size()); processor_->ProcessPacket(&packet_buffer, Direction::FROM_OFF_NETWORK); } - void SendPacketFromNetwork(quiche::QuicheStringPiece packet) { + void SendPacketFromNetwork(absl::string_view packet) { std::string packet_buffer(packet.data(), packet.size()); processor_->ProcessPacket(&packet_buffer, Direction::FROM_NETWORK); } @@ -249,8 +249,8 @@ class TestFilter : public QbonePacketProcessor::Filter { TestFilter(QuicIpAddress client_ip, QuicIpAddress network_ip) : client_ip_(client_ip), network_ip_(network_ip) {} ProcessingResult FilterPacket(Direction direction, - quiche::QuicheStringPiece full_packet, - quiche::QuicheStringPiece payload, + absl::string_view full_packet, + absl::string_view payload, icmp6_hdr* icmp_header, OutputInterface* output) override { EXPECT_EQ(kIPv6HeaderSize, full_packet.size() - payload.size()); diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h index 72030506399..8384821882d 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h @@ -5,9 +5,9 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_ #define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -15,14 +15,8 @@ class MockPacketProcessorOutput : public QbonePacketProcessor::OutputInterface { public: MockPacketProcessorOutput() {} - MOCK_METHOD(void, - SendPacketToClient, - (quiche::QuicheStringPiece), - (override)); - MOCK_METHOD(void, - SendPacketToNetwork, - (quiche::QuicheStringPiece), - (override)); + MOCK_METHOD(void, SendPacketToClient, (absl::string_view), (override)); + MOCK_METHOD(void, SendPacketToNetwork, (absl::string_view), (override)); }; class MockPacketProcessorStats : public QbonePacketProcessor::StatsInterface { 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 6561f57c24a..7f83381c875 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 @@ -6,11 +6,11 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/qbone/qbone_constants.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -20,7 +20,7 @@ bool QboneCryptoServerStreamHelper::CanAcceptClientHello( const QuicSocketAddress& peer_address, const QuicSocketAddress& self_address, std::string* error_details) const { - quiche::QuicheStringPiece alpn; + absl::string_view alpn; chlo.GetStringPiece(quic::kALPN, &alpn); if (alpn != QboneConstants::kQboneAlpn) { *error_details = "ALPN-indicated protocol is not qbone"; @@ -72,25 +72,23 @@ bool QboneServerSession::SendClientRequest(const QboneClientRequest& request) { return control_stream_->SendRequest(request); } -void QboneServerSession::ProcessPacketFromNetwork( - quiche::QuicheStringPiece packet) { +void QboneServerSession::ProcessPacketFromNetwork(absl::string_view packet) { std::string buffer = std::string(packet); processor_.ProcessPacket(&buffer, QbonePacketProcessor::Direction::FROM_NETWORK); } -void QboneServerSession::ProcessPacketFromPeer( - quiche::QuicheStringPiece packet) { +void QboneServerSession::ProcessPacketFromPeer(absl::string_view packet) { std::string buffer = std::string(packet); processor_.ProcessPacket(&buffer, QbonePacketProcessor::Direction::FROM_OFF_NETWORK); } -void QboneServerSession::SendPacketToClient(quiche::QuicheStringPiece packet) { +void QboneServerSession::SendPacketToClient(absl::string_view packet) { SendPacketToPeer(packet); } -void QboneServerSession::SendPacketToNetwork(quiche::QuicheStringPiece packet) { +void QboneServerSession::SendPacketToNetwork(absl::string_view packet) { DCHECK(writer_ != nullptr); writer_->WritePacketToNetwork(packet.data(), packet.size()); } 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 fee1c743784..63a0d8d954c 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 @@ -5,6 +5,7 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_ #define QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" @@ -13,7 +14,6 @@ #include "net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h" #include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -53,12 +53,12 @@ class QUIC_EXPORT_PRIVATE QboneServerSession virtual bool SendClientRequest(const QboneClientRequest& request); - void ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) override; - void ProcessPacketFromPeer(quiche::QuicheStringPiece packet) override; + void ProcessPacketFromNetwork(absl::string_view packet) override; + void ProcessPacketFromPeer(absl::string_view packet) override; // QbonePacketProcessor::OutputInterface implementation. - void SendPacketToClient(quiche::QuicheStringPiece packet) override; - void SendPacketToNetwork(quiche::QuicheStringPiece packet) override; + void SendPacketToClient(absl::string_view packet) override; + void SendPacketToNetwork(absl::string_view packet) override; // QbonePacketProcessor::StatsInterface implementation. void OnPacketForwarded(QbonePacketProcessor::Direction direction) override {} 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 e534398e7b3..d2d2ab4a24b 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 @@ -9,6 +9,7 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h" #include "net/third_party/quiche/src/quic/qbone/qbone_constants.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" ABSL_FLAG( bool, @@ -79,7 +79,7 @@ void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) { if (frame.offset == 0 && frame.fin && frame.data_length > 0) { ++num_ephemeral_packets_; ProcessPacketFromPeer( - quiche::QuicheStringPiece(frame.data_buffer, frame.data_length)); + absl::string_view(frame.data_buffer, frame.data_length)); flow_controller()->AddBytesConsumed(frame.data_length); // TODO(b/147817422): Add a counter for how many streams were actually // closed here. @@ -91,7 +91,7 @@ void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) { QuicSession::OnStreamFrame(frame); } -void QboneSessionBase::OnMessageReceived(quiche::QuicheStringPiece message) { +void QboneSessionBase::OnMessageReceived(absl::string_view message) { ++num_message_packets_; ProcessPacketFromPeer(message); } @@ -136,7 +136,7 @@ QuicStream* QboneSessionBase::ActivateDataStream( return raw; } -void QboneSessionBase::SendPacketToPeer(quiche::QuicheStringPiece packet) { +void QboneSessionBase::SendPacketToPeer(absl::string_view packet) { if (crypto_stream_ == nullptr) { QUIC_BUG << "Attempting to send packet before encryption established"; return; @@ -162,7 +162,7 @@ void QboneSessionBase::SendPacketToPeer(quiche::QuicheStringPiece packet) { connection()->GetGuaranteedLargestMessagePayload(); CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet, - [this](quiche::QuicheStringPiece icmp_packet) { + [this](absl::string_view icmp_packet) { writer_->WritePacketToNetwork(icmp_packet.data(), icmp_packet.size()); }); diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h index 4b9513088c4..222999b4868 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_base.h @@ -5,6 +5,7 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_ #define QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" @@ -13,7 +14,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h" #include "net/third_party/quiche/src/quic/qbone/qbone_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -34,10 +34,10 @@ class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession { // This will check if the packet is wholly contained. void OnStreamFrame(const QuicStreamFrame& frame) override; // Called whenever a MESSAGE frame is received. - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; - virtual void ProcessPacketFromNetwork(quiche::QuicheStringPiece packet) = 0; - virtual void ProcessPacketFromPeer(quiche::QuicheStringPiece packet) = 0; + virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0; + virtual void ProcessPacketFromPeer(absl::string_view packet) = 0; // Returns the number of QBONE network packets that were received // that fit into a single QuicStreamFrame and elided the creation of @@ -86,7 +86,7 @@ class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession { // packet. This function will return true if a stream was created // and the packet sent. It will return false if the stream could not // be created. - void SendPacketToPeer(quiche::QuicheStringPiece packet); + void SendPacketToPeer(absl::string_view packet); QbonePacketWriter* writer_; diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc index 243a5c535d5..505927421bd 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_session_test.cc @@ -4,6 +4,7 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h" #include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -77,7 +77,7 @@ class IndirectionProofSource : public ProofSource { const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<Callback> callback) override { if (!proof_source_) { QuicReferenceCountedPointer<ProofSource::Chain> chain = @@ -107,7 +107,7 @@ class IndirectionProofSource : public ProofSource { const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<SignatureCallback> callback) override { if (!proof_source_) { callback->Run(/*ok=*/true, "Signature", /*details=*/nullptr); @@ -141,7 +141,7 @@ class IndirectionProofVerifier : public ProofVerifier { const uint16_t port, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& certs, const std::string& cert_sct, const std::string& signature, @@ -167,13 +167,14 @@ class IndirectionProofVerifier : public ProofVerifier { const ProofVerifyContext* context, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, std::unique_ptr<ProofVerifierCallback> callback) override { if (!proof_verifier_) { return QUIC_FAILURE; } return proof_verifier_->VerifyCertChain( hostname, port, certs, ocsp_response, cert_sct, context, error_details, - details, std::move(callback)); + details, out_alert, std::move(callback)); } std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override { @@ -318,9 +319,9 @@ class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> { { client_connection_ = new QuicConnection( - TestConnectionId(), server_address, &helper_, alarm_factory_.get(), - new NiceMock<MockPacketWriter>(), true, Perspective::IS_CLIENT, - supported_versions_); + TestConnectionId(), client_address, server_address, &helper_, + alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true, + Perspective::IS_CLIENT, supported_versions_); client_connection_->SetSelfAddress(client_address); QuicConfig config; client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>( @@ -337,9 +338,9 @@ class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> { { server_connection_ = new QuicConnection( - TestConnectionId(), client_address, &helper_, alarm_factory_.get(), - new NiceMock<MockPacketWriter>(), true, Perspective::IS_SERVER, - supported_versions_); + TestConnectionId(), server_address, client_address, &helper_, + alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true, + Perspective::IS_SERVER, supported_versions_); server_connection_->SetSelfAddress(server_address); QuicConfig config; server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>( @@ -416,7 +417,7 @@ class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> { std::string expected; CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet, - [&expected](quiche::QuicheStringPiece icmp_packet) { + [&expected](absl::string_view icmp_packet) { expected = std::string(icmp_packet); }); 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 4d1888928f6..db499bab55a 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 @@ -4,12 +4,12 @@ #include "net/third_party/quiche/src/quic/qbone/qbone_stream.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/qbone/qbone_constants.h" #include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" ABSL_FLAG(int, qbone_stream_ttl_secs, 3, "The QBONE Stream TTL in seconds."); @@ -24,8 +24,7 @@ QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id, QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs))); } -void QboneWriteOnlyStream::WritePacketToQuicStream( - quiche::QuicheStringPiece packet) { +void QboneWriteOnlyStream::WritePacketToQuicStream(absl::string_view packet) { // Streams are one way and ephemeral. This function should only be // called once. WriteOrBufferData(packet, /* fin= */ true, nullptr); diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h index 8a6313bc0c2..c27a91ab702 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream.h @@ -5,10 +5,10 @@ #ifndef QUICHE_QUIC_QBONE_QBONE_STREAM_H_ #define QUICHE_QUIC_QBONE_QBONE_STREAM_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/core/quic_stream.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -26,7 +26,7 @@ class QUIC_EXPORT_PRIVATE QboneWriteOnlyStream : public QuicStream { void OnDataAvailable() override {} // Write a network packet over the quic stream. - void WritePacketToQuicStream(quiche::QuicheStringPiece packet); + void WritePacketToQuicStream(absl::string_view packet); }; // QboneReadOnlyStream will be used if we find an incoming stream that diff --git a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc index cfe9645c1d4..18f48f7331b 100644 --- a/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc @@ -6,6 +6,7 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" namespace quic { @@ -40,13 +40,12 @@ class MockQuicSession : public QboneSessionBase { ~MockQuicSession() override {} // Writes outgoing data from QuicStream to a string. - QuicConsumedData WritevData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level) override { + QuicConsumedData WritevData(QuicStreamId id, + size_t write_length, + QuicStreamOffset offset, + StreamSendingState state, + TransmissionType type, + absl::optional<EncryptionLevel> level) override { if (!writable_) { return QuicConsumedData(0, false); } @@ -58,14 +57,21 @@ class MockQuicSession : public QboneSessionBase { return nullptr; } - const QuicCryptoStream* GetCryptoStream() const override { return nullptr; } - QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; } - // Called by QuicStream when they want to close stream. MOCK_METHOD(void, SendRstStream, (QuicStreamId, QuicRstStreamErrorCode, QuicStreamOffset, bool), (override)); + MOCK_METHOD(void, + MaybeSendRstStreamFrame, + (QuicStreamId stream_id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written), + (override)); + MOCK_METHOD(void, + MaybeSendStopSendingFrame, + (QuicStreamId stream_id, QuicRstStreamErrorCode error), + (override)); // Sets whether data is written to buffer, or else if this is write blocked. void set_writable(bool writable) { writable_ = writable; } @@ -86,17 +92,11 @@ class MockQuicSession : public QboneSessionBase { } std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override { - return nullptr; + return std::make_unique<test::MockQuicCryptoStream>(this); } - MOCK_METHOD(void, - ProcessPacketFromPeer, - (quiche::QuicheStringPiece), - (override)); - MOCK_METHOD(void, - ProcessPacketFromNetwork, - (quiche::QuicheStringPiece), - (override)); + MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override)); + MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override)); private: // Whether data is written to write_buffer_. @@ -152,12 +152,14 @@ class QboneReadOnlyStreamTest : public ::testing::Test, connection_.reset(new QuicConnection( test::TestConnectionId(0), QuicSocketAddress(TestLoopback(), 0), + QuicSocketAddress(TestLoopback(), 0), this /*QuicConnectionHelperInterface*/, alarm_factory_.get(), new DummyPacketWriter(), owns_writer, perspective, ParsedVersionOfIndex(CurrentSupportedVersions(), 0))); clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_.get(), QuicConfig()); + session_->Initialize(); stream_ = new QboneReadOnlyStream(kStreamId, session_.get()); session_->ActivateReliableStream( std::unique_ptr<QboneReadOnlyStream>(stream_)); @@ -243,8 +245,15 @@ TEST_F(QboneReadOnlyStreamTest, ReadBufferedTooLarge) { CreateReliableQuicStream(); std::string packet = "0123456789"; int iterations = (QboneConstants::kMaxQbonePacketBytes / packet.size()) + 2; - EXPECT_CALL(*session_, - SendRstStream(kStreamId, QUIC_BAD_APPLICATION_PAYLOAD, _, _)); + if (!session_->split_up_send_rst()) { + EXPECT_CALL(*session_, + SendRstStream(kStreamId, QUIC_BAD_APPLICATION_PAYLOAD, _, _)); + } else { + EXPECT_CALL(*session_, MaybeSendStopSendingFrame( + kStreamId, QUIC_BAD_APPLICATION_PAYLOAD)); + EXPECT_CALL(*session_, MaybeSendRstStreamFrame( + kStreamId, QUIC_BAD_APPLICATION_PAYLOAD, _)); + } for (int i = 0; i < iterations; ++i) { QuicStreamFrame frame(kStreamId, i == (iterations - 1), i * packet.size(), packet); diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc index 4d5da07bff3..f38d6b3462b 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.cc @@ -10,6 +10,7 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h" @@ -22,7 +23,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -53,8 +53,7 @@ QuicTransportClientSession::QuicTransportClientSession( /*proof_handler=*/this, /*has_application_state = */ true); } -void QuicTransportClientSession::OnAlpnSelected( - quiche::QuicheStringPiece alpn) { +void QuicTransportClientSession::OnAlpnSelected(absl::string_view alpn) { // Defense in-depth: ensure the ALPN selected is the desired one. if (alpn != QuicTransportAlpn()) { QUIC_BUG << "QuicTransport negotiated non-QuicTransport ALPN: " << alpn; @@ -237,8 +236,7 @@ void QuicTransportClientSession::SendClientIndication() { visitor_->OnSessionReady(); } -void QuicTransportClientSession::OnMessageReceived( - quiche::QuicheStringPiece message) { +void QuicTransportClientSession::OnMessageReceived(absl::string_view message) { visitor_->OnDatagramReceived(message); } diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h index 6fe26195127..c4f417fcbb8 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h @@ -8,6 +8,7 @@ #include <cstdint> #include <memory> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "url/origin.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" @@ -24,7 +25,6 @@ #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -49,7 +49,7 @@ class QUIC_EXPORT_PRIVATE QuicTransportClientSession virtual void OnIncomingUnidirectionalStreamAvailable() = 0; // Notifies the visitor when a new datagram has been received. - virtual void OnDatagramReceived(quiche::QuicheStringPiece datagram) = 0; + virtual void OnDatagramReceived(absl::string_view datagram) = 0; // Notifies the visitor that a new outgoing stream can now be created. virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0; @@ -68,7 +68,7 @@ class QUIC_EXPORT_PRIVATE QuicTransportClientSession std::vector<std::string> GetAlpnsToOffer() const override { return std::vector<std::string>({QuicTransportAlpn()}); } - void OnAlpnSelected(quiche::QuicheStringPiece alpn) override; + void OnAlpnSelected(absl::string_view alpn) override; bool alpn_received() const { return alpn_received_; } void CryptoConnect() { crypto_stream_->CryptoConnect(); } @@ -97,7 +97,7 @@ class QUIC_EXPORT_PRIVATE QuicTransportClientSession void SetDefaultEncryptionLevel(EncryptionLevel level) override; void OnTlsHandshakeComplete() override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; // Return the earliest incoming stream that has been received by the session // but has not been accepted. Returns nullptr if there are no incoming diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc index fe855765940..129c87ee662 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session_test.cc @@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "absl/base/macros.h" #include "url/gurl.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" @@ -19,7 +20,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -116,7 +116,7 @@ TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) { const std::string client_indication = DataInStream(client_indication_stream); const std::string expected_client_indication{ kTestOriginClientIndication, - QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1}; + ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1}; EXPECT_EQ(client_indication, expected_client_indication); } @@ -142,7 +142,7 @@ TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) { const std::string client_indication = DataInStream(client_indication_stream); const std::string expected_client_indication{ kTestOriginClientIndication, - QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1}; + ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1}; EXPECT_EQ(client_indication, expected_client_indication); } diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc index f1912e2f33c..1965c6d56e2 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_integration_test.cc @@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "url/origin.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" @@ -31,7 +32,6 @@ #include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" #include "net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -62,8 +62,9 @@ class QuicTransportEndpointBase : public QuicEndpointBase { : QuicEndpointBase(simulator, name, peer_name) { QuicEnableVersion(DefaultVersionForQuicTransport()); connection_ = std::make_unique<QuicConnection>( - TestConnectionId(0x10), simulator::GetAddressFromName(peer_name), - simulator, simulator->GetAlarmFactory(), &writer_, + TestConnectionId(0x10), simulator::GetAddressFromName(name), + simulator::GetAddressFromName(peer_name), simulator, + simulator->GetAlarmFactory(), &writer_, /*owns_writer=*/false, perspective, GetVersions()); connection_->SetSelfAddress(simulator::GetAddressFromName(name)); } @@ -376,7 +377,7 @@ TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) { size_t received = 0; EXPECT_CALL(*client_->visitor(), OnDatagramReceived(_)) .WillRepeatedly( - [&received](quiche::QuicheStringPiece /*datagram*/) { received++; }); + [&received](absl::string_view /*datagram*/) { received++; }); ASSERT_TRUE(simulator_.RunUntilOrTimeout( [this]() { return client_->session()->datagram_queue()->empty(); }, 3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize))); diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc index c2de6590b0e..083e6fcd315 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.cc @@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "url/url_constants.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" @@ -16,7 +17,6 @@ #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -109,7 +109,7 @@ bool QuicTransportServerSession::ClientIndicationParser::Parse() { return false; } - quiche::QuicheStringPiece value; + absl::string_view value; if (!reader_.ReadStringPiece16(&value)) { ParseError(quiche::QuicheStrCat("Failed to read value for key ", key)); return false; @@ -160,7 +160,7 @@ bool QuicTransportServerSession::ClientIndicationParser::Parse() { } bool QuicTransportServerSession::ClientIndicationParser::ProcessPath( - quiche::QuicheStringPiece path) { + absl::string_view path) { if (path.empty() || path[0] != '/') { // https://tools.ietf.org/html/draft-vvv-webtransport-quic-01#section-3.2.2 Error("Path must begin with a '/'"); @@ -193,13 +193,13 @@ void QuicTransportServerSession::ClientIndicationParser::Error( } void QuicTransportServerSession::ClientIndicationParser::ParseError( - quiche::QuicheStringPiece error_message) { + absl::string_view error_message) { Error(quiche::QuicheStrCat("Failed to parse the client indication stream: ", error_message, reader_.DebugString())); } void QuicTransportServerSession::ProcessClientIndication( - quiche::QuicheStringPiece indication) { + absl::string_view indication) { ClientIndicationParser parser(this, indication); if (!parser.Parse()) { return; diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h index 1b9dda03538..4085998003d 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h @@ -5,6 +5,7 @@ #ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_ #define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_ +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "url/origin.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" @@ -13,7 +14,6 @@ #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_protocol.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -44,8 +44,8 @@ class QUIC_EXPORT_PRIVATE QuicTransportServerSession QuicCompressedCertsCache* compressed_certs_cache, ServerVisitor* visitor); - std::vector<quiche::QuicheStringPiece>::const_iterator SelectAlpn( - const std::vector<quiche::QuicheStringPiece>& alpns) const override { + std::vector<absl::string_view>::const_iterator SelectAlpn( + const std::vector<absl::string_view>& alpns) const override { return std::find(alpns.cbegin(), alpns.cend(), QuicTransportAlpn()); } @@ -86,7 +86,7 @@ class QUIC_EXPORT_PRIVATE QuicTransportServerSession class QUIC_EXPORT_PRIVATE ClientIndicationParser { public: ClientIndicationParser(QuicTransportServerSession* session, - quiche::QuicheStringPiece indication) + absl::string_view indication) : session_(session), reader_(indication) {} // Parses the specified indication. Automatically closes the connection @@ -96,10 +96,10 @@ class QUIC_EXPORT_PRIVATE QuicTransportServerSession private: void Error(const std::string& error_message); - void ParseError(quiche::QuicheStringPiece error_message); + void ParseError(absl::string_view error_message); // Processes the path portion of the client indication. - bool ProcessPath(quiche::QuicheStringPiece path); + bool ProcessPath(absl::string_view path); QuicTransportServerSession* session_; QuicDataReader reader_; @@ -107,7 +107,7 @@ class QUIC_EXPORT_PRIVATE QuicTransportServerSession // Parses and processes the client indication as described in // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2 - void ProcessClientIndication(quiche::QuicheStringPiece indication); + void ProcessClientIndication(absl::string_view indication); virtual void OnIncomingDataStream(QuicTransportStream* /*stream*/) {} diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc index 8176b03d156..c4e40d5f1b5 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session_test.cc @@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "url/origin.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h" @@ -20,7 +21,6 @@ #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -88,7 +88,7 @@ class QuicTransportServerSessionTest : public QuicTest { QuicServerId("test.example.com", 443), options, QuicTransportAlpn()); } - void ReceiveIndication(quiche::QuicheStringPiece indication) { + void ReceiveIndication(absl::string_view indication) { QUIC_LOG(INFO) << "Receiving indication: " << quiche::QuicheTextUtils::HexDump(indication); constexpr size_t kChunkSize = 1024; @@ -101,10 +101,10 @@ class QuicTransportServerSessionTest : public QuicTest { } session_->OnStreamFrame(QuicStreamFrame(ClientIndicationStream(), /*fin=*/true, indication.size(), - quiche::QuicheStringPiece())); + absl::string_view())); } - void ReceiveIndicationWithPath(quiche::QuicheStringPiece path) { + void ReceiveIndicationWithPath(absl::string_view path) { constexpr char kTestOriginClientIndicationPrefix[] = "\0\0" // key (0x0000, origin) "\0\x18" // length @@ -149,14 +149,14 @@ TEST_F(QuicTransportServerSessionTest, PiecewiseClientIndication) { for (; i < sizeof(kTestOriginClientIndication) - 2; i++) { QuicStreamFrame frame( ClientIndicationStream(), false, i, - quiche::QuicheStringPiece(&kTestOriginClientIndication[i], 1)); + absl::string_view(&kTestOriginClientIndication[i], 1)); session_->OnStreamFrame(frame); } EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true)); QuicStreamFrame last_frame( ClientIndicationStream(), true, i, - quiche::QuicheStringPiece(&kTestOriginClientIndication[i], 1)); + absl::string_view(&kTestOriginClientIndication[i], 1)); session_->OnStreamFrame(last_frame); EXPECT_TRUE(session_->IsSessionReady()); } @@ -170,7 +170,7 @@ TEST_F(QuicTransportServerSessionTest, OriginRejected) { EXPECT_FALSE(session_->IsSessionReady()); } -std::string MakeUnknownField(quiche::QuicheStringPiece payload) { +std::string MakeUnknownField(absl::string_view payload) { std::string buffer; buffer.resize(payload.size() + 4); QuicDataWriter writer(buffer.size(), &buffer[0]); diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc index 0fb988aed37..38614e185a0 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc @@ -6,11 +6,11 @@ #include <sys/types.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -52,7 +52,7 @@ size_t QuicTransportStream::Read(std::string* output) { return bytes_read; } -bool QuicTransportStream::Write(quiche::QuicheStringPiece data) { +bool QuicTransportStream::Write(absl::string_view data) { if (!CanWrite()) { return false; } diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h index f2bac887a40..dfe943f67d3 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h @@ -8,12 +8,12 @@ #include <cstddef> #include <memory> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/core/quic_stream.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -40,9 +40,9 @@ class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream { // Reads all available data and appends it to the end of |output|. size_t Read(std::string* output); // Writes |data| into the stream. Returns true on success. - QUIC_MUST_USE_RESULT bool Write(quiche::QuicheStringPiece data); + ABSL_MUST_USE_RESULT bool Write(absl::string_view data); // Sends the FIN on the stream. Returns true on success. - QUIC_MUST_USE_RESULT bool SendFin(); + ABSL_MUST_USE_RESULT bool SendFin(); // Indicates whether it is possible to write into stream right now. bool CanWrite() const; diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc index 0f0d770ecc5..82cd9149f7f 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream_test.cc @@ -6,6 +6,8 @@ #include <memory> +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" @@ -14,7 +16,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -42,7 +43,9 @@ class QuicTransportStreamTest : public QuicTest { session_(connection_) { QuicEnableVersion(DefaultVersionForQuicTransport()); session_.Initialize(); - + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); stream_ = new QuicTransportStream(0, &session_, &interface_); session_.ActivateStream(QuicWrapUnique(stream_)); @@ -51,8 +54,7 @@ class QuicTransportStreamTest : public QuicTest { stream_->set_visitor(std::move(visitor)); } - void ReceiveStreamData(quiche::QuicheStringPiece data, - QuicStreamOffset offset) { + void ReceiveStreamData(absl::string_view data, QuicStreamOffset offset) { QuicStreamFrame frame(0, false, offset, data); stream_->OnStreamFrame(frame); } 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 81466de1240..5932b9c6b2b 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 @@ -7,13 +7,13 @@ #include <cstdint> #include <memory> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -39,7 +39,7 @@ void NormalizeFingerprint(CertificateFingerprint& fingerprint) { constexpr char CertificateFingerprint::kSha256[]; -std::string ComputeSha256Fingerprint(quiche::QuicheStringPiece input) { +std::string ComputeSha256Fingerprint(absl::string_view input) { std::vector<uint8_t> raw_hash; raw_hash.resize(SHA256_DIGEST_LENGTH); SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(), @@ -114,7 +114,7 @@ QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof( const uint16_t /*port*/, const std::string& /*server_config*/, QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, + absl::string_view /*chlo_hash*/, const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/, const std::string& /*signature*/, @@ -139,6 +139,7 @@ QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain( const ProofVerifyContext* /*context*/, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* /*out_alert*/, std::unique_ptr<ProofVerifierCallback> /*callback*/) { if (certs.empty()) { *details = std::make_unique<Details>(Status::kInternalError); @@ -185,7 +186,7 @@ WebTransportFingerprintProofVerifier::CreateDefaultContext() { } bool WebTransportFingerprintProofVerifier::HasKnownFingerprint( - quiche::QuicheStringPiece der_certificate) { + absl::string_view der_certificate) { // https://wicg.github.io/web-transport/#verify-a-certificate-fingerprint const std::string fingerprint = ComputeSha256Fingerprint(der_certificate); for (const CertificateFingerprint& reference : fingerprints_) { 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 7e4358de60d..ad83788ecff 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 @@ -7,10 +7,10 @@ #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/quic_clock.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -30,7 +30,7 @@ struct QUIC_EXPORT_PRIVATE CertificateFingerprint { // Computes a SHA-256 fingerprint of the specified input formatted in the same // format as CertificateFingerprint::fingerprint would contain. QUIC_EXPORT_PRIVATE std::string ComputeSha256Fingerprint( - quiche::QuicheStringPiece input); + absl::string_view input); // WebTransportFingerprintProofVerifier verifies the server leaf certificate // against a supplied list of certificate fingerprints following the procedure @@ -83,7 +83,7 @@ class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier const uint16_t port, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& certs, const std::string& cert_sct, const std::string& signature, @@ -100,11 +100,12 @@ class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier const ProofVerifyContext* context, std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details, + uint8_t* out_alert, std::unique_ptr<ProofVerifierCallback> callback) override; std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override; private: - bool HasKnownFingerprint(quiche::QuicheStringPiece der_certificate); + bool HasKnownFingerprint(absl::string_view der_certificate); bool HasValidExpiry(const CertificateView& certificate); bool IsWithinValidityPeriod(const CertificateView& certificate); diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc index f9f27e5db69..a84a8a53497 100644 --- a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc +++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc @@ -6,11 +6,11 @@ #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/test_certificates.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -37,15 +37,16 @@ class WebTransportFingerprintProofVerifierTest : public QuicTest { } protected: - VerifyResult Verify(quiche::QuicheStringPiece certificate) { + VerifyResult Verify(absl::string_view certificate) { VerifyResult result; std::unique_ptr<ProofVerifyDetails> details; + uint8_t tls_alert; result.status = verifier_->VerifyCertChain( /*hostname=*/"", /*port=*/0, std::vector<std::string>{std::string(certificate)}, /*ocsp_response=*/"", /*cert_sct=*/"", - /*context=*/nullptr, &result.error, &details, + /*context=*/nullptr, &result.error, &details, &tls_alert, /*callback=*/nullptr); result.detailed_status = static_cast<WebTransportFingerprintProofVerifier::Details*>( @@ -136,7 +137,7 @@ TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) { } TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) { - constexpr quiche::QuicheStringPiece kInvalidCertificate = "Hello, world!"; + constexpr absl::string_view kInvalidCertificate = "Hello, world!"; ASSERT_TRUE(verifier_->AddFingerprint( {CertificateFingerprint::kSha256, ComputeSha256Fingerprint(kInvalidCertificate)})); 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 eacbca5287c..00f7f1b4cd7 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 @@ -9,6 +9,8 @@ #include <string> #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/ec.h" #include "third_party/boringssl/src/include/openssl/ecdsa.h" @@ -38,7 +40,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" @@ -182,15 +183,15 @@ class FullChloGenerator { EXPECT_THAT(rej->tag(), testing::Eq(kREJ)); QUIC_VLOG(1) << "Extract valid STK and SCID from\n" << rej->DebugString(); - quiche::QuicheStringPiece srct; + absl::string_view srct; ASSERT_TRUE(rej->GetStringPiece(kSourceAddressTokenTag, &srct)); - quiche::QuicheStringPiece scfg; + absl::string_view scfg; ASSERT_TRUE(rej->GetStringPiece(kSCFG, &scfg)); std::unique_ptr<CryptoHandshakeMessage> server_config( CryptoFramer::ParseMessage(scfg)); - quiche::QuicheStringPiece scid; + absl::string_view scid; ASSERT_TRUE(server_config->GetStringPiece(kSCID, &scid)); *out_ = result_->client_hello; @@ -257,10 +258,9 @@ int HandshakeWithFakeServer(QuicConfig* server_quic_config, EXPECT_CALL(*server_conn, SendCryptoData(_, _, _)) .Times(testing::AnyNumber()); EXPECT_CALL(server_session, SelectAlpn(_)) - .WillRepeatedly( - [alpn](const std::vector<quiche::QuicheStringPiece>& alpns) { - return std::find(alpns.cbegin(), alpns.cend(), alpn); - }); + .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) { + return std::find(alpns.cbegin(), alpns.cend(), alpn); + }); // The client's handshake must have been started already. CHECK_NE(0u, client_conn->encrypted_packets_.size()); @@ -464,26 +464,23 @@ uint64_t LeafCertHashForTesting() { class MockCommonCertSets : public CommonCertSets { public: - MockCommonCertSets(quiche::QuicheStringPiece cert, - uint64_t hash, - uint32_t index) + MockCommonCertSets(absl::string_view cert, uint64_t hash, uint32_t index) : cert_(cert), hash_(hash), index_(index) {} - quiche::QuicheStringPiece GetCommonHashes() const override { + absl::string_view GetCommonHashes() const override { QUIC_BUG << "not implemented"; - return quiche::QuicheStringPiece(); + return absl::string_view(); } - quiche::QuicheStringPiece GetCert(uint64_t hash, - uint32_t index) const override { + absl::string_view GetCert(uint64_t hash, uint32_t index) const override { if (hash == hash_ && index == index_) { return cert_; } - return quiche::QuicheStringPiece(); + return absl::string_view(); } - bool MatchCert(quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece common_set_hashes, + bool MatchCert(absl::string_view cert, + absl::string_view common_set_hashes, uint64_t* out_hash, uint32_t* out_index) const override { if (cert != cert_) { @@ -518,7 +515,7 @@ class MockCommonCertSets : public CommonCertSets { const uint32_t index_; }; -CommonCertSets* MockCommonCertSets(quiche::QuicheStringPiece cert, +CommonCertSets* MockCommonCertSets(absl::string_view cert, uint64_t hash, uint32_t index) { return new class MockCommonCertSets(cert, hash, index); @@ -579,10 +576,10 @@ void CompareCrypters(const QuicEncrypter* encrypter, << decrypter << " for " << label; return; } - quiche::QuicheStringPiece encrypter_key = encrypter->GetKey(); - quiche::QuicheStringPiece encrypter_iv = encrypter->GetNoncePrefix(); - quiche::QuicheStringPiece decrypter_key = decrypter->GetKey(); - quiche::QuicheStringPiece decrypter_iv = decrypter->GetNoncePrefix(); + absl::string_view encrypter_key = encrypter->GetKey(); + absl::string_view encrypter_iv = encrypter->GetNoncePrefix(); + absl::string_view decrypter_key = decrypter->GetKey(); + absl::string_view decrypter_iv = decrypter->GetNoncePrefix(); quiche::test::CompareCharArraysWithHexError( label + " key", encrypter_key.data(), encrypter_key.length(), decrypter_key.data(), decrypter_key.length()); @@ -626,9 +623,9 @@ void CompareClientAndServerKeys(QuicCryptoClientStream* client, } } - quiche::QuicheStringPiece client_subkey_secret = + absl::string_view client_subkey_secret = client->crypto_negotiated_params().subkey_secret; - quiche::QuicheStringPiece server_subkey_secret = + absl::string_view server_subkey_secret = server->crypto_negotiated_params().subkey_secret; quiche::test::CompareCharArraysWithHexError( "subkey secret", client_subkey_secret.data(), @@ -708,8 +705,8 @@ CryptoHandshakeMessage CreateCHLO( size_t value_len = value.length(); if (value_len > 0 && value[0] == '#') { // This is ascii encoded hex. - std::string hex_value = quiche::QuicheTextUtils::HexDecode( - quiche::QuicheStringPiece(&value[1])); + std::string hex_value = + absl::HexStringToBytes(absl::string_view(&value[1])); msg.SetStringPiece(quic_tag, hex_value); continue; } @@ -798,7 +795,7 @@ void MovePackets(PacketSavingConnection* source_conn, *inout_packet_index = index; QuicConnectionPeer::SetCurrentPacket(dest_conn, - quiche::QuicheStringPiece(nullptr, 0)); + absl::string_view(nullptr, 0)); } CryptoHandshakeMessage GenerateDefaultInchoateCHLO( @@ -830,19 +827,19 @@ std::string GenerateClientNonceHex(const QuicClock* clock, primary_config.set_primary_time(clock->WallNow().ToUNIXSeconds()); std::unique_ptr<CryptoHandshakeMessage> msg = crypto_config->AddConfig(primary_config, clock->WallNow()); - quiche::QuicheStringPiece orbit; + absl::string_view orbit; CHECK(msg->GetStringPiece(kORBT, &orbit)); std::string nonce; CryptoUtils::GenerateNonce(clock->WallNow(), QuicRandom::GetInstance(), orbit, &nonce); - return ("#" + quiche::QuicheTextUtils::HexEncode(nonce)); + return ("#" + absl::BytesToHexString(nonce)); } std::string GenerateClientPublicValuesHex() { char public_value[32]; memset(public_value, 42, sizeof(public_value)); - return ("#" + quiche::QuicheTextUtils::HexEncode(public_value, - sizeof(public_value))); + return ("#" + absl::BytesToHexString( + absl::string_view(public_value, sizeof(public_value)))); } void GenerateFullCHLO( 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 3d58837a813..32d761fabe4 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 @@ -11,12 +11,12 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/evp.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -136,7 +136,7 @@ std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting(); // MockCommonCertSets returns a CommonCertSets that contains a single set with // hash |hash|, consisting of the certificate |cert| at index |index|. -CommonCertSets* MockCommonCertSets(quiche::QuicheStringPiece cert, +CommonCertSets* MockCommonCertSets(absl::string_view cert, uint64_t hash, uint32_t index); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc index a21b43ab109..0769da4efdd 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc @@ -6,11 +6,12 @@ #include <utility> +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -134,17 +135,17 @@ TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) { primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds()); std::unique_ptr<CryptoHandshakeMessage> msg = crypto_config.AddConfig(primary_config, clock.WallNow()); - quiche::QuicheStringPiece orbit; + absl::string_view orbit; ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit)); std::string nonce; CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit, &nonce); - std::string nonce_hex = "#" + quiche::QuicheTextUtils::HexEncode(nonce); + std::string nonce_hex = "#" + absl::BytesToHexString(nonce); char public_value[32]; memset(public_value, 42, sizeof(public_value)); - std::string pub_hex = "#" + quiche::QuicheTextUtils::HexEncode( - public_value, sizeof(public_value)); + std::string pub_hex = "#" + absl::BytesToHexString(absl::string_view( + public_value, sizeof(public_value))); // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the // first one from the list of supported versions. diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc index 98e18fcea13..576791c2b46 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.cc @@ -4,7 +4,7 @@ #include "net/third_party/quiche/src/quic/test_tools/failing_proof_source.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { namespace test { @@ -14,7 +14,7 @@ void FailingProofSource::GetProof(const QuicSocketAddress& /*server_address*/, const std::string& /*hostname*/, const std::string& /*server_config*/, QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, + absl::string_view /*chlo_hash*/, std::unique_ptr<Callback> callback) { callback->Run(false, nullptr, QuicCryptoProof(), nullptr); } @@ -31,7 +31,7 @@ void FailingProofSource::ComputeTlsSignature( const QuicSocketAddress& /*client_address*/, const std::string& /*hostname*/, uint16_t /*signature_algorithm*/, - quiche::QuicheStringPiece /*in*/, + absl::string_view /*in*/, std::unique_ptr<SignatureCallback> callback) { callback->Run(false, "", nullptr); } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h index 6ea303d1df8..b63a952dc1f 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/failing_proof_source.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_ #define QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -18,7 +18,7 @@ class FailingProofSource : public ProofSource { const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<Callback> callback) override; QuicReferenceCountedPointer<Chain> GetCertChain( @@ -31,7 +31,7 @@ class FailingProofSource : public ProofSource { const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<SignatureCallback> callback) override; TicketCrypter* GetTicketCrypter() override { return nullptr; } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc index 9619fad5523..00af20e01e2 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.cc @@ -6,9 +6,9 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -52,7 +52,7 @@ FakeProofSource::ComputeSignatureOp::ComputeSignatureOp( const QuicSocketAddress& client_address, std::string hostname, uint16_t sig_alg, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::SignatureCallback> callback, ProofSource* delegate) : server_address_(server_address), @@ -80,7 +80,7 @@ void FakeProofSource::GetProof( const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<ProofSource::Callback> callback) { if (!active_) { delegate_->GetProof(server_address, client_address, hostname, server_config, @@ -106,7 +106,7 @@ void FakeProofSource::ComputeTlsSignature( const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::SignatureCallback> callback) { QUIC_LOG(INFO) << "FakeProofSource::ComputeTlsSignature"; if (!active_) { diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h index 94dede6b385..fc99974c32b 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/fake_proof_source.h @@ -9,8 +9,8 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -39,7 +39,7 @@ class FakeProofSource : public ProofSource { const std::string& hostname, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr<ProofSource::Callback> callback) override; QuicReferenceCountedPointer<Chain> GetCertChain( const QuicSocketAddress& server_address, @@ -50,7 +50,7 @@ class FakeProofSource : public ProofSource { const QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::SignatureCallback> callback) override; TicketCrypter* GetTicketCrypter() override; @@ -107,7 +107,7 @@ class FakeProofSource : public ProofSource { const QuicSocketAddress& client_address, std::string hostname, uint16_t sig_alg, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::SignatureCallback> callback, ProofSource* delegate); ~ComputeSignatureOp() override; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc index e4d28161ac2..665f479fb5b 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.cc @@ -46,6 +46,7 @@ class FirstFlightExtractor : public DelegatedPacketWriter::Delegate { crypto_config_.set_alpn(AlpnForVersion(version_)); connection_ = new QuicConnection(server_connection_id_, + /*initial_self_address=*/QuicSocketAddress(), QuicSocketAddress(TestPeerIPAddress(), kTestPort), &connection_helper_, &alarm_factory_, &writer_, /*owns_writer=*/false, Perspective::IS_CLIENT, diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h b/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h index 47a3216eebe..01a07ce1a1f 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h @@ -9,10 +9,10 @@ #include <list> #include <memory> +#include "absl/base/attributes.h" #include "net/third_party/quiche/src/quic/core/quic_alarm.h" #include "net/third_party/quiche/src/quic/core/quic_clock.h" #include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_client.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" @@ -126,7 +126,9 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper { } // Useful for reproducing very flaky issues. - QUIC_UNUSED void set_seed(uint64_t seed) { simple_random_.set_seed(seed); } + ABSL_ATTRIBUTE_UNUSED void set_seed(uint64_t seed) { + simple_random_.set_seed(seed); + } private: // Writes out the next packet to the contained writer and returns the time @@ -155,7 +157,7 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper { QuicTime send_time; }; - typedef std::list<DelayedWrite> DelayedPacketList; + using DelayedPacketList = std::list<DelayedWrite>; const QuicClock* clock_; std::unique_ptr<QuicAlarm> write_unblocked_alarm_; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc index 4189290eebf..9a79515ceea 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc @@ -8,20 +8,21 @@ #include <cstddef> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { void NoopEncoderStreamErrorDelegate::OnEncoderStreamError( - quiche::QuicheStringPiece /*error_message*/) {} + QuicErrorCode /* error_code */, + absl::string_view /*error_message*/) {} TestHeadersHandler::TestHeadersHandler() : decoding_completed_(false), decoding_error_detected_(false) {} -void TestHeadersHandler::OnHeaderDecoded(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +void TestHeadersHandler::OnHeaderDecoded(absl::string_view name, + absl::string_view value) { ASSERT_FALSE(decoding_completed_); ASSERT_FALSE(decoding_error_detected_); @@ -36,7 +37,7 @@ void TestHeadersHandler::OnDecodingCompleted() { } void TestHeadersHandler::OnDecodingErrorDetected( - quiche::QuicheStringPiece error_message) { + absl::string_view error_message) { ASSERT_FALSE(decoding_completed_); ASSERT_FALSE(decoding_error_detected_); @@ -44,7 +45,7 @@ void TestHeadersHandler::OnDecodingErrorDetected( error_message_.assign(error_message.data(), error_message.size()); } -spdy::SpdyHeaderBlock TestHeadersHandler::ReleaseHeaderList() { +spdy::Http2HeaderBlock TestHeadersHandler::ReleaseHeaderList() { DCHECK(decoding_completed_); DCHECK(!decoding_error_detected_); @@ -71,7 +72,7 @@ void QpackDecode( QpackStreamSenderDelegate* decoder_stream_sender_delegate, QpackProgressiveDecoder::HeadersHandlerInterface* handler, const FragmentSizeGenerator& fragment_size_generator, - quiche::QuicheStringPiece data) { + absl::string_view data) { QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams, encoder_stream_error_delegate); decoder.set_qpack_stream_sender_delegate(decoder_stream_sender_delegate); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h index 9741b05bdf5..f38bf987de9 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h @@ -7,11 +7,11 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -23,7 +23,8 @@ class NoopEncoderStreamErrorDelegate public: ~NoopEncoderStreamErrorDelegate() override = default; - void OnEncoderStreamError(quiche::QuicheStringPiece error_message) override; + void OnEncoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) override; }; // Mock QpackDecoder::EncoderStreamErrorDelegate implementation. @@ -34,12 +35,12 @@ class MockEncoderStreamErrorDelegate MOCK_METHOD(void, OnEncoderStreamError, - (quiche::QuicheStringPiece error_message), + (QuicErrorCode error_code, absl::string_view error_message), (override)); }; // HeadersHandlerInterface implementation that collects decoded headers -// into a SpdyHeaderBlock. +// into a Http2HeaderBlock. class TestHeadersHandler : public QpackProgressiveDecoder::HeadersHandlerInterface { public: @@ -47,22 +48,21 @@ class TestHeadersHandler ~TestHeadersHandler() override = default; // HeadersHandlerInterface implementation: - void OnHeaderDecoded(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) override; + void OnHeaderDecoded(absl::string_view name, + absl::string_view value) override; void OnDecodingCompleted() override; - void OnDecodingErrorDetected( - quiche::QuicheStringPiece error_message) override; + void OnDecodingErrorDetected(absl::string_view error_message) override; // Release decoded header list. Must only be called if decoding is complete // and no errors have been detected. - spdy::SpdyHeaderBlock ReleaseHeaderList(); + spdy::Http2HeaderBlock ReleaseHeaderList(); bool decoding_completed() const; bool decoding_error_detected() const; const std::string& error_message() const; private: - spdy::SpdyHeaderBlock header_list_; + spdy::Http2HeaderBlock header_list_; bool decoding_completed_; bool decoding_error_detected_; std::string error_message_; @@ -78,12 +78,12 @@ class MockHeadersHandler MOCK_METHOD(void, OnHeaderDecoded, - (quiche::QuicheStringPiece name, quiche::QuicheStringPiece value), + (absl::string_view name, absl::string_view value), (override)); MOCK_METHOD(void, OnDecodingCompleted, (), (override)); MOCK_METHOD(void, OnDecodingErrorDetected, - (quiche::QuicheStringPiece error_message), + (absl::string_view error_message), (override)); }; @@ -92,11 +92,10 @@ class NoOpHeadersHandler public: ~NoOpHeadersHandler() override = default; - void OnHeaderDecoded(quiche::QuicheStringPiece /*name*/, - quiche::QuicheStringPiece /*value*/) override {} + void OnHeaderDecoded(absl::string_view /*name*/, + absl::string_view /*value*/) override {} void OnDecodingCompleted() override {} - void OnDecodingErrorDetected( - quiche::QuicheStringPiece /*error_message*/) override {} + void OnDecodingErrorDetected(absl::string_view /*error_message*/) override {} }; void QpackDecode( @@ -106,7 +105,7 @@ void QpackDecode( QpackStreamSenderDelegate* decoder_stream_sender_delegate, QpackProgressiveDecoder::HeadersHandlerInterface* handler, const FragmentSizeGenerator& fragment_size_generator, - quiche::QuicheStringPiece data); + absl::string_view data); } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc index 1303511e2d8..9c8fd922ccf 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc @@ -4,14 +4,15 @@ #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" namespace quic { namespace test { void NoopDecoderStreamErrorDelegate::OnDecoderStreamError( - quiche::QuicheStringPiece /*error_message*/) {} + QuicErrorCode /*error_code*/, + absl::string_view /*error_message*/) {} } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h index 9b188150796..9d4e23e421a 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h @@ -7,10 +7,10 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -22,7 +22,8 @@ class NoopDecoderStreamErrorDelegate public: ~NoopDecoderStreamErrorDelegate() override = default; - void OnDecoderStreamError(quiche::QuicheStringPiece error_message) override; + void OnDecoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) override; }; // Mock QpackEncoder::DecoderStreamErrorDelegate implementation. @@ -33,7 +34,7 @@ class MockDecoderStreamErrorDelegate MOCK_METHOD(void, OnDecoderStreamError, - (quiche::QuicheStringPiece error_message), + (QuicErrorCode error_code, absl::string_view error_message), (override)); }; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc index a7ba9e48876..267fad320df 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc @@ -30,13 +30,16 @@ #include <string> #include <utility> +#include "absl/strings/match.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_file_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace quic { @@ -44,8 +47,8 @@ QpackOfflineDecoder::QpackOfflineDecoder() : encoder_stream_error_detected_(false) {} bool QpackOfflineDecoder::DecodeAndVerifyOfflineData( - quiche::QuicheStringPiece input_filename, - quiche::QuicheStringPiece expected_headers_filename) { + absl::string_view input_filename, + absl::string_view expected_headers_filename) { if (!ParseInputFilename(input_filename)) { QUIC_LOG(ERROR) << "Error parsing input filename " << input_filename; return false; @@ -67,14 +70,15 @@ bool QpackOfflineDecoder::DecodeAndVerifyOfflineData( } void QpackOfflineDecoder::OnEncoderStreamError( - quiche::QuicheStringPiece error_message) { - QUIC_LOG(ERROR) << "Encoder stream error: " << error_message; + QuicErrorCode error_code, + absl::string_view error_message) { + QUIC_LOG(ERROR) << "Encoder stream error: " + << QuicErrorCodeToString(error_code) << " " << error_message; encoder_stream_error_detected_ = true; } -bool QpackOfflineDecoder::ParseInputFilename( - quiche::QuicheStringPiece input_filename) { - auto pieces = quiche::QuicheTextUtils::Split(input_filename, '.'); +bool QpackOfflineDecoder::ParseInputFilename(absl::string_view input_filename) { + std::vector<absl::string_view> pieces = absl::StrSplit(input_filename, '.'); if (pieces.size() < 3) { QUIC_LOG(ERROR) << "Not enough fields in input filename " << input_filename; @@ -100,8 +104,7 @@ bool QpackOfflineDecoder::ParseInputFilename( // Maximum allowed number of blocked streams. uint64_t max_blocked_streams = 0; - if (!quiche::QuicheTextUtils::StringToUint64(*piece_it, - &max_blocked_streams)) { + if (!absl::SimpleAtoi(*piece_it, &max_blocked_streams)) { QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it << "\" as an integer."; return false; @@ -111,8 +114,7 @@ bool QpackOfflineDecoder::ParseInputFilename( // Maximum Dynamic Table Capacity in bytes uint64_t maximum_dynamic_table_capacity = 0; - if (!quiche::QuicheTextUtils::StringToUint64( - *piece_it, &maximum_dynamic_table_capacity)) { + if (!absl::SimpleAtoi(*piece_it, &maximum_dynamic_table_capacity)) { QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it << "\" as an integer."; return false; @@ -132,12 +134,12 @@ bool QpackOfflineDecoder::ParseInputFilename( } bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile( - quiche::QuicheStringPiece input_filename) { - // Store data in |input_data_storage|; use a quiche::QuicheStringPiece to + absl::string_view input_filename) { + // Store data in |input_data_storage|; use a absl::string_view to // efficiently keep track of remaining portion yet to be decoded. std::string input_data_storage; ReadFileContents(input_filename, &input_data_storage); - quiche::QuicheStringPiece input_data(input_data_storage); + absl::string_view input_data(input_data_storage); while (!input_data.empty()) { // Parse stream_id and length. @@ -160,7 +162,7 @@ bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile( } // Parse data. - quiche::QuicheStringPiece data = input_data.substr(0, length); + absl::string_view data = input_data.substr(0, length); input_data = input_data.substr(length); // Process data. @@ -228,21 +230,20 @@ bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile( } bool QpackOfflineDecoder::VerifyDecodedHeaderLists( - quiche::QuicheStringPiece expected_headers_filename) { + absl::string_view expected_headers_filename) { // Store data in |expected_headers_data_storage|; use a - // quiche::QuicheStringPiece to efficiently keep track of remaining portion + // absl::string_view to efficiently keep track of remaining portion // yet to be decoded. std::string expected_headers_data_storage; ReadFileContents(expected_headers_filename, &expected_headers_data_storage); - quiche::QuicheStringPiece expected_headers_data( - expected_headers_data_storage); + absl::string_view expected_headers_data(expected_headers_data_storage); while (!decoded_header_lists_.empty()) { - spdy::SpdyHeaderBlock decoded_header_list = + spdy::Http2HeaderBlock decoded_header_list = std::move(decoded_header_lists_.front()); decoded_header_lists_.pop_front(); - spdy::SpdyHeaderBlock expected_header_list; + spdy::Http2HeaderBlock expected_header_list; if (!ReadNextExpectedHeaderList(&expected_headers_data, &expected_header_list)) { QUIC_LOG(ERROR) @@ -268,14 +269,13 @@ bool QpackOfflineDecoder::VerifyDecodedHeaderLists( } bool QpackOfflineDecoder::ReadNextExpectedHeaderList( - quiche::QuicheStringPiece* expected_headers_data, - spdy::SpdyHeaderBlock* expected_header_list) { + absl::string_view* expected_headers_data, + spdy::Http2HeaderBlock* expected_header_list) { while (true) { - quiche::QuicheStringPiece::size_type endline = - expected_headers_data->find('\n'); + absl::string_view::size_type endline = expected_headers_data->find('\n'); // Even last header list must be followed by an empty line. - if (endline == quiche::QuicheStringPiece::npos) { + if (endline == absl::string_view::npos) { QUIC_LOG(ERROR) << "Unexpected end of expected header list file."; return false; } @@ -286,9 +286,8 @@ bool QpackOfflineDecoder::ReadNextExpectedHeaderList( return true; } - quiche::QuicheStringPiece header_field = - expected_headers_data->substr(0, endline); - auto pieces = quiche::QuicheTextUtils::Split(header_field, '\t'); + absl::string_view header_field = expected_headers_data->substr(0, endline); + std::vector<absl::string_view> pieces = absl::StrSplit(header_field, '\t'); if (pieces.size() != 2) { QUIC_LOG(ERROR) << "Header key and value must be separated by TAB."; @@ -302,8 +301,8 @@ bool QpackOfflineDecoder::ReadNextExpectedHeaderList( } bool QpackOfflineDecoder::CompareHeaderBlocks( - spdy::SpdyHeaderBlock decoded_header_list, - spdy::SpdyHeaderBlock expected_header_list) { + spdy::Http2HeaderBlock decoded_header_list, + spdy::Http2HeaderBlock expected_header_list) { if (decoded_header_list == expected_header_list) { return true; } @@ -314,15 +313,15 @@ bool QpackOfflineDecoder::CompareHeaderBlocks( // Remove such headers one by one if they match. const char* kContentLength = "content-length"; const char* kPseudoHeaderPrefix = ":"; - for (spdy::SpdyHeaderBlock::iterator decoded_it = decoded_header_list.begin(); + for (spdy::Http2HeaderBlock::iterator decoded_it = + decoded_header_list.begin(); decoded_it != decoded_header_list.end();) { - const quiche::QuicheStringPiece key = decoded_it->first; - if (key != kContentLength && - !quiche::QuicheTextUtils::StartsWith(key, kPseudoHeaderPrefix)) { + const absl::string_view key = decoded_it->first; + if (key != kContentLength && !absl::StartsWith(key, kPseudoHeaderPrefix)) { ++decoded_it; continue; } - spdy::SpdyHeaderBlock::iterator expected_it = + spdy::Http2HeaderBlock::iterator expected_it = expected_header_list.find(key); if (expected_it == expected_header_list.end() || decoded_it->second != expected_it->second) { diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h index f90b2c736eb..eea0b064d12 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h @@ -7,10 +7,11 @@ #include <list> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -29,12 +30,12 @@ class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate { // |expected_headers_filename|, and compare decoded header lists to expected // ones. Returns true if there is an equal number of them and the // corresponding ones match, false otherwise. - bool DecodeAndVerifyOfflineData( - quiche::QuicheStringPiece input_filename, - quiche::QuicheStringPiece expected_headers_filename); + bool DecodeAndVerifyOfflineData(absl::string_view input_filename, + absl::string_view expected_headers_filename); // QpackDecoder::EncoderStreamErrorDelegate implementation: - void OnEncoderStreamError(quiche::QuicheStringPiece error_message) override; + void OnEncoderStreamError(QuicErrorCode error_code, + absl::string_view error_message) override; private: // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until @@ -48,30 +49,28 @@ class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate { // Parse decoder parameters from |input_filename| and set up |qpack_decoder_| // accordingly. - bool ParseInputFilename(quiche::QuicheStringPiece input_filename); + bool ParseInputFilename(absl::string_view input_filename); // Read encoded header blocks and encoder stream data from |input_filename|, // pass them to |qpack_decoder_| for decoding, and add decoded header lists to // |decoded_header_lists_|. - bool DecodeHeaderBlocksFromFile(quiche::QuicheStringPiece input_filename); + bool DecodeHeaderBlocksFromFile(absl::string_view input_filename); // Read expected header lists from |expected_headers_filename| and verify // decoded header lists in |decoded_header_lists_| against them. - bool VerifyDecodedHeaderLists( - quiche::QuicheStringPiece expected_headers_filename); + bool VerifyDecodedHeaderLists(absl::string_view expected_headers_filename); // Parse next header list from |*expected_headers_data| into // |*expected_header_list|, removing consumed data from the beginning of // |*expected_headers_data|. Returns true on success, false if parsing fails. - bool ReadNextExpectedHeaderList( - quiche::QuicheStringPiece* expected_headers_data, - spdy::SpdyHeaderBlock* expected_header_list); + bool ReadNextExpectedHeaderList(absl::string_view* expected_headers_data, + spdy::Http2HeaderBlock* expected_header_list); // Compare two header lists. Allow for different orders of certain headers as // described at // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md. - bool CompareHeaderBlocks(spdy::SpdyHeaderBlock decoded_header_list, - spdy::SpdyHeaderBlock expected_header_list); + bool CompareHeaderBlocks(spdy::Http2HeaderBlock decoded_header_list, + spdy::Http2HeaderBlock expected_header_list); bool encoder_stream_error_detected_; test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_; @@ -81,7 +80,7 @@ class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate { std::list<Decoder> decoders_; // Decoded header lists. - std::list<spdy::SpdyHeaderBlock> decoded_header_lists_; + std::list<spdy::Http2HeaderBlock> decoded_header_lists_; }; } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc index faaddcb2187..65636d50f1d 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc @@ -5,6 +5,7 @@ #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" #include <limits> +#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" namespace quic { namespace test { @@ -17,6 +18,8 @@ FragmentSizeGenerator FragmentModeToFragmentSizeGenerator( case FragmentMode::kOctetByOctet: return []() { return 1; }; } + QUIC_BUG << "Unknown FragmentMode " << static_cast<int>(fragment_mode); + return []() { return 0; }; } } // namespace test 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 b9f4adfb6d9..0d0594df945 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 @@ -8,9 +8,9 @@ #include <cstddef> #include <functional> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -32,17 +32,14 @@ class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate { public: ~MockQpackStreamSenderDelegate() override = default; - MOCK_METHOD(void, - WriteStreamData, - (quiche::QuicheStringPiece data), - (override)); + MOCK_METHOD(void, WriteStreamData, (absl::string_view data), (override)); }; class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate { public: ~NoopQpackStreamSenderDelegate() override = default; - void WriteStreamData(quiche::QuicheStringPiece /*data*/) override {} + void WriteStreamData(absl::string_view /*data*/) override {} }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc index 52325d16650..b10453ec399 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc @@ -99,6 +99,12 @@ void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config, } // static +void QuicConfigPeer::SetReceivedMinAckDelayMs(QuicConfig* config, + uint32_t min_ack_delay_ms) { + config->min_ack_delay_ms_.SetReceivedValue(min_ack_delay_ms); +} + +// static void QuicConfigPeer::SetNegotiated(QuicConfig* config, bool negotiated) { config->negotiated_ = negotiated; } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h index 109bd6453b3..98c35a175e3 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h @@ -60,6 +60,9 @@ class QuicConfigPeer { static void SetReceivedMaxPacketSize(QuicConfig* config, uint32_t max_udp_payload_size); + static void SetReceivedMinAckDelayMs(QuicConfig* config, + uint32_t min_ack_delay_ms); + static void SetNegotiated(QuicConfig* config, bool negotiated); static void SetReceivedOriginalConnectionId( 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 1949df17a85..30ed4fd6914 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 @@ -4,13 +4,13 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" #include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" #include "net/third_party/quiche/src/quic/core/quic_received_packet_manager.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -94,9 +94,8 @@ void QuicConnectionPeer::SwapCrypters(QuicConnection* connection, } // static -void QuicConnectionPeer::SetCurrentPacket( - QuicConnection* connection, - quiche::QuicheStringPiece current_packet) { +void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection, + absl::string_view current_packet) { connection->current_packet_data_ = current_packet.data(); connection->last_size_ = current_packet.size(); } @@ -152,6 +151,12 @@ QuicAlarm* QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm( } // static +QuicAlarm* QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm( + QuicConnection* connection) { + return connection->discard_previous_one_rtt_keys_alarm_.get(); +} + +// static QuicPacketWriter* QuicConnectionPeer::GetWriter(QuicConnection* connection) { return connection->writer_; } @@ -292,6 +297,12 @@ void QuicConnectionPeer::SetAddressValidated(QuicConnection* connection) { } // static +void QuicConnectionPeer::SetEnableAeadLimits(QuicConnection* connection, + bool enabled) { + connection->enable_aead_limits_ = enabled; +} + +// static void QuicConnectionPeer::SendConnectionClosePacket(QuicConnection* connection, QuicErrorCode error, const std::string& details) { @@ -379,5 +390,14 @@ QuicConnectionPeer::pending_path_challenge_payloads( return connection->pending_path_challenge_payloads_; } +void QuicConnectionPeer::SetConnectionClose(QuicConnection* connection) { + connection->connected_ = false; +} + +// static +void QuicConnectionPeer::SendPing(QuicConnection* connection) { + connection->SendPingAtLevel(connection->encryption_level()); +} + } // namespace test } // namespace quic 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 b470653b793..8859a58f515 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 @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_ #define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" #include "net/third_party/quiche/src/quic/core/quic_connection_stats.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -67,7 +67,7 @@ class QuicConnectionPeer { static void SwapCrypters(QuicConnection* connection, QuicFramer* framer); static void SetCurrentPacket(QuicConnection* connection, - quiche::QuicheStringPiece current_packet); + absl::string_view current_packet); static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection); @@ -82,6 +82,8 @@ class QuicConnectionPeer { static QuicAlarm* GetMtuDiscoveryAlarm(QuicConnection* connection); static QuicAlarm* GetProcessUndecryptablePacketsAlarm( QuicConnection* connection); + static QuicAlarm* GetDiscardPreviousOneRttKeysAlarm( + QuicConnection* connection); static QuicPacketWriter* GetWriter(QuicConnection* connection); // If |owns_writer| is true, takes ownership of |writer|. @@ -122,6 +124,7 @@ class QuicConnectionPeer { PacketHeaderFormat format); static void AddBytesReceived(QuicConnection* connection, size_t length); static void SetAddressValidated(QuicConnection* connection); + static void SetEnableAeadLimits(QuicConnection* connection, bool enabled); static void SendConnectionClosePacket(QuicConnection* connection, QuicErrorCode error, @@ -157,6 +160,10 @@ class QuicConnectionPeer { static const QuicCircularDeque< std::pair<QuicPathFrameBuffer, QuicSocketAddress>>& pending_path_challenge_payloads(QuicConnection* connection); + + static void SetConnectionClose(QuicConnection* connection); + + static void SendPing(QuicConnection* connection); }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc index 3893448931c..64fd271a3af 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.cc @@ -4,10 +4,10 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -53,7 +53,7 @@ std::string QuicCryptoServerConfigPeer::NewSourceAddressToken( HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens( std::string config_id, - quiche::QuicheStringPiece srct, + absl::string_view srct, const QuicIpAddress& ip, QuicWallTime now, CachedNetworkParameters* cached_network_params) { @@ -70,7 +70,7 @@ HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens( HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSingleSourceAddressToken( - quiche::QuicheStringPiece token, + absl::string_view token, const QuicIpAddress& ip, QuicWallTime now) { SourceAddressTokens tokens; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h index 270321f8ff1..9366eae1440 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_ #define QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -43,14 +43,14 @@ class QuicCryptoServerConfigPeer { // Attempts to validate the tokens in |tokens|. HandshakeFailureReason ValidateSourceAddressTokens( std::string config_id, - quiche::QuicheStringPiece tokens, + absl::string_view tokens, const QuicIpAddress& ip, QuicWallTime now, CachedNetworkParameters* cached_network_params); // Attempts to validate the single source address token in |token|. HandshakeFailureReason ValidateSingleSourceAddressToken( - quiche::QuicheStringPiece token, + absl::string_view token, const QuicIpAddress& ip, QuicWallTime now); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc new file mode 100644 index 00000000000..54d97d02527 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2020 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 "net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h" + +namespace quic { +namespace test { +// static +QuicAlarm* QuicPathValidatorPeer::retry_timer(QuicPathValidator* validator) { + return validator->retry_timer_.get(); +} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h new file mode 100644 index 00000000000..5b2b56c7e63 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_path_validator_peer.h @@ -0,0 +1,20 @@ +// Copyright (c) 2020 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_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_ +#define QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_ + +#include "net/third_party/quiche/src/quic/core/quic_path_validator.h" + +namespace quic { +namespace test { + +class QuicPathValidatorPeer { + public: + static QuicAlarm* retry_timer(QuicPathValidator* validator); +}; + +} // namespace test +} // namespace quic +#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc index 05d74d75701..a57840e2157 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc @@ -28,7 +28,7 @@ QuicStreamId QuicSessionPeer::GetNextOutgoingUnidirectionalStreamId( void QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(QuicSession* session, QuicStreamId id) { if (VersionHasIetfQuicFrames(session->transport_version())) { - session->v99_streamid_manager_.bidirectional_stream_id_manager_ + session->ietf_streamid_manager_.bidirectional_stream_id_manager_ .next_outgoing_stream_id_ = id; return; } @@ -40,9 +40,9 @@ void QuicSessionPeer::SetMaxOpenIncomingStreams(QuicSession* session, uint32_t max_streams) { if (VersionHasIetfQuicFrames(session->transport_version())) { QUIC_BUG << "SetmaxOpenIncomingStreams deprecated for IETF QUIC"; - session->v99_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( + session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( max_streams); - session->v99_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( + session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( max_streams); return; } @@ -56,7 +56,7 @@ void QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams( DCHECK(VersionHasIetfQuicFrames(session->transport_version())) << "SetmaxOpenIncomingBidirectionalStreams not supported for Google " "QUIC"; - session->v99_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( + session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams( max_streams); } // static @@ -66,7 +66,7 @@ void QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams( DCHECK(VersionHasIetfQuicFrames(session->transport_version())) << "SetmaxOpenIncomingUnidirectionalStreams not supported for Google " "QUIC"; - session->v99_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( + session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams( max_streams); } @@ -87,7 +87,7 @@ void QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams( DCHECK(VersionHasIetfQuicFrames(session->transport_version())) << "SetmaxOpenOutgoingBidirectionalStreams not supported for Google " "QUIC"; - session->v99_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( + session->ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams( max_streams); } // static @@ -97,7 +97,7 @@ void QuicSessionPeer::SetMaxOpenOutgoingUnidirectionalStreams( DCHECK(VersionHasIetfQuicFrames(session->transport_version())) << "SetmaxOpenOutgoingUnidirectionalStreams not supported for Google " "QUIC"; - session->v99_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( + session->ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams( max_streams); } @@ -157,12 +157,12 @@ bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) { if (VersionHasIetfQuicFrames(session->transport_version())) { if (id % QuicUtils::StreamIdDelta(session->transport_version()) < 2) { return QuicContainsKey( - session->v99_streamid_manager_.bidirectional_stream_id_manager_ + session->ietf_streamid_manager_.bidirectional_stream_id_manager_ .available_streams_, id); } return QuicContainsKey( - session->v99_streamid_manager_.unidirectional_stream_id_manager_ + session->ietf_streamid_manager_.unidirectional_stream_id_manager_ .available_streams_, id); } @@ -192,21 +192,21 @@ LegacyQuicStreamIdManager* QuicSessionPeer::GetStreamIdManager( } // static -UberQuicStreamIdManager* QuicSessionPeer::v99_streamid_manager( +UberQuicStreamIdManager* QuicSessionPeer::ietf_streamid_manager( QuicSession* session) { - return &session->v99_streamid_manager_; + return &session->ietf_streamid_manager_; } // static -QuicStreamIdManager* QuicSessionPeer::v99_bidirectional_stream_id_manager( +QuicStreamIdManager* QuicSessionPeer::ietf_bidirectional_stream_id_manager( QuicSession* session) { - return &session->v99_streamid_manager_.bidirectional_stream_id_manager_; + return &session->ietf_streamid_manager_.bidirectional_stream_id_manager_; } // static -QuicStreamIdManager* QuicSessionPeer::v99_unidirectional_stream_id_manager( +QuicStreamIdManager* QuicSessionPeer::ietf_unidirectional_stream_id_manager( QuicSession* session) { - return &session->v99_streamid_manager_.unidirectional_stream_id_manager_; + return &session->ietf_streamid_manager_.unidirectional_stream_id_manager_; } // static diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h index ffd6c6f300f..fdcb4431ff6 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h @@ -71,10 +71,10 @@ class QuicSessionPeer { static bool IsStreamWriteBlocked(QuicSession* session, QuicStreamId id); static QuicAlarm* GetCleanUpClosedStreamsAlarm(QuicSession* session); static LegacyQuicStreamIdManager* GetStreamIdManager(QuicSession* session); - static UberQuicStreamIdManager* v99_streamid_manager(QuicSession* session); - static QuicStreamIdManager* v99_bidirectional_stream_id_manager( + static UberQuicStreamIdManager* ietf_streamid_manager(QuicSession* session); + static QuicStreamIdManager* ietf_bidirectional_stream_id_manager( QuicSession* session); - static QuicStreamIdManager* v99_unidirectional_stream_id_manager( + static QuicStreamIdManager* ietf_unidirectional_stream_id_manager( QuicSession* session); static PendingStream* GetPendingStream(QuicSession* session, QuicStreamId stream_id); @@ -82,6 +82,10 @@ class QuicSessionPeer { static void SetPerspective(QuicSession* session, Perspective perspective); static size_t GetNumOpenDynamicStreams(QuicSession* session); static size_t GetNumDrainingStreams(QuicSession* session); + static QuicStreamId GetLargestPeerCreatedStreamId(QuicSession* session, + bool unidirectional) { + return session->GetLargestPeerCreatedStreamId(unidirectional); + } }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc index b3bf224df4e..8f5553ac9dd 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc @@ -3,13 +3,14 @@ // found in the LICENSE file. #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h" +#include <cstddef> #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -typedef quic::QuicStreamSequencerBuffer::BufferBlock BufferBlock; +using BufferBlock = quic::QuicStreamSequencerBuffer::BufferBlock; static const size_t kBlockSizeBytes = quic::QuicStreamSequencerBuffer::kBlockSizeBytes; @@ -45,7 +46,8 @@ bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() { return true; } - size_t count = buffer_->blocks_count_; + size_t count = buffer_->allocate_blocks_on_demand_ ? current_blocks_count() + : max_blocks_count(); for (size_t i = 0; i < count; i++) { if (buffer_->blocks_[i] != nullptr) { return false; @@ -79,10 +81,11 @@ bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() { if (!capacity_sane) { QUIC_LOG(ERROR) << "read offset go beyond 1st block"; } - bool block_match_capacity = (buffer_->max_buffer_capacity_bytes_ <= - buffer_->blocks_count_ * kBlockSizeBytes) && - (buffer_->max_buffer_capacity_bytes_ > - (buffer_->blocks_count_ - 1) * kBlockSizeBytes); + bool block_match_capacity = + (buffer_->max_buffer_capacity_bytes_ <= + buffer_->max_blocks_count_ * kBlockSizeBytes) && + (buffer_->max_buffer_capacity_bytes_ > + (buffer_->max_blocks_count_ - 1) * kBlockSizeBytes); if (!capacity_sane) { QUIC_LOG(ERROR) << "block number not match capcaity."; } @@ -143,8 +146,12 @@ bool QuicStreamSequencerBufferPeer::IsBufferAllocated() { return buffer_->blocks_ != nullptr; } -size_t QuicStreamSequencerBufferPeer::block_count() { - return buffer_->blocks_count_; +size_t QuicStreamSequencerBufferPeer::max_blocks_count() { + return buffer_->max_blocks_count_; +} + +size_t QuicStreamSequencerBufferPeer::current_blocks_count() { + return buffer_->current_blocks_count_; } const QuicIntervalSet<QuicStreamOffset>& diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h index da2d054bbd3..4cac6f10dd8 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.h @@ -49,7 +49,9 @@ class QuicStreamSequencerBufferPeer { bool IsBufferAllocated(); - size_t block_count(); + size_t max_blocks_count(); + + size_t current_blocks_count(); const QuicIntervalSet<QuicStreamOffset>& bytes_received(); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc index 56dc1ec24c2..5b93de5f64f 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc @@ -8,6 +8,8 @@ #include <utility> #include <vector> +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/x509.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h" @@ -27,7 +29,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/tools/quic_url.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -49,7 +50,7 @@ class RecordingProofVerifier : public ProofVerifier { const uint16_t port, const std::string& server_config, QuicTransportVersion transport_version, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, const std::vector<std::string>& certs, const std::string& cert_sct, const std::string& signature, @@ -81,6 +82,7 @@ class RecordingProofVerifier : public ProofVerifier { const ProofVerifyContext* /*context*/, std::string* /*error_details*/, std::unique_ptr<ProofVerifyDetails>* /*details*/, + uint8_t* /*out_alert*/, std::unique_ptr<ProofVerifierCallback> /*callback*/) override { return ProcessCerts(certs, cert_sct); } @@ -438,7 +440,7 @@ void QuicTestClient::SendRequestsAndWaitForResponses( ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest( const spdy::SpdyHeaderBlock* headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { if (headers) { @@ -482,18 +484,18 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest( } ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body) { + absl::string_view body) { return SendMessage(headers, body, /*fin=*/true); } ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin) { return SendMessage(headers, body, fin, /*flush=*/true); } ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, bool flush) { // Always force creation of a stream for SendMessage. @@ -515,8 +517,7 @@ ssize_t QuicTestClient::SendData( const std::string& data, bool last_data, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { - return GetOrCreateStreamAndSendRequest(nullptr, - quiche::QuicheStringPiece(data), + return GetOrCreateStreamAndSendRequest(nullptr, absl::string_view(data), last_data, std::move(ack_listener)); } @@ -702,14 +703,13 @@ bool QuicTestClient::WaitUntil(int timeout_ms, std::function<bool()> trigger) { epoll_server()->set_timeout_in_us(old_timeout_us); } if (trigger && !trigger()) { - QUIC_VLOG(1) << "Client WaitUntil returning with trigger returning false." - << QuicStackTrace(); + QUIC_VLOG(1) << "Client WaitUntil returning with trigger returning false."; return false; } return true; } -ssize_t QuicTestClient::Send(quiche::QuicheStringPiece data) { +ssize_t QuicTestClient::Send(absl::string_view data) { return SendData(std::string(data), false); } @@ -884,7 +884,7 @@ void QuicTestClient::WaitForWriteToFlush() { QuicTestClient::TestClientDataToResend::TestClientDataToResend( std::unique_ptr<spdy::SpdyHeaderBlock> headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, QuicTestClient* test_client, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) @@ -940,8 +940,7 @@ bool QuicTestClient::PopulateHeaderBlockFromUrl( const std::string& uri, spdy::SpdyHeaderBlock* headers) { std::string url; - if (quiche::QuicheTextUtils::StartsWith(uri, "https://") || - quiche::QuicheTextUtils::StartsWith(uri, "http://")) { + if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://")) { url = uri; } else if (uri[0] == '/') { url = "https://" + client_->server_id().host() + uri; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h index 1bd0247be6e..b4d8f467c51 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h @@ -9,6 +9,7 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" @@ -18,7 +19,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/tools/quic_client.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -141,19 +141,19 @@ class QuicTestClient : public QuicSpdyStream::Visitor, // Sends a request containing |headers| and |body| and returns the number of // bytes sent (the size of the serialized request headers and body). ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body); + absl::string_view body); // Sends a request containing |headers| and |body| with the fin bit set to // |fin| and returns the number of bytes sent (the size of the serialized // request headers and body). ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin); // Sends a request containing |headers| and |body| with the fin bit set to // |fin| and returns the number of bytes sent (the size of the serialized // request headers and body). If |flush| is true, will wait for the message to // be flushed before returning. ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, bool flush); // Sends a request containing |headers| and |body|, waits for the response, @@ -170,7 +170,7 @@ class QuicTestClient : public QuicSpdyStream::Visitor, QuicSocketAddress local_address() const; void ClearPerRequestState(); bool WaitUntil(int timeout_ms, std::function<bool()> trigger); - ssize_t Send(quiche::QuicheStringPiece data); + ssize_t Send(absl::string_view data); bool connected() const; bool buffer_body() const; void set_buffer_body(bool buffer_body); @@ -264,7 +264,7 @@ class QuicTestClient : public QuicSpdyStream::Visitor, // null, only the body will be sent on the stream. ssize_t GetOrCreateStreamAndSendRequest( const spdy::SpdyHeaderBlock* headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); @@ -342,7 +342,7 @@ class QuicTestClient : public QuicSpdyStream::Visitor, public: TestClientDataToResend( std::unique_ptr<spdy::SpdyHeaderBlock> headers, - quiche::QuicheStringPiece body, + absl::string_view body, bool fin, QuicTestClient* test_client, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc index f311079a350..c69ec29f48c 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc @@ -6,13 +6,13 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -97,7 +97,7 @@ class QuicTestDispatcher : public QuicSimpleDispatcher { QuicConnectionId id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const ParsedQuicVersion& version) override { QuicReaderMutexLock lock(&factory_lock_); if (session_factory_ == nullptr && stream_factory_ == nullptr && @@ -106,7 +106,7 @@ class QuicTestDispatcher : public QuicSimpleDispatcher { id, self_address, peer_address, alpn, version); } QuicConnection* connection = new QuicConnection( - id, peer_address, helper(), alarm_factory(), writer(), + id, self_address, peer_address, helper(), alarm_factory(), writer(), /* owns_writer= */ false, Perspective::IS_SERVER, ParsedQuicVersionVector{version}); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc index ed7dc7592f3..8bf49d97be3 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc @@ -9,6 +9,8 @@ #include <memory> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/chacha.h" #include "third_party/boringssl/src/include/openssl/sha.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h" @@ -34,9 +36,7 @@ #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h" using testing::_; @@ -202,11 +202,11 @@ std::unique_ptr<QuicPacket> BuildUnsizedDataPacket( header.length_length); } -std::string Sha1Hash(quiche::QuicheStringPiece data) { +std::string Sha1Hash(absl::string_view data) { char buffer[SHA_DIGEST_LENGTH]; SHA1(reinterpret_cast<const uint8_t*>(data.data()), data.size(), reinterpret_cast<uint8_t*>(buffer)); - return std::string(buffer, QUICHE_ARRAYSIZE(buffer)); + return std::string(buffer, ABSL_ARRAYSIZE(buffer)); } bool ClearControlFrame(const QuicFrame& frame) { @@ -214,6 +214,11 @@ bool ClearControlFrame(const QuicFrame& frame) { return true; } +bool ClearControlFrameWithTransmissionType(const QuicFrame& frame, + TransmissionType /*type*/) { + return ClearControlFrame(frame); +} + uint64_t SimpleRandom::RandUint64() { uint64_t result; RandBytes(&result, sizeof(result)); @@ -525,19 +530,21 @@ MockQuicConnection::MockQuicConnection( MockQuicConnection::MockQuicConnection( QuicConnectionId connection_id, - QuicSocketAddress address, + QuicSocketAddress initial_peer_address, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, Perspective perspective, const ParsedQuicVersionVector& supported_versions) - : QuicConnection(connection_id, - address, - helper, - alarm_factory, - new testing::NiceMock<MockPacketWriter>(), - /* owns_writer= */ true, - perspective, - supported_versions) { + : QuicConnection( + connection_id, + /*initial_self_address=*/QuicSocketAddress(QuicIpAddress::Any4(), 5), + initial_peer_address, + helper, + alarm_factory, + new testing::NiceMock<MockPacketWriter>(), + /* owns_writer= */ true, + perspective, + supported_versions) { ON_CALL(*this, OnError(_)) .WillByDefault( Invoke(this, &PacketSavingConnection::QuicConnection_OnError)); @@ -627,7 +634,7 @@ QuicConsumedData MockQuicSession::ConsumeData( QuicStreamOffset offset, StreamSendingState state, TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) { + absl::optional<EncryptionLevel> /*level*/) { if (write_length > 0) { auto buf = std::make_unique<char[]>(write_length); QuicStream* stream = GetOrCreateStream(id); @@ -716,7 +723,7 @@ QuicConsumedData MockQuicSpdySession::ConsumeData( QuicStreamOffset offset, StreamSendingState state, TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) { + absl::optional<EncryptionLevel> /*level*/) { if (write_length > 0) { auto buf = std::make_unique<char[]>(write_length); QuicStream* stream = GetOrCreateStream(id); @@ -989,7 +996,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket( if (!QuicVersionUsesCryptoFrames(version.transport_version)) { QuicFrame frame( QuicStreamFrame(QuicUtils::GetCryptoStreamId(version.transport_version), - false, 0, quiche::QuicheStringPiece(data))); + false, 0, absl::string_view(data))); frames.push_back(frame); } else { QuicFrame frame(new QuicCryptoFrame(level, 0, data)); @@ -1100,8 +1107,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1; header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2; } - QuicFrame frame( - QuicStreamFrame(1, false, 0, quiche::QuicheStringPiece(data))); + QuicFrame frame(QuicStreamFrame(1, false, 0, absl::string_view(data))); QuicFrames frames; frames.push_back(frame); QuicFramer framer({version}, QuicTime::Zero(), perspective, @@ -1295,7 +1301,7 @@ StreamType DetermineStreamType(QuicStreamId id, } QuicMemSliceSpan MakeSpan(QuicBufferAllocator* allocator, - quiche::QuicheStringPiece message_data, + absl::string_view message_data, QuicMemSliceStorage* storage) { if (message_data.length() == 0) { *storage = @@ -1308,20 +1314,19 @@ QuicMemSliceSpan MakeSpan(QuicBufferAllocator* allocator, return storage->ToSpan(); } -QuicMemSlice MemSliceFromString(quiche::QuicheStringPiece data) { +QuicMemSlice MemSliceFromString(absl::string_view data) { static SimpleBufferAllocator* allocator = new SimpleBufferAllocator(); QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator, data.size()); memcpy(buffer.get(), data.data(), data.size()); return QuicMemSlice(std::move(buffer), data.size()); } -bool TaggingEncrypter::EncryptPacket( - uint64_t /*packet_number*/, - quiche::QuicheStringPiece /*associated_data*/, - quiche::QuicheStringPiece plaintext, - char* output, - size_t* output_length, - size_t max_output_length) { +bool TaggingEncrypter::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) { const size_t len = plaintext.size() + kTagSize; if (max_output_length < len) { return false; @@ -1334,13 +1339,12 @@ bool TaggingEncrypter::EncryptPacket( return true; } -bool TaggingDecrypter::DecryptPacket( - uint64_t /*packet_number*/, - quiche::QuicheStringPiece /*associated_data*/, - quiche::QuicheStringPiece ciphertext, - char* output, - size_t* output_length, - size_t /*max_output_length*/) { +bool TaggingDecrypter::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*/) { if (ciphertext.size() < kTagSize) { return false; } @@ -1352,8 +1356,7 @@ bool TaggingDecrypter::DecryptPacket( return true; } -bool TaggingDecrypter::CheckTag(quiche::QuicheStringPiece ciphertext, - uint8_t tag) { +bool TaggingDecrypter::CheckTag(absl::string_view ciphertext, uint8_t tag) { for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) { if (ciphertext.data()[i] != tag) { return false; @@ -1394,9 +1397,10 @@ TestPacketWriter::~TestPacketWriter() { WriteResult TestPacketWriter::WritePacket(const char* buffer, size_t buf_len, - const QuicIpAddress& /*self_address*/, + const QuicIpAddress& self_address, const QuicSocketAddress& peer_address, PerPacketOptions* /*options*/) { + last_write_source_address_ = self_address; last_write_peer_address_ = peer_address; // If the buffer is allocated from the pool, return it back to the pool. // Note the buffer content doesn't change. @@ -1517,5 +1521,96 @@ void TestPacketWriter::FreePacketBuffer(const char* buffer) { packet_buffer_free_list_.push_back(p); } +bool WriteServerVersionNegotiationProbeResponse( + char* packet_bytes, + size_t* packet_length_out, + const char* source_connection_id_bytes, + uint8_t source_connection_id_length) { + if (packet_bytes == nullptr) { + QUIC_BUG << "Invalid packet_bytes"; + return false; + } + if (packet_length_out == nullptr) { + QUIC_BUG << "Invalid packet_length_out"; + return false; + } + QuicConnectionId source_connection_id(source_connection_id_bytes, + source_connection_id_length); + std::unique_ptr<QuicEncryptedPacket> encrypted_packet = + QuicFramer::BuildVersionNegotiationPacket( + source_connection_id, EmptyQuicConnectionId(), + /*ietf_quic=*/true, /*use_length_prefix=*/true, + ParsedQuicVersionVector{}); + if (!encrypted_packet) { + QUIC_BUG << "Failed to create version negotiation packet"; + return false; + } + if (*packet_length_out < encrypted_packet->length()) { + QUIC_BUG << "Invalid *packet_length_out " << *packet_length_out << " < " + << encrypted_packet->length(); + return false; + } + *packet_length_out = encrypted_packet->length(); + memcpy(packet_bytes, encrypted_packet->data(), *packet_length_out); + return true; +} + +bool ParseClientVersionNegotiationProbePacket( + const char* packet_bytes, + size_t packet_length, + char* destination_connection_id_bytes, + uint8_t* destination_connection_id_length_out) { + if (packet_bytes == nullptr) { + QUIC_BUG << "Invalid packet_bytes"; + return false; + } + if (packet_length < kMinPacketSizeForVersionNegotiation || + packet_length > 65535) { + QUIC_BUG << "Invalid packet_length"; + return false; + } + if (destination_connection_id_bytes == nullptr) { + QUIC_BUG << "Invalid destination_connection_id_bytes"; + return false; + } + if (destination_connection_id_length_out == nullptr) { + QUIC_BUG << "Invalid destination_connection_id_length_out"; + return false; + } + + QuicEncryptedPacket encrypted_packet(packet_bytes, packet_length); + PacketHeaderFormat format; + QuicLongHeaderType long_packet_type; + bool version_present, has_length_prefix, retry_token_present; + QuicVersionLabel version_label; + ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported(); + QuicConnectionId destination_connection_id, source_connection_id; + absl::string_view retry_token; + std::string detailed_error; + QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher( + encrypted_packet, + /*expected_destination_connection_id_length=*/0, &format, + &long_packet_type, &version_present, &has_length_prefix, &version_label, + &parsed_version, &destination_connection_id, &source_connection_id, + &retry_token_present, &retry_token, &detailed_error); + if (error != QUIC_NO_ERROR) { + QUIC_BUG << "Failed to parse packet: " << detailed_error; + return false; + } + if (!version_present) { + QUIC_BUG << "Packet is not a long header"; + return false; + } + if (*destination_connection_id_length_out < + destination_connection_id.length()) { + QUIC_BUG << "destination_connection_id_length_out too small"; + return false; + } + *destination_connection_id_length_out = destination_connection_id.length(); + memcpy(destination_connection_id_bytes, destination_connection_id.data(), + *destination_connection_id_length_out); + return true; +} + } // namespace test } // namespace quic 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 457663e8817..f05859d9317 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 @@ -13,6 +13,7 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h" #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" @@ -23,6 +24,7 @@ #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" +#include "net/third_party/quiche/src/quic/core/quic_path_validator.h" #include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" @@ -36,7 +38,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -249,10 +250,12 @@ std::unique_ptr<QuicPacket> BuildUnsizedDataPacket( size_t packet_size); // Compute SHA-1 hash of the supplied std::string. -std::string Sha1Hash(quiche::QuicheStringPiece data); +std::string Sha1Hash(absl::string_view data); // Delete |frame| and return true. bool ClearControlFrame(const QuicFrame& frame); +bool ClearControlFrameWithTransmissionType(const QuicFrame& frame, + TransmissionType type); // Simple random number generator used to compute random numbers suitable // for pseudo-randomly dropping packets in tests. @@ -304,9 +307,9 @@ class MockFramerVisitor : public QuicFramerVisitorInterface { OnRetryPacket, (QuicConnectionId original_connection_id, QuicConnectionId new_connection_id, - quiche::QuicheStringPiece retry_token, - quiche::QuicheStringPiece retry_integrity_tag, - quiche::QuicheStringPiece retry_without_tag), + absl::string_view retry_token, + absl::string_view retry_integrity_tag, + absl::string_view retry_without_tag), (override)); // The constructor sets this up to return true by default. MOCK_METHOD(bool, @@ -424,6 +427,16 @@ class MockFramerVisitor : public QuicFramerVisitorInterface { OnAuthenticatedIetfStatelessResetPacket, (const QuicIetfStatelessResetPacket&), (override)); + MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override)); + MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override)); + MOCK_METHOD(std::unique_ptr<QuicDecrypter>, + AdvanceKeysAndCreateCurrentOneRttDecrypter, + (), + (override)); + MOCK_METHOD(std::unique_ptr<QuicEncrypter>, + CreateCurrentOneRttEncrypter, + (), + (override)); }; class NoOpFramerVisitor : public QuicFramerVisitorInterface { @@ -439,10 +452,9 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface { const QuicVersionNegotiationPacket& /*packet*/) override {} void OnRetryPacket(QuicConnectionId /*original_connection_id*/, QuicConnectionId /*new_connection_id*/, - quiche::QuicheStringPiece /*retry_token*/, - quiche::QuicheStringPiece /*retry_integrity_tag*/, - quiche::QuicheStringPiece /*retry_without_tag*/) override { - } + absl::string_view /*retry_token*/, + absl::string_view /*retry_integrity_tag*/, + absl::string_view /*retry_without_tag*/) override {} bool OnProtocolVersionMismatch(ParsedQuicVersion version) override; bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override; bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override; @@ -484,6 +496,15 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface { bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} + void OnDecryptedFirstPacketInKeyPhase() override {} + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + return nullptr; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } }; class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { @@ -506,10 +527,7 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { (override)); MOCK_METHOD(void, OnRstStream, (const QuicRstStreamFrame& frame), (override)); MOCK_METHOD(void, OnGoAway, (const QuicGoAwayFrame& frame), (override)); - MOCK_METHOD(void, - OnMessageReceived, - (quiche::QuicheStringPiece message), - (override)); + MOCK_METHOD(void, OnMessageReceived, (absl::string_view message), (override)); MOCK_METHOD(void, OnHandshakeDoneReceived, (), (override)); MOCK_METHOD(void, OnConnectionClosed, @@ -545,6 +563,10 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { (override)); MOCK_METHOD(void, OnAckNeedsRetransmittableFrame, (), (override)); MOCK_METHOD(void, SendPing, (), (override)); + MOCK_METHOD(void, + SendAckFrequency, + (const QuicAckFrequencyFrame& frame), + (override)); MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override)); MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override)); MOCK_METHOD(bool, @@ -562,6 +584,16 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override)); MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override)); MOCK_METHOD(void, OnHandshakePacketSent, (), (override)); + MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override)); + MOCK_METHOD(std::unique_ptr<QuicDecrypter>, + AdvanceKeysAndCreateCurrentOneRttDecrypter, + (), + (override)); + MOCK_METHOD(std::unique_ptr<QuicEncrypter>, + CreateCurrentOneRttEncrypter, + (), + (override)); + MOCK_METHOD(void, BeforeConnectionCloseSent, (), (override)); }; class MockQuicConnectionHelper : public QuicConnectionHelperInterface { @@ -706,6 +738,11 @@ class MockQuicConnection : public QuicConnection { QuicConnection::CloseConnection(error, details, connection_close_behavior); } + void ReallySendConnectionClosePacket(QuicErrorCode error, + const std::string& details) { + QuicConnection::SendConnectionClosePacket(error, details); + } + void ReallyProcessUdpPacket(const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, const QuicReceivedPacket& packet) { @@ -803,7 +840,11 @@ class MockQuicSession : public QuicSession { QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level), + absl::optional<EncryptionLevel> level), + (override)); + MOCK_METHOD(bool, + WriteControlFrame, + (const QuicFrame& frame, TransmissionType type), (override)); MOCK_METHOD(void, @@ -813,6 +854,16 @@ class MockQuicSession : public QuicSession { QuicStreamOffset bytes_written, bool send_rst_only), (override)); + MOCK_METHOD(void, + MaybeSendRstStreamFrame, + (QuicStreamId stream_id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written), + (override)); + MOCK_METHOD(void, + MaybeSendStopSendingFrame, + (QuicStreamId stream_id, QuicRstStreamErrorCode error), + (override)); MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override)); MOCK_METHOD(void, @@ -820,11 +871,11 @@ class MockQuicSession : public QuicSession { (QuicRstStreamErrorCode code, QuicStreamId stream_id), (override)); MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override)); - MOCK_METHOD(std::vector<quiche::QuicheStringPiece>::const_iterator, + MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn, - (const std::vector<quiche::QuicheStringPiece>&), + (const std::vector<absl::string_view>&), (const, override)); - MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece), (override)); + MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override)); using QuicSession::ActivateStream; @@ -835,7 +886,7 @@ class MockQuicSession : public QuicSession { QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level); + absl::optional<EncryptionLevel> level); void ReallySendRstStream(QuicStreamId id, QuicRstStreamErrorCode error, @@ -844,6 +895,12 @@ class MockQuicSession : public QuicSession { QuicSession::SendRstStream(id, error, bytes_written, send_rst_only); } + void ReallyMaybeSendRstStreamFrame(QuicStreamId id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written) { + QuicSession::MaybeSendRstStreamFrame(id, error, bytes_written); + } + private: std::unique_ptr<QuicCryptoStream> crypto_stream_; }; @@ -869,6 +926,14 @@ 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; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } private: QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; @@ -927,7 +992,7 @@ class MockQuicSpdySession : public QuicSpdySession { QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level), + absl::optional<EncryptionLevel> level), (override)); MOCK_METHOD(void, SendRstStream, @@ -937,6 +1002,16 @@ class MockQuicSpdySession : public QuicSpdySession { bool send_rst_only), (override)); MOCK_METHOD(void, + MaybeSendRstStreamFrame, + (QuicStreamId stream_id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written), + (override)); + MOCK_METHOD(void, + MaybeSendStopSendingFrame, + (QuicStreamId stream_id, QuicRstStreamErrorCode error), + (override)); + MOCK_METHOD(void, SendWindowUpdate, (QuicStreamId id, QuicStreamOffset byte_offset), (override)); @@ -973,7 +1048,7 @@ class MockQuicSpdySession : public QuicSpdySession { QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level); + absl::optional<EncryptionLevel> level); using QuicSession::ActivateStream; @@ -1087,11 +1162,11 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase { CreateOutgoingUnidirectionalStream, (), (override)); - MOCK_METHOD(std::vector<quiche::QuicheStringPiece>::const_iterator, + MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn, - (const std::vector<quiche::QuicheStringPiece>&), + (const std::vector<absl::string_view>&), (const, override)); - MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece), (override)); + MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override)); std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream( const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache) override; @@ -1174,7 +1249,7 @@ class TestQuicSpdyClientSession : public QuicSpdyClientSessionBase { MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override)); MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override)); MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override)); - MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece), (override)); + MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override)); MOCK_METHOD(void, OnConfigNegotiated, (), (override)); QuicCryptoClientStream* GetMutableCryptoStream() override; @@ -1409,7 +1484,9 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor { MOCK_METHOD(void, OnPacketHeader, - (const QuicPacketHeader& header), + (const QuicPacketHeader& header, + QuicTime receive_time, + EncryptionLevel level), (override)); MOCK_METHOD(void, @@ -1557,6 +1634,33 @@ class MockSessionNotifier : public SessionNotifierInterface { MOCK_METHOD(bool, HasUnackedStreamData, (), (const, override)); }; +class MockQuicPathValidationContext : public QuicPathValidationContext { + public: + MockQuicPathValidationContext(const QuicSocketAddress& self_address, + const QuicSocketAddress& peer_address, + QuicPacketWriter* writer) + : QuicPathValidationContext(self_address, peer_address), + writer_(writer) {} + QuicPacketWriter* WriterToUse() override { return writer_; } + + private: + QuicPacketWriter* writer_; +}; + +class MockQuicPathValidationResultDelegate + : public QuicPathValidator::ResultDelegate { + public: + MOCK_METHOD(void, + OnPathValidationSuccess, + (std::unique_ptr<QuicPathValidationContext>), + (override)); + + MOCK_METHOD(void, + OnPathValidationFailure, + (std::unique_ptr<QuicPathValidationContext>), + (override)); +}; + class QuicCryptoClientStreamPeer { public: QuicCryptoClientStreamPeer() = delete; @@ -1653,7 +1757,7 @@ QuicHeaderList AsHeaderList(const T& container) { } // Utility function that stores |str|'s data in |iov|. -inline void MakeIOVector(quiche::QuicheStringPiece str, struct iovec* iov) { +inline void MakeIOVector(absl::string_view str, struct iovec* iov) { iov->iov_base = const_cast<char*>(str.data()); iov->iov_len = static_cast<size_t>(str.size()); } @@ -1683,12 +1787,12 @@ StreamType DetermineStreamType(QuicStreamId id, // Utility function that stores message_data in |storage| and returns a // QuicMemSliceSpan. QuicMemSliceSpan MakeSpan(QuicBufferAllocator* allocator, - quiche::QuicheStringPiece message_data, + absl::string_view message_data, QuicMemSliceStorage* storage); // Creates a MemSlice using a singleton trivial buffer allocator. Performs a // copy. -QuicMemSlice MemSliceFromString(quiche::QuicheStringPiece data); +QuicMemSlice MemSliceFromString(absl::string_view data); // Used to compare ReceivedPacketInfo. MATCHER_P(ReceivedPacketInfoEquals, info, "") { @@ -1754,27 +1858,27 @@ class TaggingEncrypter : public QuicEncrypter { ~TaggingEncrypter() override {} // QuicEncrypter interface. - bool SetKey(quiche::QuicheStringPiece /*key*/) override { return true; } + bool SetKey(absl::string_view /*key*/) override { return true; } - bool SetNoncePrefix(quiche::QuicheStringPiece /*nonce_prefix*/) override { + bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override { return true; } - bool SetIV(quiche::QuicheStringPiece /*iv*/) override { return true; } + bool SetIV(absl::string_view /*iv*/) override { return true; } - bool SetHeaderProtectionKey(quiche::QuicheStringPiece /*key*/) override { + bool SetHeaderProtectionKey(absl::string_view /*key*/) override { return true; } bool EncryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece plaintext, + absl::string_view associated_data, + absl::string_view plaintext, char* output, size_t* output_length, size_t max_output_length) override; std::string GenerateHeaderProtectionMask( - quiche::QuicheStringPiece /*sample*/) override { + absl::string_view /*sample*/) override { return std::string(5, 0); } @@ -1790,12 +1894,14 @@ class TaggingEncrypter : public QuicEncrypter { return plaintext_size + kTagSize; } - quiche::QuicheStringPiece GetKey() const override { - return quiche::QuicheStringPiece(); + QuicPacketCount GetConfidentialityLimit() const override { + return std::numeric_limits<QuicPacketCount>::max(); } - quiche::QuicheStringPiece GetNoncePrefix() const override { - return quiche::QuicheStringPiece(); + absl::string_view GetKey() const override { return absl::string_view(); } + + absl::string_view GetNoncePrefix() const override { + return absl::string_view(); } private: @@ -1813,19 +1919,19 @@ class TaggingDecrypter : public QuicDecrypter { ~TaggingDecrypter() override {} // QuicDecrypter interface - bool SetKey(quiche::QuicheStringPiece /*key*/) override { return true; } + bool SetKey(absl::string_view /*key*/) override { return true; } - bool SetNoncePrefix(quiche::QuicheStringPiece /*nonce_prefix*/) override { + bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override { return true; } - bool SetIV(quiche::QuicheStringPiece /*iv*/) override { return true; } + bool SetIV(absl::string_view /*iv*/) override { return true; } - bool SetHeaderProtectionKey(quiche::QuicheStringPiece /*key*/) override { + bool SetHeaderProtectionKey(absl::string_view /*key*/) override { return true; } - bool SetPreliminaryKey(quiche::QuicheStringPiece /*key*/) override { + bool SetPreliminaryKey(absl::string_view /*key*/) override { QUIC_BUG << "should not be called"; return false; } @@ -1835,8 +1941,8 @@ class TaggingDecrypter : public QuicDecrypter { } bool DecryptPacket(uint64_t packet_number, - quiche::QuicheStringPiece associated_data, - quiche::QuicheStringPiece ciphertext, + absl::string_view associated_data, + absl::string_view ciphertext, char* output, size_t* output_length, size_t max_output_length) override; @@ -1849,17 +1955,18 @@ class TaggingDecrypter : public QuicDecrypter { size_t GetKeySize() const override { return 0; } size_t GetNoncePrefixSize() const override { return 0; } size_t GetIVSize() const override { return 0; } - quiche::QuicheStringPiece GetKey() const override { - return quiche::QuicheStringPiece(); - } - quiche::QuicheStringPiece GetNoncePrefix() const override { - return quiche::QuicheStringPiece(); + absl::string_view GetKey() const override { return absl::string_view(); } + absl::string_view GetNoncePrefix() const override { + return absl::string_view(); } // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. uint32_t cipher_id() const override { return 0xFFFFFFF0; } + QuicPacketCount GetIntegrityLimit() const override { + return std::numeric_limits<QuicPacketCount>::max(); + } protected: - virtual uint8_t GetTag(quiche::QuicheStringPiece ciphertext) { + virtual uint8_t GetTag(absl::string_view ciphertext) { return ciphertext.data()[ciphertext.size() - 1]; } @@ -1868,12 +1975,29 @@ class TaggingDecrypter : public QuicDecrypter { kTagSize = 12, }; - bool CheckTag(quiche::QuicheStringPiece ciphertext, uint8_t tag); + bool CheckTag(absl::string_view ciphertext, uint8_t tag); +}; + +// StringTaggingDecrypter ensures that the final kTagSize bytes of the message +// match the expected value. +class StrictTaggingDecrypter : public TaggingDecrypter { + public: + explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {} + ~StrictTaggingDecrypter() override {} + + // TaggingQuicDecrypter + uint8_t GetTag(absl::string_view /*ciphertext*/) override { return tag_; } + + // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. + uint32_t cipher_id() const override { return 0xFFFFFFF1; } + + private: + const uint8_t tag_; }; class TestPacketWriter : public QuicPacketWriter { struct PacketBuffer { - QUIC_CACHELINE_ALIGNED char buffer[1500]; + ABSL_CACHELINE_ALIGNED char buffer[1500]; bool in_use = false; }; @@ -2049,6 +2173,10 @@ class TestPacketWriter : public QuicPacketWriter { SimpleQuicFramer* framer() { return &framer_; } + const QuicIpAddress& last_write_source_address() const { + return last_write_source_address_; + } + const QuicSocketAddress& last_write_peer_address() const { return last_write_peer_address_; } @@ -2092,10 +2220,40 @@ class TestPacketWriter : public QuicPacketWriter { QuicHashMap<char*, PacketBuffer*> packet_buffer_pool_index_; // Indices in packet_buffer_pool_ that are not allocated. std::list<PacketBuffer*> packet_buffer_free_list_; - // The peer address passed into WritePacket(). + // The soruce/peer address passed into WritePacket(). + QuicIpAddress last_write_source_address_; QuicSocketAddress last_write_peer_address_; }; +// Parses a packet generated by +// QuicFramer::WriteClientVersionNegotiationProbePacket. +// |packet_bytes| must point to |packet_length| bytes in memory which represent +// the packet. This method will fill in |destination_connection_id_bytes| +// which must point to at least |*destination_connection_id_length_out| bytes in +// memory. |*destination_connection_id_length_out| will contain the length of +// the received destination connection ID, which on success will match the +// contents of the destination connection ID passed in to +// WriteClientVersionNegotiationProbePacket. +bool ParseClientVersionNegotiationProbePacket( + const char* packet_bytes, + size_t packet_length, + char* destination_connection_id_bytes, + uint8_t* destination_connection_id_length_out); + +// Writes an array of bytes that correspond to a QUIC version negotiation packet +// that a QUIC server would send in response to a probe created by +// QuicFramer::WriteClientVersionNegotiationProbePacket. +// The bytes will be written to |packet_bytes|, which must point to +// |*packet_length_out| bytes of memory. |*packet_length_out| will contain the +// length of the created packet. |source_connection_id_bytes| will be sent as +// the source connection ID, and must point to |source_connection_id_length| +// bytes of memory. +bool WriteServerVersionNegotiationProbeResponse( + char* packet_bytes, + size_t* packet_length_out, + const char* source_connection_id_bytes, + uint8_t source_connection_id_length); + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h index 50db80aec5d..ba0cc39f924 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h @@ -17,10 +17,7 @@ class MockClientVisitor : public QuicTransportClientSession::ClientVisitor { MOCK_METHOD(void, OnSessionReady, (), (override)); MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override)); MOCK_METHOD(void, OnIncomingUnidirectionalStreamAvailable, (), (override)); - MOCK_METHOD(void, - OnDatagramReceived, - (quiche::QuicheStringPiece), - (override)); + MOCK_METHOD(void, OnDatagramReceived, (absl::string_view), (override)); MOCK_METHOD(void, OnCanCreateNewOutgoingBidirectionalStream, (), (override)); MOCK_METHOD(void, OnCanCreateNewOutgoingUnidirectionalStream, (), (override)); }; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc index 1ecc65f2480..fa3408c0bb7 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.cc @@ -20,5 +20,11 @@ void QuicUnackedPacketMapPeer::SetPerspective( *const_cast<Perspective*>(&unacked_packets->perspective_) = perspective; } +// static +size_t QuicUnackedPacketMapPeer::GetCapacity( + const QuicUnackedPacketMap& unacked_packets) { + return unacked_packets.unacked_packets_.capacity(); +} + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h index 3bba0b6ced4..17c88fe93bb 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_unacked_packet_map_peer.h @@ -17,6 +17,8 @@ class QuicUnackedPacketMapPeer { static void SetPerspective(QuicUnackedPacketMap* unacked_packets, Perspective perspective); + + static size_t GetCapacity(const QuicUnackedPacketMap& unacked_packets); }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc index 0d5fa5b37a6..619051d4e7d 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.cc @@ -6,11 +6,11 @@ #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,7 +36,7 @@ void SimpleDataProducer::SaveStreamData(QuicStreamId id, void SimpleDataProducer::SaveCryptoData(EncryptionLevel level, QuicStreamOffset offset, - quiche::QuicheStringPiece data) { + absl::string_view data) { auto key = std::make_pair(level, offset); crypto_buffer_map_[key] = data; } @@ -65,7 +65,7 @@ bool SimpleDataProducer::WriteCryptoData(EncryptionLevel level, return false; } return writer->WriteStringPiece( - quiche::QuicheStringPiece(it->second.data(), data_length)); + absl::string_view(it->second.data(), data_length)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h index 626d1e991ea..4904dd35a41 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_data_producer.h @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_ #define QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h" #include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,7 +36,7 @@ class SimpleDataProducer : public QuicStreamFrameDataProducer { void SaveCryptoData(EncryptionLevel level, QuicStreamOffset offset, - quiche::QuicheStringPiece data); + absl::string_view data); // QuicStreamFrameDataProducer WriteStreamDataResult WriteStreamData(QuicStreamId id, @@ -63,7 +63,7 @@ class SimpleDataProducer : public QuicStreamFrameDataProducer { using CryptoBufferMap = QuicHashMap<std::pair<EncryptionLevel, QuicStreamOffset>, - quiche::QuicheStringPiece, + absl::string_view, PairHash>; SimpleBufferAllocator allocator_; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc index 8ec56dc9ed8..ccce52b9eba 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc @@ -7,10 +7,10 @@ #include <memory> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace test { @@ -41,10 +41,9 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { void OnRetryPacket(QuicConnectionId /*original_connection_id*/, QuicConnectionId /*new_connection_id*/, - quiche::QuicheStringPiece /*retry_token*/, - quiche::QuicheStringPiece /*retry_integrity_tag*/, - quiche::QuicheStringPiece /*retry_without_tag*/) override { - } + absl::string_view /*retry_token*/, + absl::string_view /*retry_integrity_tag*/, + absl::string_view /*retry_without_tag*/) override {} bool OnUnauthenticatedPublicHeader( const QuicPacketHeader& /*header*/) override { @@ -78,7 +77,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { // TODO(ianswett): A pointer isn't necessary with emplace_back. stream_frames_.push_back(std::make_unique<QuicStreamFrame>( frame.stream_id, frame.fin, frame.offset, - quiche::QuicheStringPiece(*string_data))); + absl::string_view(*string_data))); return true; } @@ -88,7 +87,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { new std::string(frame.data_buffer, frame.data_length); crypto_data_.push_back(QuicWrapUnique(string_data)); crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>( - frame.level, frame.offset, quiche::QuicheStringPiece(*string_data))); + frame.level, frame.offset, absl::string_view(*string_data))); return true; } @@ -221,6 +220,16 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { std::make_unique<QuicIetfStatelessResetPacket>(packet); } + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} + void OnDecryptedFirstPacketInKeyPhase() override {} + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + return nullptr; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } + const QuicPacketHeader& header() const { return header_; } const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; } const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const { diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h index 6c3c6b0ef17..f9a75607911 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.h @@ -55,7 +55,7 @@ class Queue : public Actor, public UnconstrainedPortInterface { QuicTime::Delta aggregation_timeout); private: - typedef uint64_t AggregationBundleNumber; + using AggregationBundleNumber = uint64_t; // In order to implement packet aggregation, each packet is tagged with a // bundle number. The queue keeps a bundle counter, and whenever a bundle is diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc index 0f04427522c..c02ac7e83b6 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc @@ -34,10 +34,9 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator, wrong_data_received_(false), notifier_(nullptr) { connection_ = std::make_unique<QuicConnection>( - connection_id, GetAddressFromName(peer_name), simulator, - simulator->GetAlarmFactory(), &writer_, false, perspective, + connection_id, GetAddressFromName(name), GetAddressFromName(peer_name), + simulator, simulator->GetAlarmFactory(), &writer_, false, perspective, ParsedVersionOfIndex(CurrentSupportedVersions(), 0)); - connection_->SetSelfAddress(GetAddressFromName(name)); connection_->set_visitor(this); connection_->SetEncrypter(ENCRYPTION_FORWARD_SECURE, std::make_unique<NullEncrypter>(perspective)); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h index ff9b680f58f..681cd33c93d 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h @@ -5,6 +5,7 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_ #define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" @@ -17,7 +18,6 @@ #include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/queue.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { namespace simulator { @@ -64,7 +64,7 @@ class QuicEndpoint : public QuicEndpointBase, void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {} void OnRstStream(const QuicRstStreamFrame& /*frame*/) override {} void OnGoAway(const QuicGoAwayFrame& /*frame*/) override {} - void OnMessageReceived(quiche::QuicheStringPiece /*message*/) override {} + void OnMessageReceived(absl::string_view /*message*/) override {} void OnHandshakeDoneReceived() override {} void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/, ConnectionCloseSource /*source*/) override {} @@ -80,6 +80,7 @@ class QuicEndpoint : public QuicEndpointBase, void OnForwardProgressMadeAfterPathDegrading() override {} void OnAckNeedsRetransmittableFrame() override {} void SendPing() override {} + void SendAckFrequency(const QuicAckFrequencyFrame& /*frame*/) override {} bool AllowSelfAddressChange() const override; HandshakeState GetHandshakeState() const override; bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override { @@ -93,6 +94,15 @@ class QuicEndpoint : public QuicEndpointBase, void OnPacketDecrypted(EncryptionLevel /*level*/) override {} void OnOneRttPacketAcknowledged() override {} void OnHandshakePacketSent() override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + return nullptr; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + return nullptr; + } + void BeforeConnectionCloseSent() override {} // End QuicConnectionVisitorInterface implementation. diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h index 3e4cc205bd7..750b24b93f3 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/switch.h @@ -13,7 +13,7 @@ namespace quic { namespace simulator { -typedef size_t SwitchPortNumber; +using SwitchPortNumber = size_t; // Simulates a network switch with simple persistent learning scheme and queues // on every output port. diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc index 025a81608e7..acbea922274 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc @@ -8,7 +8,7 @@ namespace quic { namespace test { // A test certificate generated by //net/tools/quic/certs/generate-certs.sh. -QUIC_CONST_INIT const char kTestCertificateRaw[] = { +ABSL_CONST_INIT const char kTestCertificateRaw[] = { '\x30', '\x82', '\x03', '\xb4', '\x30', '\x82', '\x02', '\x9c', '\xa0', '\x03', '\x02', '\x01', '\x02', '\x02', '\x01', '\x01', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', @@ -116,11 +116,11 @@ QUIC_CONST_INIT const char kTestCertificateRaw[] = { '\xd3', '\xfb', '\xba', '\xaf', '\xd9', '\x61', '\x14', '\x3c', '\xe0', '\xa1', '\xa9', '\x51', '\x51', '\x0f', '\xad', '\x60'}; -QUIC_CONST_INIT const quiche::QuicheStringPiece kTestCertificate( +ABSL_CONST_INIT const absl::string_view kTestCertificate( kTestCertificateRaw, sizeof(kTestCertificateRaw)); -QUIC_CONST_INIT const char kTestCertificatePem[] = +ABSL_CONST_INIT const char kTestCertificatePem[] = R"(Certificate: Data: Version: 3 (0x2) @@ -206,7 +206,7 @@ iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA== -----END CERTIFICATE-----)"; // Same leaf as above, but with an intermediary attached. -QUIC_CONST_INIT const char kTestCertificateChainPem[] = +ABSL_CONST_INIT const char kTestCertificateChainPem[] = R"(-----BEGIN CERTIFICATE----- MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow @@ -249,7 +249,7 @@ hTXMooR/wD7an6gtnXD8ixCh7bP0TyPiBhNsUb12WrvSEAm/UyciQbQlR7P+K0Z7 Cmn1Mj4hQ+pT0t+pw/DMOw== -----END CERTIFICATE-----)"; -QUIC_CONST_INIT const char kTestCertWithUnknownSanTypePem[] = +ABSL_CONST_INIT const char kTestCertWithUnknownSanTypePem[] = R"(-----BEGIN CERTIFICATE----- MIIEYTCCA0mgAwIBAgIJAILStmLgUUcVMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp @@ -277,7 +277,7 @@ FmKuuGZamCCj6F1QF2IjMVM8evl84hEnN0ajdkA/QWnil9kcWvBm15Ho+oTvvJ7s M8MD3RDSq/90FSiME4vbyNEyTmj0 -----END CERTIFICATE-----)"; -QUIC_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = { +ABSL_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = { '\x30', '\x82', '\x04', '\xbc', '\x02', '\x01', '\x00', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa6', '\x30', @@ -415,11 +415,11 @@ QUIC_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = { '\x3e', '\x6b', '\x2e', '\xfa', '\x4f', '\x4d', '\xe6', '\xbe', '\xd3', '\x59'}; -QUIC_CONST_INIT const quiche::QuicheStringPiece kTestCertificatePrivateKey( +ABSL_CONST_INIT const absl::string_view kTestCertificatePrivateKey( kTestCertificatePrivateKeyRaw, sizeof(kTestCertificatePrivateKeyRaw)); -QUIC_CONST_INIT const char kTestCertificatePrivateKeyPem[] = +ABSL_CONST_INIT const char kTestCertificatePrivateKeyPem[] = R"(-----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDF4lFtP9Yo8q00 c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO @@ -450,7 +450,7 @@ K6WjyPfTPmsu+k9N5r7TWQ== -----END PRIVATE KEY-----)"; // The legacy version was manually generated from the one above using der2ascii. -QUIC_CONST_INIT const char kTestCertificatePrivateKeyLegacyPem[] = +ABSL_CONST_INIT const char kTestCertificatePrivateKeyLegacyPem[] = R"(-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAxeJRbT/WKPKtNHOHZMozGTO3dZGrMRkr46QmCSmLLfdSdadVFfARx8LE7Rgb MwtxMuY1ic0tWgVXTsJ4dWVyLYoXg9YykIX4IuJlqeCg/hmyOS0UAxAvzIteqiUnDaM3EAwX7PCL @@ -475,7 +475,7 @@ DtM+YIvvZU1YJToItSG2YQz68Gl4Tmg220FLUNjTjj10gI6g5trscIl3sp3WbgrEvfaaBxW6VZ/U TToPURKk2cKYdsW3KUDK9Lt0LXEDTecFdcCNln5ZoYs7oyulo8j30z5rLvpPTea+01k= -----END RSA PRIVATE KEY-----)"; -QUIC_CONST_INIT const char kWildcardCertificateRaw[] = { +ABSL_CONST_INIT const char kWildcardCertificateRaw[] = { '\x30', '\x82', '\x03', '\x5f', '\x30', '\x82', '\x02', '\x47', '\xa0', '\x03', '\x02', '\x01', '\x02', '\x02', '\x14', '\x36', '\x1d', '\xe3', '\xd2', '\x39', '\x35', '\x20', '\xb1', '\xae', '\x18', '\xdd', '\x71', @@ -574,11 +574,11 @@ QUIC_CONST_INIT const char kWildcardCertificateRaw[] = { '\xf0', '\xb7', '\xbb', '\x58', '\x4c', '\x8f', '\x6a', '\x5d', '\x8e', '\x93', '\x5f', '\x35'}; -QUIC_CONST_INIT const quiche::QuicheStringPiece kWildcardCertificate( +ABSL_CONST_INIT const absl::string_view kWildcardCertificate( kWildcardCertificateRaw, sizeof(kWildcardCertificateRaw)); -QUIC_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = { +ABSL_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = { '\x30', '\x82', '\x04', '\xbe', '\x02', '\x01', '\x00', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa8', '\x30', @@ -716,11 +716,11 @@ QUIC_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = { '\x47', '\xca', '\x21', '\x30', '\x65', '\xa4', '\xe5', '\xaa', '\x4e', '\x9c', '\xbc', '\xa5'}; -QUIC_CONST_INIT const quiche::QuicheStringPiece kWildcardCertificatePrivateKey( +ABSL_CONST_INIT const absl::string_view kWildcardCertificatePrivateKey( kWildcardCertificatePrivateKeyRaw, sizeof(kWildcardCertificatePrivateKeyRaw)); -QUIC_CONST_INIT const char kTestEcPrivateKeyLegacyPem[] = +ABSL_CONST_INIT const char kTestEcPrivateKeyLegacyPem[] = R"(-----BEGIN EC PARAMETERS----- BggqhkjOPQMBBw== -----END EC PARAMETERS----- diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h index f6179419d35..6a7eba768f1 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h @@ -5,46 +5,44 @@ #ifndef QUICHE_QUIC_TEST_TOOLS_TEST_CERTIFICATES_H_ #define QUICHE_QUIC_TEST_TOOLS_TEST_CERTIFICATES_H_ -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" namespace quic { namespace test { // A test certificate generated by //net/tools/quic/certs/generate-certs.sh. -QUIC_CONST_INIT extern const quiche::QuicheStringPiece kTestCertificate; +ABSL_CONST_INIT extern const absl::string_view kTestCertificate; // PEM-encoded version of |kTestCertificate|. -QUIC_CONST_INIT extern const char kTestCertificatePem[]; +ABSL_CONST_INIT extern const char kTestCertificatePem[]; // |kTestCertificatePem| with a PEM-encoded root appended to the end. -QUIC_CONST_INIT extern const char kTestCertificateChainPem[]; +ABSL_CONST_INIT extern const char kTestCertificateChainPem[]; // PEM-encoded certificate that contains a subjectAltName with an // unknown/unsupported type. -QUIC_CONST_INIT extern const char kTestCertWithUnknownSanTypePem[]; +ABSL_CONST_INIT extern const char kTestCertWithUnknownSanTypePem[]; // DER-encoded private key for |kTestCertificate|. -QUIC_CONST_INIT extern const quiche::QuicheStringPiece - kTestCertificatePrivateKey; +ABSL_CONST_INIT extern const absl::string_view kTestCertificatePrivateKey; // PEM-encoded version of |kTestCertificatePrivateKey|. -QUIC_CONST_INIT extern const char kTestCertificatePrivateKeyPem[]; +ABSL_CONST_INIT extern const char kTestCertificatePrivateKeyPem[]; // The legacy PEM-encoded version of |kTestCertificatePrivateKey| manually // generated from the one above using der2ascii. -QUIC_CONST_INIT extern const char kTestCertificatePrivateKeyLegacyPem[]; +ABSL_CONST_INIT extern const char kTestCertificatePrivateKeyLegacyPem[]; // Another DER-encoded test certificate, valid for foo.test, www.foo.test and // *.wildcard.test. -QUIC_CONST_INIT extern const quiche::QuicheStringPiece kWildcardCertificate; +ABSL_CONST_INIT extern const absl::string_view kWildcardCertificate; // DER-encoded private key for |kWildcardCertificate|. -QUIC_CONST_INIT extern const quiche::QuicheStringPiece - kWildcardCertificatePrivateKey; +ABSL_CONST_INIT extern const absl::string_view kWildcardCertificatePrivateKey; // PEM-encoded P-256 private key using legacy OpenSSL encoding. -QUIC_CONST_INIT extern const char kTestEcPrivateKeyLegacyPem[]; +ABSL_CONST_INIT extern const char kTestEcPrivateKeyLegacyPem[]; } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc index 4d0d93e8f17..40f28d2c125 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.cc @@ -6,7 +6,8 @@ #include <cstring> -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "absl/base/macros.h" +#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" namespace quic { namespace test { @@ -25,29 +26,36 @@ constexpr char kTicketPrefix[] = "TEST TICKET"; } // namespace +TestTicketCrypter::TestTicketCrypter() + : ticket_prefix_(ABSL_ARRAYSIZE(kTicketPrefix) + 16) { + memcpy(ticket_prefix_.data(), kTicketPrefix, ABSL_ARRAYSIZE(kTicketPrefix)); + QuicRandom::GetInstance()->RandBytes( + ticket_prefix_.data() + ABSL_ARRAYSIZE(kTicketPrefix), 16); +} + size_t TestTicketCrypter::MaxOverhead() { - return QUICHE_ARRAYSIZE(kTicketPrefix); + return ticket_prefix_.size(); } -std::vector<uint8_t> TestTicketCrypter::Encrypt(quiche::QuicheStringPiece in) { - size_t prefix_len = QUICHE_ARRAYSIZE(kTicketPrefix); +std::vector<uint8_t> TestTicketCrypter::Encrypt(absl::string_view in) { + size_t prefix_len = ticket_prefix_.size(); std::vector<uint8_t> out(prefix_len + in.size()); - memcpy(out.data(), kTicketPrefix, prefix_len); + memcpy(out.data(), ticket_prefix_.data(), prefix_len); memcpy(out.data() + prefix_len, in.data(), in.size()); return out; } -std::vector<uint8_t> TestTicketCrypter::Decrypt(quiche::QuicheStringPiece in) { - size_t prefix_len = QUICHE_ARRAYSIZE(kTicketPrefix); +std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) { + size_t prefix_len = ticket_prefix_.size(); if (fail_decrypt_ || in.size() < prefix_len || - memcmp(kTicketPrefix, in.data(), prefix_len) != 0) { + memcmp(ticket_prefix_.data(), in.data(), prefix_len) != 0) { return std::vector<uint8_t>(); } return std::vector<uint8_t>(in.begin() + prefix_len, in.end()); } void TestTicketCrypter::Decrypt( - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<ProofSource::DecryptCallback> callback) { auto decrypted_ticket = Decrypt(in); if (run_async_) { diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h index b59634856c0..5785463b604 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/test_ticket_crypter.h @@ -14,12 +14,13 @@ namespace test { // THIS IMPLEMENTATION IS NOT SECURE. It is only intended for testing purposes. class TestTicketCrypter : public ProofSource::TicketCrypter { public: + TestTicketCrypter(); ~TestTicketCrypter() override = default; // TicketCrypter interface size_t MaxOverhead() override; - std::vector<uint8_t> Encrypt(quiche::QuicheStringPiece in) override; - void Decrypt(quiche::QuicheStringPiece in, + std::vector<uint8_t> Encrypt(absl::string_view in) override; + void Decrypt(absl::string_view in, std::unique_ptr<ProofSource::DecryptCallback> callback) override; void SetRunCallbacksAsync(bool run_async); @@ -31,7 +32,7 @@ class TestTicketCrypter : public ProofSource::TicketCrypter { private: // Performs the Decrypt operation synchronously. - std::vector<uint8_t> Decrypt(quiche::QuicheStringPiece in); + std::vector<uint8_t> Decrypt(absl::string_view in); struct PendingCallback { std::unique_ptr<ProofSource::DecryptCallback> callback; @@ -41,6 +42,7 @@ class TestTicketCrypter : public ProofSource::TicketCrypter { bool fail_decrypt_ = false; bool run_async_ = false; std::vector<PendingCallback> pending_callbacks_; + std::vector<uint8_t> ticket_prefix_; }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h b/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h index 7f4a38ea5ec..87078798edf 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h +++ b/chromium/net/third_party/quiche/src/quic/tools/fake_proof_verifier.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_ #define QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -19,7 +19,7 @@ class FakeProofVerifier : public ProofVerifier { const uint16_t /*port*/, const std::string& /*server_config*/, QuicTransportVersion /*quic_version*/, - quiche::QuicheStringPiece /*chlo_hash*/, + absl::string_view /*chlo_hash*/, const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/, const std::string& /*signature*/, @@ -38,6 +38,7 @@ class FakeProofVerifier : public ProofVerifier { const ProofVerifyContext* /*context*/, std::string* /*error_details*/, std::unique_ptr<ProofVerifyDetails>* /*details*/, + uint8_t* /*out_alert*/, std::unique_ptr<ProofVerifierCallback> /*callback*/) override { return QUIC_SUCCESS; } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc index 7900683913d..defa9bfec02 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.cc @@ -8,7 +8,7 @@ namespace quic { QuicBackendResponse::ServerPushInfo::ServerPushInfo( QuicUrl request_url, - spdy::SpdyHeaderBlock headers, + spdy::Http2HeaderBlock headers, spdy::SpdyPriority priority, std::string body) : request_url(request_url), diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h index af6cf84ee0c..9209038f4b3 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_backend_response.h @@ -5,8 +5,8 @@ #ifndef QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_ #define QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/tools/quic_url.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" namespace quic { @@ -19,13 +19,13 @@ class QuicBackendResponse { // comprising a response for the push request. struct ServerPushInfo { ServerPushInfo(QuicUrl request_url, - spdy::SpdyHeaderBlock headers, + spdy::Http2HeaderBlock headers, spdy::SpdyPriority priority, std::string body); ServerPushInfo(const ServerPushInfo& other); QuicUrl request_url; - spdy::SpdyHeaderBlock headers; + spdy::Http2HeaderBlock headers; spdy::SpdyPriority priority; std::string body; }; @@ -51,30 +51,28 @@ class QuicBackendResponse { ~QuicBackendResponse(); SpecialResponseType response_type() const { return response_type_; } - const spdy::SpdyHeaderBlock& headers() const { return headers_; } - const spdy::SpdyHeaderBlock& trailers() const { return trailers_; } - const quiche::QuicheStringPiece body() const { - return quiche::QuicheStringPiece(body_); - } + const spdy::Http2HeaderBlock& headers() const { return headers_; } + const spdy::Http2HeaderBlock& trailers() const { return trailers_; } + const absl::string_view body() const { return absl::string_view(body_); } void set_response_type(SpecialResponseType response_type) { response_type_ = response_type; } - void set_headers(spdy::SpdyHeaderBlock headers) { + void set_headers(spdy::Http2HeaderBlock headers) { headers_ = std::move(headers); } - void set_trailers(spdy::SpdyHeaderBlock trailers) { + void set_trailers(spdy::Http2HeaderBlock trailers) { trailers_ = std::move(trailers); } - void set_body(quiche::QuicheStringPiece body) { + void set_body(absl::string_view body) { body_.assign(body.data(), body.size()); } private: SpecialResponseType response_type_; - spdy::SpdyHeaderBlock headers_; - spdy::SpdyHeaderBlock trailers_; + spdy::Http2HeaderBlock headers_; + spdy::Http2HeaderBlock trailers_; std::string body_; }; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc index c1d2ea2103c..5d89797f8c9 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc @@ -121,8 +121,8 @@ void QuicClientBase::StartConnect() { session_ = CreateQuicClientSession( client_supported_versions, - new QuicConnection(GetNextConnectionId(), server_address(), helper(), - alarm_factory(), writer, + new QuicConnection(GetNextConnectionId(), QuicSocketAddress(), + server_address(), helper(), alarm_factory(), writer, /* owns_writer= */ false, Perspective::IS_CLIENT, client_supported_versions)); if (connection_debug_visitor_ != nullptr) { diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h index 4df3a2bb927..ce2444ce925 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h @@ -10,14 +10,14 @@ #include <string> +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h" #include "net/third_party/quiche/src/quic/core/quic_config.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -104,12 +104,12 @@ class QuicClientBase { // Wait for 1-RTT keys become available. // Returns true once 1-RTT keys are available, false otherwise. - QUIC_MUST_USE_RESULT bool WaitForOneRttKeysAvailable(); + ABSL_MUST_USE_RESULT bool WaitForOneRttKeysAvailable(); // Wait for handshake state proceeds to HANDSHAKE_CONFIRMED. // In QUIC crypto, this does the same as WaitForOneRttKeysAvailable, while in // TLS, this waits for HANDSHAKE_DONE frame is received. - QUIC_MUST_USE_RESULT bool WaitForHandshakeConfirmed(); + ABSL_MUST_USE_RESULT bool WaitForHandshakeConfirmed(); // Wait up to 50ms, and handle any events which occur. // Returns true if there are any outstanding requests. @@ -227,7 +227,7 @@ class QuicClientBase { bool initialized() const { return initialized_; } - void SetPreSharedKey(quiche::QuicheStringPiece key) { + void SetPreSharedKey(absl::string_view key) { crypto_config_.set_pre_shared_key(key); } 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 80dfd3b2139..e16afe686cf 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 @@ -52,6 +52,8 @@ enum class Feature { // Second row of features (anything else protocol-related) // We switched to a different port and the server migrated to it. kRebinding, + // One endpoint can update keys and its peer responds correctly. + kKeyUpdate, // Third row of features (H3 tests) // An H3 transaction succeeded. @@ -81,6 +83,8 @@ char MatrixLetter(Feature f) { return 'Q'; case Feature::kRebinding: return 'B'; + case Feature::kKeyUpdate: + return 'U'; case Feature::kHttp3: return '3'; case Feature::kDynamicEntryReferenced: @@ -107,15 +111,16 @@ class QuicClientInteropRunner : QuicConnectionDebugVisitor { ParsedQuicVersion version, bool test_version_negotiation, bool attempt_rebind, - bool attempt_multi_packet_chlo); + bool attempt_multi_packet_chlo, + bool attempt_key_update); // Constructs a SpdyHeaderBlock containing the pseudo-headers needed to make a // GET request to "/" on the hostname |authority|. - spdy::SpdyHeaderBlock ConstructHeaderBlock(const std::string& authority); + spdy::Http2HeaderBlock ConstructHeaderBlock(const std::string& authority); // Sends an HTTP request represented by |header_block| using |client|. void SendRequest(QuicClient* client, - const spdy::SpdyHeaderBlock& header_block); + const spdy::Http2HeaderBlock& header_block); void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override { switch (frame.close_type) { @@ -165,7 +170,7 @@ void QuicClientInteropRunner::AttemptResumption(QuicClient* client, bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable(); - spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority); + spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority); SendRequest(client, header_block); if (!client->session()->OneRttKeysAvailable()) { @@ -191,7 +196,8 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, ParsedQuicVersion version, bool test_version_negotiation, bool attempt_rebind, - bool attempt_multi_packet_chlo) { + bool attempt_multi_packet_chlo, + bool attempt_key_update) { ParsedQuicVersionVector versions = {version}; if (test_version_negotiation) { versions.insert(versions.begin(), QuicVersionReservedForNegotiation()); @@ -238,7 +244,7 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, // Failed to negotiate version, retry without version negotiation. AttemptRequest(addr, authority, server_id, version, /*test_version_negotiation=*/false, attempt_rebind, - attempt_multi_packet_chlo); + attempt_multi_packet_chlo, attempt_key_update); return; } if (!client->session()->OneRttKeysAvailable()) { @@ -246,7 +252,7 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, // Failed to handshake with multi-packet client hello, retry without it. AttemptRequest(addr, authority, server_id, version, test_version_negotiation, attempt_rebind, - /*attempt_multi_packet_chlo=*/false); + /*attempt_multi_packet_chlo=*/false, attempt_key_update); return; } return; @@ -256,7 +262,7 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, InsertFeature(Feature::kQuantum); } - spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority); + spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority); SendRequest(client.get(), header_block); if (!client->connected()) { @@ -278,7 +284,7 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, // Rebinding does not work, retry without attempting it. AttemptRequest(addr, authority, server_id, version, test_version_negotiation, /*attempt_rebind=*/false, - attempt_multi_packet_chlo); + attempt_multi_packet_chlo, attempt_key_update); return; } InsertFeature(Feature::kRebinding); @@ -290,6 +296,28 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, QUIC_LOG(ERROR) << "Failed to change ephemeral port"; } } + + if (attempt_key_update) { + if (connection->IsKeyUpdateAllowed()) { + if (connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForInteropRunner)) { + client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true); + if (!client->connected()) { + // Key update does not work, retry without attempting it. + AttemptRequest(addr, authority, server_id, version, + test_version_negotiation, attempt_rebind, + attempt_multi_packet_chlo, + /*attempt_key_update=*/false); + return; + } + InsertFeature(Feature::kKeyUpdate); + } else { + QUIC_LOG(ERROR) << "Failed to initiate key update"; + } + } else { + QUIC_LOG(ERROR) << "Key update not allowed"; + } + } } if (connection->connected()) { @@ -302,10 +330,10 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr, AttemptResumption(client.get(), authority); } -spdy::SpdyHeaderBlock QuicClientInteropRunner::ConstructHeaderBlock( +spdy::Http2HeaderBlock QuicClientInteropRunner::ConstructHeaderBlock( const std::string& authority) { // Construct and send a request. - spdy::SpdyHeaderBlock header_block; + spdy::Http2HeaderBlock header_block; header_block[":method"] = "GET"; header_block[":scheme"] = "https"; header_block[":authority"] = authority; @@ -315,7 +343,7 @@ spdy::SpdyHeaderBlock QuicClientInteropRunner::ConstructHeaderBlock( void QuicClientInteropRunner::SendRequest( QuicClient* client, - const spdy::SpdyHeaderBlock& header_block) { + const spdy::Http2HeaderBlock& header_block) { client->set_store_response(true); client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true); @@ -368,7 +396,8 @@ std::set<Feature> ServerSupport(std::string dns_host, runner.AttemptRequest(addr, authority, server_id, version, /*test_version_negotiation=*/true, /*attempt_rebind=*/true, - /*attempt_multi_packet_chlo=*/true); + /*attempt_multi_packet_chlo=*/true, + /*attempt_key_update=*/true); return runner.features(); } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc index b1923b67c7c..034c4dda6ca 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_client_test.cc @@ -10,13 +10,14 @@ #include <memory> #include <utility> +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h" #include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_client_peer.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace quic { @@ -40,13 +41,13 @@ size_t NumOpenSocketFDs() { std::unique_ptr<DIR, int (*)(DIR*)> fd_directory(opendir(kPathToFds), closedir); while ((file = readdir(fd_directory.get())) != nullptr) { - quiche::QuicheStringPiece name(file->d_name); + absl::string_view name(file->d_name); if (name == "." || name == "..") { continue; } std::string fd_path = ReadLink(quiche::QuicheStrCat(kPathToFds, "/", name)); - if (quiche::QuicheTextUtils::StartsWith(fd_path, "socket:")) { + if (absl::StartsWith(fd_path, "socket:")) { socket_count++; } } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc index 370eb4aaedb..465e0a9f8bc 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.cc @@ -6,16 +6,18 @@ #include <utility> +#include "absl/strings/match.h" +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_file_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" +using spdy::Http2HeaderBlock; using spdy::kV3LowestPriority; -using spdy::SpdyHeaderBlock; namespace quic { @@ -40,7 +42,7 @@ void QuicMemoryCacheBackend::ResourceFile::Read() { if (file_contents_[pos - 1] == '\r') { len -= 1; } - quiche::QuicheStringPiece line(file_contents_.data() + start, len); + absl::string_view line(file_contents_.data() + start, len); start = pos + 1; // Headers end with an empty line. if (line.empty()) { @@ -83,30 +85,29 @@ void QuicMemoryCacheBackend::ResourceFile::Read() { // stuff as described in https://w3c.github.io/preload/. it = spdy_headers_.find("x-push-url"); if (it != spdy_headers_.end()) { - quiche::QuicheStringPiece push_urls = it->second; + absl::string_view push_urls = it->second; size_t start = 0; while (start < push_urls.length()) { size_t pos = push_urls.find('\0', start); if (pos == std::string::npos) { - push_urls_.push_back(quiche::QuicheStringPiece( - push_urls.data() + start, push_urls.length() - start)); + push_urls_.push_back(absl::string_view(push_urls.data() + start, + push_urls.length() - start)); break; } - push_urls_.push_back( - quiche::QuicheStringPiece(push_urls.data() + start, pos)); + push_urls_.push_back(absl::string_view(push_urls.data() + start, pos)); start += pos + 1; } } - body_ = quiche::QuicheStringPiece(file_contents_.data() + start, - file_contents_.size() - start); + body_ = absl::string_view(file_contents_.data() + start, + file_contents_.size() - start); } void QuicMemoryCacheBackend::ResourceFile::SetHostPathFromBase( - quiche::QuicheStringPiece base) { + absl::string_view base) { DCHECK(base[0] != '/') << base; size_t path_start = base.find_first_of('/'); - if (path_start == quiche::QuicheStringPiece::npos) { + if (path_start == absl::string_view::npos) { host_ = std::string(base); path_ = ""; return; @@ -121,33 +122,32 @@ void QuicMemoryCacheBackend::ResourceFile::SetHostPathFromBase( } } -quiche::QuicheStringPiece QuicMemoryCacheBackend::ResourceFile::RemoveScheme( - quiche::QuicheStringPiece url) { - if (quiche::QuicheTextUtils::StartsWith(url, "https://")) { +absl::string_view QuicMemoryCacheBackend::ResourceFile::RemoveScheme( + absl::string_view url) { + if (absl::StartsWith(url, "https://")) { url.remove_prefix(8); - } else if (quiche::QuicheTextUtils::StartsWith(url, "http://")) { + } else if (absl::StartsWith(url, "http://")) { url.remove_prefix(7); } return url; } void QuicMemoryCacheBackend::ResourceFile::HandleXOriginalUrl() { - quiche::QuicheStringPiece url(x_original_url_); + absl::string_view url(x_original_url_); SetHostPathFromBase(RemoveScheme(url)); } const QuicBackendResponse* QuicMemoryCacheBackend::GetResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path) const { + absl::string_view host, + absl::string_view path) const { QuicWriterMutexLock lock(&response_mutex_); auto it = responses_.find(GetKey(host, path)); if (it == responses_.end()) { uint64_t ignored = 0; if (generate_bytes_response_) { - if (quiche::QuicheTextUtils::StringToUint64( - quiche::QuicheStringPiece(path.data() + 1, path.size() - 1), - &ignored)) { + if (absl::SimpleAtoi(absl::string_view(path.data() + 1, path.size() - 1), + &ignored)) { // The actual parsed length is ignored here and will be recomputed // by the caller. return generate_bytes_response_.get(); @@ -163,14 +163,14 @@ const QuicBackendResponse* QuicMemoryCacheBackend::GetResponse( return it->second.get(); } -typedef QuicBackendResponse::ServerPushInfo ServerPushInfo; -typedef QuicBackendResponse::SpecialResponseType SpecialResponseType; +using ServerPushInfo = QuicBackendResponse::ServerPushInfo; +using SpecialResponseType = QuicBackendResponse::SpecialResponseType; -void QuicMemoryCacheBackend::AddSimpleResponse(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, +void QuicMemoryCacheBackend::AddSimpleResponse(absl::string_view host, + absl::string_view path, int response_code, - quiche::QuicheStringPiece body) { - SpdyHeaderBlock response_headers; + absl::string_view body) { + Http2HeaderBlock response_headers; response_headers[":status"] = quiche::QuicheTextUtils::Uint64ToString(response_code); response_headers["content-length"] = @@ -179,10 +179,10 @@ void QuicMemoryCacheBackend::AddSimpleResponse(quiche::QuicheStringPiece host, } void QuicMemoryCacheBackend::AddSimpleResponseWithServerPushResources( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + absl::string_view host, + absl::string_view path, int response_code, - quiche::QuicheStringPiece body, + absl::string_view body, std::list<ServerPushInfo> push_resources) { AddSimpleResponse(host, path, response_code, body); MaybeAddServerPushResources(host, path, push_resources); @@ -193,43 +193,41 @@ void QuicMemoryCacheBackend::AddDefaultResponse(QuicBackendResponse* response) { default_response_.reset(response); } -void QuicMemoryCacheBackend::AddResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body) { +void QuicMemoryCacheBackend::AddResponse(absl::string_view host, + absl::string_view path, + Http2HeaderBlock response_headers, + absl::string_view response_body) { AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE, std::move(response_headers), response_body, - SpdyHeaderBlock()); + Http2HeaderBlock()); } -void QuicMemoryCacheBackend::AddResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, - SpdyHeaderBlock response_trailers) { +void QuicMemoryCacheBackend::AddResponse(absl::string_view host, + absl::string_view path, + Http2HeaderBlock response_headers, + absl::string_view response_body, + Http2HeaderBlock response_trailers) { AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE, std::move(response_headers), response_body, std::move(response_trailers)); } void QuicMemoryCacheBackend::AddSpecialResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + absl::string_view host, + absl::string_view path, SpecialResponseType response_type) { - AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "", - SpdyHeaderBlock()); + AddResponseImpl(host, path, response_type, Http2HeaderBlock(), "", + Http2HeaderBlock()); } void QuicMemoryCacheBackend::AddSpecialResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, + absl::string_view host, + absl::string_view path, + spdy::Http2HeaderBlock response_headers, + absl::string_view response_body, SpecialResponseType response_type) { AddResponseImpl(host, path, response_type, std::move(response_headers), - response_body, SpdyHeaderBlock()); + response_body, Http2HeaderBlock()); } QuicMemoryCacheBackend::QuicMemoryCacheBackend() : cache_initialized_(false) {} @@ -294,7 +292,7 @@ bool QuicMemoryCacheBackend::InitializeBackend( void QuicMemoryCacheBackend::GenerateDynamicResponses() { QuicWriterMutexLock lock(&response_mutex_); // Add a generate bytes response. - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = "200"; generate_bytes_response_ = std::make_unique<QuicBackendResponse>(); generate_bytes_response_->set_headers(std::move(response_headers)); @@ -307,7 +305,7 @@ bool QuicMemoryCacheBackend::IsBackendInitialized() const { } void QuicMemoryCacheBackend::FetchResponseFromBackend( - const SpdyHeaderBlock& request_headers, + const Http2HeaderBlock& request_headers, const std::string& /*request_body*/, QuicSimpleServerBackend::RequestHandler* quic_stream) { const QuicBackendResponse* quic_response = nullptr; @@ -353,12 +351,12 @@ QuicMemoryCacheBackend::~QuicMemoryCacheBackend() { } void QuicMemoryCacheBackend::AddResponseImpl( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + absl::string_view host, + absl::string_view path, SpecialResponseType response_type, - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, - SpdyHeaderBlock response_trailers) { + Http2HeaderBlock response_headers, + absl::string_view response_body, + Http2HeaderBlock response_trailers) { QuicWriterMutexLock lock(&response_mutex_); DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\""; @@ -376,9 +374,8 @@ void QuicMemoryCacheBackend::AddResponseImpl( responses_[key] = std::move(new_response); } -std::string QuicMemoryCacheBackend::GetKey( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path) const { +std::string QuicMemoryCacheBackend::GetKey(absl::string_view host, + absl::string_view path) const { std::string host_string = std::string(host); size_t port = host_string.find(':'); if (port != std::string::npos) @@ -387,8 +384,8 @@ std::string QuicMemoryCacheBackend::GetKey( } void QuicMemoryCacheBackend::MaybeAddServerPushResources( - quiche::QuicheStringPiece request_host, - quiche::QuicheStringPiece request_path, + absl::string_view request_host, + absl::string_view request_path, std::list<ServerPushInfo> push_resources) { std::string request_url = GetKey(request_host, request_path); @@ -418,7 +415,7 @@ void QuicMemoryCacheBackend::MaybeAddServerPushResources( } if (!found_existing_response) { // Add a server push response to responses map, if it is not in the map. - quiche::QuicheStringPiece body = push_resource.body; + absl::string_view body = push_resource.body; QUIC_DVLOG(1) << "Add response for push resource: host " << host << " path " << path; AddResponse(host, path, push_resource.headers.Clone(), body); 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 1c56ce6355e..e43bf60f823 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 @@ -10,13 +10,13 @@ #include <memory> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" #include "net/third_party/quiche/src/quic/tools/quic_backend_response.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_url.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" namespace quic { @@ -40,32 +40,30 @@ class QuicMemoryCacheBackend : public QuicSimpleServerBackend { void Read(); // |base| is |file_name_| with |cache_directory| prefix stripped. - void SetHostPathFromBase(quiche::QuicheStringPiece base); + void SetHostPathFromBase(absl::string_view base); const std::string& file_name() { return file_name_; } - quiche::QuicheStringPiece host() { return host_; } + absl::string_view host() { return host_; } - quiche::QuicheStringPiece path() { return path_; } + absl::string_view path() { return path_; } - const spdy::SpdyHeaderBlock& spdy_headers() { return spdy_headers_; } + const spdy::Http2HeaderBlock& spdy_headers() { return spdy_headers_; } - quiche::QuicheStringPiece body() { return body_; } + absl::string_view body() { return body_; } - const std::vector<quiche::QuicheStringPiece>& push_urls() { - return push_urls_; - } + const std::vector<absl::string_view>& push_urls() { return push_urls_; } private: void HandleXOriginalUrl(); - quiche::QuicheStringPiece RemoveScheme(quiche::QuicheStringPiece url); + absl::string_view RemoveScheme(absl::string_view url); std::string file_name_; std::string file_contents_; - quiche::QuicheStringPiece body_; - spdy::SpdyHeaderBlock spdy_headers_; - quiche::QuicheStringPiece x_original_url_; - std::vector<quiche::QuicheStringPiece> push_urls_; + absl::string_view body_; + spdy::Http2HeaderBlock spdy_headers_; + absl::string_view x_original_url_; + std::vector<absl::string_view> push_urls_; std::string host_; std::string path_; }; @@ -77,51 +75,51 @@ class QuicMemoryCacheBackend : public QuicSimpleServerBackend { // Retrieve a response from this cache for a given host and path.. // If no appropriate response exists, nullptr is returned. - const QuicBackendResponse* GetResponse(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path) const; + const QuicBackendResponse* GetResponse(absl::string_view host, + absl::string_view path) const; // Adds a simple response to the cache. The response headers will // only contain the "content-length" header with the length of |body|. - void AddSimpleResponse(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + void AddSimpleResponse(absl::string_view host, + absl::string_view path, int response_code, - quiche::QuicheStringPiece body); + absl::string_view body); // Add a simple response to the cache as AddSimpleResponse() does, and add // some server push resources(resource path, corresponding response status and // path) associated with it. // Push resource implicitly come from the same host. void AddSimpleResponseWithServerPushResources( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + absl::string_view host, + absl::string_view path, int response_code, - quiche::QuicheStringPiece body, + absl::string_view body, std::list<QuicBackendResponse::ServerPushInfo> push_resources); // Add a response to the cache. - void AddResponse(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body); + void AddResponse(absl::string_view host, + absl::string_view path, + spdy::Http2HeaderBlock response_headers, + absl::string_view response_body); // Add a response, with trailers, to the cache. - void AddResponse(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, - spdy::SpdyHeaderBlock response_trailers); + void AddResponse(absl::string_view host, + absl::string_view path, + spdy::Http2HeaderBlock response_headers, + absl::string_view response_body, + spdy::Http2HeaderBlock response_trailers); // Simulate a special behavior at a particular path. void AddSpecialResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + absl::string_view host, + absl::string_view path, QuicBackendResponse::SpecialResponseType response_type); void AddSpecialResponse( - quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, - spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, + absl::string_view host, + absl::string_view path, + spdy::Http2HeaderBlock response_headers, + absl::string_view response_body, QuicBackendResponse::SpecialResponseType response_type); // Sets a default response in case of cache misses. Takes ownership of @@ -141,28 +139,27 @@ class QuicMemoryCacheBackend : public QuicSimpleServerBackend { bool InitializeBackend(const std::string& cache_directory) override; bool IsBackendInitialized() const override; void FetchResponseFromBackend( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, QuicSimpleServerBackend::RequestHandler* quic_server_stream) override; void CloseBackendResponseStream( QuicSimpleServerBackend::RequestHandler* quic_server_stream) override; private: - void AddResponseImpl(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path, + void AddResponseImpl(absl::string_view host, + absl::string_view path, QuicBackendResponse::SpecialResponseType response_type, - spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece response_body, - spdy::SpdyHeaderBlock response_trailers); + spdy::Http2HeaderBlock response_headers, + absl::string_view response_body, + spdy::Http2HeaderBlock response_trailers); - std::string GetKey(quiche::QuicheStringPiece host, - quiche::QuicheStringPiece path) const; + std::string GetKey(absl::string_view host, absl::string_view path) const; // Add some server push urls with given responses for specified // request if these push resources are not associated with this request yet. void MaybeAddServerPushResources( - quiche::QuicheStringPiece request_host, - quiche::QuicheStringPiece request_path, + absl::string_view request_host, + absl::string_view request_path, std::list<QuicBackendResponse::ServerPushInfo> push_resources); // Check if push resource(push_host/push_path) associated with given request diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc index e4b8d8e1f38..5940baaf849 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_memory_cache_backend_test.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" +#include "absl/strings/match.h" #include "net/third_party/quiche/src/quic/platform/api/quic_file_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" @@ -15,15 +16,15 @@ namespace quic { namespace test { namespace { -typedef QuicBackendResponse Response; -typedef QuicBackendResponse::ServerPushInfo ServerPushInfo; +using Response = QuicBackendResponse; +using ServerPushInfo = QuicBackendResponse::ServerPushInfo; } // namespace class QuicMemoryCacheBackendTest : public QuicTest { protected: void CreateRequest(std::string host, std::string path, - spdy::SpdyHeaderBlock* headers) { + spdy::Http2HeaderBlock* headers) { (*headers)[":method"] = "GET"; (*headers)[":path"] = path; (*headers)[":authority"] = host; @@ -45,7 +46,7 @@ TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) { std::string response_body("hello response"); cache_.AddSimpleResponse("www.google.com", "/", 200, response_body); - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; CreateRequest("www.google.com", "/", &request_headers); const Response* response = cache_.GetResponse("www.google.com", "/"); ASSERT_TRUE(response); @@ -59,12 +60,12 @@ TEST_F(QuicMemoryCacheBackendTest, AddResponse) { const std::string kRequestPath = "/"; const std::string kResponseBody("hello response"); - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = "200"; response_headers["content-length"] = quiche::QuicheTextUtils::Uint64ToString(kResponseBody.size()); - spdy::SpdyHeaderBlock response_trailers; + spdy::Http2HeaderBlock response_trailers; response_trailers["key-1"] = "value-1"; response_trailers["key-2"] = "value-2"; response_trailers["key-3"] = "value-3"; @@ -123,7 +124,7 @@ TEST_F(QuicMemoryCacheBackendTest, UsesOriginalUrlOnly) { std::string dir; std::string path = "map.html"; for (const std::string& file : ReadFileContents(CacheDirectory())) { - if (quiche::QuicheTextUtils::EndsWithIgnoreCase(file, "map.html")) { + if (absl::EndsWithIgnoreCase(file, "map.html")) { dir = file; dir.erase(dir.length() - path.length() - 1); break; @@ -148,7 +149,7 @@ TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) { ASSERT_FALSE(response); // Add a default response. - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = "200"; response_headers["content-length"] = "0"; Response* default_response = new Response; @@ -189,7 +190,7 @@ TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseWithServerPushResources) { QuicUrl resource_url(url); std::string body = quiche::QuicheStrCat("This is server push response body for ", path); - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = "200"; response_headers["content-length"] = quiche::QuicheTextUtils::Uint64ToString(body.size()); @@ -228,7 +229,7 @@ TEST_F(QuicMemoryCacheBackendTest, GetServerPushResourcesAndPushResponses) { std::string url = scheme + "://" + request_host + path; QuicUrl resource_url(url); std::string body = "This is server push response body for " + path; - spdy::SpdyHeaderBlock response_headers; + spdy::Http2HeaderBlock response_headers; response_headers[":status"] = push_response_status[i]; response_headers["content-length"] = quiche::QuicheTextUtils::Uint64ToString(body.size()); 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 3efeddec2fb..cfe0b8d0d8c 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 @@ -32,7 +32,8 @@ #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" +#include "absl/strings/escaping.h" DEFINE_QUIC_COMMAND_LINE_FLAG(std::string, quic_version, @@ -65,9 +66,9 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface { } void OnRetryPacket(QuicConnectionId /*original_connection_id*/, QuicConnectionId /*new_connection_id*/, - quiche::QuicheStringPiece /*retry_token*/, - quiche::QuicheStringPiece /*retry_integrity_tag*/, - quiche::QuicheStringPiece /*retry_without_tag*/) override { + absl::string_view /*retry_token*/, + absl::string_view /*retry_integrity_tag*/, + absl::string_view /*retry_without_tag*/) override { std::cerr << "OnRetryPacket\n"; } bool OnUnauthenticatedPublicHeader( @@ -99,16 +100,16 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface { bool OnStreamFrame(const QuicStreamFrame& frame) override { std::cerr << "OnStreamFrame: " << frame; std::cerr << " data: { " - << quiche::QuicheTextUtils::HexEncode(frame.data_buffer, - frame.data_length) + << absl::BytesToHexString( + absl::string_view(frame.data_buffer, frame.data_length)) << " }\n"; return true; } bool OnCryptoFrame(const QuicCryptoFrame& frame) override { std::cerr << "OnCryptoFrame: " << frame; std::cerr << " data: { " - << quiche::QuicheTextUtils::HexEncode(frame.data_buffer, - frame.data_length) + << absl::BytesToHexString( + absl::string_view(frame.data_buffer, frame.data_length)) << " }\n"; return true; } @@ -220,6 +221,21 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface { const QuicIetfStatelessResetPacket& /*packet*/) override { std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n"; } + void OnKeyUpdate(KeyUpdateReason reason) override { + std::cerr << "OnKeyUpdate: " << reason << "\n"; + } + void OnDecryptedFirstPacketInKeyPhase() override { + std::cerr << "OnDecryptedFirstPacketInKeyPhase\n"; + } + std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() + override { + std::cerr << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n"; + return nullptr; + } + std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { + std::cerr << "CreateCurrentOneRttEncrypter\n"; + return nullptr; + } private: QuicFramer* framer_; // Unowned. @@ -248,7 +264,7 @@ int main(int argc, char* argv[]) { quic::QuicPrintCommandLineFlagHelp(usage); return 1; } - std::string hex = quiche::QuicheTextUtils::HexDecode(args[1]); + std::string hex = absl::HexStringToBytes(args[1]); quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions(); // Fake a time since we're not actually generating acks. quic::QuicTime start(quic::QuicTime::Zero()); 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 f7e3b75eaac..f17cd031715 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 @@ -7,6 +7,7 @@ #include <iostream> +#include "absl/strings/numbers.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" @@ -27,7 +28,7 @@ int main(int argc, char* argv[]) { } uint32_t packed_error = 0; - if (!quiche::QuicheTextUtils::StringToUint32(args[0], &packed_error)) { + if (!absl::SimpleAtoi(args[0], &packed_error)) { std::cerr << "Unable to parse: " << args[0] << "\n"; return 2; } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server.h b/chromium/net/third_party/quiche/src/quic/tools/quic_server.h index 6059ea08746..bf1555ce3ef 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_server.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_server.h @@ -13,6 +13,7 @@ #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" #include "net/third_party/quiche/src/quic/core/quic_config.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h" @@ -24,7 +25,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -81,7 +81,7 @@ class QuicServer : public QuicSpdyServerBase, crypto_config_.set_chlo_multiplier(multiplier); } - void SetPreSharedKey(quiche::QuicheStringPiece key) { + void SetPreSharedKey(absl::string_view key) { crypto_config_.set_pre_shared_key(key); } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc index 3c4372018fb..06aa105dd78 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_server_test.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/tools/quic_server.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h" #include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h" @@ -19,7 +20,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h" #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" namespace quic { namespace test { @@ -136,9 +136,9 @@ TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) { ASSERT_LT(0, fd); char buf[1024]; - memset(buf, 0, QUICHE_ARRAYSIZE(buf)); + memset(buf, 0, ABSL_ARRAYSIZE(buf)); sockaddr_storage storage = server_address_.generic_address(); - int rc = sendto(fd, buf, QUICHE_ARRAYSIZE(buf), 0, + int rc = sendto(fd, buf, ABSL_ARRAYSIZE(buf), 0, reinterpret_cast<sockaddr*>(&storage), sizeof(storage)); if (rc < 0) { QUIC_DLOG(INFO) << errno << " " << strerror(errno); @@ -202,7 +202,7 @@ TEST_F(QuicServerDispatchPacketTest, DispatchPacket) { }; // clang-format on QuicReceivedPacket encrypted_valid_packet( - reinterpret_cast<char*>(valid_packet), QUICHE_ARRAYSIZE(valid_packet), + reinterpret_cast<char*>(valid_packet), ABSL_ARRAYSIZE(valid_packet), QuicTime::Zero(), false); EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1); diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc index eb06dd5a0f0..95d507155d5 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -50,15 +50,16 @@ void QuicSimpleDispatcher::OnRstStreamReceived( std::unique_ptr<QuicSession> QuicSimpleDispatcher::CreateQuicSession( QuicConnectionId connection_id, - const QuicSocketAddress& /*self_address*/, + const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece /*alpn*/, + absl::string_view /*alpn*/, const ParsedQuicVersion& version) { // The QuicServerSessionBase takes ownership of |connection| below. - QuicConnection* connection = new QuicConnection( - connection_id, peer_address, helper(), alarm_factory(), writer(), - /* owns_writer= */ false, Perspective::IS_SERVER, - ParsedQuicVersionVector{version}); + QuicConnection* connection = + new QuicConnection(connection_id, self_address, peer_address, helper(), + alarm_factory(), writer(), + /* owns_writer= */ false, Perspective::IS_SERVER, + ParsedQuicVersionVector{version}); auto session = std::make_unique<QuicSimpleServerSession>( config(), GetSupportedVersions(), connection, this, session_helper(), diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h index c01359d8498..d213814e295 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h @@ -5,10 +5,10 @@ #ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_ #define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_server_session_base.h" #include "net/third_party/quiche/src/quic/core/quic_dispatcher.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -35,7 +35,7 @@ class QuicSimpleDispatcher : public QuicDispatcher { QuicConnectionId connection_id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const ParsedQuicVersion& version) override; QuicSimpleServerBackend* server_backend() { diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h index 968ec66dd09..fad30415a37 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h @@ -7,10 +7,7 @@ #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/tools/quic_backend_response.h" - -namespace spdy { -class SpdyHeaderBlock; -} // namespace spdy +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" namespace quic { @@ -49,7 +46,7 @@ class QuicSimpleServerBackend { // If the response has to be fetched over the network, the function // asynchronously calls |request_handler| with the HTTP response. virtual void FetchResponseFromBackend( - const spdy::SpdyHeaderBlock& request_headers, + const spdy::Http2HeaderBlock& request_headers, const std::string& request_body, RequestHandler* request_handler) = 0; // Clears the state of the backend instance diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc index 0637109d5c0..72d6259fdff 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc @@ -66,13 +66,13 @@ void QuicSimpleServerSession::PromisePushResources( const std::list<QuicBackendResponse::ServerPushInfo>& resources, QuicStreamId original_stream_id, const spdy::SpdyStreamPrecedence& original_precedence, - const spdy::SpdyHeaderBlock& original_request_headers) { + const spdy::Http2HeaderBlock& original_request_headers) { if (!server_push_enabled()) { return; } for (const QuicBackendResponse::ServerPushInfo& resource : resources) { - spdy::SpdyHeaderBlock headers = SynthesizePushRequestHeaders( + spdy::Http2HeaderBlock headers = SynthesizePushRequestHeaders( request_url, resource, original_request_headers); // TODO(b/136295430): Use sequential push IDs for IETF QUIC. auto new_highest_promised_stream_id = @@ -171,13 +171,13 @@ void QuicSimpleServerSession::HandleRstOnValidNonexistentStream( } } -spdy::SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders( +spdy::Http2HeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders( std::string request_url, QuicBackendResponse::ServerPushInfo resource, - const spdy::SpdyHeaderBlock& original_request_headers) { + const spdy::Http2HeaderBlock& original_request_headers) { QuicUrl push_request_url = resource.request_url; - spdy::SpdyHeaderBlock spdy_headers = original_request_headers.Clone(); + spdy::Http2HeaderBlock spdy_headers = original_request_headers.Clone(); // :authority could be different from original request. spdy_headers[":authority"] = push_request_url.host(); spdy_headers[":path"] = push_request_url.path(); @@ -196,7 +196,7 @@ spdy::SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders( void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id, QuicStreamId promised_stream_id, - spdy::SpdyHeaderBlock headers) { + spdy::Http2HeaderBlock headers) { QUIC_DLOG(INFO) << "stream " << original_stream_id << " send PUSH_PROMISE for promised stream " << promised_stream_id; @@ -226,7 +226,7 @@ void QuicSimpleServerSession::HandlePromisedPushRequests() { promised_stream->SetPriority(promised_info.precedence); - spdy::SpdyHeaderBlock request_headers( + spdy::Http2HeaderBlock request_headers( std::move(promised_info.request_headers)); promised_streams_.pop_front(); diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h index 9942c7d80ad..6d1bc81e64c 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.h @@ -38,14 +38,14 @@ class QuicSimpleServerSession : public QuicServerSessionBase { // stream id with its priority and the headers sent out in PUSH_PROMISE. struct PromisedStreamInfo { public: - PromisedStreamInfo(spdy::SpdyHeaderBlock request_headers, + PromisedStreamInfo(spdy::Http2HeaderBlock request_headers, QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) : request_headers(std::move(request_headers)), stream_id(stream_id), precedence(precedence), is_cancelled(false) {} - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; QuicStreamId stream_id; spdy::SpdyStreamPrecedence precedence; bool is_cancelled; @@ -77,7 +77,7 @@ class QuicSimpleServerSession : public QuicServerSessionBase { const std::list<QuicBackendResponse::ServerPushInfo>& resources, QuicStreamId original_stream_id, const spdy::SpdyStreamPrecedence& original_precedence, - const spdy::SpdyHeaderBlock& original_request_headers); + const spdy::Http2HeaderBlock& original_request_headers); void OnCanCreateNewOutgoingStream(bool unidirectional) override; @@ -113,15 +113,15 @@ class QuicSimpleServerSession : public QuicServerSessionBase { // :authority, :path, :method, :scheme, referer. // Copying the rest headers ensures they are the same as the original // request, especially cookies. - spdy::SpdyHeaderBlock SynthesizePushRequestHeaders( + spdy::Http2HeaderBlock SynthesizePushRequestHeaders( std::string request_url, QuicBackendResponse::ServerPushInfo resource, - const spdy::SpdyHeaderBlock& original_request_headers); + const spdy::Http2HeaderBlock& original_request_headers); // Send PUSH_PROMISE frame on headers stream. void SendPushPromise(QuicStreamId original_stream_id, QuicStreamId promised_stream_id, - spdy::SpdyHeaderBlock headers); + spdy::Http2HeaderBlock headers); // Fetch response from cache for request headers enqueued into // promised_headers_and_streams_ and send them on dedicated stream until 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 780ff9df099..66ee8c4591a 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 @@ -8,6 +8,8 @@ #include <memory> #include <utility> +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" @@ -35,7 +37,6 @@ #include "net/third_party/quiche/src/quic/tools/quic_backend_response.h" #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" using testing::_; @@ -50,7 +51,7 @@ namespace quic { namespace test { namespace { -typedef QuicSimpleServerSession::PromisedStreamInfo PromisedStreamInfo; +using PromisedStreamInfo = QuicSimpleServerSession::PromisedStreamInfo; const QuicByteCount kHeadersFrameHeaderLength = 2; const QuicByteCount kHeadersFramePayloadLength = 9; @@ -187,11 +188,11 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { crypto_config, compressed_certs_cache, quic_simple_server_backend) {} - // Methods taking non-copyable types like SpdyHeaderBlock by value cannot be + // Methods taking non-copyable types like Http2HeaderBlock by value cannot be // mocked directly. void WritePushPromise(QuicStreamId original_stream_id, QuicStreamId promised_stream_id, - spdy::SpdyHeaderBlock headers) override { + spdy::Http2HeaderBlock headers) override { return WritePushPromiseMock(original_stream_id, promised_stream_id, headers); } @@ -199,10 +200,14 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { WritePushPromiseMock, (QuicStreamId original_stream_id, QuicStreamId promised_stream_id, - const spdy::SpdyHeaderBlock& headers), + const spdy::Http2HeaderBlock& headers), ()); MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override)); + MOCK_METHOD(bool, + WriteControlFrame, + (const QuicFrame& frame, TransmissionType type), + (override)); }; class QuicSimpleServerSessionTest @@ -256,6 +261,9 @@ class QuicSimpleServerSessionTest connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>( &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions); connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_ = std::make_unique<MockQuicSimpleServerSession>( config_, connection_, &owner_, &stream_helper_, &crypto_config_, &compressed_certs_cache_, &memory_cache_backend_); @@ -266,9 +274,8 @@ class QuicSimpleServerSessionTest session_->Initialize(); if (VersionHasIetfQuicFrames(transport_version())) { - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke( - this, &QuicSimpleServerSessionTest::ClearMaxStreamsControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); } session_->OnConfigNegotiated(); } @@ -326,7 +333,7 @@ TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) { // Open a stream, then reset it. // Send two bytes of payload to open it. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -335,7 +342,8 @@ TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) { GetNthClientInitiatedBidirectionalId(0), QUIC_ERROR_PROCESSING_STREAM, 0); EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); + if (!VersionHasIetfQuicFrames(transport_version())) { // For version 99, this is covered in InjectStopSending() EXPECT_CALL(*connection_, @@ -365,7 +373,7 @@ TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) { QUIC_ERROR_PROCESSING_STREAM, 0); EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1); if (!VersionHasIetfQuicFrames(transport_version())) { - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); // For version 99, this is covered in InjectStopSending() EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedBidirectionalId(0), @@ -382,7 +390,7 @@ TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) { // Send two bytes of payload. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data1); // The stream should never be opened, now that the reset is received. @@ -393,9 +401,9 @@ TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) { TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) { // Send (empty) compressed headers followed by two bytes of data. QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("\1\0\0\0\0\0\0\0HT")); + absl::string_view("\1\0\0\0\0\0\0\0HT")); QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0, - quiche::QuicheStringPiece("\2\0\0\0\0\0\0\0HT")); + absl::string_view("\3\0\0\0\0\0\0\0HT")); session_->OnStreamFrame(frame1); session_->OnStreamFrame(frame2); EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); @@ -406,7 +414,7 @@ TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) { QUIC_ERROR_PROCESSING_STREAM, 0); EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1); if (!VersionHasIetfQuicFrames(transport_version())) { - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); // For version 99, this is covered in InjectStopSending() EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedBidirectionalId(0), @@ -423,9 +431,9 @@ TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) { // past the reset point of stream 3. As it's a closed stream we just drop the // data on the floor, but accept the packet because it has data for stream 5. QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2, - quiche::QuicheStringPiece("TP")); + absl::string_view("TP")); QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2, - quiche::QuicheStringPiece("TP")); + absl::string_view("TP")); session_->OnStreamFrame(frame3); session_->OnStreamFrame(frame4); // The stream should never be opened, now that the reset is received. @@ -502,7 +510,7 @@ TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) { // Receive some data to initiate a incoming stream which should not effect // creating outgoing streams. QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get())); EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) - @@ -551,7 +559,7 @@ TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) { // Create peer initiated stream should have no problem. QuicStreamFrame data2(GetNthClientInitiatedBidirectionalId(1), false, 0, - quiche::QuicheStringPiece("HT")); + absl::string_view("HT")); session_->OnStreamFrame(data2); EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) - /*outcoming=*/kMaxStreamsForTest); @@ -559,7 +567,7 @@ TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) { TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) { QuicStreamFrame frame(GetNthServerInitiatedUnidirectionalId(0), false, 0, - quiche::QuicheStringPiece()); + absl::string_view()); EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, "Client sent data on server push stream", _)); @@ -622,6 +630,9 @@ class QuicSimpleServerSessionServerPushTest ParsedQuicVersionVector supported_versions = SupportedVersions(GetParam()); connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>( &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions); + connection_->SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(connection_->perspective())); session_ = std::make_unique<MockQuicSimpleServerSession>( config_, connection_, &owner_, &stream_helper_, &crypto_config_, &compressed_certs_cache_, &memory_cache_backend_); @@ -629,9 +640,8 @@ class QuicSimpleServerSessionServerPushTest // Needed to make new session flow control window and server push work. if (VersionHasIetfQuicFrames(transport_version())) { - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(this, &QuicSimpleServerSessionServerPushTest:: - ClearMaxStreamsControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType)); } session_->OnConfigNegotiated(); @@ -676,7 +686,7 @@ class QuicSimpleServerSessionServerPushTest size_t body_size = 2 * kStreamFlowControlWindowSize; // 64KB. std::string request_url = "mail.google.com/"; - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; std::string resource_host = "www.google.com"; std::string partial_push_resource_path = "/server_push_src"; std::list<QuicBackendResponse::ServerPushInfo> push_resources; @@ -708,7 +718,7 @@ class QuicSimpleServerSessionServerPushTest memory_cache_backend_.AddSimpleResponse(resource_host, path, 200, data); push_resources.push_back(QuicBackendResponse::ServerPushInfo( - resource_url, spdy::SpdyHeaderBlock(), QuicStream::kDefaultPriority, + resource_url, spdy::Http2HeaderBlock(), QuicStream::kDefaultPriority, body)); // PUSH_PROMISED are sent for all the resources. EXPECT_CALL(*session_, @@ -881,8 +891,8 @@ TEST_P(QuicSimpleServerSessionServerPushTest, // V99 will send out a STREAMS_BLOCKED frame when it tries to exceed the // limit. This will clear the frames so that they do not block the later // rst-stream frame. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); } QuicByteCount data_frame_header_length = PromisePushResources(num_resources); @@ -898,8 +908,8 @@ TEST_P(QuicSimpleServerSessionServerPushTest, QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset, QUIC_STREAM_CANCELLED, 0); EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); EXPECT_CALL(*connection_, OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT)); session_->OnRstStream(rst); @@ -968,8 +978,8 @@ TEST_P(QuicSimpleServerSessionServerPushTest, // V99 will send out a stream-id-blocked frame when the we desired to exceed // the limit. This will clear the frames so that they do not block the later // rst-stream frame. - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillOnce(Invoke(&ClearControlFrame)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke(&ClearControlFrameWithTransmissionType)); } QuicByteCount data_frame_header_length = PromisePushResources(num_resources); QuicStreamId stream_to_open; @@ -983,7 +993,7 @@ TEST_P(QuicSimpleServerSessionServerPushTest, // Resetting an open stream will close the stream and give space for extra // stream to be opened. QuicStreamId stream_got_reset = GetNthServerInitiatedUnidirectionalId(3); - EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*session_, WriteControlFrame(_, _)); if (!VersionHasIetfQuicFrames(transport_version())) { EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1); // For version 99, this is covered in InjectStopSending() diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc index 84ddb055aa7..93b43562842 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.cc @@ -7,6 +7,8 @@ #include <list> #include <utility> +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -15,11 +17,10 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" -using spdy::SpdyHeaderBlock; +using spdy::Http2HeaderBlock; namespace quic { @@ -109,7 +110,7 @@ void QuicSimpleServerStream::OnBodyAvailable() { } void QuicSimpleServerStream::PushResponse( - SpdyHeaderBlock push_request_headers) { + Http2HeaderBlock push_request_headers) { if (QuicUtils::IsClientInitiatedStreamId(session()->transport_version(), id())) { QUIC_BUG << "Client initiated stream shouldn't be used as promised stream."; @@ -208,7 +209,7 @@ void QuicSimpleServerStream::OnResponseBackendComplete( std::string request_url = request_headers_[":authority"].as_string() + request_headers_[":path"].as_string(); int response_code; - const SpdyHeaderBlock& response_headers = response->headers(); + const Http2HeaderBlock& response_headers = response->headers(); if (!ParseHeaderStatusCode(response_headers, &response_code)) { auto status = response_headers.find(":status"); if (status == response_headers.end()) { @@ -257,13 +258,12 @@ void QuicSimpleServerStream::OnResponseBackendComplete( if (response->response_type() == QuicBackendResponse::GENERATE_BYTES) { QUIC_DVLOG(1) << "Stream " << id() << " sending a generate bytes response."; std::string path = request_headers_[":path"].as_string().substr(1); - if (!quiche::QuicheTextUtils::StringToUint64(path, - &generate_bytes_length_)) { + if (!absl::SimpleAtoi(path, &generate_bytes_length_)) { QUIC_LOG(ERROR) << "Path is not a number."; SendNotFoundResponse(); return; } - SpdyHeaderBlock headers = response->headers().Clone(); + Http2HeaderBlock headers = response->headers().Clone(); headers["content-length"] = quiche::QuicheTextUtils::Uint64ToString(generate_bytes_length_); @@ -297,7 +297,7 @@ void QuicSimpleServerStream::WriteGeneratedBytes() { void QuicSimpleServerStream::SendNotFoundResponse() { QUIC_DVLOG(1) << "Stream " << id() << " sending not found response."; - SpdyHeaderBlock headers; + Http2HeaderBlock headers; headers[":status"] = "404"; headers["content-length"] = quiche::QuicheTextUtils::Uint64ToString(strlen(kNotFoundResponseBody)); @@ -310,7 +310,7 @@ void QuicSimpleServerStream::SendErrorResponse() { void QuicSimpleServerStream::SendErrorResponse(int resp_code) { QUIC_DVLOG(1) << "Stream " << id() << " sending error response."; - SpdyHeaderBlock headers; + Http2HeaderBlock headers; if (resp_code <= 0) { headers[":status"] = "500"; } else { @@ -322,8 +322,8 @@ void QuicSimpleServerStream::SendErrorResponse(int resp_code) { } void QuicSimpleServerStream::SendIncompleteResponse( - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body) { + Http2HeaderBlock response_headers, + absl::string_view body) { QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : " << response_headers.DebugString(); WriteHeaders(std::move(response_headers), /*fin=*/false, nullptr); @@ -336,16 +336,16 @@ void QuicSimpleServerStream::SendIncompleteResponse( } void QuicSimpleServerStream::SendHeadersAndBody( - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body) { + Http2HeaderBlock response_headers, + absl::string_view body) { SendHeadersAndBodyAndTrailers(std::move(response_headers), body, - SpdyHeaderBlock()); + Http2HeaderBlock()); } void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers( - SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body, - SpdyHeaderBlock response_trailers) { + Http2HeaderBlock response_headers, + absl::string_view body, + Http2HeaderBlock response_trailers) { // Send the headers, with a FIN if there's nothing else to send. bool send_fin = (body.empty() && response_trailers.empty()); QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h index add4a12875d..6b8826cd866 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h @@ -5,11 +5,11 @@ #ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_ #define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/tools/quic_backend_response.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_framer.h" namespace quic { @@ -47,7 +47,7 @@ class QuicSimpleServerStream : public QuicSpdyServerStreamBase, // Make this stream start from as if it just finished parsing an incoming // request whose headers are equivalent to |push_request_headers|. // Doing so will trigger this toy stream to fetch response and send it back. - virtual void PushResponse(spdy::SpdyHeaderBlock push_request_headers); + virtual void PushResponse(spdy::Http2HeaderBlock push_request_headers); // The response body of error responses. static const char* const kErrorResponseBody; @@ -76,16 +76,16 @@ class QuicSimpleServerStream : public QuicSpdyServerStreamBase, void SendNotFoundResponse(); // Sends the response header and body, but not the fin. - void SendIncompleteResponse(spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body); + void SendIncompleteResponse(spdy::Http2HeaderBlock response_headers, + absl::string_view body); - void SendHeadersAndBody(spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body); - void SendHeadersAndBodyAndTrailers(spdy::SpdyHeaderBlock response_headers, - quiche::QuicheStringPiece body, - spdy::SpdyHeaderBlock response_trailers); + void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers, + absl::string_view body); + void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers, + absl::string_view body, + spdy::Http2HeaderBlock response_trailers); - spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; } + spdy::Http2HeaderBlock* request_headers() { return &request_headers_; } const std::string& body() { return body_; } @@ -93,7 +93,7 @@ class QuicSimpleServerStream : public QuicSpdyServerStreamBase, void WriteGeneratedBytes(); // The parsed headers received from the client. - spdy::SpdyHeaderBlock request_headers_; + spdy::Http2HeaderBlock request_headers_; int64_t content_length_; std::string body_; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc index f5c1b53dde1..4b21ccaded1 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc @@ -8,8 +8,13 @@ #include <memory> #include <utility> +#include "absl/base/macros.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_encoder.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" @@ -26,9 +31,6 @@ #include "net/third_party/quiche/src/quic/tools/quic_backend_response.h" #include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quic/tools/quic_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" using testing::_; using testing::AnyNumber; @@ -58,7 +60,7 @@ class TestStream : public QuicSimpleServerStream { MOCK_METHOD(void, WriteHeadersMock, (bool fin), ()); - size_t WriteHeaders(spdy::SpdyHeaderBlock /*header_block*/, + size_t WriteHeaders(spdy::Http2HeaderBlock /*header_block*/, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> /*ack_listener*/) override { @@ -70,12 +72,12 @@ class TestStream : public QuicSimpleServerStream { void DoSendResponse() { SendResponse(); } void DoSendErrorResponse() { SendErrorResponse(); } - spdy::SpdyHeaderBlock* mutable_headers() { return &request_headers_; } + spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; } void set_body(std::string body) { body_ = std::move(body); } const std::string& body() const { return body_; } int content_length() const { return content_length_; } - quiche::QuicheStringPiece GetHeader(quiche::QuicheStringPiece key) const { + absl::string_view GetHeader(absl::string_view key) const { auto it = request_headers_.find(key); DCHECK(it != request_headers_.end()); return it->second; @@ -137,7 +139,7 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { QuicStreamOffset offset, StreamSendingState state, TransmissionType type, - quiche::QuicheOptional<EncryptionLevel> level), + absl::optional<EncryptionLevel> level), (override)); MOCK_METHOD(void, OnStreamHeaderList, @@ -158,13 +160,23 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { QuicStreamOffset bytes_written, bool send_rst_only), (override)); - // Matchers cannot be used on non-copyable types like SpdyHeaderBlock. + MOCK_METHOD(void, + MaybeSendRstStreamFrame, + (QuicStreamId stream_id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written), + (override)); + MOCK_METHOD(void, + MaybeSendStopSendingFrame, + (QuicStreamId stream_id, QuicRstStreamErrorCode error), + (override)); + // Matchers cannot be used on non-copyable types like Http2HeaderBlock. void PromisePushResources( const std::string& request_url, const std::list<QuicBackendResponse::ServerPushInfo>& resources, QuicStreamId original_stream_id, const spdy::SpdyStreamPrecedence& original_precedence, - const spdy::SpdyHeaderBlock& original_request_headers) override { + const spdy::Http2HeaderBlock& original_request_headers) override { original_request_headers_ = original_request_headers.Clone(); PromisePushResourcesMock(request_url, resources, original_stream_id, original_precedence, original_request_headers); @@ -175,18 +187,17 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { const std::list<QuicBackendResponse::ServerPushInfo>&, QuicStreamId, const spdy::SpdyStreamPrecedence&, - const spdy::SpdyHeaderBlock&), + const spdy::Http2HeaderBlock&), ()); using QuicSession::ActivateStream; - QuicConsumedData ConsumeData( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state, - TransmissionType /*type*/, - quiche::QuicheOptional<EncryptionLevel> /*level*/) { + QuicConsumedData ConsumeData(QuicStreamId id, + size_t write_length, + QuicStreamOffset offset, + StreamSendingState state, + TransmissionType /*type*/, + absl::optional<EncryptionLevel> /*level*/) { if (write_length > 0) { auto buf = std::make_unique<char[]>(write_length); QuicStream* stream = GetOrCreateStream(id); @@ -199,7 +210,7 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession { return QuicConsumedData(write_length, state != NO_FIN); } - spdy::SpdyHeaderBlock original_request_headers_; + spdy::Http2HeaderBlock original_request_headers_; }; class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> { @@ -241,6 +252,9 @@ class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> { session_.config()->SetInitialSessionFlowControlWindowToSend( kInitialSessionFlowControlWindowForTest); session_.Initialize(); + connection_->SetEncrypter( + quic::ENCRYPTION_FORWARD_SECURE, + std::make_unique<quic::NullEncrypter>(connection_->perspective())); if (connection_->version().SupportsAntiAmplificationLimit()) { QuicConnectionPeer::SetAddressValidated(connection_); } @@ -273,7 +287,7 @@ class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> { return VersionUsesHttp3(connection_->transport_version()); } - spdy::SpdyHeaderBlock response_headers_; + spdy::Http2HeaderBlock response_headers_; MockQuicConnectionHelper helper_; MockAlarmFactory alarm_factory_; StrictMock<MockQuicConnection>* connection_; @@ -342,7 +356,18 @@ TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) { QuicStreamPeer::SetFinSent(stream_); stream_->CloseWriteSide(); - EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(1); + if (!session_.split_up_send_rst()) { + EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)) + .Times(1); + } else { + if (session_.version().UsesHttp3()) { + EXPECT_CALL(session_, MaybeSendStopSendingFrame(_, QUIC_STREAM_NO_ERROR)) + .Times(1); + } else { + EXPECT_CALL(session_, MaybeSendRstStreamFrame(_, QUIC_STREAM_NO_ERROR, _)) + .Times(1); + } + } stream_->StopReading(); } @@ -384,7 +409,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) { TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) { // Send an illegal response with response status not supported by HTTP/2. - spdy::SpdyHeaderBlock* request_headers = stream_->mutable_headers(); + spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers(); (*request_headers)[":path"] = "/bar"; (*request_headers)[":authority"] = "www.google.com"; (*request_headers)[":method"] = "GET"; @@ -416,7 +441,7 @@ TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) { TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) { // Send an illegal response with response status not supported by HTTP/2. - spdy::SpdyHeaderBlock* request_headers = stream_->mutable_headers(); + spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers(); (*request_headers)[":path"] = "/bar"; (*request_headers)[":authority"] = "www.google.com"; (*request_headers)[":method"] = "GET"; @@ -457,7 +482,7 @@ TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) { // Send a push response with response status 404, which will be regarded as // invalid server push response. - spdy::SpdyHeaderBlock* request_headers = promised_stream->mutable_headers(); + spdy::Http2HeaderBlock* request_headers = promised_stream->mutable_headers(); (*request_headers)[":path"] = "/bar"; (*request_headers)[":authority"] = "www.google.com"; (*request_headers)[":method"] = "GET"; @@ -470,15 +495,23 @@ TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) { std::move(response_headers_), body); InSequence s; - EXPECT_CALL(session_, SendRstStream(promised_stream->id(), - QUIC_STREAM_CANCELLED, 0, _)); + if (!session_.split_up_send_rst()) { + EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_CANCELLED, 0, _)); + } else { + if (session_.version().UsesHttp3()) { + EXPECT_CALL(session_, MaybeSendStopSendingFrame(promised_stream->id(), + QUIC_STREAM_CANCELLED)); + } + EXPECT_CALL(session_, MaybeSendRstStreamFrame(promised_stream->id(), + QUIC_STREAM_CANCELLED, 0)); + } promised_stream->DoSendResponse(); } TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) { // Add a request and response with valid headers. - spdy::SpdyHeaderBlock* request_headers = stream_->mutable_headers(); + spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers(); (*request_headers)[":path"] = "/bar"; (*request_headers)[":authority"] = "www.google.com"; (*request_headers)[":method"] = "GET"; @@ -519,14 +552,14 @@ TEST_P(QuicSimpleServerStreamTest, SendResponseWithPushResources) { QuicByteCount header_length = HttpEncoder::SerializeDataFrameHeader(body.length(), &buffer); QuicBackendResponse::ServerPushInfo push_info( - QuicUrl(host, "/bar"), spdy::SpdyHeaderBlock(), + QuicUrl(host, "/bar"), spdy::Http2HeaderBlock(), QuicStream::kDefaultPriority, "Push body"); std::list<QuicBackendResponse::ServerPushInfo> push_resources; push_resources.push_back(push_info); memory_cache_backend_.AddSimpleResponseWithServerPushResources( host, request_path, 200, body, push_resources); - spdy::SpdyHeaderBlock* request_headers = stream_->mutable_headers(); + spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers(); (*request_headers)[":path"] = request_path; (*request_headers)[":authority"] = host; (*request_headers)[":method"] = "GET"; @@ -555,7 +588,7 @@ TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) { // Calling PushResponse() on a client initialted stream is never supposed to // happen. - EXPECT_QUIC_BUG(stream_->PushResponse(spdy::SpdyHeaderBlock()), + EXPECT_QUIC_BUG(stream_->PushResponse(spdy::Http2HeaderBlock()), "Client initiated stream" " shouldn't be used as promised stream."); } @@ -576,7 +609,7 @@ TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) { const std::string kHost = "www.foo.com"; const std::string kPath = "/bar"; - spdy::SpdyHeaderBlock headers; + spdy::Http2HeaderBlock headers; headers[":path"] = kPath; headers[":authority"] = kHost; headers[":method"] = "GET"; @@ -627,10 +660,9 @@ TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) { TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) { EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(0); - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; // \000 is a way to write the null byte when followed by a literal digit. - header_list_.OnHeader("content-length", - quiche::QuicheStringPiece("11\00012", 5)); + header_list_.OnHeader("content-length", absl::string_view("11\00012", 5)); EXPECT_CALL(*stream_, WriteHeadersMock(false)); EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) @@ -646,10 +678,9 @@ TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) { TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) { EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(0); - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; // \000 is a way to write the null byte when followed by a literal digit. - header_list_.OnHeader("content-length", - quiche::QuicheStringPiece("\00012", 3)); + header_list_.OnHeader("content-length", absl::string_view("\00012", 3)); EXPECT_CALL(*stream_, WriteHeadersMock(false)); EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)) @@ -663,10 +694,9 @@ TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) { } TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) { - spdy::SpdyHeaderBlock request_headers; + spdy::Http2HeaderBlock request_headers; // \000 is a way to write the null byte when followed by a literal digit. - header_list_.OnHeader("content-length", - quiche::QuicheStringPiece("11\00011", 5)); + header_list_.OnHeader("content-length", absl::string_view("11\00011", 5)); stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_); @@ -678,7 +708,6 @@ TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) { TEST_P(QuicSimpleServerStreamTest, DoNotSendQuicRstStreamNoErrorWithRstReceived) { - InSequence s; EXPECT_FALSE(stream_->reading_stopped()); EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _, _)).Times(0); @@ -691,16 +720,33 @@ TEST_P(QuicSimpleServerStreamTest, EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _)) .Times(AnyNumber()); } - EXPECT_CALL(session_, SendRstStream(_, QUIC_RST_ACKNOWLEDGEMENT, _, _)) - .Times(1); + + if (!session_.split_up_send_rst()) { + EXPECT_CALL(session_, SendRstStream(_, + session_.version().UsesHttp3() + ? QUIC_STREAM_CANCELLED + : QUIC_RST_ACKNOWLEDGEMENT, + _, _)) + .Times(1); + } else { + EXPECT_CALL(session_, + MaybeSendRstStreamFrame(_, + session_.version().UsesHttp3() + ? QUIC_STREAM_CANCELLED + : QUIC_RST_ACKNOWLEDGEMENT, + _)) + .Times(1); + } QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 1234); stream_->OnStreamReset(rst_frame); if (VersionHasIetfQuicFrames(connection_->transport_version())) { - // For V99 receiving a RST_STREAM causes a 1-way close; the test requires - // a full close. A CloseWriteSide closes the other half of the stream. - // Everything should then work properly. - stream_->CloseWriteSide(); + EXPECT_CALL(session_owner_, OnStopSendingReceived(_)); + // Create and inject a STOP SENDING frame to complete the close + // of the stream. This is only needed for version 99/IETF QUIC. + QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(), + QUIC_STREAM_CANCELLED); + session_.OnStopSendingFrame(stop_sending); } EXPECT_TRUE(stream_->reading_stopped()); EXPECT_TRUE(stream_->write_side_closed()); @@ -730,7 +776,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) { 0x54, 0x54, 0x50, 0x2f, // TTP/ 0x31, 0x2e, 0x31, // 1.1 }; - quiche::QuicheStringPiece data(arr, QUICHE_ARRAYSIZE(arr)); + absl::string_view data(arr, ABSL_ARRAYSIZE(arr)); QuicStreamFrame frame(stream_->id(), true, 0, data); // Verify that we don't crash when we get a invalid headers in stream frame. stream_->OnStreamFrame(frame); diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc index 212e605f298..134e673dd9f 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.cc @@ -6,15 +6,16 @@ #include <utility> +#include "absl/strings/numbers.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" -using spdy::SpdyHeaderBlock; +using spdy::Http2HeaderBlock; namespace quic { @@ -24,8 +25,8 @@ void QuicSpdyClientBase::ClientQuicDataToResend::Resend() { } QuicSpdyClientBase::QuicDataToResend::QuicDataToResend( - std::unique_ptr<SpdyHeaderBlock> headers, - quiche::QuicheStringPiece body, + std::unique_ptr<Http2HeaderBlock> headers, + absl::string_view body, bool fin) : headers_(std::move(headers)), body_(body), fin_(fin) {} @@ -80,7 +81,7 @@ void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) { QuicSpdyClientStream* client_stream = static_cast<QuicSpdyClientStream*>(stream); - const SpdyHeaderBlock& response_headers = client_stream->response_headers(); + const Http2HeaderBlock& response_headers = client_stream->response_headers(); if (response_listener_ != nullptr) { response_listener_->OnCompleteResponse(stream->id(), response_headers, client_stream->data()); @@ -91,8 +92,7 @@ void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) { auto status = response_headers.find(":status"); if (status == response_headers.end()) { QUIC_LOG(ERROR) << "Missing :status response header"; - } else if (!quiche::QuicheTextUtils::StringToInt(status->second, - &latest_response_code_)) { + } else if (!absl::SimpleAtoi(status->second, &latest_response_code_)) { QUIC_LOG(ERROR) << "Invalid :status response header: " << status->second; } latest_response_headers_ = response_headers.DebugString(); @@ -113,12 +113,12 @@ std::unique_ptr<QuicSession> QuicSpdyClientBase::CreateQuicClientSession( &push_promise_index_); } -void QuicSpdyClientBase::SendRequest(const SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, +void QuicSpdyClientBase::SendRequest(const Http2HeaderBlock& headers, + absl::string_view body, bool fin) { if (GetQuicFlag(FLAGS_quic_client_convert_http_header_name_to_lowercase)) { QUIC_CODE_COUNT(quic_client_convert_http_header_name_to_lowercase); - SpdyHeaderBlock sanitized_headers; + Http2HeaderBlock sanitized_headers; for (const auto& p : headers) { sanitized_headers[quiche::QuicheTextUtils::ToLower(p.first)] = p.second; } @@ -129,8 +129,8 @@ void QuicSpdyClientBase::SendRequest(const SpdyHeaderBlock& headers, } } -void QuicSpdyClientBase::SendRequestInternal(SpdyHeaderBlock sanitized_headers, - quiche::QuicheStringPiece body, +void QuicSpdyClientBase::SendRequestInternal(Http2HeaderBlock sanitized_headers, + absl::string_view body, bool fin) { QuicClientPushPromiseIndex::TryHandle* handle; QuicAsyncStatus rv = @@ -153,8 +153,8 @@ void QuicSpdyClientBase::SendRequestInternal(SpdyHeaderBlock sanitized_headers, } void QuicSpdyClientBase::SendRequestAndWaitForResponse( - const SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + const Http2HeaderBlock& headers, + absl::string_view body, bool fin) { SendRequest(headers, body, fin); while (WaitForEvents()) { @@ -164,7 +164,7 @@ void QuicSpdyClientBase::SendRequestAndWaitForResponse( void QuicSpdyClientBase::SendRequestsAndWaitForResponse( const std::vector<std::string>& url_list) { for (size_t i = 0; i < url_list.size(); ++i) { - SpdyHeaderBlock headers; + Http2HeaderBlock headers; if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) { QUIC_BUG << "Unable to create request"; continue; @@ -232,19 +232,19 @@ void QuicSpdyClientBase::ResendSavedData() { } } -void QuicSpdyClientBase::AddPromiseDataToResend(const SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, +void QuicSpdyClientBase::AddPromiseDataToResend(const Http2HeaderBlock& headers, + absl::string_view body, bool fin) { - std::unique_ptr<SpdyHeaderBlock> new_headers( - new SpdyHeaderBlock(headers.Clone())); + std::unique_ptr<Http2HeaderBlock> new_headers( + new Http2HeaderBlock(headers.Clone())); push_promise_data_to_resend_.reset( new ClientQuicDataToResend(std::move(new_headers), body, fin, this)); } bool QuicSpdyClientBase::CheckVary( - const SpdyHeaderBlock& /*client_request*/, - const SpdyHeaderBlock& /*promise_request*/, - const SpdyHeaderBlock& /*promise_response*/) { + const Http2HeaderBlock& /*client_request*/, + const Http2HeaderBlock& /*promise_request*/, + const Http2HeaderBlock& /*promise_response*/) { return true; } @@ -274,7 +274,7 @@ const std::string& QuicSpdyClientBase::preliminary_response_headers() const { return preliminary_response_headers_; } -const SpdyHeaderBlock& QuicSpdyClientBase::latest_response_header_block() +const Http2HeaderBlock& QuicSpdyClientBase::latest_response_header_block() const { QUIC_BUG_IF(!store_response_) << "Response not stored!"; return latest_response_header_block_; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h index fdd67fbc3b5..90dfe8a92d2 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_spdy_client_base.h @@ -10,6 +10,7 @@ #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h" #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h" @@ -17,7 +18,6 @@ #include "net/third_party/quiche/src/quic/core/quic_config.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/tools/quic_client_base.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,7 +36,7 @@ class QuicSpdyClientBase : public QuicClientBase, virtual ~ResponseListener() {} virtual void OnCompleteResponse( QuicStreamId id, - const spdy::SpdyHeaderBlock& response_headers, + const spdy::Http2HeaderBlock& response_headers, const std::string& response_body) = 0; }; @@ -46,8 +46,8 @@ class QuicSpdyClientBase : public QuicClientBase, class QuicDataToResend { public: // |headers| may be null, since it's possible to send data without headers. - QuicDataToResend(std::unique_ptr<spdy::SpdyHeaderBlock> headers, - quiche::QuicheStringPiece body, + QuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers, + absl::string_view body, bool fin); QuicDataToResend(const QuicDataToResend&) = delete; QuicDataToResend& operator=(const QuicDataToResend&) = delete; @@ -59,8 +59,8 @@ class QuicSpdyClientBase : public QuicClientBase, virtual void Resend() = 0; protected: - std::unique_ptr<spdy::SpdyHeaderBlock> headers_; - quiche::QuicheStringPiece body_; + std::unique_ptr<spdy::Http2HeaderBlock> headers_; + absl::string_view body_; bool fin_; }; @@ -85,13 +85,13 @@ class QuicSpdyClientBase : public QuicClientBase, void InitializeSession() override; // Sends an HTTP request and does not wait for response before returning. - void SendRequest(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + void SendRequest(const spdy::Http2HeaderBlock& headers, + absl::string_view body, bool fin); // Sends an HTTP request and waits for response before returning. - void SendRequestAndWaitForResponse(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + void SendRequestAndWaitForResponse(const spdy::Http2HeaderBlock& headers, + absl::string_view body, bool fin); // Sends a request simple GET for each URL in |url_list|, and then waits for @@ -110,9 +110,9 @@ class QuicSpdyClientBase : public QuicClientBase, return &push_promise_index_; } - bool CheckVary(const spdy::SpdyHeaderBlock& client_request, - const spdy::SpdyHeaderBlock& promise_request, - const spdy::SpdyHeaderBlock& promise_response) override; + bool CheckVary(const spdy::Http2HeaderBlock& client_request, + const spdy::Http2HeaderBlock& promise_request, + const spdy::Http2HeaderBlock& promise_response) override; void OnRendezvousResult(QuicSpdyStream*) override; // If the crypto handshake has not yet been confirmed, adds the data to the @@ -126,7 +126,7 @@ class QuicSpdyClientBase : public QuicClientBase, int latest_response_code() const; const std::string& latest_response_headers() const; const std::string& preliminary_response_headers() const; - const spdy::SpdyHeaderBlock& latest_response_header_block() const; + const spdy::Http2HeaderBlock& latest_response_header_block() const; const std::string& latest_response_body() const; const std::string& latest_response_trailers() const; @@ -161,8 +161,8 @@ class QuicSpdyClientBase : public QuicClientBase, void ResendSavedData() override; - void AddPromiseDataToResend(const spdy::SpdyHeaderBlock& headers, - quiche::QuicheStringPiece body, + void AddPromiseDataToResend(const spdy::Http2HeaderBlock& headers, + absl::string_view body, bool fin); bool HasActiveRequests() override; @@ -170,8 +170,8 @@ class QuicSpdyClientBase : public QuicClientBase, // Specific QuicClient class for storing data to resend. class ClientQuicDataToResend : public QuicDataToResend { public: - ClientQuicDataToResend(std::unique_ptr<spdy::SpdyHeaderBlock> headers, - quiche::QuicheStringPiece body, + ClientQuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers, + absl::string_view body, bool fin, QuicSpdyClientBase* client) : QuicDataToResend(std::move(headers), body, fin), client_(client) { @@ -189,8 +189,8 @@ class QuicSpdyClientBase : public QuicClientBase, QuicSpdyClientBase* client_; }; - void SendRequestInternal(spdy::SpdyHeaderBlock sanitized_headers, - quiche::QuicheStringPiece body, + void SendRequestInternal(spdy::Http2HeaderBlock sanitized_headers, + absl::string_view body, bool fin); // Index of pending promised streams. Must outlive |session_|. @@ -205,7 +205,7 @@ class QuicSpdyClientBase : public QuicClientBase, // preliminary 100 Continue HTTP/2 headers from most recent response, if any. std::string preliminary_response_headers_; // HTTP/2 headers from most recent response. - spdy::SpdyHeaderBlock latest_response_header_block_; + spdy::Http2HeaderBlock latest_response_header_block_; // Body of most recent response. std::string latest_response_body_; // HTTP/2 trailers from most recent response. 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 582f3c7cd4a..c25411d9bb5 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 @@ -48,6 +48,9 @@ #include <utility> #include <vector> +#include "absl/strings/escaping.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -58,13 +61,11 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h" #include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h" #include "net/third_party/quiche/src/quic/tools/quic_url.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" namespace { using quic::QuicUrl; -using quiche::QuicheStringPiece; using quiche::QuicheTextUtils; } // namespace @@ -322,11 +323,11 @@ int QuicToyClient::SendRequestsAndPrintResponses( if (!GetQuicFlag(FLAGS_body_hex).empty()) { DCHECK(GetQuicFlag(FLAGS_body).empty()) << "Only set one of --body and --body_hex."; - body = QuicheTextUtils::HexDecode(GetQuicFlag(FLAGS_body_hex)); + body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex)); } // Construct a GET or POST request for supplied URL. - spdy::SpdyHeaderBlock header_block; + spdy::Http2HeaderBlock header_block; header_block[":method"] = body.empty() ? "GET" : "POST"; header_block[":scheme"] = url.scheme(); header_block[":authority"] = url.HostPort(); @@ -334,12 +335,12 @@ int QuicToyClient::SendRequestsAndPrintResponses( // Append any additional headers supplied on the command line. const std::string headers = GetQuicFlag(FLAGS_headers); - for (QuicheStringPiece sp : QuicheTextUtils::Split(headers, ';')) { + for (absl::string_view sp : absl::StrSplit(headers, ';')) { QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp); if (sp.empty()) { continue; } - std::vector<QuicheStringPiece> kv = QuicheTextUtils::Split(sp, ':'); + std::vector<absl::string_view> kv = absl::StrSplit(sp, ':'); QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]); QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]); header_block[kv[0]] = kv[1]; @@ -359,8 +360,8 @@ int QuicToyClient::SendRequestsAndPrintResponses( if (!GetQuicFlag(FLAGS_body_hex).empty()) { // Print the user provided hex, rather than binary body. std::cout << "body:\n" - << QuicheTextUtils::HexDump(QuicheTextUtils::HexDecode( - GetQuicFlag(FLAGS_body_hex))) + << QuicheTextUtils::HexDump( + absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex))) << std::endl; } else { std::cout << "body: " << body << std::endl; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc index d445b548a8c..ec52d3a35ca 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.cc @@ -6,12 +6,12 @@ #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/quic_connection.h" #include "net/third_party/quiche/src/quic/core/quic_dispatcher.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -36,12 +36,13 @@ QuicTransportSimpleServerDispatcher::QuicTransportSimpleServerDispatcher( std::unique_ptr<QuicSession> QuicTransportSimpleServerDispatcher::CreateQuicSession( QuicConnectionId server_connection_id, - const QuicSocketAddress& /*self_address*/, + const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece /*alpn*/, + absl::string_view /*alpn*/, const ParsedQuicVersion& version) { auto connection = std::make_unique<QuicConnection>( - server_connection_id, peer_address, helper(), alarm_factory(), writer(), + server_connection_id, self_address, peer_address, helper(), + alarm_factory(), writer(), /*owns_writer=*/false, Perspective::IS_SERVER, ParsedQuicVersionVector{version}); auto session = std::make_unique<QuicTransportSimpleServerSession>( diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h index da27585e28c..62e4432a2d6 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_dispatcher.h @@ -5,10 +5,10 @@ #ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_ #define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_ +#include "absl/strings/string_view.h" #include "url/origin.h" #include "net/third_party/quiche/src/quic/core/quic_dispatcher.h" #include "net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -31,7 +31,7 @@ class QuicTransportSimpleServerDispatcher : public QuicDispatcher { QuicConnectionId server_connection_id, const QuicSocketAddress& self_address, const QuicSocketAddress& peer_address, - quiche::QuicheStringPiece alpn, + absl::string_view alpn, const ParsedQuicVersion& version) override; std::vector<url::Origin> accepted_origins_; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc index d07da11672b..386bd0056fa 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.cc @@ -226,7 +226,7 @@ bool QuicTransportSimpleServerSession::ProcessPath(const GURL& url) { } void QuicTransportSimpleServerSession::OnMessageReceived( - quiche::QuicheStringPiece message) { + absl::string_view message) { if (mode_ != ECHO) { return; } diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h index 7cfd1975c4e..fc018fbd5a1 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h @@ -58,7 +58,7 @@ class QuicTransportSimpleServerSession void OnCanCreateNewOutgoingStream(bool unidirectional) override; bool CheckOrigin(url::Origin origin) override; bool ProcessPath(const GURL& url) override; - void OnMessageReceived(quiche::QuicheStringPiece message) override; + void OnMessageReceived(absl::string_view message) override; void EchoStreamBack(const std::string& data) { streams_to_echo_back_.push_back(data); diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc index 438847c35f8..9f9e98aeaf5 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_url.cc @@ -4,18 +4,16 @@ #include "net/third_party/quiche/src/quic/tools/quic_url.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { static constexpr size_t kMaxHostNameLength = 256; -QuicUrl::QuicUrl(quiche::QuicheStringPiece url) - : url_(static_cast<std::string>(url)) {} +QuicUrl::QuicUrl(absl::string_view url) : url_(static_cast<std::string>(url)) {} -QuicUrl::QuicUrl(quiche::QuicheStringPiece url, - quiche::QuicheStringPiece default_scheme) +QuicUrl::QuicUrl(absl::string_view url, absl::string_view default_scheme) : QuicUrl(url) { if (url_.has_scheme()) { return; diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_url.h b/chromium/net/third_party/quiche/src/quic/tools/quic_url.h index 4b057db3b3a..ca4ac8e346f 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/quic_url.h +++ b/chromium/net/third_party/quiche/src/quic/tools/quic_url.h @@ -7,9 +7,9 @@ #include <string> +#include "absl/strings/string_view.h" #include "url/gurl.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace quic { @@ -24,12 +24,11 @@ class QuicUrl { // NOTE: If |url| doesn't have a scheme, it will have an empty scheme // field. If that's not what you want, use the QuicUrlImpl(url, // default_scheme) form below. - explicit QuicUrl(quiche::QuicheStringPiece url); + explicit QuicUrl(absl::string_view url); // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL // is |default_scheme| if there is no scheme specified in |url|. - QuicUrl(quiche::QuicheStringPiece url, - quiche::QuicheStringPiece default_scheme); + QuicUrl(absl::string_view url, absl::string_view default_scheme); // Returns false if the URL is not valid. bool IsValid() const; diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc index 3da114e5526..b742dbff322 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.cc @@ -38,8 +38,7 @@ size_t SimpleTicketCrypter::MaxOverhead() { return kEpochSize + kIVSize + kAuthTagSize; } -std::vector<uint8_t> SimpleTicketCrypter::Encrypt( - quiche::QuicheStringPiece in) { +std::vector<uint8_t> SimpleTicketCrypter::Encrypt(absl::string_view in) { MaybeRotateKeys(); std::vector<uint8_t> out(in.size() + MaxOverhead()); out[0] = key_epoch_; @@ -56,8 +55,7 @@ std::vector<uint8_t> SimpleTicketCrypter::Encrypt( return out; } -std::vector<uint8_t> SimpleTicketCrypter::Decrypt( - quiche::QuicheStringPiece in) { +std::vector<uint8_t> SimpleTicketCrypter::Decrypt(absl::string_view in) { MaybeRotateKeys(); if (in.size() < kMessageOffset) { return std::vector<uint8_t>(); @@ -83,7 +81,7 @@ std::vector<uint8_t> SimpleTicketCrypter::Decrypt( } void SimpleTicketCrypter::Decrypt( - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<quic::ProofSource::DecryptCallback> callback) { callback->Run(Decrypt(in)); } diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h index 330c5091094..c150ae24579 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h +++ b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter.h @@ -24,13 +24,13 @@ class QUIC_NO_EXPORT SimpleTicketCrypter ~SimpleTicketCrypter() override; size_t MaxOverhead() override; - std::vector<uint8_t> Encrypt(quiche::QuicheStringPiece in) override; + std::vector<uint8_t> Encrypt(absl::string_view in) override; void Decrypt( - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr<quic::ProofSource::DecryptCallback> callback) override; private: - std::vector<uint8_t> Decrypt(quiche::QuicheStringPiece in); + std::vector<uint8_t> Decrypt(absl::string_view in); void MaybeRotateKeys(); diff --git a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc index e609dc03571..568fa2b846c 100644 --- a/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/tools/simple_ticket_crypter_test.cc @@ -26,9 +26,8 @@ class DecryptCallback : public quic::ProofSource::DecryptCallback { std::vector<uint8_t>* out_; }; -quiche::QuicheStringPiece StringPiece(const std::vector<uint8_t>& in) { - return quiche::QuicheStringPiece(reinterpret_cast<const char*>(in.data()), - in.size()); +absl::string_view StringPiece(const std::vector<uint8_t>& in) { + return absl::string_view(reinterpret_cast<const char*>(in.data()), in.size()); } class SimpleTicketCrypterTest : public QuicTest { @@ -81,7 +80,7 @@ TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithModifiedCiphertext) { TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithEmptyCiphertext) { std::vector<uint8_t> out_plaintext; - ticket_crypter_.Decrypt(quiche::QuicheStringPiece(), + ticket_crypter_.Decrypt(absl::string_view(), std::make_unique<DecryptCallback>(&out_plaintext)); EXPECT_TRUE(out_plaintext.empty()); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_constants.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_constants.cc index 71ac1395e94..8d60d5e86d1 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_constants.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_constants.cc @@ -8,7 +8,7 @@ #include <memory> #include <vector> -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h" @@ -290,7 +290,7 @@ const std::vector<HpackHuffmanSymbol>& HpackHuffmanCodeVector() { // The "constructor" for a HpackStaticEntry that computes the lengths at // compile time. #define STATIC_ENTRY(name, value) \ - { name, QUICHE_ARRAYSIZE(name) - 1, value, QUICHE_ARRAYSIZE(value) - 1 } + { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 } const std::vector<HpackStaticEntry>& HpackStaticTableVector() { static const auto* kHpackStaticTable = new std::vector<HpackStaticEntry>{ diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.cc index cf9a0e79b35..fa54464ed94 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.cc @@ -185,7 +185,7 @@ void HpackDecoderAdapter::ListenerAdapter::OnHeaderListEnd() { } void HpackDecoderAdapter::ListenerAdapter::OnHeaderErrorDetected( - quiche::QuicheStringPiece error_message) { + absl::string_view error_message) { SPDY_VLOG(1) << error_message; } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h index f521ee12cd5..36f42b7b749 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h @@ -13,13 +13,13 @@ #include <cstdint> #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_listener.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables.h" #include "net/third_party/quiche/src/http2/hpack/hpack_string.h" #include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" #include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" @@ -113,8 +113,7 @@ class QUICHE_EXPORT_PRIVATE HpackDecoderAdapter { void OnHeader(const http2::HpackString& name, const http2::HpackString& value) override; void OnHeaderListEnd() override; - void OnHeaderErrorDetected( - quiche::QuicheStringPiece error_message) override; + void OnHeaderErrorDetected(absl::string_view error_message) override; // Override the HpackDecoderTablesDebugListener methods: int64_t OnEntryInserted(const http2::HpackStringPair& entry, diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter_test.cc index 2fe01fcf7cd..5a69a126a59 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter_test.cc @@ -13,15 +13,16 @@ #include <utility> #include <vector> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_state.h" #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder_tables.h" #include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h" +#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h" @@ -65,8 +66,8 @@ class HpackDecoderAdapterPeer { explicit HpackDecoderAdapterPeer(HpackDecoderAdapter* decoder) : decoder_(decoder) {} - void HandleHeaderRepresentation(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void HandleHeaderRepresentation(absl::string_view name, + absl::string_view value) { decoder_->listener_adapter_.OnHeader(HpackString(name), HpackString(value)); } @@ -133,7 +134,7 @@ class HpackDecoderAdapterTest } } - bool HandleControlFrameHeadersData(quiche::QuicheStringPiece str) { + bool HandleControlFrameHeadersData(absl::string_view str) { SPDY_VLOG(3) << "HandleControlFrameHeadersData:\n" << SpdyHexDump(str); bytes_passed_in_ += str.size(); return decoder_.HandleControlFrameHeadersData(str.data(), str.size()); @@ -147,7 +148,7 @@ class HpackDecoderAdapterTest return rc; } - bool DecodeHeaderBlock(quiche::QuicheStringPiece str, + bool DecodeHeaderBlock(absl::string_view str, bool check_decoded_size = true) { // Don't call this again if HandleControlFrameHeadersData failed previously. EXPECT_FALSE(decode_has_failed_); @@ -178,7 +179,7 @@ class HpackDecoderAdapterTest decode_has_failed_ = true; return false; } - total_hpack_bytes = handler_.compressed_header_bytes_parsed(); + total_hpack_bytes = handler_.compressed_header_bytes(); } else { if (!HandleControlFrameHeadersComplete(&total_hpack_bytes)) { decode_has_failed_ = true; @@ -187,7 +188,8 @@ class HpackDecoderAdapterTest } EXPECT_EQ(total_hpack_bytes, bytes_passed_in_); if (check_decoded_size && start_choice_ == START_WITH_HANDLER) { - EXPECT_EQ(handler_.header_bytes_parsed(), SizeOfHeaders(decoded_block())); + EXPECT_EQ(handler_.uncompressed_header_bytes(), + SizeOfHeaders(decoded_block())); } return true; } @@ -225,8 +227,7 @@ class HpackDecoderAdapterTest return size; } - const SpdyHeaderBlock& DecodeBlockExpectingSuccess( - quiche::QuicheStringPiece str) { + const SpdyHeaderBlock& DecodeBlockExpectingSuccess(absl::string_view str) { EXPECT_TRUE(DecodeHeaderBlock(str)); return decoded_block(); } @@ -253,7 +254,7 @@ class HpackDecoderAdapterTest http2::test::Http2Random random_; HpackDecoderAdapter decoder_; test::HpackDecoderAdapterPeer decoder_peer_; - TestHeadersHandler handler_; + RecordingHeadersHandler handler_; StartChoice start_choice_; bool randomly_split_input_buffer_; bool decode_has_failed_ = false; @@ -434,11 +435,10 @@ TEST_P(HpackDecoderAdapterTest, HandleHeaderRepresentation) { decoded_block(), ElementsAre( Pair("cookie", " part 1; part 2 ; part3; fin!"), - Pair("passed-through", quiche::QuicheStringPiece("foo\0baz", 7)), - Pair("joined", - quiche::QuicheStringPiece("joined\0value 1\0value 2", 22)), + Pair("passed-through", absl::string_view("foo\0baz", 7)), + Pair("joined", absl::string_view("joined\0value 1\0value 2", 22)), Pair("empty", ""), - Pair("empty-joined", quiche::QuicheStringPiece("\0foo\0\0", 6)))); + Pair("empty-joined", absl::string_view("\0foo\0\0", 6)))); } // Decoding indexed static table field should work. @@ -503,7 +503,7 @@ TEST_P(HpackDecoderAdapterTest, ContextUpdateMaximumSize) { output_stream.AppendUint32(126); output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(126u, decoder_peer_.header_table_size_limit()); } { @@ -513,7 +513,7 @@ TEST_P(HpackDecoderAdapterTest, ContextUpdateMaximumSize) { output_stream.AppendUint32(kDefaultHeaderTableSizeSetting); output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(kDefaultHeaderTableSizeSetting, decoder_peer_.header_table_size_limit()); } @@ -524,7 +524,7 @@ TEST_P(HpackDecoderAdapterTest, ContextUpdateMaximumSize) { output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1); output_stream.TakeString(&input); - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(kDefaultHeaderTableSizeSetting, decoder_peer_.header_table_size_limit()); } @@ -542,7 +542,7 @@ TEST_P(HpackDecoderAdapterTest, TwoTableSizeUpdates) { output_stream.AppendUint32(122); output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(122u, decoder_peer_.header_table_size_limit()); } } @@ -562,7 +562,7 @@ TEST_P(HpackDecoderAdapterTest, ThreeTableSizeUpdatesError) { output_stream.TakeString(&input); - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(10u, decoder_peer_.header_table_size_limit()); } } @@ -581,7 +581,7 @@ TEST_P(HpackDecoderAdapterTest, TableSizeUpdateSecondError) { output_stream.TakeString(&input); - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(kDefaultHeaderTableSizeSetting, decoder_peer_.header_table_size_limit()); } @@ -604,7 +604,7 @@ TEST_P(HpackDecoderAdapterTest, TableSizeUpdateFirstThirdError) { output_stream.TakeString(&input); - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece(input))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view(input))); EXPECT_EQ(60u, decoder_peer_.header_table_size_limit()); } } @@ -616,7 +616,7 @@ TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexing) { // name. const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2"; const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess( - quiche::QuicheStringPiece(input, QUICHE_ARRAYSIZE(input) - 1)); + absl::string_view(input, ABSL_ARRAYSIZE(input) - 1)); SpdyHeaderBlock expected_header_set; expected_header_set[":path"] = "/sample/path"; @@ -629,7 +629,7 @@ TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexing) { TEST_P(HpackDecoderAdapterTest, LiteralHeaderIncrementalIndexing) { const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"; const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess( - quiche::QuicheStringPiece(input, QUICHE_ARRAYSIZE(input) - 1)); + absl::string_view(input, ABSL_ARRAYSIZE(input) - 1)); SpdyHeaderBlock expected_header_set; expected_header_set[":path"] = "/sample/path"; @@ -642,23 +642,23 @@ TEST_P(HpackDecoderAdapterTest, LiteralHeaderWithIndexingInvalidNameIndex) { EXPECT_TRUE(EncodeAndDecodeDynamicTableSizeUpdates(0, 0)); // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x7d\x03ooo"))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x7d\x03ooo"))); // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x7e\x03ooo"))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x7e\x03ooo"))); } TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexingInvalidNameIndex) { // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x0f\x2e\x03ooo"))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x0f\x2e\x03ooo"))); // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x0f\x2f\x03ooo"))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x0f\x2f\x03ooo"))); } TEST_P(HpackDecoderAdapterTest, LiteralHeaderNeverIndexedInvalidNameIndex) { // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x1f\x2e\x03ooo"))); + EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x1f\x2e\x03ooo"))); // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(quiche::QuicheStringPiece("\x1f\x2f\x03ooo"))); + EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x1f\x2f\x03ooo"))); } TEST_P(HpackDecoderAdapterTest, TruncatedIndex) { @@ -710,7 +710,7 @@ TEST_P(HpackDecoderAdapterTest, HuffmanEOSError) { // Round-tripping the header set from RFC 7541 C.3.1 should work. // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 TEST_P(HpackDecoderAdapterTest, BasicC31) { - HpackEncoder encoder(ObtainHpackHuffmanTable()); + HpackEncoder encoder; SpdyHeaderBlock expected_header_set; expected_header_set[":method"] = "GET"; @@ -1055,10 +1055,10 @@ TEST_P(HpackDecoderAdapterTest, ReuseNameOfEvictedEntry) { hbb.AppendDynamicTableSizeUpdate(0); hbb.AppendDynamicTableSizeUpdate(63); - const quiche::QuicheStringPiece name("some-name"); - const quiche::QuicheStringPiece value1("some-value"); - const quiche::QuicheStringPiece value2("another-value"); - const quiche::QuicheStringPiece value3("yet-another-value"); + const absl::string_view name("some-name"); + const absl::string_view value1("some-value"); + const absl::string_view value2("another-value"); + const absl::string_view value3("yet-another-value"); // Add an entry that will become the first in the dynamic table, entry 62. hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false, @@ -1106,7 +1106,7 @@ TEST_P(HpackDecoderAdapterTest, ReuseNameOfEvictedEntry) { EXPECT_EQ(expected_header_set, decoded_block()); if (start_choice_ == START_WITH_HANDLER) { - EXPECT_EQ(handler_.header_bytes_parsed(), + EXPECT_EQ(handler_.uncompressed_header_bytes(), 6 * name.size() + 2 * value1.size() + 2 * value2.size() + 2 * value3.size()); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.cc index 71b94a37f3f..c0d2ec6f8c8 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.cc @@ -8,6 +8,7 @@ #include <limits> #include <utility> +#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h" @@ -57,12 +58,10 @@ class HpackEncoder::RepresentationIterator { namespace { // The default header listener. -void NoOpListener(quiche::QuicheStringPiece /*name*/, - quiche::QuicheStringPiece /*value*/) {} +void NoOpListener(absl::string_view /*name*/, absl::string_view /*value*/) {} // The default HPACK indexing policy. -bool DefaultPolicy(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece /* value */) { +bool DefaultPolicy(absl::string_view name, absl::string_view /* value */) { if (name.empty()) { return false; } @@ -77,14 +76,16 @@ bool DefaultPolicy(quiche::QuicheStringPiece name, } // namespace -HpackEncoder::HpackEncoder(const HpackHuffmanTable& table) +HpackEncoder::HpackEncoder() : output_stream_(), - huffman_table_(table), + huffman_table_(ObtainHpackHuffmanTable()), min_table_size_setting_received_(std::numeric_limits<size_t>::max()), listener_(NoOpListener), should_index_(DefaultPolicy), enable_compression_(true), - should_emit_table_size_(false) {} + should_emit_table_size_(false), + use_fast_huffman_encoder_( + GetSpdyReloadableFlag(http2_use_fast_huffman_encoder)) {} HpackEncoder::~HpackEncoder() = default; @@ -197,15 +198,24 @@ void HpackEncoder::EmitLiteral(const Representation& representation) { EmitString(representation.second); } -void HpackEncoder::EmitString(quiche::QuicheStringPiece str) { +void HpackEncoder::EmitString(absl::string_view str) { size_t encoded_size = - enable_compression_ ? huffman_table_.EncodedSize(str) : str.size(); + enable_compression_ + ? (use_fast_huffman_encoder_ ? http2::HuffmanSize(str) + : huffman_table_.EncodedSize(str)) + : str.size(); if (encoded_size < str.size()) { SPDY_DVLOG(2) << "Emitted Huffman-encoded string of length " << encoded_size; output_stream_.AppendPrefix(kStringLiteralHuffmanEncoded); output_stream_.AppendUint32(encoded_size); - huffman_table_.EncodeString(str, &output_stream_); + if (use_fast_huffman_encoder_) { + SPDY_CODE_COUNT(http2_use_fast_huffman_encoder); + http2::HuffmanEncodeFast(str, encoded_size, + output_stream_.MutableString()); + } else { + huffman_table_.EncodeString(str, &output_stream_); + } } else { SPDY_DVLOG(2) << "Emitted literal string of length " << str.size(); output_stream_.AppendPrefix(kStringLiteralIdentityEncoded); @@ -238,21 +248,19 @@ void HpackEncoder::CookieToCrumbs(const Representation& cookie, // See Section 8.1.2.5. "Compressing the Cookie Header Field" in the HTTP/2 // specification at https://tools.ietf.org/html/draft-ietf-httpbis-http2-14. // Cookie values are split into individually-encoded HPACK representations. - quiche::QuicheStringPiece cookie_value = cookie.second; + absl::string_view cookie_value = cookie.second; // Consume leading and trailing whitespace if present. - quiche::QuicheStringPiece::size_type first = - cookie_value.find_first_not_of(" \t"); - quiche::QuicheStringPiece::size_type last = - cookie_value.find_last_not_of(" \t"); - if (first == quiche::QuicheStringPiece::npos) { - cookie_value = quiche::QuicheStringPiece(); + absl::string_view::size_type first = cookie_value.find_first_not_of(" \t"); + absl::string_view::size_type last = cookie_value.find_last_not_of(" \t"); + if (first == absl::string_view::npos) { + cookie_value = absl::string_view(); } else { cookie_value = cookie_value.substr(first, (last - first) + 1); } for (size_t pos = 0;;) { size_t end = cookie_value.find(";", pos); - if (end == quiche::QuicheStringPiece::npos) { + if (end == absl::string_view::npos) { out->push_back(std::make_pair(cookie.first, cookie_value.substr(pos))); break; } @@ -272,12 +280,12 @@ void HpackEncoder::DecomposeRepresentation(const Representation& header_field, Representations* out) { size_t pos = 0; size_t end = 0; - while (end != quiche::QuicheStringPiece::npos) { + while (end != absl::string_view::npos) { end = header_field.second.find('\0', pos); out->push_back(std::make_pair( header_field.first, header_field.second.substr( - pos, end == quiche::QuicheStringPiece::npos ? end : end - pos))); + pos, end == absl::string_view::npos ? end : end - pos))); pos = end + 1; } } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h index 534b9e6c086..f9cc0d10f10 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h @@ -14,8 +14,8 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" @@ -33,23 +33,20 @@ class HpackEncoderPeer; class QUICHE_EXPORT_PRIVATE HpackEncoder { public: - using Representation = - std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece>; + using Representation = std::pair<absl::string_view, absl::string_view>; using Representations = std::vector<Representation>; // Callers may provide a HeaderListener to be informed of header name-value // pairs processed by this encoder. using HeaderListener = - std::function<void(quiche::QuicheStringPiece, quiche::QuicheStringPiece)>; + std::function<void(absl::string_view, absl::string_view)>; // An indexing policy should return true if the provided header name-value // pair should be inserted into the HPACK dynamic table. using IndexingPolicy = - std::function<bool(quiche::QuicheStringPiece, quiche::QuicheStringPiece)>; + std::function<bool(absl::string_view, absl::string_view)>; - // |table| is an initialized HPACK Huffman table, having an - // externally-managed lifetime which spans beyond HpackEncoder. - explicit HpackEncoder(const HpackHuffmanTable& table); + HpackEncoder(); HpackEncoder(const HpackEncoder&) = delete; HpackEncoder& operator=(const HpackEncoder&) = delete; ~HpackEncoder(); @@ -127,7 +124,7 @@ class QUICHE_EXPORT_PRIVATE HpackEncoder { void EmitLiteral(const Representation& representation); // Emits a Huffman or identity string (whichever is smaller). - void EmitString(quiche::QuicheStringPiece str); + void EmitString(absl::string_view str); // Emits the current dynamic table size if the table size was recently // updated and we have not yet emitted it (Section 6.3). @@ -150,6 +147,8 @@ class QUICHE_EXPORT_PRIVATE HpackEncoder { IndexingPolicy should_index_; bool enable_compression_; bool should_emit_table_size_; + // Latched value of gfe2_reloadable_flag_http2_use_fast_huffman_encoder. + const bool use_fast_huffman_encoder_; }; } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder_test.cc index f6f9f87a1c0..52693dbbab4 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder_test.cc @@ -5,8 +5,9 @@ #include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" #include <cstdint> -#include <map> +#include <utility> +#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h" #include "net/third_party/quiche/src/http2/test_tools/http2_random.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h" @@ -39,15 +40,12 @@ class HpackEncoderPeer { bool compression_enabled() const { return encoder_->enable_compression_; } HpackHeaderTable* table() { return &encoder_->header_table_; } HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); } - const HpackHuffmanTable& huffman_table() const { - return encoder_->huffman_table_; - } - void EmitString(quiche::QuicheStringPiece str) { encoder_->EmitString(str); } + void EmitString(absl::string_view str) { encoder_->EmitString(str); } void TakeString(std::string* out) { encoder_->output_stream_.TakeString(out); } - static void CookieToCrumbs(quiche::QuicheStringPiece cookie, - std::vector<quiche::QuicheStringPiece>* out) { + static void CookieToCrumbs(absl::string_view cookie, + std::vector<absl::string_view>* out) { Representations tmp; HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp); @@ -56,9 +54,8 @@ class HpackEncoderPeer { out->push_back(tmp[i].second); } } - static void DecomposeRepresentation( - quiche::QuicheStringPiece value, - std::vector<quiche::QuicheStringPiece>* out) { + static void DecomposeRepresentation(absl::string_view value, + std::vector<absl::string_view>* out) { Representations tmp; HpackEncoder::DecomposeRepresentation(std::make_pair("foobar", value), &tmp); @@ -128,15 +125,17 @@ enum EncodeStrategy { kRepresentations, }; -class HpackEncoderTestBase : public QuicheTest { +class HpackEncoderTest + : public QuicheTestWithParam<std::tuple<EncodeStrategy, bool>> { protected: typedef test::HpackEncoderPeer::Representations Representations; - HpackEncoderTestBase() - : encoder_(ObtainHpackHuffmanTable()), - peer_(&encoder_), + HpackEncoderTest() + : peer_(&encoder_), static_(peer_.table()->GetByIndex(1)), - headers_storage_(1024 /* block size */) {} + headers_storage_(1024 /* block size */), + strategy_(std::get<0>(GetParam())), + use_fast_huffman_encoder_(std::get<1>(GetParam())) {} void SetUp() override { // Populate dynamic entries into the table fixture. For simplicity each @@ -150,12 +149,11 @@ class HpackEncoderTestBase : public QuicheTest { peer_.table()->SetMaxSize(peer_.table()->size()); } - void SaveHeaders(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { - quiche::QuicheStringPiece n( - headers_storage_.Memdup(name.data(), name.size()), name.size()); - quiche::QuicheStringPiece v( - headers_storage_.Memdup(value.data(), value.size()), value.size()); + void SaveHeaders(absl::string_view name, absl::string_view value) { + absl::string_view n(headers_storage_.Memdup(name.data(), name.size()), + name.size()); + absl::string_view v(headers_storage_.Memdup(value.data(), value.size()), + value.size()); headers_observed_.push_back(std::make_pair(n, v)); } @@ -164,40 +162,45 @@ class HpackEncoderTestBase : public QuicheTest { expected_.AppendUint32(index); } void ExpectIndexedLiteral(const HpackEntry* key_entry, - quiche::QuicheStringPiece value) { + absl::string_view value) { expected_.AppendPrefix(kLiteralIncrementalIndexOpcode); expected_.AppendUint32(IndexOf(key_entry)); ExpectString(&expected_, value); } - void ExpectIndexedLiteral(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void ExpectIndexedLiteral(absl::string_view name, absl::string_view value) { expected_.AppendPrefix(kLiteralIncrementalIndexOpcode); expected_.AppendUint32(0); ExpectString(&expected_, name); ExpectString(&expected_, value); } - void ExpectNonIndexedLiteral(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void ExpectNonIndexedLiteral(absl::string_view name, + absl::string_view value) { expected_.AppendPrefix(kLiteralNoIndexOpcode); expected_.AppendUint32(0); ExpectString(&expected_, name); ExpectString(&expected_, value); } void ExpectNonIndexedLiteralWithNameIndex(const HpackEntry* key_entry, - quiche::QuicheStringPiece value) { + absl::string_view value) { expected_.AppendPrefix(kLiteralNoIndexOpcode); expected_.AppendUint32(IndexOf(key_entry)); ExpectString(&expected_, value); } - void ExpectString(HpackOutputStream* stream, quiche::QuicheStringPiece str) { - const HpackHuffmanTable& huffman_table = peer_.huffman_table(); - size_t encoded_size = peer_.compression_enabled() - ? huffman_table.EncodedSize(str) - : str.size(); + void ExpectString(HpackOutputStream* stream, absl::string_view str) { + const HpackHuffmanTable& huffman_table = ObtainHpackHuffmanTable(); + size_t encoded_size = + peer_.compression_enabled() + ? (use_fast_huffman_encoder_ ? http2::HuffmanSize(str) + : huffman_table.EncodedSize(str)) + : str.size(); if (encoded_size < str.size()) { expected_.AppendPrefix(kStringLiteralHuffmanEncoded); expected_.AppendUint32(encoded_size); - huffman_table.EncodeString(str, stream); + if (use_fast_huffman_encoder_) { + http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString()); + } else { + huffman_table.EncodeString(str, stream); + } } else { expected_.AppendPrefix(kStringLiteralIdentityEncoded); expected_.AppendUint32(str.size()); @@ -255,25 +258,32 @@ class HpackEncoderTestBase : public QuicheTest { const HpackEntry* cookie_c_; SpdySimpleArena headers_storage_; - std::vector<std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece>> + std::vector<std::pair<absl::string_view, absl::string_view>> headers_observed_; HpackOutputStream expected_; - EncodeStrategy strategy_ = kDefault; + const EncodeStrategy strategy_; + const bool use_fast_huffman_encoder_; }; -TEST_F(HpackEncoderTestBase, EncodeRepresentations) { +using HpackEncoderTestWithDefaultStrategy = HpackEncoderTest; + +INSTANTIATE_TEST_SUITE_P(HpackEncoderTests, + HpackEncoderTestWithDefaultStrategy, + ::testing::Combine(::testing::Values(kDefault), + ::testing::Bool())); + +TEST_P(HpackEncoderTestWithDefaultStrategy, EncodeRepresentations) { encoder_.SetHeaderListener( - [this](quiche::QuicheStringPiece name, quiche::QuicheStringPiece value) { + [this](absl::string_view name, absl::string_view value) { this->SaveHeaders(name, value); }); - const std::vector< - std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece>> + const std::vector<std::pair<absl::string_view, absl::string_view>> header_list = {{"cookie", "val1; val2;val3"}, {":path", "/home"}, {"accept", "text/html, text/plain,application/xml"}, {"cookie", "val4"}, - {"withnul", quiche::QuicheStringPiece("one\0two", 7)}}; + {"withnul", absl::string_view("one\0two", 7)}}; ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"), "/home"); ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val1"); @@ -282,7 +292,7 @@ TEST_F(HpackEncoderTestBase, EncodeRepresentations) { ExpectIndexedLiteral(peer_.table()->GetByName("accept"), "text/html, text/plain,application/xml"); ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val4"); - ExpectIndexedLiteral("withnul", quiche::QuicheStringPiece("one\0two", 7)); + ExpectIndexedLiteral("withnul", absl::string_view("one\0two", 7)); CompareWithExpectedEncoding(header_list); EXPECT_THAT( @@ -291,27 +301,19 @@ TEST_F(HpackEncoderTestBase, EncodeRepresentations) { Pair("cookie", "val2"), Pair("cookie", "val3"), Pair("accept", "text/html, text/plain,application/xml"), Pair("cookie", "val4"), - Pair("withnul", quiche::QuicheStringPiece("one\0two", 7)))); + Pair("withnul", absl::string_view("one\0two", 7)))); } -class HpackEncoderTest : public HpackEncoderTestBase, - public ::testing::WithParamInterface<EncodeStrategy> { - protected: - void SetUp() override { - strategy_ = GetParam(); - HpackEncoderTestBase::SetUp(); - } -}; - INSTANTIATE_TEST_SUITE_P(HpackEncoderTests, HpackEncoderTest, - ::testing::Values(kDefault, - kIncremental, - kRepresentations)); + ::testing::Combine(::testing::Values(kDefault, + kIncremental, + kRepresentations), + ::testing::Bool())); TEST_P(HpackEncoderTest, SingleDynamicIndex) { encoder_.SetHeaderListener( - [this](quiche::QuicheStringPiece name, quiche::QuicheStringPiece value) { + [this](absl::string_view name, absl::string_view value) { this->SaveHeaders(name, value); }); @@ -432,7 +434,7 @@ TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) { TEST_P(HpackEncoderTest, EncodingWithoutCompression) { encoder_.SetHeaderListener( - [this](quiche::QuicheStringPiece name, quiche::QuicheStringPiece value) { + [this](absl::string_view name, absl::string_view value) { this->SaveHeaders(name, value); }); encoder_.DisableCompression(); @@ -460,11 +462,10 @@ TEST_P(HpackEncoderTest, EncodingWithoutCompression) { if (strategy_ == kRepresentations) { EXPECT_THAT( headers_observed_, - ElementsAre( - Pair(":path", "/index.html"), Pair("cookie", "foo=bar"), - Pair("cookie", "baz=bing"), - Pair("hello", quiche::QuicheStringPiece("goodbye\0aloha", 13)), - Pair("multivalue", "value1, value2"))); + ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"), + Pair("cookie", "baz=bing"), + Pair("hello", absl::string_view("goodbye\0aloha", 13)), + Pair("multivalue", "value1, value2"))); } else { EXPECT_THAT( headers_observed_, @@ -477,7 +478,7 @@ TEST_P(HpackEncoderTest, EncodingWithoutCompression) { TEST_P(HpackEncoderTest, MultipleEncodingPasses) { encoder_.SetHeaderListener( - [this](quiche::QuicheStringPiece name, quiche::QuicheStringPiece value) { + [this](absl::string_view name, absl::string_view value) { this->SaveHeaders(name, value); }); @@ -574,7 +575,7 @@ TEST_P(HpackEncoderTest, PseudoHeadersFirst) { TEST_P(HpackEncoderTest, CookieToCrumbs) { test::HpackEncoderPeer peer(nullptr); - std::vector<quiche::QuicheStringPiece> out; + std::vector<absl::string_view> out; // Leading and trailing whitespace is consumed. A space after ';' is consumed. // All other spaces remain. ';' at beginning and end of string produce empty @@ -608,7 +609,7 @@ TEST_P(HpackEncoderTest, CookieToCrumbs) { TEST_P(HpackEncoderTest, DecomposeRepresentation) { test::HpackEncoderPeer peer(nullptr); - std::vector<quiche::QuicheStringPiece> out; + std::vector<absl::string_view> out; peer.DecomposeRepresentation("", &out); EXPECT_THAT(out, ElementsAre("")); @@ -616,19 +617,16 @@ TEST_P(HpackEncoderTest, DecomposeRepresentation) { peer.DecomposeRepresentation("foobar", &out); EXPECT_THAT(out, ElementsAre("foobar")); - peer.DecomposeRepresentation(quiche::QuicheStringPiece("foo\0bar", 7), &out); + peer.DecomposeRepresentation(absl::string_view("foo\0bar", 7), &out); EXPECT_THAT(out, ElementsAre("foo", "bar")); - peer.DecomposeRepresentation(quiche::QuicheStringPiece("\0foo\0bar", 8), - &out); + peer.DecomposeRepresentation(absl::string_view("\0foo\0bar", 8), &out); EXPECT_THAT(out, ElementsAre("", "foo", "bar")); - peer.DecomposeRepresentation(quiche::QuicheStringPiece("foo\0bar\0", 8), - &out); + peer.DecomposeRepresentation(absl::string_view("foo\0bar\0", 8), &out); EXPECT_THAT(out, ElementsAre("foo", "bar", "")); - peer.DecomposeRepresentation(quiche::QuicheStringPiece("\0foo\0bar\0", 9), - &out); + peer.DecomposeRepresentation(absl::string_view("\0foo\0bar\0", 9), &out); EXPECT_THAT(out, ElementsAre("", "foo", "bar", "")); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.cc index 586f3216d24..7f251e6e1ff 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.cc @@ -12,8 +12,8 @@ namespace spdy { const size_t HpackEntry::kSizeOverhead = 32; -HpackEntry::HpackEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, +HpackEntry::HpackEntry(absl::string_view name, + absl::string_view value, bool is_static, size_t insertion_index) : name_(name.data(), name.size()), @@ -24,8 +24,7 @@ HpackEntry::HpackEntry(quiche::QuicheStringPiece name, type_(is_static ? STATIC : DYNAMIC), time_added_(0) {} -HpackEntry::HpackEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) +HpackEntry::HpackEntry(absl::string_view name, absl::string_view value) : name_ref_(name), value_ref_(value), insertion_index_(0), @@ -44,8 +43,8 @@ HpackEntry::HpackEntry(const HpackEntry& other) } else { name_ = other.name_; value_ = other.value_; - name_ref_ = quiche::QuicheStringPiece(name_.data(), name_.size()); - value_ref_ = quiche::QuicheStringPiece(value_.data(), value_.size()); + name_ref_ = absl::string_view(name_.data(), name_.size()); + value_ref_ = absl::string_view(value_.data(), value_.size()); } } @@ -61,16 +60,15 @@ HpackEntry& HpackEntry::operator=(const HpackEntry& other) { } name_ = other.name_; value_ = other.value_; - name_ref_ = quiche::QuicheStringPiece(name_.data(), name_.size()); - value_ref_ = quiche::QuicheStringPiece(value_.data(), value_.size()); + name_ref_ = absl::string_view(name_.data(), name_.size()); + value_ref_ = absl::string_view(value_.data(), value_.size()); return *this; } HpackEntry::~HpackEntry() = default; // static -size_t HpackEntry::Size(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +size_t HpackEntry::Size(absl::string_view name, absl::string_view value) { return name.size() + value.size() + kSizeOverhead; } size_t HpackEntry::Size() const { diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h index 750c7e61782..e9c4efcfc96 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h @@ -9,8 +9,8 @@ #include <cstdint> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" // All section references below are to // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08 @@ -34,15 +34,15 @@ class QUICHE_EXPORT_PRIVATE HpackEntry { // The combination of |is_static| and |insertion_index| allows an // HpackEntryTable to determine the index of an HpackEntry in O(1) time. // Copies |name| and |value|. - HpackEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, + HpackEntry(absl::string_view name, + absl::string_view value, bool is_static, size_t insertion_index); // Create a 'lookup' entry (only) suitable for querying a HpackEntrySet. The // instance InsertionIndex() always returns 0 and IsLookup() returns true. // The memory backing |name| and |value| must outlive this object. - HpackEntry(quiche::QuicheStringPiece name, quiche::QuicheStringPiece value); + HpackEntry(absl::string_view name, absl::string_view value); HpackEntry(const HpackEntry& other); HpackEntry& operator=(const HpackEntry& other); @@ -53,8 +53,8 @@ class QUICHE_EXPORT_PRIVATE HpackEntry { ~HpackEntry(); - quiche::QuicheStringPiece name() const { return name_ref_; } - quiche::QuicheStringPiece value() const { return value_ref_; } + absl::string_view name() const { return name_ref_; } + absl::string_view value() const { return value_ref_; } // Returns whether this entry is a member of the static (as opposed to // dynamic) table. @@ -67,8 +67,7 @@ class QUICHE_EXPORT_PRIVATE HpackEntry { size_t InsertionIndex() const { return insertion_index_; } // Returns the size of an entry as defined in 5.1. - static size_t Size(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + static size_t Size(absl::string_view name, absl::string_view value); size_t Size() const; std::string GetDebugString() const; @@ -92,8 +91,8 @@ class QUICHE_EXPORT_PRIVATE HpackEntry { // These members are always valid. For DYNAMIC and STATIC entries, they // always point to |name_| and |value_|. - quiche::QuicheStringPiece name_ref_; - quiche::QuicheStringPiece value_ref_; + absl::string_view name_ref_; + absl::string_view value_ref_; // The entry's index in the total set of entries ever inserted into the header // table. diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.cc index 67a0a5f443f..8adbf43aad3 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_containers.h" @@ -60,7 +61,7 @@ const HpackEntry* HpackHeaderTable::GetByIndex(size_t index) { return nullptr; } -const HpackEntry* HpackHeaderTable::GetByName(quiche::QuicheStringPiece name) { +const HpackEntry* HpackHeaderTable::GetByName(absl::string_view name) { { auto it = static_name_index_.find(name); if (it != static_name_index_.end()) { @@ -80,9 +81,8 @@ const HpackEntry* HpackHeaderTable::GetByName(quiche::QuicheStringPiece name) { return nullptr; } -const HpackEntry* HpackHeaderTable::GetByNameAndValue( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +const HpackEntry* HpackHeaderTable::GetByNameAndValue(absl::string_view name, + absl::string_view value) { HpackEntry query(name, value); { auto it = static_index_.find(&query); @@ -128,8 +128,8 @@ void HpackHeaderTable::SetSettingsHeaderTableSize(size_t settings_size) { SetMaxSize(settings_size_bound_); } -void HpackHeaderTable::EvictionSet(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, +void HpackHeaderTable::EvictionSet(absl::string_view name, + absl::string_view value, EntryTable::iterator* begin_out, EntryTable::iterator* end_out) { size_t eviction_count = EvictionCountForEntry(name, value); @@ -137,9 +137,8 @@ void HpackHeaderTable::EvictionSet(quiche::QuicheStringPiece name, *end_out = dynamic_entries_.end(); } -size_t HpackHeaderTable::EvictionCountForEntry( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) const { +size_t HpackHeaderTable::EvictionCountForEntry(absl::string_view name, + absl::string_view value) const { size_t available_size = max_size_ - size_; size_t entry_size = HpackEntry::Size(name, value); @@ -185,9 +184,8 @@ void HpackHeaderTable::Evict(size_t count) { } } -const HpackEntry* HpackHeaderTable::TryAddEntry( - quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { +const HpackEntry* HpackHeaderTable::TryAddEntry(absl::string_view name, + absl::string_view value) { Evict(EvictionCountForEntry(name, value)); size_t entry_size = HpackEntry::Size(name, value); @@ -255,7 +253,7 @@ void HpackHeaderTable::DebugLogTableState() const { SPDY_DVLOG(2) << " " << entry->GetDebugString(); } SPDY_DVLOG(2) << "Full Static Name Index:"; - for (const auto it : static_name_index_) { + for (const auto& it : static_name_index_) { SPDY_DVLOG(2) << " " << it.first << ": " << it.second->GetDebugString(); } SPDY_DVLOG(2) << "Full Dynamic Index:"; @@ -263,7 +261,7 @@ void HpackHeaderTable::DebugLogTableState() const { SPDY_DVLOG(2) << " " << entry->GetDebugString(); } SPDY_DVLOG(2) << "Full Dynamic Name Index:"; - for (const auto it : dynamic_name_index_) { + for (const auto& it : dynamic_name_index_) { SPDY_DVLOG(2) << " " << it.first << ": " << it.second->GetDebugString(); } } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h index 88ef6d7b73a..f835ae72874 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h @@ -10,8 +10,9 @@ #include <deque> #include <memory> +#include "absl/hash/hash.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_containers.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_macros.h" @@ -67,9 +68,9 @@ class QUICHE_EXPORT_PRIVATE HpackHeaderTable { bool operator()(const HpackEntry* lhs, const HpackEntry* rhs) const; }; using UnorderedEntrySet = SpdyHashSet<HpackEntry*, EntryHasher, EntriesEq>; - using NameToEntryMap = SpdyHashMap<quiche::QuicheStringPiece, + using NameToEntryMap = SpdyHashMap<absl::string_view, const HpackEntry*, - quiche::QuicheStringPieceHash>; + absl::Hash<absl::string_view>>; HpackHeaderTable(); HpackHeaderTable(const HpackHeaderTable&) = delete; @@ -89,11 +90,11 @@ class QUICHE_EXPORT_PRIVATE HpackHeaderTable { const HpackEntry* GetByIndex(size_t index); // Returns the lowest-value entry having |name|, or NULL. - const HpackEntry* GetByName(quiche::QuicheStringPiece name); + const HpackEntry* GetByName(absl::string_view name); // Returns the lowest-index matching entry, or NULL. - const HpackEntry* GetByNameAndValue(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + const HpackEntry* GetByNameAndValue(absl::string_view name, + absl::string_view value); // Returns the index of an entry within this header table. size_t IndexOf(const HpackEntry* entry) const; @@ -109,8 +110,8 @@ class QUICHE_EXPORT_PRIVATE HpackHeaderTable { // Determine the set of entries which would be evicted by the insertion // of |name| & |value| into the table, as per section 4.4. No eviction // actually occurs. The set is returned via range [begin_out, end_out). - void EvictionSet(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value, + void EvictionSet(absl::string_view name, + absl::string_view value, EntryTable::iterator* begin_out, EntryTable::iterator* end_out); @@ -118,8 +119,8 @@ class QUICHE_EXPORT_PRIVATE HpackHeaderTable { // and |value| must not be owned by an entry which could be evicted. The // added HpackEntry is returned, or NULL is returned if all entries were // evicted and the empty table is of insufficent size for the representation. - const HpackEntry* TryAddEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value); + const HpackEntry* TryAddEntry(absl::string_view name, + absl::string_view value); void DebugLogTableState() const SPDY_UNUSED; @@ -132,8 +133,8 @@ class QUICHE_EXPORT_PRIVATE HpackHeaderTable { private: // Returns number of evictions required to enter |name| & |value|. - size_t EvictionCountForEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) const; + size_t EvictionCountForEntry(absl::string_view name, + absl::string_view value) const; // Returns number of evictions required to reclaim |reclaim_size| table size. size_t EvictionCountToReclaim(size_t reclaim_size) const; diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table_test.cc index cc5674f137f..0b6799eb958 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_header_table_test.cc @@ -33,8 +33,8 @@ class HpackHeaderTablePeer { size_t index_size() { return table_->static_index_.size() + table_->dynamic_index_.size(); } - std::vector<HpackEntry*> EvictionSet(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + std::vector<HpackEntry*> EvictionSet(absl::string_view name, + absl::string_view value) { HpackHeaderTable::EntryTable::iterator begin, end; table_->EvictionSet(name, value, &begin, &end); std::vector<HpackEntry*> result; @@ -45,8 +45,8 @@ class HpackHeaderTablePeer { } size_t total_insertions() { return table_->total_insertions_; } size_t dynamic_entries_count() { return table_->dynamic_entries_.size(); } - size_t EvictionCountForEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + size_t EvictionCountForEntry(absl::string_view name, + absl::string_view value) { return table_->EvictionCountForEntry(name, value); } size_t EvictionCountToReclaim(size_t reclaim_size) { @@ -54,8 +54,7 @@ class HpackHeaderTablePeer { } void Evict(size_t count) { return table_->Evict(count); } - void AddDynamicEntry(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void AddDynamicEntry(absl::string_view name, absl::string_view value) { table_->dynamic_entries_.push_back( HpackEntry(name, value, false, table_->total_insertions_++)); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.cc index eb799d08728..aac6d1b8d10 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.cc @@ -96,7 +96,7 @@ bool HpackHuffmanTable::IsInitialized() const { return !code_by_id_.empty(); } -void HpackHuffmanTable::EncodeString(quiche::QuicheStringPiece in, +void HpackHuffmanTable::EncodeString(absl::string_view in, HpackOutputStream* out) const { size_t bit_remnant = 0; for (size_t i = 0; i != in.size(); i++) { @@ -129,7 +129,7 @@ void HpackHuffmanTable::EncodeString(quiche::QuicheStringPiece in, } } -size_t HpackHuffmanTable::EncodedSize(quiche::QuicheStringPiece in) const { +size_t HpackHuffmanTable::EncodedSize(absl::string_view in) const { size_t bit_count = 0; for (size_t i = 0; i != in.size(); i++) { uint16_t symbol_id = static_cast<uint8_t>(in[i]); diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h index b7c264933b3..81af770afb5 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h @@ -9,8 +9,8 @@ #include <cstdint> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" namespace spdy { @@ -45,10 +45,10 @@ class QUICHE_EXPORT_PRIVATE HpackHuffmanTable { // Encodes the input string to the output stream using the table's Huffman // context. - void EncodeString(quiche::QuicheStringPiece in, HpackOutputStream* out) const; + void EncodeString(absl::string_view in, HpackOutputStream* out) const; // Returns the encoded size of the input string. - size_t EncodedSize(quiche::QuicheStringPiece in) const; + size_t EncodedSize(absl::string_view in) const; // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_benchmark.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_benchmark.cc deleted file mode 100644 index aeea7268965..00000000000 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_benchmark.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2020 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. - -// -// $ blaze run -c opt --dynamic_mode=off \ -// -- //net/third_party/quiche/src/spdy/core/hpack:hpack_huffman_table_benchmark \ -// --benchmarks=all --benchmark_memory_usage --benchmark_repetitions=1 -// -// Benchmark Time(ns) CPU(ns) Allocs Iterations -// ----------------------------------------------------------------------------- -// BM_EncodeSmallStrings 463 441 0 100000 0.000B peak-mem -// BM_EncodeLargeString/1k 9003 9069 5 4861 1.125kB peak-mem -// BM_EncodeLargeString/4k 34808 35157 7 1597 4.500kB peak-mem -// BM_EncodeLargeString/32k 275973 270741 10 207 36.000kB peak-mem -// BM_EncodeLargeString/256k 2234748 2236850 13 29 288.000kB peak-mem -// BM_EncodeLargeString/2M 18248449 18717995 16 3 2.250MB peak-mem -// BM_EncodeLargeString/16M 144944895 144415061 19 1 18.000MB peak-mem -// BM_EncodeLargeString/128M 1200907841 1207238809 86 1 144.009MB peak-mem -// - -#include <string> - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" -// This header has multiple DCHECK_* macros with signed-unsigned comparison. -#include "testing/base/public/benchmark.h" -#pragma clang diagnostic pop - -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h" - -namespace spdy { -namespace { - -void BM_EncodeSmallStrings(benchmark::State& state) { - const HpackHuffmanTable& table = ObtainHpackHuffmanTable(); - const std::vector<const std::string> inputs{ - ":method", ":path", "cookie", "set-cookie", "vary", "accept-encoding"}; - for (auto s : state) { - for (const auto& input : inputs) { - HpackOutputStream output_stream; - table.EncodedSize(input); - table.EncodeString(input, &output_stream); - } - } -} - -void BM_EncodeLargeString(benchmark::State& state) { - const HpackHuffmanTable& table = ObtainHpackHuffmanTable(); - const std::string input(state.range(0), 'a'); - for (auto s : state) { - HpackOutputStream output_stream; - table.EncodedSize(input); - table.EncodeString(input, &output_stream); - } -} - -BENCHMARK(BM_EncodeSmallStrings); -BENCHMARK(BM_EncodeLargeString)->Range(1024, 128 * 1024 * 1024); - -} // namespace -} // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_test.cc index f49c73daab6..6c3e288ad20 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table_test.cc @@ -7,8 +7,8 @@ #include <string> #include <utility> +#include "absl/base/macros.h" #include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h" @@ -42,7 +42,7 @@ class GenericHuffmanTableTest : public QuicheTest { protected: GenericHuffmanTableTest() : table_(), peer_(table_) {} - std::string EncodeString(quiche::QuicheStringPiece input) { + std::string EncodeString(absl::string_view input) { std::string result; HpackOutputStream output_stream; table_.EncodeString(input, &output_stream); @@ -69,7 +69,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 3, 6}, {0b11100000000000000000000000000000, 8, 7}}; HpackHuffmanTable table; - EXPECT_TRUE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_TRUE(table.Initialize(code, ABSL_ARRAYSIZE(code))); } { // But using 2 bits with one symbol overflows the code. @@ -83,7 +83,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11100000000000000000000000000000, 3, 6}, {0b00000000000000000000000000000000, 8, 7}}; // Overflow. HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); EXPECT_EQ(7, HpackHuffmanTablePeer(table).failed_symbol_id()); } { @@ -93,7 +93,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 3, 2}, {0b11100000000000000000000000000000, 8, 3}}; HpackHuffmanTable table; - EXPECT_TRUE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_TRUE(table.Initialize(code, ABSL_ARRAYSIZE(code))); } { // But repeating a length overflows the code. @@ -103,7 +103,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 2, 2}, {0b00000000000000000000000000000000, 8, 3}}; // Overflow. HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); EXPECT_EQ(3, HpackHuffmanTablePeer(table).failed_symbol_id()); } { @@ -114,7 +114,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 3, 1}, // Repeat. {0b11100000000000000000000000000000, 8, 3}}; HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); EXPECT_EQ(2, HpackHuffmanTablePeer(table).failed_symbol_id()); } { @@ -124,7 +124,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b10100000000000000000000000000000, 4, 2}, {0b10110000000000000000000000000000, 8, 3}}; HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); EXPECT_EQ(0, HpackHuffmanTablePeer(table).failed_symbol_id()); } { @@ -135,7 +135,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 2, 2}, // Code not canonical. {0b10000000000000000000000000000000, 8, 3}}; HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); EXPECT_EQ(2, HpackHuffmanTablePeer(table).failed_symbol_id()); } { @@ -145,7 +145,7 @@ TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { {0b11000000000000000000000000000000, 3, 2}, {0b11100000000000000000000000000000, 7, 3}}; HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); } } @@ -159,11 +159,11 @@ TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) { {0b10001000000000000000000000000000, 5, 5}, // 6th. {0b10011000000000000000000000000000, 8, 6}, // 8th. {0b10010000000000000000000000000000, 5, 7}}; // 7th. - EXPECT_TRUE(table_.Initialize(code, QUICHE_ARRAYSIZE(code))); + EXPECT_TRUE(table_.Initialize(code, ABSL_ARRAYSIZE(code))); - ASSERT_EQ(QUICHE_ARRAYSIZE(code), peer_.code_by_id().size()); - ASSERT_EQ(QUICHE_ARRAYSIZE(code), peer_.length_by_id().size()); - for (size_t i = 0; i < QUICHE_ARRAYSIZE(code); ++i) { + ASSERT_EQ(ABSL_ARRAYSIZE(code), peer_.code_by_id().size()); + ASSERT_EQ(ABSL_ARRAYSIZE(code), peer_.length_by_id().size()); + for (size_t i = 0; i < ABSL_ARRAYSIZE(code); ++i) { EXPECT_EQ(code[i].code, peer_.code_by_id()[i]); EXPECT_EQ(code[i].length, peer_.length_by_id()[i]); } @@ -171,12 +171,10 @@ TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) { EXPECT_EQ(0b10011000, peer_.pad_bits()); char input_storage[] = {2, 3, 2, 7, 4}; - quiche::QuicheStringPiece input(input_storage, - QUICHE_ARRAYSIZE(input_storage)); + absl::string_view input(input_storage, ABSL_ARRAYSIZE(input_storage)); // By symbol: (2) 00 (3) 010 (2) 00 (7) 10010 (4) 10000 (6 as pad) 1001100. char expect_storage[] = {0b00010001, 0b00101000, 0b01001100}; - quiche::QuicheStringPiece expect(expect_storage, - QUICHE_ARRAYSIZE(expect_storage)); + absl::string_view expect(expect_storage, ABSL_ARRAYSIZE(expect_storage)); EXPECT_EQ(expect, EncodeString(input)); } @@ -215,7 +213,7 @@ TEST_F(HpackHuffmanTableTest, SpecRequestExamples) { "custom-value", }; // Round-trip each test example. - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& encodedFixture(test_table[i]); const std::string& decodedFixture(test_table[i + 1]); DecodeString(encodedFixture, &buffer); @@ -244,7 +242,7 @@ TEST_F(HpackHuffmanTableTest, SpecResponseExamples) { "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", }; // Round-trip each test example. - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { const std::string& encodedFixture(test_table[i]); const std::string& decodedFixture(test_table[i + 1]); DecodeString(encodedFixture, &buffer); @@ -258,7 +256,7 @@ TEST_F(HpackHuffmanTableTest, RoundTripIndividualSymbols) { for (size_t i = 0; i != 256; i++) { char c = static_cast<char>(i); char storage[3] = {c, c, c}; - quiche::QuicheStringPiece input(storage, QUICHE_ARRAYSIZE(storage)); + absl::string_view input(storage, ABSL_ARRAYSIZE(storage)); std::string buffer_in = EncodeString(input); std::string buffer_out; DecodeString(buffer_in, &buffer_out); @@ -272,7 +270,7 @@ TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) { storage[i] = static_cast<char>(i); storage[511 - i] = static_cast<char>(i); } - quiche::QuicheStringPiece input(storage, QUICHE_ARRAYSIZE(storage)); + absl::string_view input(storage, ABSL_ARRAYSIZE(storage)); std::string buffer_in = EncodeString(input); std::string buffer_out; DecodeString(buffer_in, &buffer_out); @@ -291,12 +289,12 @@ TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) { }; for (size_t i = 0; i != 256; ++i) { // Expand last |test_table| entry to cover all codes. - test_table[QUICHE_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i); + test_table[ABSL_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i); } HpackOutputStream output_stream; std::string encoding; - for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); ++i) { + for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); ++i) { table_.EncodeString(test_table[i], &output_stream); output_stream.TakeString(&encoding); EXPECT_EQ(encoding.size(), table_.EncodedSize(test_table[i])); diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.cc index 5c2dd683f1c..a532f0b379e 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.cc @@ -41,7 +41,7 @@ void HpackOutputStream::AppendPrefix(HpackPrefix prefix) { AppendBits(prefix.bits, prefix.bit_size); } -void HpackOutputStream::AppendBytes(quiche::QuicheStringPiece buffer) { +void HpackOutputStream::AppendBytes(absl::string_view buffer) { DCHECK_EQ(bit_offset_, 0u); buffer_.append(buffer.data(), buffer.size()); } @@ -61,6 +61,12 @@ void HpackOutputStream::AppendUint32(uint32_t I) { } AppendBits(static_cast<uint8_t>(I), 8); } + DCHECK_EQ(bit_offset_, 0u); +} + +std::string* HpackOutputStream::MutableString() { + DCHECK_EQ(bit_offset_, 0u); + return &buffer_; } void HpackOutputStream::TakeString(std::string* output) { diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h index f7e71f1fb2a..b94aa0c91c6 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h @@ -9,8 +9,8 @@ #include <map> #include <string> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" // All section references below are to @@ -37,7 +37,7 @@ class QUICHE_EXPORT_PRIVATE HpackOutputStream { void AppendPrefix(HpackPrefix prefix); // Directly appends |buffer|. - void AppendBytes(quiche::QuicheStringPiece buffer); + void AppendBytes(absl::string_view buffer); // Appends the given integer using the representation described in // 6.1. If the internal buffer ends on a byte boundary, the prefix @@ -48,6 +48,9 @@ class QUICHE_EXPORT_PRIVATE HpackOutputStream { // boundary after this function is called. void AppendUint32(uint32_t I); + // Return pointer to internal buffer. |bit_offset_| needs to be zero. + std::string* MutableString(); + // Swaps the internal buffer with |output|, then resets state. void TakeString(std::string* output); diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream_test.cc index 21e6947de1c..20d320c902c 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream_test.cc @@ -271,6 +271,20 @@ TEST(HpackOutputStreamTest, BoundedTakeString) { EXPECT_EQ("\x10", str); } +TEST(HpackOutputStreamTest, MutableString) { + HpackOutputStream output_stream; + + output_stream.AppendBytes("1"); + output_stream.MutableString()->append("2"); + + output_stream.AppendBytes("foo"); + output_stream.MutableString()->append("bar"); + + std::string str; + output_stream.TakeString(&str); + EXPECT_EQ("12foobar", str); +} + } // namespace } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_round_trip_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_round_trip_test.cc index c4bf0371884..4b5dd5b395f 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_round_trip_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_round_trip_test.cc @@ -24,8 +24,6 @@ enum InputSizeParam { ALL_INPUT, ONE_BYTE, ZERO_THEN_ONE_BYTE }; class HpackRoundTripTest : public QuicheTestWithParam<InputSizeParam> { protected: - HpackRoundTripTest() : encoder_(ObtainHpackHuffmanTable()), decoder_() {} - void SetUp() override { // Use a small table size to tickle eviction handling. encoder_.ApplyHeaderTableSizeSetting(256); diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.cc index e8b07f1ccbc..c0815ce159b 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.cc @@ -4,7 +4,7 @@ #include "net/third_party/quiche/src/spdy/core/hpack/hpack_static_table.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_estimate_memory_usage.h" @@ -24,8 +24,8 @@ void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table, for (const HpackStaticEntry* it = static_entry_table; it != static_entry_table + static_entry_count; ++it) { static_entries_.push_back( - HpackEntry(quiche::QuicheStringPiece(it->name, it->name_len), - quiche::QuicheStringPiece(it->value, it->value_len), + HpackEntry(absl::string_view(it->name, it->name_len), + absl::string_view(it->value, it->value_len), true, // is_static total_insertions)); HpackEntry* entry = &static_entries_.back(); diff --git a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table_test.cc b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table_test.cc index 42c62548224..36eb8315a2d 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_static_table_test.cc @@ -7,7 +7,7 @@ #include <set> #include <vector> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" @@ -39,7 +39,7 @@ TEST_F(HpackStaticTableTest, Initialize) { HpackHeaderTable::NameToEntryMap static_name_index = table_.GetStaticNameIndex(); - std::set<quiche::QuicheStringPiece> names; + std::set<absl::string_view> names; for (auto* entry : static_index) { names.insert(entry->name()); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.cc b/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.cc index 8f62a93a734..1313c7d3bfc 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.cc @@ -21,6 +21,7 @@ #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" #include "net/third_party/quiche/src/http2/http2_constants.h" #include "net/third_party/quiche/src/http2/http2_structures.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" @@ -28,7 +29,6 @@ #include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_estimate_memory_usage.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_flags.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h" @@ -67,7 +67,7 @@ SpdyFrameType ToSpdyFrameType(Http2FrameType type) { uint64_t ToSpdyPingId(const Http2PingFields& ping) { uint64_t v; std::memcpy(&v, ping.opaque_bytes, Http2PingFields::EncodedSize()); - return spdy::SpdyNetToHost64(v); + return quiche::QuicheEndian::NetToHost64(v); } // Overwrites the fields of the header with invalid values, for the purpose diff --git a/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h b/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h index 1ac20c28b76..89d7fdc011a 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h +++ b/chromium/net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h @@ -11,10 +11,10 @@ #include <memory> #include <string> +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" @@ -269,7 +269,7 @@ class QUICHE_EXPORT_PRIVATE Http2DecoderAdapter // Amount of trailing padding. Currently used just as an indicator of whether // OnPadLength has been called. - quiche::QuicheOptional<size_t> opt_pad_length_; + absl::optional<size_t> opt_pad_length_; // Temporary buffers for the AltSvc fields. std::string alt_svc_origin_; @@ -494,7 +494,7 @@ class QUICHE_EXPORT_PRIVATE SpdyFramerVisitorInterface { // Called when an ALTSVC frame has been parsed. virtual void OnAltSvc( SpdyStreamId /*stream_id*/, - quiche::QuicheStringPiece /*origin*/, + absl::string_view /*origin*/, const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) { } diff --git a/chromium/net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h b/chromium/net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h index e54c869212b..5faf2fb2da1 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h +++ b/chromium/net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h @@ -9,9 +9,10 @@ #include <memory> #include <utility> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" +#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h" namespace spdy { @@ -90,7 +91,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface { void, OnAltSvc, (SpdyStreamId stream_id, - quiche::QuicheStringPiece origin, + absl::string_view origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector), (override)); MOCK_METHOD(void, @@ -117,7 +118,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface { SpdyHeadersHandlerInterface* ReturnTestHeadersHandler( SpdyStreamId /* stream_id */) { if (headers_handler_ == nullptr) { - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); } return headers_handler_.get(); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.cc b/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.cc new file mode 100644 index 00000000000..02e5edeed2e --- /dev/null +++ b/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2020 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 "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" + +namespace spdy { + +RecordingHeadersHandler::RecordingHeadersHandler( + SpdyHeadersHandlerInterface* wrapped) + : wrapped_(wrapped) {} + +void RecordingHeadersHandler::OnHeaderBlockStart() { + block_.clear(); + if (wrapped_ != nullptr) { + wrapped_->OnHeaderBlockStart(); + } +} + +void RecordingHeadersHandler::OnHeader(absl::string_view key, + absl::string_view value) { + block_.AppendValueOrAddHeader(key, value); + if (wrapped_ != nullptr) { + wrapped_->OnHeader(key, value); + } +} + +void RecordingHeadersHandler::OnHeaderBlockEnd(size_t uncompressed_header_bytes, + size_t compressed_header_bytes) { + uncompressed_header_bytes_ = uncompressed_header_bytes; + compressed_header_bytes_ = compressed_header_bytes; + if (wrapped_ != nullptr) { + wrapped_->OnHeaderBlockEnd(uncompressed_header_bytes, + compressed_header_bytes); + } +} + +} // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.h b/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.h new file mode 100644 index 00000000000..a61670ef8d8 --- /dev/null +++ b/chromium/net/third_party/quiche/src/spdy/core/recording_headers_handler.h @@ -0,0 +1,51 @@ +// Copyright (c) 2020 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_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_ +#define QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_ + +#include <cstddef> +#include <cstdint> +#include <string> + +#include "absl/strings/string_view.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_export.h" +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" +#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" + +namespace spdy { + +// RecordingHeadersHandler copies the headers emitted from the deframer, and +// when needed can forward events to another wrapped handler. +class QUICHE_EXPORT_PRIVATE RecordingHeadersHandler + : public SpdyHeadersHandlerInterface { + public: + explicit RecordingHeadersHandler( + SpdyHeadersHandlerInterface* wrapped = nullptr); + RecordingHeadersHandler(const RecordingHeadersHandler&) = delete; + RecordingHeadersHandler& operator=(const RecordingHeadersHandler&) = delete; + + void OnHeaderBlockStart() override; + + void OnHeader(absl::string_view key, absl::string_view value) override; + + void OnHeaderBlockEnd(size_t uncompressed_header_bytes, + size_t compressed_header_bytes) override; + + const Http2HeaderBlock& decoded_block() const { return block_; } + size_t uncompressed_header_bytes() const { + return uncompressed_header_bytes_; + } + size_t compressed_header_bytes() const { return compressed_header_bytes_; } + + private: + SpdyHeadersHandlerInterface* wrapped_ = nullptr; + Http2HeaderBlock block_; + size_t uncompressed_header_bytes_ = 0; + size_t compressed_header_bytes_ = 0; +}; + +} // namespace spdy + +#endif // QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_ diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.cc index 7f7ca298ab7..ac85b9c4f59 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.cc @@ -17,8 +17,8 @@ namespace spdy { namespace { template <class T> -bool ParsePositiveIntegerImpl(quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, +bool ParsePositiveIntegerImpl(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, T* value) { *value = 0; for (; c != end && std::isdigit(*c); ++c) { @@ -57,20 +57,20 @@ SpdyAltSvcWireFormat::AlternativeService::AlternativeService( // static bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( - quiche::QuicheStringPiece value, + absl::string_view value, AlternativeServiceVector* altsvc_vector) { // Empty value is invalid according to the specification. if (value.empty()) { return false; } altsvc_vector->clear(); - if (value == quiche::QuicheStringPiece("clear")) { + if (value == absl::string_view("clear")) { return true; } - quiche::QuicheStringPiece::const_iterator c = value.begin(); + absl::string_view::const_iterator c = value.begin(); while (c != value.end()) { // Parse protocol-id. - quiche::QuicheStringPiece::const_iterator percent_encoded_protocol_id_end = + absl::string_view::const_iterator percent_encoded_protocol_id_end = std::find(c, value.end(), '='); std::string protocol_id; if (percent_encoded_protocol_id_end == c || @@ -91,7 +91,7 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( return false; } ++c; - quiche::QuicheStringPiece::const_iterator alt_authority_begin = c; + absl::string_view::const_iterator alt_authority_begin = c; for (; c != value.end() && *c != '"'; ++c) { // Decode backslash encoding. if (*c != '\\') { @@ -115,7 +115,7 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( // Parse parameters. uint32_t max_age = 86400; VersionVector version; - quiche::QuicheStringPiece::const_iterator parameters_end = + absl::string_view::const_iterator parameters_end = std::find(c, value.end(), ','); while (c != parameters_end) { SkipWhiteSpace(&c, parameters_end); @@ -140,7 +140,7 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( } ++c; SkipWhiteSpace(&c, parameters_end); - quiche::QuicheStringPiece::const_iterator parameter_value_begin = c; + absl::string_view::const_iterator parameter_value_begin = c; for (; c != parameters_end && *c != ';' && *c != ' ' && *c != '\t'; ++c) { } if (c == parameter_value_begin) { @@ -164,10 +164,9 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( } ++c; parameters_end = std::find(c, value.end(), ','); - quiche::QuicheStringPiece::const_iterator v_begin = - parameter_value_begin + 1; + absl::string_view::const_iterator v_begin = parameter_value_begin + 1; while (v_begin < c) { - quiche::QuicheStringPiece::const_iterator v_end = v_begin; + absl::string_view::const_iterator v_end = v_begin; while (v_end < c - 1 && *v_end != ',') { ++v_end; } @@ -196,10 +195,9 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( // hq=":443";quic=51303338 // ... will be stored in |versions| as 0x51303338. uint32_t quic_version; - if (!SpdyHexDecodeToUInt32( - quiche::QuicheStringPiece(&*parameter_value_begin, - c - parameter_value_begin), - &quic_version) || + if (!SpdyHexDecodeToUInt32(absl::string_view(&*parameter_value_begin, + c - parameter_value_begin), + &quic_version) || quic_version == 0) { return false; } @@ -295,17 +293,16 @@ std::string SpdyAltSvcWireFormat::SerializeHeaderFieldValue( // static void SpdyAltSvcWireFormat::SkipWhiteSpace( - quiche::QuicheStringPiece::const_iterator* c, - quiche::QuicheStringPiece::const_iterator end) { + absl::string_view::const_iterator* c, + absl::string_view::const_iterator end) { for (; *c != end && (**c == ' ' || **c == '\t'); ++*c) { } } // static -bool SpdyAltSvcWireFormat::PercentDecode( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, - std::string* output) { +bool SpdyAltSvcWireFormat::PercentDecode(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, + std::string* output) { output->clear(); for (; c != end; ++c) { if (*c != '%') { @@ -331,8 +328,8 @@ bool SpdyAltSvcWireFormat::PercentDecode( // static bool SpdyAltSvcWireFormat::ParseAltAuthority( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + absl::string_view::const_iterator c, + absl::string_view::const_iterator end, std::string* host, uint16_t* port) { host->clear(); @@ -378,16 +375,16 @@ bool SpdyAltSvcWireFormat::ParseAltAuthority( // static bool SpdyAltSvcWireFormat::ParsePositiveInteger16( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + absl::string_view::const_iterator c, + absl::string_view::const_iterator end, uint16_t* value) { return ParsePositiveIntegerImpl<uint16_t>(c, end, value); } // static bool SpdyAltSvcWireFormat::ParsePositiveInteger32( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + absl::string_view::const_iterator c, + absl::string_view::const_iterator end, uint32_t* value) { return ParsePositiveIntegerImpl<uint32_t>(c, end, value); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h index 4d2545035b1..30462feb031 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h @@ -14,8 +14,8 @@ #include <string> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_containers.h" namespace spdy { @@ -60,29 +60,27 @@ class QUICHE_EXPORT_PRIVATE SpdyAltSvcWireFormat { typedef std::vector<AlternativeService> AlternativeServiceVector; friend class test::SpdyAltSvcWireFormatPeer; - static bool ParseHeaderFieldValue(quiche::QuicheStringPiece value, + static bool ParseHeaderFieldValue(absl::string_view value, AlternativeServiceVector* altsvc_vector); static std::string SerializeHeaderFieldValue( const AlternativeServiceVector& altsvc_vector); private: - static void SkipWhiteSpace(quiche::QuicheStringPiece::const_iterator* c, - quiche::QuicheStringPiece::const_iterator end); - static bool PercentDecode(quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + static void SkipWhiteSpace(absl::string_view::const_iterator* c, + absl::string_view::const_iterator end); + static bool PercentDecode(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, std::string* output); - static bool ParseAltAuthority(quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + static bool ParseAltAuthority(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, std::string* host, uint16_t* port); - static bool ParsePositiveInteger16( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, - uint16_t* value); - static bool ParsePositiveInteger32( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, - uint32_t* value); + static bool ParsePositiveInteger16(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, + uint16_t* value); + static bool ParsePositiveInteger32(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, + uint32_t* value); }; } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format_test.cc index d80de7df00e..a4127c8dc65 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format_test.cc @@ -14,31 +14,29 @@ namespace test { // Expose all private methods of class SpdyAltSvcWireFormat. class SpdyAltSvcWireFormatPeer { public: - static void SkipWhiteSpace(quiche::QuicheStringPiece::const_iterator* c, - quiche::QuicheStringPiece::const_iterator end) { + static void SkipWhiteSpace(absl::string_view::const_iterator* c, + absl::string_view::const_iterator end) { SpdyAltSvcWireFormat::SkipWhiteSpace(c, end); } - static bool PercentDecode(quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + static bool PercentDecode(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, std::string* output) { return SpdyAltSvcWireFormat::PercentDecode(c, end, output); } - static bool ParseAltAuthority(quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, + static bool ParseAltAuthority(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, std::string* host, uint16_t* port) { return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port); } - static bool ParsePositiveInteger16( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, - uint16_t* max_age) { + static bool ParsePositiveInteger16(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, + uint16_t* max_age) { return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end, max_age); } - static bool ParsePositiveInteger32( - quiche::QuicheStringPiece::const_iterator c, - quiche::QuicheStringPiece::const_iterator end, - uint32_t* max_age) { + static bool ParsePositiveInteger32(absl::string_view::const_iterator c, + absl::string_view::const_iterator end, + uint32_t* max_age) { return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age); } }; @@ -389,8 +387,8 @@ TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) { // Test SkipWhiteSpace(). TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) { - quiche::QuicheStringPiece input("a \tb "); - quiche::QuicheStringPiece::const_iterator c = input.begin(); + absl::string_view input("a \tb "); + absl::string_view::const_iterator c = input.begin(); test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end()); ASSERT_EQ(input.begin(), c); ++c; @@ -403,19 +401,19 @@ TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) { // Test PercentDecode() on valid input. TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) { - quiche::QuicheStringPiece input(""); + absl::string_view input(""); std::string output; ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode( input.begin(), input.end(), &output)); EXPECT_EQ("", output); - input = quiche::QuicheStringPiece("foo"); + input = absl::string_view("foo"); output.clear(); ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode( input.begin(), input.end(), &output)); EXPECT_EQ("foo", output); - input = quiche::QuicheStringPiece("%2ca%5Cb"); + input = absl::string_view("%2ca%5Cb"); output.clear(); ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode( input.begin(), input.end(), &output)); @@ -426,7 +424,7 @@ TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) { TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) { const char* invalid_input_array[] = {"a%", "a%x", "a%b", "%J22", "%9z"}; for (const char* invalid_input : invalid_input_array) { - quiche::QuicheStringPiece input(invalid_input); + absl::string_view input(invalid_input); std::string output; EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::PercentDecode( input.begin(), input.end(), &output)) @@ -436,7 +434,7 @@ TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) { // Test ParseAltAuthority() on valid input. TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) { - quiche::QuicheStringPiece input(":42"); + absl::string_view input(":42"); std::string host; uint16_t port; ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority( @@ -444,13 +442,13 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) { EXPECT_TRUE(host.empty()); EXPECT_EQ(42, port); - input = quiche::QuicheStringPiece("foo:137"); + input = absl::string_view("foo:137"); ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority( input.begin(), input.end(), &host, &port)); EXPECT_EQ("foo", host); EXPECT_EQ(137, port); - input = quiche::QuicheStringPiece("[2003:8:0:16::509d:9615]:443"); + input = absl::string_view("[2003:8:0:16::509d:9615]:443"); ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority( input.begin(), input.end(), &host, &port)); EXPECT_EQ("[2003:8:0:16::509d:9615]", host); @@ -477,7 +475,7 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) { "[2003:8:0:16::509d:9615:443", "2003:8:0:16::509d:9615]:443"}; for (const char* invalid_input : invalid_input_array) { - quiche::QuicheStringPiece input(invalid_input); + absl::string_view input(invalid_input); std::string host; uint16_t port; EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority( @@ -488,13 +486,13 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) { // Test ParseInteger() on valid input. TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) { - quiche::QuicheStringPiece input("3"); + absl::string_view input("3"); uint16_t value; ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value)); EXPECT_EQ(3, value); - input = quiche::QuicheStringPiece("1337"); + input = absl::string_view("1337"); ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value)); EXPECT_EQ(1337, value); @@ -505,7 +503,7 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) { TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) { const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"}; for (const char* invalid_input : invalid_input_array) { - quiche::QuicheStringPiece input(invalid_input); + absl::string_view input(invalid_input); uint16_t value; EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value)) @@ -516,39 +514,39 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) { // Test ParseIntegerValid() around overflow limit. TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) { // Largest possible uint16_t value. - quiche::QuicheStringPiece input("65535"); + absl::string_view input("65535"); uint16_t value16; ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value16)); EXPECT_EQ(65535, value16); // Overflow uint16_t, ParsePositiveInteger16() should return false. - input = quiche::QuicheStringPiece("65536"); + input = absl::string_view("65536"); ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value16)); // However, even if overflow is not checked for, 65536 overflows to 0, which // returns false anyway. Check for a larger number which overflows to 1. - input = quiche::QuicheStringPiece("65537"); + input = absl::string_view("65537"); ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16( input.begin(), input.end(), &value16)); // Largest possible uint32_t value. - input = quiche::QuicheStringPiece("4294967295"); + input = absl::string_view("4294967295"); uint32_t value32; ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32( input.begin(), input.end(), &value32)); EXPECT_EQ(4294967295, value32); // Overflow uint32_t, ParsePositiveInteger32() should return false. - input = quiche::QuicheStringPiece("4294967296"); + input = absl::string_view("4294967296"); ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32( input.begin(), input.end(), &value32)); // However, even if overflow is not checked for, 4294967296 overflows to 0, // which returns false anyway. Check for a larger number which overflows to // 1. - input = quiche::QuicheStringPiece("4294967297"); + input = absl::string_view("4294967297"); ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32( input.begin(), input.end(), &value32)); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.cc index 9e20e3e0188..835fea9d354 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.cc @@ -11,10 +11,11 @@ #include <limits> #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/http2/platform/api/http2_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h" +#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h" @@ -138,7 +139,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer, // alphabetical order for ease of navigation, and are not in same order // as in SpdyFramerVisitorInterface. void OnAltSvc(SpdyStreamId stream_id, - quiche::QuicheStringPiece origin, + absl::string_view origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) override; void OnContinuation(SpdyStreamId stream_id, bool end) override; @@ -185,8 +186,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer, // Callbacks defined in SpdyHeadersHandlerInterface. void OnHeaderBlockStart() override; - void OnHeader(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece value) override; + void OnHeader(absl::string_view key, absl::string_view value) override; void OnHeaderBlockEnd(size_t header_bytes_parsed, size_t compressed_header_bytes_parsed) override; @@ -227,7 +227,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer, std::unique_ptr<std::string> goaway_description_; std::unique_ptr<StringPairVector> headers_; std::unique_ptr<SettingVector> settings_; - std::unique_ptr<TestHeadersHandler> headers_handler_; + std::unique_ptr<RecordingHeadersHandler> headers_handler_; std::unique_ptr<SpdyGoAwayIR> goaway_ir_; std::unique_ptr<SpdyHeadersIR> headers_ir_; @@ -411,7 +411,7 @@ bool SpdyTestDeframerImpl::AtFrameEnd() { void SpdyTestDeframerImpl::OnAltSvc( SpdyStreamId stream_id, - quiche::QuicheStringPiece origin, + absl::string_view origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) { SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id; CHECK_EQ(frame_type_, UNSET) @@ -532,7 +532,7 @@ void SpdyTestDeframerImpl::OnHeaders(SpdyStreamId stream_id, end_ = end; headers_ = std::make_unique<StringPairVector>(); - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); headers_ir_ = std::make_unique<SpdyHeadersIR>(stream_id); headers_ir_->set_fin(fin); if (has_priority) { @@ -588,7 +588,7 @@ void SpdyTestDeframerImpl::OnPushPromise(SpdyStreamId stream_id, end_ = end; headers_ = std::make_unique<StringPairVector>(); - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); push_promise_ir_ = std::make_unique<SpdyPushPromiseIR>(stream_id, promised_stream_id); } @@ -757,8 +757,8 @@ void SpdyTestDeframerImpl::OnHeaderBlockStart() { got_hpack_end_ = false; } -void SpdyTestDeframerImpl::OnHeader(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece value) { +void SpdyTestDeframerImpl::OnHeader(absl::string_view key, + absl::string_view value) { CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION || frame_type_ == PUSH_PROMISE) << " frame_type_=" << Http2FrameTypeToString(frame_type_); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h index 27535236aef..f17df98720f 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h @@ -45,7 +45,7 @@ // framer.set_visitor(the_deframer.get()); // // // Process frames. -// QuicheStringPiece input = ... +// absl::string_view input = ... // while (!input.empty() && !framer.HasError()) { // size_t consumed = framer.ProcessInput(input.data(), input.size()); // input.remove_prefix(consumed); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.cc index 492cd438d4c..93fb2843a38 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.cc @@ -120,8 +120,7 @@ bool SpdyFrameBuilder::BeginNewFrameInternal(uint8_t raw_frame_type, return success; } -bool SpdyFrameBuilder::WriteStringPiece32( - const quiche::QuicheStringPiece value) { +bool SpdyFrameBuilder::WriteStringPiece32(const absl::string_view value) { if (!WriteUInt32(value.size())) { return false; } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.h index 4853d44eff3..9079a72ad14 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder.h @@ -9,12 +9,12 @@ #include <cstdint> #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" #include "net/third_party/quiche/src/spdy/core/zero_copy_output_buffer.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h" namespace spdy { @@ -83,24 +83,26 @@ class QUICHE_EXPORT_PRIVATE SpdyFrameBuilder { // host to network form. bool WriteUInt8(uint8_t value) { return WriteBytes(&value, sizeof(value)); } bool WriteUInt16(uint16_t value) { - value = SpdyHostToNet16(value); + value = quiche::QuicheEndian::HostToNet16(value); return WriteBytes(&value, sizeof(value)); } bool WriteUInt24(uint32_t value) { - value = SpdyHostToNet32(value); + value = quiche::QuicheEndian::HostToNet32(value); return WriteBytes(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1); } bool WriteUInt32(uint32_t value) { - value = SpdyHostToNet32(value); + value = quiche::QuicheEndian::HostToNet32(value); return WriteBytes(&value, sizeof(value)); } bool WriteUInt64(uint64_t value) { - uint32_t upper = SpdyHostToNet32(static_cast<uint32_t>(value >> 32)); - uint32_t lower = SpdyHostToNet32(static_cast<uint32_t>(value)); + uint32_t upper = + quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value >> 32)); + uint32_t lower = + quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value)); return (WriteBytes(&upper, sizeof(upper)) && WriteBytes(&lower, sizeof(lower))); } - bool WriteStringPiece32(const quiche::QuicheStringPiece value); + bool WriteStringPiece32(const absl::string_view value); bool WriteBytes(const void* data, uint32_t data_len); private: diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder_test.cc index b10932334cc..8f6a7b40551 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_builder_test.cc @@ -48,8 +48,8 @@ TEST(SpdyFrameBuilderTest, GetWritableBuffer) { SpdySerializedFrame frame(builder.take()); char expected[kBuilderSize]; memset(expected, ~1, kBuilderSize); - EXPECT_EQ(quiche::QuicheStringPiece(expected, kBuilderSize), - quiche::QuicheStringPiece(frame.data(), kBuilderSize)); + EXPECT_EQ(absl::string_view(expected, kBuilderSize), + absl::string_view(frame.data(), kBuilderSize)); } // Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a @@ -66,8 +66,8 @@ TEST(SpdyFrameBuilderTest, GetWritableOutput) { SpdySerializedFrame frame(output.Begin(), kBuilderSize, false); char expected[kBuilderSize]; memset(expected, ~1, kBuilderSize); - EXPECT_EQ(quiche::QuicheStringPiece(expected, kBuilderSize), - quiche::QuicheStringPiece(frame.data(), kBuilderSize)); + EXPECT_EQ(absl::string_view(expected, kBuilderSize), + absl::string_view(frame.data(), kBuilderSize)); } // Verifies the case that the buffer's capacity is too small. diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.cc index 253f90639de..a53a8acb9a2 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.cc @@ -4,8 +4,8 @@ #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h" namespace spdy { @@ -36,7 +36,8 @@ bool SpdyFrameReader::ReadUInt16(uint16_t* result) { } // Read into result. - *result = SpdyNetToHost16(*(reinterpret_cast<const uint16_t*>(data_ + ofs_))); + *result = quiche::QuicheEndian::NetToHost16( + *(reinterpret_cast<const uint16_t*>(data_ + ofs_))); // Iterate. ofs_ += 2; @@ -52,7 +53,8 @@ bool SpdyFrameReader::ReadUInt32(uint32_t* result) { } // Read into result. - *result = SpdyNetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_))); + *result = quiche::QuicheEndian::NetToHost32( + *(reinterpret_cast<const uint32_t*>(data_ + ofs_))); // Iterate. ofs_ += 4; @@ -68,10 +70,10 @@ bool SpdyFrameReader::ReadUInt64(uint64_t* result) { } // Read into result. Network byte order is big-endian. - uint64_t upper = - SpdyNetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_))); - uint64_t lower = - SpdyNetToHost32(*(reinterpret_cast<const uint32_t*>(data_ + ofs_ + 4))); + uint64_t upper = quiche::QuicheEndian::NetToHost32( + *(reinterpret_cast<const uint32_t*>(data_ + ofs_))); + uint64_t lower = quiche::QuicheEndian::NetToHost32( + *(reinterpret_cast<const uint32_t*>(data_ + ofs_ + 4))); *result = (upper << 32) + lower; // Iterate. @@ -101,7 +103,7 @@ bool SpdyFrameReader::ReadUInt24(uint32_t* result) { // Read into result. *result = 0; memcpy(reinterpret_cast<char*>(result) + 1, data_ + ofs_, 3); - *result = SpdyNetToHost32(*result); + *result = quiche::QuicheEndian::NetToHost32(*result); // Iterate. ofs_ += 3; @@ -109,7 +111,7 @@ bool SpdyFrameReader::ReadUInt24(uint32_t* result) { return true; } -bool SpdyFrameReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { +bool SpdyFrameReader::ReadStringPiece16(absl::string_view* result) { // Read resultant length. uint16_t result_len; if (!ReadUInt16(&result_len)) { @@ -124,7 +126,7 @@ bool SpdyFrameReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { } // Set result. - *result = quiche::QuicheStringPiece(data_ + ofs_, result_len); + *result = absl::string_view(data_ + ofs_, result_len); // Iterate. ofs_ += result_len; @@ -132,7 +134,7 @@ bool SpdyFrameReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { return true; } -bool SpdyFrameReader::ReadStringPiece32(quiche::QuicheStringPiece* result) { +bool SpdyFrameReader::ReadStringPiece32(absl::string_view* result) { // Read resultant length. uint32_t result_len; if (!ReadUInt32(&result_len)) { @@ -147,7 +149,7 @@ bool SpdyFrameReader::ReadStringPiece32(quiche::QuicheStringPiece* result) { } // Set result. - *result = quiche::QuicheStringPiece(data_ + ofs_, result_len); + *result = absl::string_view(data_ + ofs_, result_len); // Iterate. ofs_ += result_len; diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.h index 0ed5be48884..e097ee33905 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader.h @@ -7,8 +7,8 @@ #include <cstdint> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace spdy { @@ -73,7 +73,7 @@ class QUICHE_EXPORT_PRIVATE SpdyFrameReader { // // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPiece16(quiche::QuicheStringPiece* result); + bool ReadStringPiece16(absl::string_view* result); // Reads a string prefixed with 32-bit length into the given output parameter. // @@ -82,7 +82,7 @@ class QUICHE_EXPORT_PRIVATE SpdyFrameReader { // // Forwards the internal iterator on success. // Returns true on success, false otherwise. - bool ReadStringPiece32(quiche::QuicheStringPiece* result); + bool ReadStringPiece32(absl::string_view* result); // Reads a given number of bytes into the given buffer. The buffer // must be of adequate size. diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader_test.cc index 0bbe7f62cf2..1e46c48f9af 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_frame_reader_test.cc @@ -6,17 +6,17 @@ #include <cstdint> -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" namespace spdy { TEST(SpdyFrameReaderTest, ReadUInt16) { // Frame data in network byte order. const uint16_t kFrameData[] = { - SpdyHostToNet16(1), - SpdyHostToNet16(1 << 15), + quiche::QuicheEndian::HostToNet16(1), + quiche::QuicheEndian::HostToNet16(1 << 15), }; SpdyFrameReader frame_reader(reinterpret_cast<const char*>(kFrameData), @@ -36,12 +36,12 @@ TEST(SpdyFrameReaderTest, ReadUInt16) { TEST(SpdyFrameReaderTest, ReadUInt32) { // Frame data in network byte order. const uint32_t kFrameData[] = { - SpdyHostToNet32(1), - SpdyHostToNet32(0x80000000), + quiche::QuicheEndian::HostToNet32(1), + quiche::QuicheEndian::HostToNet32(0x80000000), }; SpdyFrameReader frame_reader(reinterpret_cast<const char*>(kFrameData), - QUICHE_ARRAYSIZE(kFrameData) * sizeof(uint32_t)); + ABSL_ARRAYSIZE(kFrameData) * sizeof(uint32_t)); EXPECT_FALSE(frame_reader.IsDoneReading()); uint32_t uint32_val; @@ -64,10 +64,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16) { 0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, // "Testing, 1, 2, 3" }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_TRUE(frame_reader.ReadStringPiece16(&stringpiece_val)); EXPECT_FALSE(frame_reader.IsDoneReading()); EXPECT_EQ(0, stringpiece_val.compare("Hi")); @@ -87,10 +87,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32) { 0x20, 0x34, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x36, // "Testing, 4, 5, 6" }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_TRUE(frame_reader.ReadStringPiece32(&stringpiece_val)); EXPECT_FALSE(frame_reader.IsDoneReading()); EXPECT_EQ(0, stringpiece_val.compare("foo")); @@ -106,7 +106,7 @@ TEST(SpdyFrameReaderTest, ReadUInt16WithBufferTooSmall) { 0x00, // part of a uint16_t }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); uint16_t uint16_val; @@ -119,7 +119,7 @@ TEST(SpdyFrameReaderTest, ReadUInt32WithBufferTooSmall) { 0x00, 0x00, 0x00, // part of a uint32_t }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); uint32_t uint32_val; @@ -139,10 +139,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferTooSmall) { 0x48, 0x69, // "Hi" }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val)); // Also make sure that trying to read a uint16_t, which technically could @@ -158,10 +158,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece16WithBufferWayTooSmall) { 0x00, // part of a uint16_t }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_FALSE(frame_reader.ReadStringPiece16(&stringpiece_val)); // Also make sure that trying to read a uint16_t, which technically could @@ -178,10 +178,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferTooSmall) { 0x48, 0x69, // "Hi" }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val)); // Also make sure that trying to read a uint16_t, which technically could @@ -197,10 +197,10 @@ TEST(SpdyFrameReaderTest, ReadStringPiece32WithBufferWayTooSmall) { 0x00, 0x00, 0x00, // part of a uint32_t }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - quiche::QuicheStringPiece stringpiece_val; + absl::string_view stringpiece_val; EXPECT_FALSE(frame_reader.ReadStringPiece32(&stringpiece_val)); // Also make sure that trying to read a uint16_t, which technically could @@ -216,18 +216,18 @@ TEST(SpdyFrameReaderTest, ReadBytes) { 0x48, 0x69, // "Hi" }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); char dest1[3] = {}; - EXPECT_TRUE(frame_reader.ReadBytes(&dest1, QUICHE_ARRAYSIZE(dest1))); + EXPECT_TRUE(frame_reader.ReadBytes(&dest1, ABSL_ARRAYSIZE(dest1))); EXPECT_FALSE(frame_reader.IsDoneReading()); - EXPECT_EQ("foo", quiche::QuicheStringPiece(dest1, QUICHE_ARRAYSIZE(dest1))); + EXPECT_EQ("foo", absl::string_view(dest1, ABSL_ARRAYSIZE(dest1))); char dest2[2] = {}; - EXPECT_TRUE(frame_reader.ReadBytes(&dest2, QUICHE_ARRAYSIZE(dest2))); + EXPECT_TRUE(frame_reader.ReadBytes(&dest2, ABSL_ARRAYSIZE(dest2))); EXPECT_TRUE(frame_reader.IsDoneReading()); - EXPECT_EQ("Hi", quiche::QuicheStringPiece(dest2, QUICHE_ARRAYSIZE(dest2))); + EXPECT_EQ("Hi", absl::string_view(dest2, ABSL_ARRAYSIZE(dest2))); } TEST(SpdyFrameReaderTest, ReadBytesWithBufferTooSmall) { @@ -236,11 +236,11 @@ TEST(SpdyFrameReaderTest, ReadBytesWithBufferTooSmall) { 0x01, }; - SpdyFrameReader frame_reader(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + SpdyFrameReader frame_reader(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_FALSE(frame_reader.IsDoneReading()); - char dest[QUICHE_ARRAYSIZE(kFrameData) + 2] = {}; - EXPECT_FALSE(frame_reader.ReadBytes(&dest, QUICHE_ARRAYSIZE(kFrameData) + 1)); + char dest[ABSL_ARRAYSIZE(kFrameData) + 2] = {}; + EXPECT_FALSE(frame_reader.ReadBytes(&dest, ABSL_ARRAYSIZE(kFrameData) + 1)); EXPECT_STREQ("", dest); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.cc index 7b3d388cfb4..d425bddaf09 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.cc @@ -11,9 +11,8 @@ #include <new> #include <utility> +#include "absl/memory/memory.h" #include "net/third_party/quiche/src/http2/platform/api/http2_macros.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_ptr_util.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/spdy_bitmasks.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h" @@ -46,7 +45,7 @@ const size_t kPadLengthFieldSize = 1; // The size of one parameter in SETTINGS frame. const size_t kOneSettingParameterSize = 6; -size_t GetUncompressedSerializedLength(const SpdyHeaderBlock& headers) { +size_t GetUncompressedSerializedLength(const Http2HeaderBlock& headers) { const size_t num_name_value_pairs_size = sizeof(uint32_t); const size_t length_of_name_size = num_name_value_pairs_size; const size_t length_of_value_size = num_name_value_pairs_size; @@ -414,12 +413,12 @@ std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator( switch (frame_ir->frame_type()) { case SpdyFrameType::HEADERS: { return std::make_unique<SpdyHeaderFrameIterator>( - framer, quiche::QuicheWrapUnique( + framer, absl::WrapUnique( static_cast<const SpdyHeadersIR*>(frame_ir.release()))); } case SpdyFrameType::PUSH_PROMISE: { return std::make_unique<SpdyPushPromiseFrameIterator>( - framer, quiche::QuicheWrapUnique( + framer, absl::WrapUnique( static_cast<const SpdyPushPromiseIR*>(frame_ir.release()))); } case SpdyFrameType::DATA: { @@ -1269,7 +1268,7 @@ size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame, HpackEncoder* SpdyFramer::GetHpackEncoder() { if (hpack_encoder_ == nullptr) { - hpack_encoder_ = std::make_unique<HpackEncoder>(ObtainHpackHuffmanTable()); + hpack_encoder_ = std::make_unique<HpackEncoder>(); if (!compression_enabled()) { hpack_encoder_->DisableCompression(); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.h index f16e3bd1916..99c20376830 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer.h @@ -13,8 +13,8 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer_test.cc index e36a17e6591..6a14d0c436c 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_framer_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_framer_test.cc @@ -13,11 +13,11 @@ #include <utility> #include <vector> -#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" +#include "absl/base/macros.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include "net/third_party/quiche/src/spdy/core/array_output_buffer.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" #include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h" +#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h" #include "net/third_party/quiche/src/spdy/core/spdy_bitmasks.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h" @@ -288,7 +288,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SPDY_VLOG(1) << "OnStreamFrameData(" << stream_id << ", data, " << len << ", " << ") data:\n" - << SpdyHexDump(quiche::QuicheStringPiece(data, len)); + << SpdyHexDump(absl::string_view(data, len)); EXPECT_EQ(header_stream_id_, stream_id); data_bytes_ += len; @@ -316,7 +316,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SpdyHeadersHandlerInterface* OnHeaderFrameStart( SpdyStreamId /*stream_id*/) override { if (headers_handler_ == nullptr) { - headers_handler_ = std::make_unique<TestHeadersHandler>(); + headers_handler_ = std::make_unique<RecordingHeadersHandler>(); } return headers_handler_.get(); } @@ -324,7 +324,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override { CHECK(headers_handler_ != nullptr); headers_ = headers_handler_->decoded_block().Clone(); - header_bytes_received_ = headers_handler_->header_bytes_parsed(); + header_bytes_received_ = headers_handler_->uncompressed_header_bytes(); headers_handler_.reset(); } @@ -404,7 +404,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, } void OnAltSvc(SpdyStreamId stream_id, - quiche::QuicheStringPiece origin, + absl::string_view origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) override { SPDY_VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin @@ -532,8 +532,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SpdyStreamId header_stream_id_; SpdyFrameType header_control_type_; bool header_buffer_valid_; - std::unique_ptr<TestHeadersHandler> headers_handler_; - SpdyHeaderBlock headers_; + std::unique_ptr<RecordingHeadersHandler> headers_handler_; + Http2HeaderBlock headers_; bool header_has_priority_; SpdyStreamId header_parent_stream_id_; bool header_exclusive_; @@ -1103,10 +1103,10 @@ TEST_P(SpdyFramerTest, MultiValueHeader) { SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); std::string value("value1\0value2", 13); // TODO(jgraettinger): If this pattern appears again, move to test class. - SpdyHeaderBlock header_set; + Http2HeaderBlock header_set; header_set["name"] = value; std::string buffer; - HpackEncoder encoder(ObtainHpackHuffmanTable()); + HpackEncoder encoder; encoder.DisableCompression(); encoder.EncodeHeaderSet(header_set, &buffer); // Frame builder with plentiful buffer size. @@ -1126,7 +1126,7 @@ TEST_P(SpdyFramerTest, MultiValueHeader) { control_frame.size()); EXPECT_THAT(visitor.headers_, testing::ElementsAre(testing::Pair( - "name", quiche::QuicheStringPiece(value)))); + "name", absl::string_view(value)))); } TEST_P(SpdyFramerTest, CompressEmptyHeaders) { @@ -1316,7 +1316,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) { const char bytes[] = "this is a test test test test test!"; SpdyDataIR data_ir(/* stream_id = */ 1, - quiche::QuicheStringPiece(bytes, QUICHE_ARRAYSIZE(bytes))); + absl::string_view(bytes, ABSL_ARRAYSIZE(bytes))); data_ir.set_fin(true); SpdySerializedFrame send_frame(framer_.SerializeData(data_ir)); @@ -1336,8 +1336,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) { EXPECT_EQ(0, visitor.error_count_); EXPECT_EQ(1, visitor.headers_frame_count_); - EXPECT_EQ(QUICHE_ARRAYSIZE(bytes), - static_cast<unsigned>(visitor.data_bytes_)); + EXPECT_EQ(ABSL_ARRAYSIZE(bytes), static_cast<unsigned>(visitor.data_bytes_)); EXPECT_EQ(0, visitor.fin_frame_count_); EXPECT_EQ(0, visitor.fin_flag_count_); EXPECT_EQ(1, visitor.end_of_stream_count_); @@ -1362,8 +1361,7 @@ TEST_P(SpdyFramerTest, WindowUpdateFrame) { 0x12, 0x34, 0x56, 0x78, // Increment: 305419896 }; - CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + CompareFrame(kDescription, frame, kH2FrameData, ABSL_ARRAYSIZE(kH2FrameData)); } TEST_P(SpdyFramerTest, CreateDataFrame) { @@ -1384,7 +1382,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { SpdyDataIR data_ir(/* stream_id = */ 1, bytes); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); SpdyDataIR data_header_ir(/* stream_id = */ 1); data_header_ir.SetDataShallow(bytes); @@ -1440,7 +1438,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { data_ir.set_padding_len(248); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir); CompareCharArraysWithHexError( @@ -1470,7 +1468,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { data_ir.set_padding_len(8); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir); CompareCharArraysWithHexError( @@ -1500,7 +1498,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { data_ir.set_padding_len(1); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir); CompareCharArraysWithHexError( @@ -1520,7 +1518,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { SpdyDataIR data_ir(/* stream_id = */ 1, "\xff"); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1537,7 +1535,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { data_ir.set_fin(true); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1551,7 +1549,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { SpdyDataIR data_ir(/* stream_id = */ 1, ""); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir); CompareCharArraysWithHexError( @@ -1573,7 +1571,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { data_ir.set_fin(true); SpdySerializedFrame frame(framer_.SerializeData(data_ir)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -1594,7 +1592,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1615,7 +1613,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1636,7 +1634,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -1664,7 +1662,7 @@ TEST_P(SpdyFramerTest, CreateSettings) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1700,7 +1698,7 @@ TEST_P(SpdyFramerTest, CreateSettings) { } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1720,7 +1718,7 @@ TEST_P(SpdyFramerTest, CreateSettings) { } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -1753,7 +1751,7 @@ TEST_P(SpdyFramerTest, CreatePingFrame) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); // Tests SpdyPingIR when the ping is an ack. ping_ir.set_is_ack(true); @@ -1764,7 +1762,7 @@ TEST_P(SpdyFramerTest, CreatePingFrame) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameDataWithAck, - QUICHE_ARRAYSIZE(kH2FrameDataWithAck)); + ABSL_ARRAYSIZE(kH2FrameDataWithAck)); } } @@ -1788,7 +1786,7 @@ TEST_P(SpdyFramerTest, CreateGoAway) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1811,7 +1809,7 @@ TEST_P(SpdyFramerTest, CreateGoAway) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -1846,7 +1844,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1878,7 +1876,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1910,7 +1908,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers_ir, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1947,7 +1945,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers_ir, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -1987,7 +1985,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers_ir, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kV4FrameData, - QUICHE_ARRAYSIZE(kV4FrameData)); + ABSL_ARRAYSIZE(kV4FrameData)); } { @@ -2027,7 +2025,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers_ir, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kV4FrameData, - QUICHE_ARRAYSIZE(kV4FrameData)); + ABSL_ARRAYSIZE(kV4FrameData)); } { @@ -2065,7 +2063,7 @@ TEST_P(SpdyFramerTest, CreateHeadersUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders( &framer, headers_ir, use_output_ ? &output_ : nullptr)); CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -2088,7 +2086,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -2110,7 +2108,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } { @@ -2132,7 +2130,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) { frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } CompareFrame(kDescription, frame, kH2FrameData, - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); } } @@ -2170,7 +2168,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { push_promise.SetHeader("foo", "bar"); SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise( &framer, push_promise, use_output_ ? &output_ : nullptr)); - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } { @@ -2210,7 +2208,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise( &framer, push_promise, use_output_ ? &output_ : nullptr)); - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } { @@ -2270,7 +2268,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise( &framer, push_promise, use_output_ ? &output_ : nullptr)); - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } } @@ -2307,11 +2305,11 @@ TEST_P(SpdyFramerTest, CreateContinuationUncompressed) { }; // frame-format on - SpdyHeaderBlock header_block; + Http2HeaderBlock header_block; header_block["bar"] = "foo"; header_block["foo"] = "bar"; auto buffer = std::make_unique<std::string>(); - HpackEncoder encoder(ObtainHpackHuffmanTable()); + HpackEncoder encoder; encoder.DisableCompression(); encoder.EncodeHeaderSet(header_block, buffer.get()); @@ -2324,7 +2322,7 @@ TEST_P(SpdyFramerTest, CreateContinuationUncompressed) { ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_)); frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } // Test that if we send an unexpected CONTINUATION @@ -2456,17 +2454,16 @@ TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) { // Partially compare the PUSH_PROMISE frame against the template. const unsigned char* frame_data = reinterpret_cast<const unsigned char*>(frame.data()); - CompareCharArraysWithHexError( - kDescription, frame_data, - QUICHE_ARRAYSIZE(kPartialPushPromiseFrameData), - kPartialPushPromiseFrameData, - QUICHE_ARRAYSIZE(kPartialPushPromiseFrameData)); + CompareCharArraysWithHexError(kDescription, frame_data, + ABSL_ARRAYSIZE(kPartialPushPromiseFrameData), + kPartialPushPromiseFrameData, + ABSL_ARRAYSIZE(kPartialPushPromiseFrameData)); // Compare the CONTINUATION frame against the template. frame_data += kHttp2MaxControlFrameSendSize; CompareCharArraysWithHexError( - kDescription, frame_data, QUICHE_ARRAYSIZE(kContinuationFrameData), - kContinuationFrameData, QUICHE_ARRAYSIZE(kContinuationFrameData)); + kDescription, frame_data, ABSL_ARRAYSIZE(kContinuationFrameData), + kContinuationFrameData, ABSL_ARRAYSIZE(kContinuationFrameData)); } } @@ -2493,7 +2490,7 @@ TEST_P(SpdyFramerTest, CreateAltSvc) { EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size()); frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } TEST_P(SpdyFramerTest, CreatePriority) { @@ -2515,7 +2512,7 @@ TEST_P(SpdyFramerTest, CreatePriority) { EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size()); frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } TEST_P(SpdyFramerTest, CreateUnknown) { @@ -2542,7 +2539,7 @@ TEST_P(SpdyFramerTest, CreateUnknown) { EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size()); frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } // Test serialization of a SpdyUnknownIR with a defined type, a length field @@ -2574,7 +2571,7 @@ TEST_P(SpdyFramerTest, CreateUnknownUnchecked) { EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size()); frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); } - CompareFrame(kDescription, frame, kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData)); } TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) { @@ -3610,7 +3607,7 @@ TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) { // Simulate the case where the stream id validation checks out. visitor.on_unknown_frame_result_ = true; - visitor.SimulateInFramer(unknown_frame, QUICHE_ARRAYSIZE(unknown_frame)); + visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame)); EXPECT_EQ(0, visitor.error_count_); // Follow it up with a valid control frame to make sure we handle @@ -3646,7 +3643,7 @@ TEST_P(SpdyFramerTest, ReadUnknownExtensionFrameWithExtension) { TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); TestExtension extension; visitor.set_extension_visitor(&extension); - visitor.SimulateInFramer(unknown_frame, QUICHE_ARRAYSIZE(unknown_frame)); + visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame)); EXPECT_EQ(0, visitor.error_count_); EXPECT_EQ(0x7fffffffu, extension.stream_id_); EXPECT_EQ(20u, extension.length_); @@ -3677,7 +3674,7 @@ TEST_P(SpdyFramerTest, ReadGarbageWithValidLength) { 0xff, 0xff, 0xff, 0xff, // }; TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); - visitor.SimulateInFramer(kFrameData, QUICHE_ARRAYSIZE(kFrameData)); + visitor.SimulateInFramer(kFrameData, ABSL_ARRAYSIZE(kFrameData)); EXPECT_EQ(1, visitor.error_count_); } @@ -3696,7 +3693,7 @@ TEST_P(SpdyFramerTest, ReadGarbageHPACKEncoding) { }; TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); - visitor.SimulateInFramer(kInput, QUICHE_ARRAYSIZE(kInput)); + visitor.SimulateInFramer(kInput, ABSL_ARRAYSIZE(kInput)); EXPECT_EQ(1, visitor.error_count_); } @@ -4221,7 +4218,7 @@ TEST_P(SpdyFramerTest, RstStreamStatusBounds) { EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_NO_ERROR)); deframer_.ProcessInput(reinterpret_cast<const char*>(kH2RstStreamInvalid), - QUICHE_ARRAYSIZE(kH2RstStreamInvalid)); + ABSL_ARRAYSIZE(kH2RstStreamInvalid)); EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_.state()); EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_.spdy_framer_error()) << Http2DecoderAdapter::SpdyFramerErrorToString( @@ -4231,7 +4228,7 @@ TEST_P(SpdyFramerTest, RstStreamStatusBounds) { EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_INTERNAL_ERROR)); deframer_.ProcessInput( reinterpret_cast<const char*>(kH2RstStreamNumStatusCodes), - QUICHE_ARRAYSIZE(kH2RstStreamNumStatusCodes)); + ABSL_ARRAYSIZE(kH2RstStreamNumStatusCodes)); EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_.state()); EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_.spdy_framer_error()) << Http2DecoderAdapter::SpdyFramerErrorToString( @@ -4254,7 +4251,7 @@ TEST_P(SpdyFramerTest, GoAwayStatusBounds) { EXPECT_CALL(visitor, OnGoAway(1, ERROR_CODE_INTERNAL_ERROR)); deframer_.ProcessInput(reinterpret_cast<const char*>(kH2FrameData), - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_.state()); EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_.spdy_framer_error()) << Http2DecoderAdapter::SpdyFramerErrorToString( @@ -4278,7 +4275,7 @@ TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) { EXPECT_CALL(visitor, OnGoAway(0x7fffffff, ERROR_CODE_NO_ERROR)); deframer_.ProcessInput(reinterpret_cast<const char*>(kH2FrameData), - QUICHE_ARRAYSIZE(kH2FrameData)); + ABSL_ARRAYSIZE(kH2FrameData)); EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_.state()); EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_.spdy_framer_error()) << Http2DecoderAdapter::SpdyFramerErrorToString( @@ -4299,8 +4296,8 @@ TEST_P(SpdyFramerTest, OnAltSvcWithOrigin) { SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; altsvc_vector.push_back(altsvc1); altsvc_vector.push_back(altsvc2); - EXPECT_CALL(visitor, OnAltSvc(kStreamId, quiche::QuicheStringPiece("o_r|g!n"), - altsvc_vector)); + EXPECT_CALL(visitor, + OnAltSvc(kStreamId, absl::string_view("o_r|g!n"), altsvc_vector)); SpdyAltSvcIR altsvc_ir(kStreamId); altsvc_ir.set_origin("o_r|g!n"); @@ -4334,8 +4331,8 @@ TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) { SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; altsvc_vector.push_back(altsvc1); altsvc_vector.push_back(altsvc2); - EXPECT_CALL(visitor, OnAltSvc(kStreamId, quiche::QuicheStringPiece(""), - altsvc_vector)); + EXPECT_CALL(visitor, + OnAltSvc(kStreamId, absl::string_view(""), altsvc_vector)); SpdyAltSvcIR altsvc_ir(kStreamId); altsvc_ir.add_altsvc(altsvc1); @@ -4771,8 +4768,7 @@ TEST_P(SpdyFramerTest, SpdyFrameIRSize) { SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); const char bytes[] = "this is a very short data frame"; - SpdyDataIR data_ir(1, - quiche::QuicheStringPiece(bytes, QUICHE_ARRAYSIZE(bytes))); + SpdyDataIR data_ir(1, absl::string_view(bytes, ABSL_ARRAYSIZE(bytes))); CheckFrameAndIRSize(&data_ir, &framer, &output_); SpdyRstStreamIR rst_ir(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.cc index d7e3faa9ba0..23dd9996c34 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.cc @@ -27,35 +27,34 @@ const size_t kInitialMapBuckets = 11; const char kCookieKey[] = "cookie"; const char kNullSeparator = 0; -quiche::QuicheStringPiece SeparatorForKey(quiche::QuicheStringPiece key) { +absl::string_view SeparatorForKey(absl::string_view key) { if (key == kCookieKey) { - static quiche::QuicheStringPiece cookie_separator = "; "; + static absl::string_view cookie_separator = "; "; return cookie_separator; } else { - return quiche::QuicheStringPiece(&kNullSeparator, 1); + return absl::string_view(&kNullSeparator, 1); } } } // namespace -SpdyHeaderBlock::HeaderValue::HeaderValue( - SpdyHeaderStorage* storage, - quiche::QuicheStringPiece key, - quiche::QuicheStringPiece initial_value) +Http2HeaderBlock::HeaderValue::HeaderValue(SpdyHeaderStorage* storage, + absl::string_view key, + absl::string_view initial_value) : storage_(storage), fragments_({initial_value}), pair_({key, {}}), size_(initial_value.size()), separator_size_(SeparatorForKey(key).size()) {} -SpdyHeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other) +Http2HeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other) : storage_(other.storage_), fragments_(std::move(other.fragments_)), pair_(std::move(other.pair_)), size_(other.size_), separator_size_(other.separator_size_) {} -SpdyHeaderBlock::HeaderValue& SpdyHeaderBlock::HeaderValue::operator=( +Http2HeaderBlock::HeaderValue& Http2HeaderBlock::HeaderValue::operator=( HeaderValue&& other) { storage_ = other.storage_; fragments_ = std::move(other.fragments_); @@ -65,16 +64,15 @@ SpdyHeaderBlock::HeaderValue& SpdyHeaderBlock::HeaderValue::operator=( return *this; } -void SpdyHeaderBlock::HeaderValue::set_storage(SpdyHeaderStorage* storage) { +void Http2HeaderBlock::HeaderValue::set_storage(SpdyHeaderStorage* storage) { storage_ = storage; } -SpdyHeaderBlock::HeaderValue::~HeaderValue() = default; +Http2HeaderBlock::HeaderValue::~HeaderValue() = default; -quiche::QuicheStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() - const { +absl::string_view Http2HeaderBlock::HeaderValue::ConsolidatedValue() const { if (fragments_.empty()) { - return quiche::QuicheStringPiece(); + return absl::string_view(); } if (fragments_.size() > 1) { fragments_ = { @@ -83,27 +81,27 @@ quiche::QuicheStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() return fragments_[0]; } -void SpdyHeaderBlock::HeaderValue::Append(quiche::QuicheStringPiece fragment) { +void Http2HeaderBlock::HeaderValue::Append(absl::string_view fragment) { size_ += (fragment.size() + separator_size_); fragments_.push_back(fragment); } -const std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece>& -SpdyHeaderBlock::HeaderValue::as_pair() const { +const std::pair<absl::string_view, absl::string_view>& +Http2HeaderBlock::HeaderValue::as_pair() const { pair_.second = ConsolidatedValue(); return pair_; } -SpdyHeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {} +Http2HeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {} -SpdyHeaderBlock::iterator::iterator(const iterator& other) = default; +Http2HeaderBlock::iterator::iterator(const iterator& other) = default; -SpdyHeaderBlock::iterator::~iterator() = default; +Http2HeaderBlock::iterator::~iterator() = default; -SpdyHeaderBlock::ValueProxy::ValueProxy( - SpdyHeaderBlock* block, - SpdyHeaderBlock::MapType::iterator lookup_result, - const quiche::QuicheStringPiece key, +Http2HeaderBlock::ValueProxy::ValueProxy( + Http2HeaderBlock* block, + Http2HeaderBlock::MapType::iterator lookup_result, + const absl::string_view key, size_t* spdy_header_block_value_size) : block_(block), lookup_result_(lookup_result), @@ -111,7 +109,7 @@ SpdyHeaderBlock::ValueProxy::ValueProxy( spdy_header_block_value_size_(spdy_header_block_value_size), valid_(true) {} -SpdyHeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other) +Http2HeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other) : block_(other.block_), lookup_result_(other.lookup_result_), key_(other.key_), @@ -120,8 +118,8 @@ SpdyHeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other) other.valid_ = false; } -SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=( - SpdyHeaderBlock::ValueProxy&& other) { +Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=( + Http2HeaderBlock::ValueProxy&& other) { block_ = other.block_; lookup_result_ = other.lookup_result_; key_ = other.key_; @@ -131,18 +129,18 @@ SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=( return *this; } -SpdyHeaderBlock::ValueProxy::~ValueProxy() { +Http2HeaderBlock::ValueProxy::~ValueProxy() { // If the ValueProxy is destroyed while lookup_result_ == block_->end(), // the assignment operator was never used, and the block's SpdyHeaderStorage // can reclaim the memory used by the key. This makes lookup-only access to - // SpdyHeaderBlock through operator[] memory-neutral. + // Http2HeaderBlock through operator[] memory-neutral. if (valid_ && lookup_result_ == block_->map_.end()) { block_->storage_.Rewind(key_); } } -SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=( - quiche::QuicheStringPiece value) { +Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=( + absl::string_view value) { *spdy_header_block_value_size_ += value.size(); SpdyHeaderStorage* storage = &block_->storage_; if (lookup_result_ == block_->map_.end()) { @@ -160,8 +158,7 @@ SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=( return *this; } -bool SpdyHeaderBlock::ValueProxy::operator==( - quiche::QuicheStringPiece value) const { +bool Http2HeaderBlock::ValueProxy::operator==(absl::string_view value) const { if (lookup_result_ == block_->map_.end()) { return false; } else { @@ -169,7 +166,7 @@ bool SpdyHeaderBlock::ValueProxy::operator==( } } -std::string SpdyHeaderBlock::ValueProxy::as_string() const { +std::string Http2HeaderBlock::ValueProxy::as_string() const { if (lookup_result_ == block_->map_.end()) { return ""; } else { @@ -177,9 +174,9 @@ std::string SpdyHeaderBlock::ValueProxy::as_string() const { } } -SpdyHeaderBlock::SpdyHeaderBlock() : map_(kInitialMapBuckets) {} +Http2HeaderBlock::Http2HeaderBlock() : map_(kInitialMapBuckets) {} -SpdyHeaderBlock::SpdyHeaderBlock(SpdyHeaderBlock&& other) +Http2HeaderBlock::Http2HeaderBlock(Http2HeaderBlock&& other) : map_(kInitialMapBuckets) { map_.swap(other.map_); storage_ = std::move(other.storage_); @@ -190,9 +187,9 @@ SpdyHeaderBlock::SpdyHeaderBlock(SpdyHeaderBlock&& other) value_size_ = other.value_size_; } -SpdyHeaderBlock::~SpdyHeaderBlock() = default; +Http2HeaderBlock::~Http2HeaderBlock() = default; -SpdyHeaderBlock& SpdyHeaderBlock::operator=(SpdyHeaderBlock&& other) { +Http2HeaderBlock& Http2HeaderBlock::operator=(Http2HeaderBlock&& other) { map_.swap(other.map_); storage_ = std::move(other.storage_); for (auto& p : map_) { @@ -203,23 +200,23 @@ SpdyHeaderBlock& SpdyHeaderBlock::operator=(SpdyHeaderBlock&& other) { return *this; } -SpdyHeaderBlock SpdyHeaderBlock::Clone() const { - SpdyHeaderBlock copy; +Http2HeaderBlock Http2HeaderBlock::Clone() const { + Http2HeaderBlock copy; for (const auto& p : *this) { copy.AppendHeader(p.first, p.second); } return copy; } -bool SpdyHeaderBlock::operator==(const SpdyHeaderBlock& other) const { +bool Http2HeaderBlock::operator==(const Http2HeaderBlock& other) const { return size() == other.size() && std::equal(begin(), end(), other.begin()); } -bool SpdyHeaderBlock::operator!=(const SpdyHeaderBlock& other) const { +bool Http2HeaderBlock::operator!=(const Http2HeaderBlock& other) const { return !(operator==(other)); } -std::string SpdyHeaderBlock::DebugString() const { +std::string Http2HeaderBlock::DebugString() const { if (empty()) { return "{}"; } @@ -232,7 +229,7 @@ std::string SpdyHeaderBlock::DebugString() const { return output; } -void SpdyHeaderBlock::erase(quiche::QuicheStringPiece key) { +void Http2HeaderBlock::erase(absl::string_view key) { auto iter = map_.find(key); if (iter != map_.end()) { SPDY_DVLOG(1) << "Erasing header with name: " << key; @@ -242,14 +239,14 @@ void SpdyHeaderBlock::erase(quiche::QuicheStringPiece key) { } } -void SpdyHeaderBlock::clear() { +void Http2HeaderBlock::clear() { key_size_ = 0; value_size_ = 0; map_.clear(); storage_.Clear(); } -void SpdyHeaderBlock::insert(const SpdyHeaderBlock::value_type& value) { +void Http2HeaderBlock::insert(const Http2HeaderBlock::value_type& value) { // TODO(birenroy): Write new value in place of old value, if it fits. value_size_ += value.second.size(); @@ -267,14 +264,14 @@ void SpdyHeaderBlock::insert(const SpdyHeaderBlock::value_type& value) { } } -SpdyHeaderBlock::ValueProxy SpdyHeaderBlock::operator[]( - const quiche::QuicheStringPiece key) { +Http2HeaderBlock::ValueProxy Http2HeaderBlock::operator[]( + const absl::string_view key) { SPDY_DVLOG(2) << "Operator[] saw key: " << key; - quiche::QuicheStringPiece out_key; + absl::string_view out_key; auto iter = map_.find(key); if (iter == map_.end()) { // We write the key first, to assure that the ValueProxy has a - // reference to a valid QuicheStringPiece in its operator=. + // reference to a valid absl::string_view in its operator=. out_key = WriteKey(key); SPDY_DVLOG(2) << "Key written as: " << std::hex << static_cast<const void*>(key.data()) << ", " << std::dec @@ -285,9 +282,8 @@ SpdyHeaderBlock::ValueProxy SpdyHeaderBlock::operator[]( return ValueProxy(this, iter, out_key, &value_size_); } -void SpdyHeaderBlock::AppendValueOrAddHeader( - const quiche::QuicheStringPiece key, - const quiche::QuicheStringPiece value) { +void Http2HeaderBlock::AppendValueOrAddHeader(const absl::string_view key, + const absl::string_view value) { value_size_ += value.size(); auto iter = map_.find(key); @@ -303,26 +299,25 @@ void SpdyHeaderBlock::AppendValueOrAddHeader( iter->second.Append(storage_.Write(value)); } -size_t SpdyHeaderBlock::EstimateMemoryUsage() const { +size_t Http2HeaderBlock::EstimateMemoryUsage() const { // TODO(xunjieli): https://crbug.com/669108. Also include |map_| when EMU() // supports linked_hash_map. return SpdyEstimateMemoryUsage(storage_); } -void SpdyHeaderBlock::AppendHeader(const quiche::QuicheStringPiece key, - const quiche::QuicheStringPiece value) { +void Http2HeaderBlock::AppendHeader(const absl::string_view key, + const absl::string_view value) { auto backed_key = WriteKey(key); map_.emplace(std::make_pair( backed_key, HeaderValue(&storage_, backed_key, storage_.Write(value)))); } -quiche::QuicheStringPiece SpdyHeaderBlock::WriteKey( - const quiche::QuicheStringPiece key) { +absl::string_view Http2HeaderBlock::WriteKey(const absl::string_view key) { key_size_ += key.size(); return storage_.Write(key); } -size_t SpdyHeaderBlock::bytes_allocated() const { +size_t Http2HeaderBlock::bytes_allocated() const { return storage_.bytes_allocated(); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.h index 2348551f567..8961b497e82 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block.h @@ -13,8 +13,8 @@ #include <utility> #include <vector> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_storage.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_containers.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_macros.h" @@ -23,7 +23,7 @@ namespace spdy { namespace test { -class SpdyHeaderBlockPeer; +class Http2HeaderBlockPeer; class ValueProxyPeer; } // namespace test @@ -39,22 +39,22 @@ class ValueProxyPeer; // names and values. This data structure preserves insertion order. // // Under the hood, this data structure uses large, contiguous blocks of memory -// to store names and values. Lookups may be performed with QuicheStringPiece -// keys, and values are returned as QuicheStringPieces (via ValueProxy, below). -// Value QuicheStringPieces are valid as long as the SpdyHeaderBlock exists; -// allocated memory is never freed until SpdyHeaderBlock's destruction. +// to store names and values. Lookups may be performed with absl::string_view +// keys, and values are returned as absl::string_views (via ValueProxy, below). +// Value absl::string_views are valid as long as the Http2HeaderBlock exists; +// allocated memory is never freed until Http2HeaderBlock's destruction. // // This implementation does not make much of an effort to minimize wasted space. -// It's expected that keys are rarely deleted from a SpdyHeaderBlock. -class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { +// It's expected that keys are rarely deleted from a Http2HeaderBlock. +class QUICHE_EXPORT_PRIVATE Http2HeaderBlock { private: // Stores a list of value fragments that can be joined later with a // key-dependent separator. class QUICHE_EXPORT_PRIVATE HeaderValue { public: HeaderValue(SpdyHeaderStorage* storage, - quiche::QuicheStringPiece key, - quiche::QuicheStringPiece initial_value); + absl::string_view key, + absl::string_view initial_value); // Moves are allowed. HeaderValue(HeaderValue&& other); @@ -69,50 +69,46 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { ~HeaderValue(); // Consumes at most |fragment.size()| bytes of memory. - void Append(quiche::QuicheStringPiece fragment); + void Append(absl::string_view fragment); - quiche::QuicheStringPiece value() const { return as_pair().second; } - const std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece>& - as_pair() const; + absl::string_view value() const { return as_pair().second; } + const std::pair<absl::string_view, absl::string_view>& as_pair() const; // Size estimate including separators. Used when keys are erased from - // SpdyHeaderBlock. + // Http2HeaderBlock. size_t SizeEstimate() const { return size_; } private: // May allocate a large contiguous region of memory to hold the concatenated // fragments and separators. - quiche::QuicheStringPiece ConsolidatedValue() const; + absl::string_view ConsolidatedValue() const; mutable SpdyHeaderStorage* storage_; - mutable std::vector<quiche::QuicheStringPiece> fragments_; + mutable std::vector<absl::string_view> fragments_; // The first element is the key; the second is the consolidated value. - mutable std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece> - pair_; + mutable std::pair<absl::string_view, absl::string_view> pair_; size_t size_ = 0; size_t separator_size_ = 0; }; - typedef SpdyLinkedHashMap<quiche::QuicheStringPiece, + typedef SpdyLinkedHashMap<absl::string_view, HeaderValue, SpdyStringPieceCaseHash, SpdyStringPieceCaseEq> MapType; public: - typedef std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece> - value_type; + typedef std::pair<absl::string_view, absl::string_view> value_type; - // Provides iteration over a sequence of std::pair<QuicheStringPiece, - // QuicheStringPiece>, even though the underlying MapType::value_type is + // Provides iteration over a sequence of std::pair<absl::string_view, + // absl::string_view>, even though the underlying MapType::value_type is // different. Dereferencing the iterator will result in memory allocation for // multi-value headers. class QUICHE_EXPORT_PRIVATE iterator { public: // The following type definitions fulfill the requirements for iterator // implementations. - typedef std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece> - value_type; + typedef std::pair<absl::string_view, absl::string_view> value_type; typedef value_type& reference; typedef value_type* pointer; typedef std::forward_iterator_tag iterator_category; @@ -162,17 +158,17 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { }; typedef iterator const_iterator; - SpdyHeaderBlock(); - SpdyHeaderBlock(const SpdyHeaderBlock& other) = delete; - SpdyHeaderBlock(SpdyHeaderBlock&& other); - ~SpdyHeaderBlock(); + Http2HeaderBlock(); + Http2HeaderBlock(const Http2HeaderBlock& other) = delete; + Http2HeaderBlock(Http2HeaderBlock&& other); + ~Http2HeaderBlock(); - SpdyHeaderBlock& operator=(const SpdyHeaderBlock& other) = delete; - SpdyHeaderBlock& operator=(SpdyHeaderBlock&& other); - SpdyHeaderBlock Clone() const; + Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete; + Http2HeaderBlock& operator=(Http2HeaderBlock&& other); + Http2HeaderBlock Clone() const; - bool operator==(const SpdyHeaderBlock& other) const; - bool operator!=(const SpdyHeaderBlock& other) const; + bool operator==(const Http2HeaderBlock& other) const; + bool operator!=(const Http2HeaderBlock& other) const; // Provides a human readable multi-line representation of the stored header // keys and values. @@ -184,13 +180,11 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { const_iterator end() const { return wrap_const_iterator(map_.end()); } bool empty() const { return map_.empty(); } size_t size() const { return map_.size(); } - iterator find(quiche::QuicheStringPiece key) { - return wrap_iterator(map_.find(key)); - } - const_iterator find(quiche::QuicheStringPiece key) const { + iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); } + const_iterator find(absl::string_view key) const { return wrap_const_iterator(map_.find(key)); } - void erase(quiche::QuicheStringPiece key); + void erase(absl::string_view key); // Clears both our MapType member and the memory used to hold headers. void clear(); @@ -205,11 +199,11 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { // existing header value, NUL ("\0") separated unless the key is cookie, in // which case the separator is "; ". // If there is no such key, a new header with the key and value is added. - void AppendValueOrAddHeader(const quiche::QuicheStringPiece key, - const quiche::QuicheStringPiece value); + void AppendValueOrAddHeader(const absl::string_view key, + const absl::string_view value); - // This object provides automatic conversions that allow SpdyHeaderBlock to be - // nearly a drop-in replacement for + // This object provides automatic conversions that allow Http2HeaderBlock to + // be nearly a drop-in replacement for // SpdyLinkedHashMap<std::string, std::string>. // It reads data from or writes data to a SpdyHeaderStorage. class QUICHE_EXPORT_PRIVATE ValueProxy { @@ -224,33 +218,32 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { ValueProxy(const ValueProxy& other) = delete; ValueProxy& operator=(const ValueProxy& other) = delete; - // Assignment modifies the underlying SpdyHeaderBlock. - ValueProxy& operator=(quiche::QuicheStringPiece value); + // Assignment modifies the underlying Http2HeaderBlock. + ValueProxy& operator=(absl::string_view value); - // Provides easy comparison against QuicheStringPiece. - bool operator==(quiche::QuicheStringPiece value) const; + // Provides easy comparison against absl::string_view. + bool operator==(absl::string_view value) const; std::string as_string() const; private: - friend class SpdyHeaderBlock; + friend class Http2HeaderBlock; friend class test::ValueProxyPeer; - ValueProxy(SpdyHeaderBlock* block, - SpdyHeaderBlock::MapType::iterator lookup_result, - const quiche::QuicheStringPiece key, + ValueProxy(Http2HeaderBlock* block, + Http2HeaderBlock::MapType::iterator lookup_result, + const absl::string_view key, size_t* spdy_header_block_value_size); - SpdyHeaderBlock* block_; - SpdyHeaderBlock::MapType::iterator lookup_result_; - quiche::QuicheStringPiece key_; + Http2HeaderBlock* block_; + Http2HeaderBlock::MapType::iterator lookup_result_; + absl::string_view key_; size_t* spdy_header_block_value_size_; bool valid_; }; // Allows either lookup or mutation of the value associated with a key. - SPDY_MUST_USE_RESULT ValueProxy - operator[](const quiche::QuicheStringPiece key); + SPDY_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key); // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; @@ -258,7 +251,7 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { size_t TotalBytesUsed() const { return key_size_ + value_size_; } private: - friend class test::SpdyHeaderBlockPeer; + friend class test::Http2HeaderBlockPeer; inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const { #if SPDY_HEADER_DEBUG @@ -285,12 +278,11 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { #endif // SPDY_HEADER_DEBUG } - void AppendHeader(const quiche::QuicheStringPiece key, - const quiche::QuicheStringPiece value); - quiche::QuicheStringPiece WriteKey(const quiche::QuicheStringPiece key); + void AppendHeader(const absl::string_view key, const absl::string_view value); + absl::string_view WriteKey(const absl::string_view key); size_t bytes_allocated() const; - // QuicheStringPieces held by |map_| point to memory owned by |storage_|. + // absl::string_views held by |map_| point to memory owned by |storage_|. MapType map_; SpdyHeaderStorage storage_; @@ -298,6 +290,9 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderBlock { size_t value_size_ = 0; }; +// TODO(b/156770486): Remove this alias when the rename is complete. +using SpdyHeaderBlock = Http2HeaderBlock; + } // namespace spdy #endif // QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_ diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block_test.cc index b670c2ae650..9fd7b6871c5 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_block_test.cc @@ -17,20 +17,19 @@ namespace test { class ValueProxyPeer { public: - static quiche::QuicheStringPiece key(SpdyHeaderBlock::ValueProxy* p) { + static absl::string_view key(Http2HeaderBlock::ValueProxy* p) { return p->key_; } }; -std::pair<quiche::QuicheStringPiece, quiche::QuicheStringPiece> Pair( - quiche::QuicheStringPiece k, - quiche::QuicheStringPiece v) { +std::pair<absl::string_view, absl::string_view> Pair(absl::string_view k, + absl::string_view v) { return std::make_pair(k, v); } -// This test verifies that SpdyHeaderBlock behaves correctly when empty. -TEST(SpdyHeaderBlockTest, EmptyBlock) { - SpdyHeaderBlock block; +// This test verifies that Http2HeaderBlock behaves correctly when empty. +TEST(Http2HeaderBlockTest, EmptyBlock) { + Http2HeaderBlock block; EXPECT_TRUE(block.empty()); EXPECT_EQ(0u, block.size()); EXPECT_EQ(block.end(), block.find("foo")); @@ -40,21 +39,21 @@ TEST(SpdyHeaderBlockTest, EmptyBlock) { block.erase("bar"); } -TEST(SpdyHeaderBlockTest, KeyMemoryReclaimedOnLookup) { - SpdyHeaderBlock block; - quiche::QuicheStringPiece copied_key1; +TEST(Http2HeaderBlockTest, KeyMemoryReclaimedOnLookup) { + Http2HeaderBlock block; + absl::string_view copied_key1; { auto proxy1 = block["some key name"]; copied_key1 = ValueProxyPeer::key(&proxy1); } - quiche::QuicheStringPiece copied_key2; + absl::string_view copied_key2; { auto proxy2 = block["some other key name"]; copied_key2 = ValueProxyPeer::key(&proxy2); } // Because proxy1 was never used to modify the block, the memory used for the // key could be reclaimed and used for the second call to operator[]. - // Therefore, we expect the pointers of the two QuicheStringPieces to be + // Therefore, we expect the pointers of the two absl::string_views to be // equal. EXPECT_EQ(copied_key1.data(), copied_key2.data()); @@ -63,7 +62,7 @@ TEST(SpdyHeaderBlockTest, KeyMemoryReclaimedOnLookup) { block["some other key name"] = "some value"; } // Nothing should blow up when proxy1 is destructed, and we should be able to - // modify and access the SpdyHeaderBlock. + // modify and access the Http2HeaderBlock. block["key"] = "value"; EXPECT_EQ("value", block["key"]); EXPECT_EQ("some value", block["some other key name"]); @@ -71,8 +70,8 @@ TEST(SpdyHeaderBlockTest, KeyMemoryReclaimedOnLookup) { } // This test verifies that headers can be set in a variety of ways. -TEST(SpdyHeaderBlockTest, AddHeaders) { - SpdyHeaderBlock block; +TEST(Http2HeaderBlockTest, AddHeaders) { + Http2HeaderBlock block; block["foo"] = std::string(300, 'x'); block["bar"] = "baz"; block["qux"] = "qux1"; @@ -90,29 +89,29 @@ TEST(SpdyHeaderBlockTest, AddHeaders) { EXPECT_EQ(block.end(), block.find("key")); } -// This test verifies that SpdyHeaderBlock can be copied using Clone(). -TEST(SpdyHeaderBlockTest, CopyBlocks) { - SpdyHeaderBlock block1; +// This test verifies that Http2HeaderBlock can be copied using Clone(). +TEST(Http2HeaderBlockTest, CopyBlocks) { + Http2HeaderBlock block1; block1["foo"] = std::string(300, 'x'); block1["bar"] = "baz"; block1.insert(std::make_pair("qux", "qux1")); - SpdyHeaderBlock block2 = block1.Clone(); - SpdyHeaderBlock block3(block1.Clone()); + Http2HeaderBlock block2 = block1.Clone(); + Http2HeaderBlock block3(block1.Clone()); EXPECT_EQ(block1, block2); EXPECT_EQ(block1, block3); } -TEST(SpdyHeaderBlockTest, Equality) { +TEST(Http2HeaderBlockTest, Equality) { // Test equality and inequality operators. - SpdyHeaderBlock block1; + Http2HeaderBlock block1; block1["foo"] = "bar"; - SpdyHeaderBlock block2; + Http2HeaderBlock block2; block2["foo"] = "bar"; - SpdyHeaderBlock block3; + Http2HeaderBlock block3; block3["baz"] = "qux"; EXPECT_EQ(block1, block2); @@ -122,28 +121,28 @@ TEST(SpdyHeaderBlockTest, Equality) { EXPECT_NE(block1, block2); } -SpdyHeaderBlock ReturnTestHeaderBlock() { - SpdyHeaderBlock block; +Http2HeaderBlock ReturnTestHeaderBlock() { + Http2HeaderBlock block; block["foo"] = "bar"; block.insert(std::make_pair("foo2", "baz")); return block; } // Test that certain methods do not crash on moved-from instances. -TEST(SpdyHeaderBlockTest, MovedFromIsValid) { - SpdyHeaderBlock block1; +TEST(Http2HeaderBlockTest, MovedFromIsValid) { + Http2HeaderBlock block1; block1["foo"] = "bar"; - SpdyHeaderBlock block2(std::move(block1)); + Http2HeaderBlock block2(std::move(block1)); EXPECT_THAT(block2, ElementsAre(Pair("foo", "bar"))); block1["baz"] = "qux"; // NOLINT testing post-move behavior - SpdyHeaderBlock block3(std::move(block1)); + Http2HeaderBlock block3(std::move(block1)); block1["foo"] = "bar"; // NOLINT testing post-move behavior - SpdyHeaderBlock block4(std::move(block1)); + Http2HeaderBlock block4(std::move(block1)); block1.clear(); // NOLINT testing post-move behavior EXPECT_TRUE(block1.empty()); @@ -151,7 +150,7 @@ TEST(SpdyHeaderBlockTest, MovedFromIsValid) { block1["foo"] = "bar"; EXPECT_THAT(block1, ElementsAre(Pair("foo", "bar"))); - SpdyHeaderBlock block5 = ReturnTestHeaderBlock(); + Http2HeaderBlock block5 = ReturnTestHeaderBlock(); block5.AppendValueOrAddHeader("foo", "bar2"); EXPECT_THAT(block5, ElementsAre(Pair("foo", std::string("bar\0bar2", 8)), Pair("foo2", "baz"))); @@ -159,8 +158,8 @@ TEST(SpdyHeaderBlockTest, MovedFromIsValid) { // This test verifies that headers can be appended to no matter how they were // added originally. -TEST(SpdyHeaderBlockTest, AppendHeaders) { - SpdyHeaderBlock block; +TEST(Http2HeaderBlockTest, AppendHeaders) { + Http2HeaderBlock block; block["foo"] = "foo"; block.AppendValueOrAddHeader("foo", "bar"); EXPECT_EQ(Pair("foo", std::string("foo\0bar", 7)), *block.find("foo")); @@ -193,31 +192,31 @@ TEST(SpdyHeaderBlockTest, AppendHeaders) { EXPECT_EQ("singleton", block["h4"]); } -TEST(SpdyHeaderBlockTest, CompareValueToStringPiece) { - SpdyHeaderBlock block; +TEST(Http2HeaderBlockTest, CompareValueToStringPiece) { + Http2HeaderBlock block; block["foo"] = "foo"; block.AppendValueOrAddHeader("foo", "bar"); const auto& val = block["foo"]; const char expected[] = "foo\0bar"; - EXPECT_TRUE(quiche::QuicheStringPiece(expected, 7) == val); - EXPECT_TRUE(val == quiche::QuicheStringPiece(expected, 7)); - EXPECT_FALSE(quiche::QuicheStringPiece(expected, 3) == val); - EXPECT_FALSE(val == quiche::QuicheStringPiece(expected, 3)); + EXPECT_TRUE(absl::string_view(expected, 7) == val); + EXPECT_TRUE(val == absl::string_view(expected, 7)); + EXPECT_FALSE(absl::string_view(expected, 3) == val); + EXPECT_FALSE(val == absl::string_view(expected, 3)); const char not_expected[] = "foo\0barextra"; - EXPECT_FALSE(quiche::QuicheStringPiece(not_expected, 12) == val); - EXPECT_FALSE(val == quiche::QuicheStringPiece(not_expected, 12)); + EXPECT_FALSE(absl::string_view(not_expected, 12) == val); + EXPECT_FALSE(val == absl::string_view(not_expected, 12)); const auto& val2 = block["foo2"]; - EXPECT_FALSE(quiche::QuicheStringPiece(expected, 7) == val2); - EXPECT_FALSE(val2 == quiche::QuicheStringPiece(expected, 7)); - EXPECT_FALSE(quiche::QuicheStringPiece("") == val2); - EXPECT_FALSE(val2 == quiche::QuicheStringPiece("")); + EXPECT_FALSE(absl::string_view(expected, 7) == val2); + EXPECT_FALSE(val2 == absl::string_view(expected, 7)); + EXPECT_FALSE(absl::string_view("") == val2); + EXPECT_FALSE(val2 == absl::string_view("")); } -// This test demonstrates that the SpdyHeaderBlock data structure does not place -// any limitations on the characters present in the header names. -TEST(SpdyHeaderBlockTest, UpperCaseNames) { - SpdyHeaderBlock block; +// This test demonstrates that the Http2HeaderBlock data structure does not +// place any limitations on the characters present in the header names. +TEST(Http2HeaderBlockTest, UpperCaseNames) { + Http2HeaderBlock block; block["Foo"] = "foo"; block.AppendValueOrAddHeader("Foo", "bar"); EXPECT_NE(block.end(), block.find("foo")); @@ -231,7 +230,7 @@ TEST(SpdyHeaderBlockTest, UpperCaseNames) { } namespace { -size_t SpdyHeaderBlockSize(const SpdyHeaderBlock& block) { +size_t Http2HeaderBlockSize(const Http2HeaderBlock& block) { size_t size = 0; for (const auto& pair : block) { size += pair.first.size() + pair.second.size(); @@ -240,38 +239,38 @@ size_t SpdyHeaderBlockSize(const SpdyHeaderBlock& block) { } } // namespace -// Tests SpdyHeaderBlock SizeEstimate(). -TEST(SpdyHeaderBlockTest, TotalBytesUsed) { - SpdyHeaderBlock block; +// Tests Http2HeaderBlock SizeEstimate(). +TEST(Http2HeaderBlockTest, TotalBytesUsed) { + Http2HeaderBlock block; const size_t value_size = 300; block["foo"] = std::string(value_size, 'x'); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); block.insert(std::make_pair("key", std::string(value_size, 'x'))); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); block.AppendValueOrAddHeader("abc", std::string(value_size, 'x')); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); // Replace value for existing key. block["foo"] = std::string(value_size, 'x'); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); block.insert(std::make_pair("key", std::string(value_size, 'x'))); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); // Add value for existing key. block.AppendValueOrAddHeader("abc", std::string(value_size, 'x')); - EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block)); + EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block)); - // Copies/clones SpdyHeaderBlock. + // Copies/clones Http2HeaderBlock. size_t block_size = block.TotalBytesUsed(); - SpdyHeaderBlock block_copy = std::move(block); + Http2HeaderBlock block_copy = std::move(block); EXPECT_EQ(block_size, block_copy.TotalBytesUsed()); // Erases key. block_copy.erase("foo"); - EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy)); + EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy)); block_copy.erase("key"); - EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy)); + EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy)); block_copy.erase("abc"); - EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy)); + EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.cc index 90493e11b5a..29ed0a45b87 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.cc @@ -14,34 +14,33 @@ const size_t kDefaultStorageBlockSize = 2048; SpdyHeaderStorage::SpdyHeaderStorage() : arena_(kDefaultStorageBlockSize) {} -quiche::QuicheStringPiece SpdyHeaderStorage::Write( - const quiche::QuicheStringPiece s) { - return quiche::QuicheStringPiece(arena_.Memdup(s.data(), s.size()), s.size()); +absl::string_view SpdyHeaderStorage::Write(const absl::string_view s) { + return absl::string_view(arena_.Memdup(s.data(), s.size()), s.size()); } -void SpdyHeaderStorage::Rewind(const quiche::QuicheStringPiece s) { +void SpdyHeaderStorage::Rewind(const absl::string_view s) { arena_.Free(const_cast<char*>(s.data()), s.size()); } -quiche::QuicheStringPiece SpdyHeaderStorage::WriteFragments( - const std::vector<quiche::QuicheStringPiece>& fragments, - quiche::QuicheStringPiece separator) { +absl::string_view SpdyHeaderStorage::WriteFragments( + const std::vector<absl::string_view>& fragments, + absl::string_view separator) { if (fragments.empty()) { - return quiche::QuicheStringPiece(); + return absl::string_view(); } size_t total_size = separator.size() * (fragments.size() - 1); - for (const quiche::QuicheStringPiece& fragment : fragments) { + for (const absl::string_view& fragment : fragments) { total_size += fragment.size(); } char* dst = arena_.Alloc(total_size); size_t written = Join(dst, fragments, separator); DCHECK_EQ(written, total_size); - return quiche::QuicheStringPiece(dst, total_size); + return absl::string_view(dst, total_size); } size_t Join(char* dst, - const std::vector<quiche::QuicheStringPiece>& fragments, - quiche::QuicheStringPiece separator) { + const std::vector<absl::string_view>& fragments, + absl::string_view separator) { if (fragments.empty()) { return 0; } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.h index aace3c06ab4..4e5a6abe7ef 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage.h @@ -1,15 +1,15 @@ #ifndef QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_ #define QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_ +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_simple_arena.h" namespace spdy { -// This class provides a backing store for QuicheStringPieces. It previously +// This class provides a backing store for absl::string_views. It previously // used custom allocation logic, but now uses an UnsafeArena instead. It has the -// property that QuicheStringPieces that refer to data in SpdyHeaderStorage are +// property that absl::string_views that refer to data in SpdyHeaderStorage are // never invalidated until the SpdyHeaderStorage is deleted or Clear() is // called. // @@ -26,20 +26,20 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderStorage { SpdyHeaderStorage(SpdyHeaderStorage&& other) = default; SpdyHeaderStorage& operator=(SpdyHeaderStorage&& other) = default; - quiche::QuicheStringPiece Write(quiche::QuicheStringPiece s); + absl::string_view Write(absl::string_view s); // If |s| points to the most recent allocation from arena_, the arena will // reclaim the memory. Otherwise, this method is a no-op. - void Rewind(quiche::QuicheStringPiece s); + void Rewind(absl::string_view s); void Clear() { arena_.Reset(); } // Given a list of fragments and a separator, writes the fragments joined by - // the separator to a contiguous region of memory. Returns a QuicheStringPiece + // the separator to a contiguous region of memory. Returns a absl::string_view // pointing to the region of memory. - quiche::QuicheStringPiece WriteFragments( - const std::vector<quiche::QuicheStringPiece>& fragments, - quiche::QuicheStringPiece separator); + absl::string_view WriteFragments( + const std::vector<absl::string_view>& fragments, + absl::string_view separator); size_t bytes_allocated() const { return arena_.status().bytes_allocated(); } @@ -53,8 +53,8 @@ class QUICHE_EXPORT_PRIVATE SpdyHeaderStorage { // enough to hold the result. Returns the number of bytes written. QUICHE_EXPORT_PRIVATE size_t Join(char* dst, - const std::vector<quiche::QuicheStringPiece>& fragments, - quiche::QuicheStringPiece separator); + const std::vector<absl::string_view>& fragments, + absl::string_view separator); } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage_test.cc index 71af6be43aa..af8cd06bb5a 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_header_storage_test.cc @@ -6,29 +6,29 @@ namespace spdy { namespace test { TEST(JoinTest, JoinEmpty) { - std::vector<quiche::QuicheStringPiece> empty; - quiche::QuicheStringPiece separator = ", "; + std::vector<absl::string_view> empty; + absl::string_view separator = ", "; char buf[10] = ""; size_t written = Join(buf, empty, separator); EXPECT_EQ(0u, written); } TEST(JoinTest, JoinOne) { - std::vector<quiche::QuicheStringPiece> v = {"one"}; - quiche::QuicheStringPiece separator = ", "; + std::vector<absl::string_view> v = {"one"}; + absl::string_view separator = ", "; char buf[15]; size_t written = Join(buf, v, separator); EXPECT_EQ(3u, written); - EXPECT_EQ("one", quiche::QuicheStringPiece(buf, written)); + EXPECT_EQ("one", absl::string_view(buf, written)); } TEST(JoinTest, JoinMultiple) { - std::vector<quiche::QuicheStringPiece> v = {"one", "two", "three"}; - quiche::QuicheStringPiece separator = ", "; + std::vector<absl::string_view> v = {"one", "two", "three"}; + absl::string_view separator = ", "; char buf[15]; size_t written = Join(buf, v, separator); EXPECT_EQ(15u, written); - EXPECT_EQ("one, two, three", quiche::QuicheStringPiece(buf, written)); + EXPECT_EQ("one, two, three", absl::string_view(buf, written)); } } // namespace test diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h index 870997758be..39bda07dc6b 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h @@ -7,8 +7,8 @@ #include <stddef.h> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace spdy { @@ -25,8 +25,7 @@ class QUICHE_EXPORT_PRIVATE SpdyHeadersHandlerInterface { // A callback method which notifies on a header key value pair. Multiple // values for a given key will be emitted as multiple calls to OnHeader. - virtual void OnHeader(quiche::QuicheStringPiece key, - quiche::QuicheStringPiece value) = 0; + virtual void OnHeader(absl::string_view key, absl::string_view value) = 0; // A callback method which notifies when the parser finishes handling a // header block (i.e. the containing frame has the END_HEADERS flag set). diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_intrusive_list_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_intrusive_list_test.cc index e158d44a7f3..5f5243bddb3 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_intrusive_list_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_intrusive_list_test.cc @@ -409,8 +409,7 @@ TEST(NewIntrusiveListTest, HandleInheritanceHierarchies) { } } - -class IntrusiveListTagTypeTest : public testing::Test { +class IntrusiveListTagTypeTest : public QuicheTest { protected: struct Tag {}; class Element : public SpdyIntrusiveLink<Element, Tag> {}; diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_no_op_visitor.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_no_op_visitor.h index 93a32357719..26bab9cba8b 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_no_op_visitor.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_no_op_visitor.h @@ -11,7 +11,7 @@ #include <cstdint> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" @@ -61,7 +61,7 @@ class SpdyNoOpVisitor : public SpdyFramerVisitorInterface, bool /*end*/) override {} void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {} void OnAltSvc(SpdyStreamId /*stream_id*/, - quiche::QuicheStringPiece /*origin*/, + absl::string_view /*origin*/, const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) override {} void OnPriority(SpdyStreamId /*stream_id*/, @@ -82,8 +82,8 @@ class SpdyNoOpVisitor : public SpdyFramerVisitorInterface, // SpdyHeadersHandlerInterface methods: void OnHeaderBlockStart() override {} - void OnHeader(quiche::QuicheStringPiece /*key*/, - quiche::QuicheStringPiece /*value*/) override {} + void OnHeader(absl::string_view /*key*/, + absl::string_view /*value*/) override {} void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */, size_t /* compressed_header_bytes */) override {} }; diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece.h index fe9639f73f2..2822410da55 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece.h @@ -9,8 +9,8 @@ #include <memory> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" namespace spdy { @@ -27,8 +27,8 @@ struct QUICHE_EXPORT_PRIVATE SpdyPinnableBufferPiece { const char* buffer() const { return buffer_; } - explicit operator quiche::QuicheStringPiece() const { - return quiche::QuicheStringPiece(buffer_, length_); + explicit operator absl::string_view() const { + return absl::string_view(buffer_, length_); } // Allocates and copies the buffer to internal storage. diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece_test.cc index b30a7c0d916..42329d788a3 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_pinnable_buffer_piece_test.cc @@ -31,16 +31,14 @@ TEST_F(SpdyPinnableBufferPieceTest, Pin) { EXPECT_TRUE(reader.ReadN(6, &piece)); // Piece points to underlying prefix storage. - EXPECT_EQ(quiche::QuicheStringPiece("foobar"), - quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); EXPECT_FALSE(piece.IsPinned()); EXPECT_EQ(prefix_.data(), piece.buffer()); piece.Pin(); // Piece now points to allocated storage. - EXPECT_EQ(quiche::QuicheStringPiece("foobar"), - quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); EXPECT_TRUE(piece.IsPinned()); EXPECT_NE(prefix_.data(), piece.buffer()); @@ -58,24 +56,22 @@ TEST_F(SpdyPinnableBufferPieceTest, Swap) { piece1.Pin(); - EXPECT_EQ(quiche::QuicheStringPiece("foob"), - quiche::QuicheStringPiece(piece1)); + EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece1)); EXPECT_TRUE(piece1.IsPinned()); - EXPECT_EQ(quiche::QuicheStringPiece("ar"), quiche::QuicheStringPiece(piece2)); + EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece2)); EXPECT_FALSE(piece2.IsPinned()); piece1.Swap(&piece2); - EXPECT_EQ(quiche::QuicheStringPiece("ar"), quiche::QuicheStringPiece(piece1)); + EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece1)); EXPECT_FALSE(piece1.IsPinned()); - EXPECT_EQ(quiche::QuicheStringPiece("foob"), - quiche::QuicheStringPiece(piece2)); + EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece2)); EXPECT_TRUE(piece2.IsPinned()); SpdyPinnableBufferPiece empty; piece2.Swap(&empty); - EXPECT_EQ(quiche::QuicheStringPiece(""), quiche::QuicheStringPiece(piece2)); + EXPECT_EQ(absl::string_view(""), absl::string_view(piece2)); EXPECT_FALSE(piece2.IsPinned()); } diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_prefixed_buffer_reader_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_prefixed_buffer_reader_test.cc index d48fde1abb7..83559567886 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_prefixed_buffer_reader_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_prefixed_buffer_reader_test.cc @@ -6,7 +6,7 @@ #include <string> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace spdy { @@ -46,8 +46,7 @@ TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromPrefix) { EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. EXPECT_TRUE(reader.ReadN(6, &piece)); EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(quiche::QuicheStringPiece("foobar"), - quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); EXPECT_EQ(0u, reader.Available()); } @@ -70,8 +69,7 @@ TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromSuffix) { EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. EXPECT_TRUE(reader.ReadN(6, &piece)); EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(quiche::QuicheStringPiece("foobar"), - quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); EXPECT_EQ(0u, reader.Available()); } @@ -94,8 +92,7 @@ TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceSpanning) { EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. EXPECT_TRUE(reader.ReadN(6, &piece)); EXPECT_TRUE(piece.IsPinned()); - EXPECT_EQ(quiche::QuicheStringPiece("foobar"), - quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); EXPECT_EQ(0u, reader.Available()); } @@ -115,12 +112,12 @@ TEST_F(SpdyPrefixedBufferReaderTest, ReadMixed) { EXPECT_EQ(6u, reader.Available()); EXPECT_TRUE(reader.ReadN(3, &piece)); - EXPECT_EQ(quiche::QuicheStringPiece("fhi"), quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("fhi"), absl::string_view(piece)); EXPECT_TRUE(piece.IsPinned()); EXPECT_EQ(3u, reader.Available()); EXPECT_TRUE(reader.ReadN(2, &piece)); - EXPECT_EQ(quiche::QuicheStringPiece("jk"), quiche::QuicheStringPiece(piece)); + EXPECT_EQ(absl::string_view("jk"), absl::string_view(piece)); EXPECT_FALSE(piece.IsPinned()); EXPECT_EQ(1u, reader.Available()); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.cc index a4a72d67325..f9a18007088 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.cc @@ -276,12 +276,12 @@ bool SpdyFrameWithFinIR::fin() const { SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR( SpdyStreamId stream_id, - SpdyHeaderBlock header_block) + Http2HeaderBlock header_block) : SpdyFrameWithFinIR(stream_id), header_block_(std::move(header_block)) {} SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() = default; -SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, quiche::QuicheStringPiece data) +SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, absl::string_view data) : SpdyFrameWithFinIR(stream_id), data_(nullptr), data_len_(0), @@ -291,7 +291,7 @@ SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, quiche::QuicheStringPiece data) } SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const char* data) - : SpdyDataIR(stream_id, quiche::QuicheStringPiece(data)) {} + : SpdyDataIR(stream_id, absl::string_view(data)) {} SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, std::string data) : SpdyFrameWithFinIR(stream_id), @@ -377,7 +377,7 @@ size_t SpdyPingIR::size() const { SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyErrorCode error_code, - quiche::QuicheStringPiece description) + absl::string_view description) : description_(description) { set_last_good_stream_id(last_good_stream_id); set_error_code(error_code); @@ -388,7 +388,7 @@ SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id, const char* description) : SpdyGoAwayIR(last_good_stream_id, error_code, - quiche::QuicheStringPiece(description)) {} + absl::string_view(description)) {} SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyErrorCode error_code, diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.h index 0bf8bb9d69f..a2b9c4d39ca 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol.h @@ -19,8 +19,8 @@ #include <string> #include <utility> +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_export.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" #include "net/third_party/quiche/src/spdy/core/spdy_bitmasks.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" @@ -492,31 +492,30 @@ class QUICHE_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR public: ~SpdyFrameWithHeaderBlockIR() override; - const SpdyHeaderBlock& header_block() const { return header_block_; } - void set_header_block(SpdyHeaderBlock header_block) { + const Http2HeaderBlock& header_block() const { return header_block_; } + void set_header_block(Http2HeaderBlock header_block) { // Deep copy. header_block_ = std::move(header_block); } - void SetHeader(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { + void SetHeader(absl::string_view name, absl::string_view value) { header_block_[name] = value; } protected: SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id, - SpdyHeaderBlock header_block); + Http2HeaderBlock header_block); SpdyFrameWithHeaderBlockIR(const SpdyFrameWithHeaderBlockIR&) = delete; SpdyFrameWithHeaderBlockIR& operator=(const SpdyFrameWithHeaderBlockIR&) = delete; private: - SpdyHeaderBlock header_block_; + Http2HeaderBlock header_block_; }; class QUICHE_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR { public: // Performs a deep copy on data. - SpdyDataIR(SpdyStreamId stream_id, quiche::QuicheStringPiece data); + SpdyDataIR(SpdyStreamId stream_id, absl::string_view data); // Performs a deep copy on data. SpdyDataIR(SpdyStreamId stream_id, const char* data); @@ -547,14 +546,14 @@ class QUICHE_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR { } // Deep-copy of data (keep private copy). - void SetDataDeep(quiche::QuicheStringPiece data) { + void SetDataDeep(absl::string_view data) { data_store_ = std::make_unique<std::string>(data.data(), data.size()); data_ = data_store_->data(); data_len_ = data.size(); } // Shallow-copy of data (do not keep private copy). - void SetDataShallow(quiche::QuicheStringPiece data) { + void SetDataShallow(absl::string_view data) { data_store_.reset(); data_ = data.data(); data_len_ = data.size(); @@ -660,7 +659,7 @@ class QUICHE_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { // this SpdyGoAwayIR. SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyErrorCode error_code, - quiche::QuicheStringPiece description); + absl::string_view description); // References description, doesn't copy it, so description must outlast // this SpdyGoAwayIR. @@ -689,7 +688,7 @@ class QUICHE_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { error_code_ = error_code; } - const quiche::QuicheStringPiece& description() const { return description_; } + const absl::string_view& description() const { return description_; } void Visit(SpdyFrameVisitor* visitor) const override; @@ -701,14 +700,14 @@ class QUICHE_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR { SpdyStreamId last_good_stream_id_; SpdyErrorCode error_code_; const std::string description_store_; - const quiche::QuicheStringPiece description_; + const absl::string_view description_; }; class QUICHE_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR { public: explicit SpdyHeadersIR(SpdyStreamId stream_id) - : SpdyHeadersIR(stream_id, SpdyHeaderBlock()) {} - SpdyHeadersIR(SpdyStreamId stream_id, SpdyHeaderBlock header_block) + : SpdyHeadersIR(stream_id, Http2HeaderBlock()) {} + SpdyHeadersIR(SpdyStreamId stream_id, Http2HeaderBlock header_block) : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)) {} SpdyHeadersIR(const SpdyHeadersIR&) = delete; SpdyHeadersIR& operator=(const SpdyHeadersIR&) = delete; @@ -776,10 +775,10 @@ class QUICHE_EXPORT_PRIVATE SpdyPushPromiseIR : public SpdyFrameWithHeaderBlockIR { public: SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id) - : SpdyPushPromiseIR(stream_id, promised_stream_id, SpdyHeaderBlock()) {} + : SpdyPushPromiseIR(stream_id, promised_stream_id, Http2HeaderBlock()) {} SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, - SpdyHeaderBlock header_block) + Http2HeaderBlock header_block) : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)), promised_stream_id_(promised_stream_id), padded_(false), diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test.cc index c952bce0677..f4cbc42cc8d 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test.cc @@ -226,8 +226,8 @@ TEST(SpdyStreamPrecedenceTest, Equals) { TEST(SpdyDataIRTest, Construct) { // Confirm that it makes a string of zero length from a - // QuicheStringPiece(nullptr). - quiche::QuicheStringPiece s1; + // absl::string_view(nullptr). + absl::string_view s1; SpdyDataIR d1(/* stream_id = */ 1, s1); EXPECT_EQ(0u, d1.data_len()); EXPECT_NE(nullptr, d1.data()); @@ -235,8 +235,8 @@ TEST(SpdyDataIRTest, Construct) { // Confirms makes a copy of char array. const char s2[] = "something"; SpdyDataIR d2(/* stream_id = */ 2, s2); - EXPECT_EQ(quiche::QuicheStringPiece(d2.data(), d2.data_len()), s2); - EXPECT_NE(quiche::QuicheStringPiece(d1.data(), d1.data_len()), s2); + EXPECT_EQ(absl::string_view(d2.data(), d2.data_len()), s2); + EXPECT_NE(absl::string_view(d1.data(), d1.data_len()), s2); EXPECT_EQ((int)d1.data_len(), d1.flow_control_window_consumed()); // Confirm copies a const string. @@ -249,20 +249,18 @@ TEST(SpdyDataIRTest, Construct) { std::string bar = "bar"; SpdyDataIR d4(/* stream_id = */ 4, bar); EXPECT_EQ("bar", bar); - EXPECT_EQ("bar", quiche::QuicheStringPiece(d4.data(), d4.data_len())); + EXPECT_EQ("bar", absl::string_view(d4.data(), d4.data_len())); // Confirm moves an rvalue reference. Note that the test string "baz" is too // short to trigger the move optimization, and instead a copy occurs. std::string baz = "the quick brown fox"; SpdyDataIR d5(/* stream_id = */ 5, std::move(baz)); EXPECT_EQ("", baz); - EXPECT_EQ(quiche::QuicheStringPiece(d5.data(), d5.data_len()), - "the quick brown fox"); + EXPECT_EQ(absl::string_view(d5.data(), d5.data_len()), "the quick brown fox"); // Confirms makes a copy of string literal. SpdyDataIR d7(/* stream_id = */ 7, "something else"); - EXPECT_EQ(quiche::QuicheStringPiece(d7.data(), d7.data_len()), - "something else"); + EXPECT_EQ(absl::string_view(d7.data(), d7.data_len()), "something else"); SpdyDataIR d8(/* stream_id = */ 8, "shawarma"); d8.set_padding_len(20); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.cc index 7390f50bdc6..37199f646d1 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.cc @@ -6,7 +6,7 @@ #include <cstdint> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace spdy { namespace test { @@ -47,8 +47,8 @@ namespace test { if (expected.data() == nullptr) { VERIFY_EQ(nullptr, actual.data()); } else { - VERIFY_EQ(quiche::QuicheStringPiece(expected.data(), expected.data_len()), - quiche::QuicheStringPiece(actual.data(), actual.data_len())); + VERIFY_EQ(absl::string_view(expected.data(), expected.data_len()), + absl::string_view(actual.data(), actual.data_len())); } VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual)); return ::testing::AssertionSuccess(); diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_simple_arena_test.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_simple_arena_test.cc index 7e66567b78f..b9e9f757168 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_simple_arena_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_simple_arena_test.cc @@ -7,7 +7,7 @@ #include <string> #include <vector> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace spdy { @@ -27,7 +27,7 @@ TEST(SpdySimpleArenaTest, Memdup) { char* c = arena.Memdup(kTestString, length); EXPECT_NE(nullptr, c); EXPECT_NE(c, kTestString); - EXPECT_EQ(quiche::QuicheStringPiece(c, length), kTestString); + EXPECT_EQ(absl::string_view(c, length), kTestString); } TEST(SpdySimpleArenaTest, MemdupLargeString) { @@ -36,7 +36,7 @@ TEST(SpdySimpleArenaTest, MemdupLargeString) { char* c = arena.Memdup(kTestString, length); EXPECT_NE(nullptr, c); EXPECT_NE(c, kTestString); - EXPECT_EQ(quiche::QuicheStringPiece(c, length), kTestString); + EXPECT_EQ(absl::string_view(c, length), kTestString); } TEST(SpdySimpleArenaTest, MultipleBlocks) { @@ -44,9 +44,9 @@ TEST(SpdySimpleArenaTest, MultipleBlocks) { std::vector<std::string> strings = { "One decently long string.", "Another string.", "A third string that will surely go in a different block."}; - std::vector<quiche::QuicheStringPiece> copies; + std::vector<absl::string_view> copies; for (const std::string& s : strings) { - quiche::QuicheStringPiece sp(arena.Memdup(s.data(), s.size()), s.size()); + absl::string_view sp(arena.Memdup(s.data(), s.size()), s.size()); copies.push_back(sp); } EXPECT_EQ(strings.size(), copies.size()); @@ -63,7 +63,7 @@ TEST(SpdySimpleArenaTest, UseAfterReset) { c = arena.Memdup(kTestString, length); EXPECT_NE(nullptr, c); EXPECT_NE(c, kTestString); - EXPECT_EQ(quiche::QuicheStringPiece(c, length), kTestString); + EXPECT_EQ(absl::string_view(c, length), kTestString); } TEST(SpdySimpleArenaTest, Free) { @@ -102,7 +102,7 @@ TEST(SpdySimpleArenaTest, Alloc) { EXPECT_EQ(c1 + length, c2); EXPECT_EQ(c2 + 2 * length, c3); EXPECT_EQ(c3 + 3 * length, c4); - EXPECT_EQ(quiche::QuicheStringPiece(c4, length), kTestString); + EXPECT_EQ(absl::string_view(c4, length), kTestString); } TEST(SpdySimpleArenaTest, Realloc) { @@ -113,28 +113,28 @@ TEST(SpdySimpleArenaTest, Realloc) { char* c2 = arena.Realloc(c1, length, 2 * length); EXPECT_TRUE(c1); EXPECT_EQ(c1, c2); - EXPECT_EQ(quiche::QuicheStringPiece(c1, length), kTestString); + EXPECT_EQ(absl::string_view(c1, length), kTestString); // Multiple reallocs. char* c3 = arena.Memdup(kTestString, length); EXPECT_EQ(c2 + 2 * length, c3); - EXPECT_EQ(quiche::QuicheStringPiece(c3, length), kTestString); + EXPECT_EQ(absl::string_view(c3, length), kTestString); char* c4 = arena.Realloc(c3, length, 2 * length); EXPECT_EQ(c3, c4); - EXPECT_EQ(quiche::QuicheStringPiece(c4, length), kTestString); + EXPECT_EQ(absl::string_view(c4, length), kTestString); char* c5 = arena.Realloc(c4, 2 * length, 3 * length); EXPECT_EQ(c4, c5); - EXPECT_EQ(quiche::QuicheStringPiece(c5, length), kTestString); + EXPECT_EQ(absl::string_view(c5, length), kTestString); char* c6 = arena.Memdup(kTestString, length); EXPECT_EQ(c5 + 3 * length, c6); - EXPECT_EQ(quiche::QuicheStringPiece(c6, length), kTestString); + EXPECT_EQ(absl::string_view(c6, length), kTestString); // Realloc that does not fit in the remainder of the first block. char* c7 = arena.Realloc(c6, length, kDefaultBlockSize); - EXPECT_EQ(quiche::QuicheStringPiece(c7, length), kTestString); + EXPECT_EQ(absl::string_view(c7, length), kTestString); arena.Free(c7, kDefaultBlockSize); char* c8 = arena.Memdup(kTestString, length); EXPECT_NE(c6, c7); EXPECT_EQ(c7, c8); - EXPECT_EQ(quiche::QuicheStringPiece(c8, length), kTestString); + EXPECT_EQ(absl::string_view(c8, length), kTestString); } } // namespace diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.cc b/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.cc index 1d8db971f9c..5372bcdbf73 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.cc +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.cc @@ -12,7 +12,7 @@ #include <vector> #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h" +#include "net/third_party/quiche/src/common/quiche_endian.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h" namespace spdy { @@ -95,26 +95,10 @@ void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags) { void SetFrameLength(SpdySerializedFrame* frame, size_t length) { CHECK_GT(1u << 14, length); { - int32_t wire_length = SpdyHostToNet32(length); + int32_t wire_length = quiche::QuicheEndian::HostToNet32(length); memcpy(frame->data(), reinterpret_cast<char*>(&wire_length) + 1, 3); } } -void TestHeadersHandler::OnHeaderBlockStart() { - block_.clear(); -} - -void TestHeadersHandler::OnHeader(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) { - block_.AppendValueOrAddHeader(name, value); -} - -void TestHeadersHandler::OnHeaderBlockEnd( - size_t header_bytes_parsed, - size_t compressed_header_bytes_parsed) { - header_bytes_parsed_ = header_bytes_parsed; - compressed_header_bytes_parsed_ = compressed_header_bytes_parsed; -} - } // namespace test } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.h b/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.h index b3c3aa5d38b..920838eb301 100644 --- a/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.h +++ b/chromium/net/third_party/quiche/src/spdy/core/spdy_test_utils.h @@ -9,16 +9,14 @@ #include <cstdint> #include <string> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" -#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h" namespace spdy { -inline bool operator==(quiche::QuicheStringPiece x, - const SpdyHeaderBlock::ValueProxy& y) { +inline bool operator==(absl::string_view x, + const Http2HeaderBlock::ValueProxy& y) { return y.operator==(x); } @@ -39,34 +37,6 @@ void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags); void SetFrameLength(SpdySerializedFrame* frame, size_t length); -// A test implementation of SpdyHeadersHandlerInterface that correctly -// reconstructs multiple header values for the same name. -class TestHeadersHandler : public SpdyHeadersHandlerInterface { - public: - TestHeadersHandler() {} - TestHeadersHandler(const TestHeadersHandler&) = delete; - TestHeadersHandler& operator=(const TestHeadersHandler&) = delete; - - void OnHeaderBlockStart() override; - - void OnHeader(quiche::QuicheStringPiece name, - quiche::QuicheStringPiece value) override; - - void OnHeaderBlockEnd(size_t header_bytes_parsed, - size_t compressed_header_bytes_parsed) override; - - const SpdyHeaderBlock& decoded_block() const { return block_; } - size_t header_bytes_parsed() const { return header_bytes_parsed_; } - size_t compressed_header_bytes_parsed() const { - return compressed_header_bytes_parsed_; - } - - private: - SpdyHeaderBlock block_; - size_t header_bytes_parsed_ = 0; - size_t compressed_header_bytes_parsed_ = 0; -}; - } // namespace test } // namespace spdy diff --git a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h deleted file mode 100644 index e4074d710ce..00000000000 --- a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2018 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_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_ -#define QUICHE_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_ - -#include <stdint.h> - -#include "net/spdy/platform/impl/spdy_endianness_util_impl.h" - -namespace spdy { - -// Converts the bytes in |x| from network to host order (endianness), and -// returns the result. -inline uint16_t SpdyNetToHost16(uint16_t x) { - return SpdyNetToHost16Impl(x); -} - -inline uint32_t SpdyNetToHost32(uint32_t x) { - return SpdyNetToHost32Impl(x); -} - -inline uint64_t SpdyNetToHost64(uint64_t x) { - return SpdyNetToHost64Impl(x); -} - -// Converts the bytes in |x| from host to network order (endianness), and -// returns the result. -inline uint16_t SpdyHostToNet16(uint16_t x) { - return SpdyHostToNet16Impl(x); -} - -inline uint32_t SpdyHostToNet32(uint32_t x) { - return SpdyHostToNet32Impl(x); -} - -inline uint64_t SpdyHostToNet64(uint64_t x) { - return SpdyHostToNet64Impl(x); -} - -} // namespace spdy - -#endif // QUICHE_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_ diff --git a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice_test.cc b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice_test.cc index 84313b0a7b2..fa41b5e4dd7 100644 --- a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice_test.cc @@ -6,17 +6,13 @@ #include <utility> -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" - -#include "testing/gtest/include/gtest/gtest.h" -#pragma clang diagnostic pop +#include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace spdy { namespace test { namespace { -class SpdyMemSliceTest : public ::testing::Test { +class SpdyMemSliceTest : public QuicheTest { public: SpdyMemSliceTest() { slice_ = SpdyMemSlice(1024); diff --git a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h index b023f733e04..e7ee6a9ca98 100644 --- a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h +++ b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h @@ -14,7 +14,7 @@ // non-test code. #include "net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice.h" -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/spdy/platform/impl/spdy_string_utils_impl.h" namespace spdy { @@ -28,12 +28,11 @@ inline char SpdyHexDigitToInt(char c) { return SpdyHexDigitToIntImpl(c); } -inline std::string SpdyHexDecode(quiche::QuicheStringPiece data) { +inline std::string SpdyHexDecode(absl::string_view data) { return SpdyHexDecodeImpl(data); } -inline bool SpdyHexDecodeToUInt32(quiche::QuicheStringPiece data, - uint32_t* out) { +inline bool SpdyHexDecodeToUInt32(absl::string_view data, uint32_t* out) { return SpdyHexDecodeToUInt32Impl(data, out); } @@ -45,7 +44,7 @@ inline std::string SpdyHexEncodeUInt32AndTrim(uint32_t data) { return SpdyHexEncodeUInt32AndTrimImpl(data); } -inline std::string SpdyHexDump(quiche::QuicheStringPiece data) { +inline std::string SpdyHexDump(absl::string_view data) { return SpdyHexDumpImpl(data); } diff --git a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils_test.cc b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils_test.cc index 4848bf0a54a..2f8c0220e84 100644 --- a/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils_test.cc +++ b/chromium/net/third_party/quiche/src/spdy/platform/api/spdy_string_utils_test.cc @@ -6,7 +6,7 @@ #include <cstdint> -#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" namespace spdy { @@ -22,7 +22,7 @@ TEST(SpdyStringUtilsTest, SpdyStrAppend) { // Single string-like argument. const char kFoo[] = "foo"; const std::string string_foo(kFoo); - const quiche::QuicheStringPiece stringpiece_foo(string_foo); + const absl::string_view stringpiece_foo(string_foo); SpdyStrAppend(&output, kFoo); EXPECT_EQ("foo", output); SpdyStrAppend(&output, string_foo); @@ -38,7 +38,7 @@ TEST(SpdyStringUtilsTest, SpdyStrAppend) { // Two string-like arguments. const char kBar[] = "bar"; - const quiche::QuicheStringPiece stringpiece_bar(kBar); + const absl::string_view stringpiece_bar(kBar); const std::string string_bar(kBar); SpdyStrAppend(&output, kFoo, kBar); EXPECT_EQ("foobar", output); diff --git a/chromium/net/third_party/uri_template/DIR_METADATA b/chromium/net/third_party/uri_template/DIR_METADATA new file mode 100644 index 00000000000..23af0ebe901 --- /dev/null +++ b/chromium/net/third_party/uri_template/DIR_METADATA @@ -0,0 +1,11 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +monorail { + component: "Internals>Network>DNS" +}
\ No newline at end of file diff --git a/chromium/net/third_party/uri_template/OWNERS b/chromium/net/third_party/uri_template/OWNERS index 3c466ff27a9..53e68eb7787 100644 --- a/chromium/net/third_party/uri_template/OWNERS +++ b/chromium/net/third_party/uri_template/OWNERS @@ -1,3 +1 @@ mmenke@chromium.org - -# COMPONENT: Internals>Network>DNS |