diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index e8c84f7a145c8..e7a654c919231 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -92,9 +92,9 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_core_write_scheduler_lib", + ":quiche_common_platform", ":spdy_core_intrusive_list_lib", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -105,8 +105,8 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_core_write_scheduler_lib", + ":quiche_common_platform", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -125,13 +125,10 @@ envoy_cc_library( name = "http2_platform", hdrs = [ "quiche/http2/platform/api/http2_bug_tracker.h", - "quiche/http2/platform/api/http2_containers.h", - "quiche/http2/platform/api/http2_estimate_memory_usage.h", "quiche/http2/platform/api/http2_flag_utils.h", "quiche/http2/platform/api/http2_flags.h", "quiche/http2/platform/api/http2_logging.h", "quiche/http2/platform/api/http2_macros.h", - "quiche/http2/platform/api/http2_string_utils.h", # TODO: uncomment the following files as implementations are added. # "quiche/http2/platform/api/http2_test_helpers.h", ], @@ -686,6 +683,7 @@ envoy_cc_library( ":http2_hpack_decoder_hpack_whole_entry_listener_lib", ":http2_hpack_hpack_constants_lib", ":http2_platform", + ":quiche_common_text_utils_lib", ], ) @@ -773,28 +771,15 @@ envoy_cc_library( deps = [":http2_platform"], ) -envoy_cc_library( - name = "spdy_platform", - hdrs = [ - "quiche/spdy/platform/api/spdy_containers.h", - "quiche/spdy/platform/api/spdy_estimate_memory_usage.h", - "quiche/spdy/platform/api/spdy_string_utils.h", - ], - repository = "@envoy", - visibility = ["//visibility:public"], - deps = [ - ":quiche_common_lib", - "@envoy//source/common/quic/platform:spdy_platform_impl_lib", - ], -) - envoy_cc_library( name = "spdy_simple_arena_lib", srcs = ["quiche/spdy/core/spdy_simple_arena.cc"], hdrs = ["quiche/spdy/core/spdy_simple_arena.h"], repository = "@envoy", visibility = ["//visibility:public"], - deps = [":spdy_platform"], + deps = [ + ":quiche_common_platform", + ], ) envoy_cc_library( @@ -804,7 +789,7 @@ envoy_cc_library( copts = quiche_copts, repository = "@envoy", visibility = ["//visibility:public"], - deps = [":spdy_platform"], + deps = [":quiche_common_platform"], ) envoy_cc_library( @@ -821,6 +806,7 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_platform", + ":quiche_common_platform", ":spdy_core_alt_svc_wire_format_lib", ":spdy_core_frame_reader_lib", ":spdy_core_header_block_lib", @@ -828,7 +814,6 @@ envoy_cc_library( ":spdy_core_hpack_hpack_lib", ":spdy_core_protocol_lib", ":spdy_core_zero_copy_output_buffer_lib", - ":spdy_platform", ], ) @@ -839,8 +824,8 @@ envoy_cc_library( copts = quiche_copts, repository = "@envoy", deps = [ + ":quiche_common_platform", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -852,8 +837,9 @@ envoy_cc_library( repository = "@envoy", visibility = ["//visibility:public"], deps = [ + ":quiche_common_lib", + ":quiche_common_platform", ":spdy_core_header_storage_lib", - ":spdy_platform", ], ) @@ -865,7 +851,7 @@ envoy_cc_library( repository = "@envoy", deps = [ "spdy_simple_arena_lib", - ":spdy_platform", + ":quiche_common_platform", ], ) @@ -875,7 +861,7 @@ envoy_cc_library( copts = quiche_copts, repository = "@envoy", visibility = ["//visibility:public"], - deps = [":spdy_platform"], + deps = [":quiche_common_platform"], ) envoy_cc_library( @@ -892,13 +878,13 @@ envoy_cc_library( ":http2_decoder_frame_decoder_listener_lib", ":http2_platform", ":http2_structures_lib", + ":quiche_common_platform", ":spdy_core_alt_svc_wire_format_lib", ":spdy_core_header_block_lib", ":spdy_core_headers_handler_interface_lib", ":spdy_core_hpack_hpack_decoder_adapter_lib", ":spdy_core_hpack_hpack_lib", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -930,8 +916,8 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_hpack_huffman_hpack_huffman_encoder_lib", + ":quiche_common_platform", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -948,10 +934,10 @@ envoy_cc_library( ":http2_hpack_decoder_hpack_decoder_listener_lib", ":http2_hpack_decoder_hpack_decoder_tables_lib", ":http2_hpack_hpack_constants_lib", + ":quiche_common_platform", ":spdy_core_header_block_lib", ":spdy_core_headers_handler_interface_lib", ":spdy_core_hpack_hpack_lib", - ":spdy_platform", ], ) @@ -966,9 +952,9 @@ envoy_cc_library( repository = "@envoy", visibility = ["//visibility:public"], deps = [ + ":quiche_common_platform", ":spdy_core_alt_svc_wire_format_lib", ":spdy_core_header_block_lib", - ":spdy_platform", ], ) @@ -977,8 +963,8 @@ envoy_cc_library( hdrs = ["quiche/spdy/core/write_scheduler.h"], repository = "@envoy", deps = [ + ":quiche_common_platform", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -989,11 +975,11 @@ envoy_cc_test_library( copts = quiche_copts, repository = "@envoy", deps = [ + ":quiche_common_platform", ":quiche_common_test_tools_test_utils_lib", ":spdy_core_header_block_lib", ":spdy_core_headers_handler_interface_lib", ":spdy_core_protocol_lib", - ":spdy_platform", ], ) @@ -1007,12 +993,10 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform", srcs = [ - "quiche/quic/platform/api/quic_file_utils.cc", "quiche/quic/platform/api/quic_hostname_utils.cc", "quiche/quic/platform/api/quic_mutex.cc", ], hdrs = [ - "quiche/quic/platform/api/quic_file_utils.h", "quiche/quic/platform/api/quic_hostname_utils.h", "quiche/quic/platform/api/quic_mutex.h", ], @@ -1033,13 +1017,11 @@ envoy_cc_library( "quiche/quic/platform/api/quic_client_stats.h", "quiche/quic/platform/api/quic_containers.h", "quiche/quic/platform/api/quic_error_code_wrappers.h", - "quiche/quic/platform/api/quic_estimate_memory_usage.h", "quiche/quic/platform/api/quic_exported_stats.h", "quiche/quic/platform/api/quic_flag_utils.h", "quiche/quic/platform/api/quic_flags.h", "quiche/quic/platform/api/quic_iovec.h", "quiche/quic/platform/api/quic_logging.h", - "quiche/quic/platform/api/quic_map_util.h", "quiche/quic/platform/api/quic_mem_slice.h", "quiche/quic/platform/api/quic_reference_counted.h", "quiche/quic/platform/api/quic_server_stats.h", @@ -1605,6 +1587,7 @@ envoy_cc_library( ":quic_core_time_lib", ":quic_core_types_lib", ":quic_platform", + ":quiche_common_print_elements_lib", ], ) @@ -2683,6 +2666,7 @@ envoy_cc_library( ":quic_core_versions_lib", ":quic_platform_base", ":quiche_common_circular_deque_lib", + ":quiche_common_print_elements_lib", ], ) @@ -3124,6 +3108,7 @@ envoy_cc_library( ":quic_core_unacked_packet_map_lib", ":quic_core_utils_lib", ":quic_platform_base", + ":quiche_common_print_elements_lib", ], ) @@ -4017,8 +4002,6 @@ envoy_cc_library( hdrs = [ "quiche/common/platform/default/quiche_platform_impl/quic_mutex_impl.h", "quiche/common/platform/default/quiche_platform_impl/quic_testvalue_impl.h", - "quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h", - "quiche/common/platform/default/quiche_platform_impl/quiche_estimate_memory_usage_impl.h", "quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h", "quiche/common/platform/default/quiche_platform_impl/quiche_sleep_impl.h", "quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h", @@ -4058,6 +4041,19 @@ envoy_cc_test_library( ], ) +envoy_cc_library( + name = "quiche_common_print_elements_lib", + hdrs = ["quiche/common/print_elements.h"], + external_deps = [ + "abseil_inlined_vector", + ], + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quiche_common_platform_export", + ], +) + envoy_cc_test_library( name = "quiche_common_test_tools_test_utils_lib", srcs = ["quiche/common/test_tools/quiche_test_utils.cc"], @@ -4188,10 +4184,8 @@ envoy_cc_test( envoy_cc_test( name = "quic_platform_api_test", srcs = [ - "quiche/quic/platform/api/quic_containers_test.cc", "quiche/quic/platform/api/quic_mem_slice_span_test.cc", - # Re-enable it when tests pass. - # "quiche/quic/platform/api/quic_mem_slice_storage_test.cc", + "quiche/quic/platform/api/quic_mem_slice_storage_test.cc", "quiche/quic/platform/api/quic_mem_slice_test.cc", "quiche/quic/platform/api/quic_reference_counted_test.cc", ], diff --git a/bazel/external/quiche.genrule_cmd b/bazel/external/quiche.genrule_cmd index 43f17a517e408..6719aa0f7227c 100644 --- a/bazel/external/quiche.genrule_cmd +++ b/bazel/external/quiche.genrule_cmd @@ -51,6 +51,7 @@ cat <sed_commands # Use envoy specific implementations for below platform APIs. /^#include/ s!"quiche_platform_impl/quiche_logging_impl.h!"source/common/quic/platform/quiche_logging_impl.h! +/^#include/ s!"quiche_platform_impl/quiche_bug_tracker_impl.h!"source/common/quic/platform/quiche_bug_tracker_impl.h! # The reset platform APIs use the QUICHE default implementations. /^#include/ s!"quiche_platform_impl/!"quiche/common/platform/default/quiche_platform_impl/! diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 357c387c6ec98..47b28f6a7e80f 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -808,12 +808,12 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "QUICHE", project_desc = "QUICHE (QUIC, HTTP/2, Etc) is Google‘s implementation of QUIC and related protocols", project_url = "https://quiche.googlesource.com/quiche", - version = "aee86fb6ffce85e884a6f613ae5f47ce2c6b1e23", - sha256 = "a1b2c0cdd53a3a932db991bee736c6df20912c3d8070be9fbb4152575837cbf9", + version = "5dd7a030209f9a6b5043bebd8ac3ee54f18d1d08", + sha256 = "306342cb35cb9d8baea079c7b924b0133c53cbf182b251655e589d3b4604dc41", # Static snapshot of https://quiche.googlesource.com/quiche/+archive/{version}.tar.gz urls = ["https://storage.googleapis.com/quiche-envoy-integration/{version}.tar.gz"], use_category = ["dataplane_core"], - release_date = "2021-06-02", + release_date = "2021-07-16", cpe = "N/A", ), com_googlesource_googleurl = dict( diff --git a/source/common/quic/platform/BUILD b/source/common/quic/platform/BUILD index 13e879f96eaed..ef8aa550ab179 100644 --- a/source/common/quic/platform/BUILD +++ b/source/common/quic/platform/BUILD @@ -64,10 +64,8 @@ envoy_cc_library( envoy_cc_library( name = "http2_platform_impl_lib", hdrs = [ - "http2_containers_impl.h", "http2_logging_impl.h", "http2_macros_impl.h", - "http2_string_utils_impl.h", ], external_deps = [ "abseil_base", @@ -90,7 +88,10 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform_logging_impl_lib", - srcs = ["quic_logging_impl.cc"], + srcs = [ + "quic_logging_impl.cc", + "quiche_bug_tracker_impl.cc", + ], hdrs = [ "quic_logging_impl.h", "quiche_bug_tracker_impl.h", @@ -115,7 +116,6 @@ envoy_cc_library( "quic_error_code_wrappers_impl.h", "quic_flags_impl.h", "quic_iovec_impl.h", - "quic_map_util_impl.h", "quic_mem_slice_impl.h", "quic_reference_counted_impl.h", "quic_server_stats_impl.h", @@ -151,11 +151,9 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform_impl_lib", srcs = [ - "quic_file_utils_impl.cc", "quic_hostname_utils_impl.cc", ], hdrs = [ - "quic_file_utils_impl.h", "quic_hostname_utils_impl.h", "quic_mutex_impl.h", "quic_pcc_sender_impl.h", @@ -259,9 +257,7 @@ envoy_cc_library( name = "spdy_platform_impl_lib", hdrs = [ "spdy_bug_tracker_impl.h", - "spdy_containers_impl.h", "spdy_logging_impl.h", - "spdy_string_utils_impl.h", "spdy_test_utils_prod_impl.h", ], external_deps = [ diff --git a/source/common/quic/platform/http2_containers_impl.h b/source/common/quic/platform/http2_containers_impl.h deleted file mode 100644 index e43ec40bfc13a..0000000000000 --- a/source/common/quic/platform/http2_containers_impl.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -namespace http2 { - -template using Http2DequeImpl = std::deque; - -} // namespace http2 diff --git a/source/common/quic/platform/http2_string_utils_impl.h b/source/common/quic/platform/http2_string_utils_impl.h deleted file mode 100644 index 38c75a57a3948..0000000000000 --- a/source/common/quic/platform/http2_string_utils_impl.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) -// -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "source/common/quic/platform/string_utils.h" - -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "fmt/printf.h" - -namespace http2 { - -template inline std::string Http2StrCatImpl(const Args&... args) { - return absl::StrCat(std::forward(args)...); -} - -template -inline void Http2StrAppendImpl(std::string* output, const Args&... args) { - absl::StrAppend(output, std::forward(args)...); -} - -template inline std::string Http2StringPrintfImpl(const Args&... args) { - return fmt::sprintf(std::forward(args)...); -} - -inline std::string Http2HexEncodeImpl(const void* bytes, size_t size) { - return absl::BytesToHexString(absl::string_view(static_cast(bytes), size)); -} - -inline std::string Http2HexDecodeImpl(absl::string_view data) { - return absl::HexStringToBytes(data); -} - -inline std::string Http2HexDumpImpl(absl::string_view data) { return quiche::HexDump(data); } - -inline std::string Http2HexEscapeImpl(absl::string_view data) { return absl::CHexEscape(data); } - -template inline std::string Http2HexImpl(Number number) { - return absl::StrCat(absl::Hex(number)); -} - -} // namespace http2 diff --git a/source/common/quic/platform/quic_containers_impl.h b/source/common/quic/platform/quic_containers_impl.h index 061fe114695d3..2e45c63eba05f 100644 --- a/source/common/quic/platform/quic_containers_impl.h +++ b/source/common/quic/platform/quic_containers_impl.h @@ -23,48 +23,7 @@ namespace quic { -template using QuicDefaultHasherImpl = absl::Hash; - -template -using QuicUnorderedMapImpl = absl::node_hash_map; - -template -using QuicHashMapImpl = absl::flat_hash_map; - -template using QuicHashSetImpl = absl::flat_hash_set; - -template using QuicUnorderedSetImpl = absl::node_hash_set; - -template -using QuicLinkedHashMapImpl = quiche::QuicheLinkedHashMap; - -template -using QuicSmallMapImpl = absl::flat_hash_map; - -template using QuicQueueImpl = std::queue; - -template using QuicDequeImpl = std::deque; - -template > -using QuicInlinedVectorImpl = absl::InlinedVector; - -template -inline std::ostream& operator<<(std::ostream& os, - const QuicInlinedVectorImpl inlined_vector) { - std::stringstream debug_string; - debug_string << "{"; - typename QuicInlinedVectorImpl::const_iterator it = inlined_vector.cbegin(); - debug_string << *it; - ++it; - while (it != inlined_vector.cend()) { - debug_string << ", " << *it; - ++it; - } - debug_string << "}"; - return os << debug_string.str(); -} - -template -using QuicOrderedSetImpl = absl::btree_set; +template +using QuicSmallOrderedSetImpl = absl::btree_set; } // namespace quic diff --git a/source/common/quic/platform/quic_file_utils_impl.cc b/source/common/quic/platform/quic_file_utils_impl.cc deleted file mode 100644 index 9c909c801643c..0000000000000 --- a/source/common/quic/platform/quic_file_utils_impl.cc +++ /dev/null @@ -1,53 +0,0 @@ -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "source/common/quic/platform/quic_file_utils_impl.h" - -#include "source/common/filesystem/directory.h" -#include "source/common/filesystem/filesystem_impl.h" - -#include "absl/strings/str_cat.h" - -namespace quic { -namespace { - -void depthFirstTraverseDirectory(const std::string& dirname, std::vector& files) { - Envoy::Filesystem::Directory directory(dirname); - for (const Envoy::Filesystem::DirectoryEntry& entry : directory) { - switch (entry.type_) { - case Envoy::Filesystem::FileType::Regular: - files.push_back(absl::StrCat(dirname, "/", entry.name_)); - break; - case Envoy::Filesystem::FileType::Directory: - if (entry.name_ != "." && entry.name_ != "..") { - depthFirstTraverseDirectory(absl::StrCat(dirname, "/", entry.name_), files); - } - break; - default: - ASSERT(false, - absl::StrCat("Unknow file entry type ", entry.type_, " under directory ", dirname)); - } - } -} - -} // namespace - -// Traverses the directory |dirname| and returns all of the files it contains. -// NOLINTNEXTLINE(readability-identifier-naming) -std::vector ReadFileContentsImpl(const std::string& dirname) { - std::vector files; - depthFirstTraverseDirectory(dirname, files); - return files; -} - -// Reads the contents of |filename| as a string into |contents|. -// NOLINTNEXTLINE(readability-identifier-naming) -void ReadFileContentsImpl(absl::string_view filename, std::string* contents) { - Envoy::Filesystem::InstanceImpl fs; - *contents = fs.fileReadToEnd(std::string(filename.data(), filename.size())); -} - -} // namespace quic diff --git a/source/common/quic/platform/quic_file_utils_impl.h b/source/common/quic/platform/quic_file_utils_impl.h deleted file mode 100644 index 25c31e9deca27..0000000000000 --- a/source/common/quic/platform/quic_file_utils_impl.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include - -#include "absl/strings/string_view.h" - -namespace quic { - -/** - * Traverses the directory |dirname| and returns all of the files it contains. - * @param dirname full path without trailing '/'. - */ -// NOLINTNEXTLINE(readability-identifier-naming)` -std::vector ReadFileContentsImpl(const std::string& dirname); - -/** - * Reads the contents of |filename| as a string into |contents|. - * @param filename the full path to the file. - * @param contents output location of the file content. - */ -// NOLINTNEXTLINE(readability-identifier-naming) -void ReadFileContentsImpl(absl::string_view filename, std::string* contents); - -} // namespace quic diff --git a/source/common/quic/platform/quic_map_util_impl.h b/source/common/quic/platform/quic_map_util_impl.h deleted file mode 100644 index 2bf549d9c353a..0000000000000 --- a/source/common/quic/platform/quic_map_util_impl.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) -// -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include - -namespace quic { - -template -bool QuicContainsKeyImpl(const Collection& collection, const Key& key) { - return collection.find(key) != collection.end(); -} - -template -bool QuicContainsValueImpl(const Collection& collection, const Value& value) { - return std::find(collection.begin(), collection.end(), value) != collection.end(); -} - -} // namespace quic diff --git a/source/common/quic/platform/quic_mem_slice_impl.cc b/source/common/quic/platform/quic_mem_slice_impl.cc index 3744ae0597e44..a9e9876ffd10c 100644 --- a/source/common/quic/platform/quic_mem_slice_impl.cc +++ b/source/common/quic/platform/quic_mem_slice_impl.cc @@ -44,6 +44,11 @@ QuicMemSliceImpl::QuicMemSliceImpl(std::unique_ptr buffer, size_t length ASSERT(this->length() == length); } +QuicMemSliceImpl::~QuicMemSliceImpl() { + ASSERT(fragment_ == nullptr || (firstSliceLength(single_slice_buffer_) == fragment_->size() && + data() == fragment_->data())); +} + const char* QuicMemSliceImpl::data() const { return reinterpret_cast(single_slice_buffer_.frontSlice().mem_); } diff --git a/source/common/quic/platform/quic_mem_slice_impl.h b/source/common/quic/platform/quic_mem_slice_impl.h index c6e90cba507a2..6e97d5faab1d8 100644 --- a/source/common/quic/platform/quic_mem_slice_impl.h +++ b/source/common/quic/platform/quic_mem_slice_impl.h @@ -23,6 +23,8 @@ class QuicMemSliceImpl { // Constructs an empty QuicMemSliceImpl. QuicMemSliceImpl() = default; + ~QuicMemSliceImpl(); + // Constructs a QuicMemSliceImpl by taking ownership of the memory in |buffer|. QuicMemSliceImpl(QuicUniqueBufferPtr buffer, size_t length); QuicMemSliceImpl(std::unique_ptr buffer, size_t length); @@ -47,7 +49,11 @@ class QuicMemSliceImpl { } // Below methods implements interface needed by QuicMemSlice. - void Reset() { single_slice_buffer_.drain(length()); } + // NOLINTNEXTLINE(readability-identifier-naming) + void Reset() { + single_slice_buffer_.drain(length()); + fragment_ = nullptr; + } // Returns a char pointer to the one and only slice in buffer. const char* data() const; @@ -55,10 +61,9 @@ class QuicMemSliceImpl { size_t length() const { return single_slice_buffer_.length(); } bool empty() const { return length() == 0; } - Envoy::Buffer::OwnedImpl& single_slice_buffer() { return single_slice_buffer_; } + Envoy::Buffer::OwnedImpl& getSingleSliceBuffer() { return single_slice_buffer_; } private: - // Prerequisite: buffer has at least one slice. size_t firstSliceLength(Envoy::Buffer::Instance& buffer); std::unique_ptr fragment_; diff --git a/source/common/quic/platform/quic_mem_slice_span_impl.h b/source/common/quic/platform/quic_mem_slice_span_impl.h index ef40e63870573..d1e9855551282 100644 --- a/source/common/quic/platform/quic_mem_slice_span_impl.h +++ b/source/common/quic/platform/quic_mem_slice_span_impl.h @@ -25,19 +25,24 @@ class QuicMemSliceSpanImpl { * @param buffer has to outlive the life time of this class. */ explicit QuicMemSliceSpanImpl(Envoy::Buffer::Instance& buffer) : buffer_(&buffer) {} - explicit QuicMemSliceSpanImpl(QuicMemSliceImpl* slice) : buffer_(&slice->single_slice_buffer()) {} + explicit QuicMemSliceSpanImpl(QuicMemSliceImpl* slice) + : buffer_(&slice->getSingleSliceBuffer()), mem_slice_(slice) {} QuicMemSliceSpanImpl(const QuicMemSliceSpanImpl& other) = default; QuicMemSliceSpanImpl& operator=(const QuicMemSliceSpanImpl& other) = default; - QuicMemSliceSpanImpl(QuicMemSliceSpanImpl&& other) noexcept : buffer_(other.buffer_) { + QuicMemSliceSpanImpl(QuicMemSliceSpanImpl&& other) noexcept + : buffer_(other.buffer_), mem_slice_(other.mem_slice_) { other.buffer_ = nullptr; + other.mem_slice_ = nullptr; } QuicMemSliceSpanImpl& operator=(QuicMemSliceSpanImpl&& other) noexcept { if (this != &other) { buffer_ = other.buffer_; + mem_slice_ = other.mem_slice_; other.buffer_ = nullptr; + other.mem_slice_ = nullptr; } return *this; } @@ -54,23 +59,33 @@ class QuicMemSliceSpanImpl { bool empty() const { return buffer_->length() == 0; } private: + // If constructed with a QuicMemSlice, mem_slice_ point to that object and this points to + // mem_slice_->getSingleSliceBuffer(). If constructed with an Envoy buffer, this points to the + // buffer itself. Envoy::Buffer::Instance* buffer_{nullptr}; + // If this span is not constructed with a QuicMemSlice, this points to nullptr. + QuicMemSliceImpl* mem_slice_{nullptr}; }; template // NOLINTNEXTLINE(readability-identifier-naming) QuicByteCount QuicMemSliceSpanImpl::ConsumeAll(ConsumeFunction consume) { size_t saved_length = 0; - for (auto& slice : buffer_->getRawSlices()) { - if (slice.len_ == 0) { - continue; + if (mem_slice_ == nullptr) { + for (auto& slice : buffer_->getRawSlices()) { + if (slice.len_ == 0) { + continue; + } + // Move each slice into a stand-alone buffer. + // TODO(danzh): investigate the cost of allocating one buffer per slice. + // If it turns out to be expensive, add a new function to free data in the middle in buffer + // interface and re-design QuicMemSliceImpl. + consume(QuicMemSlice(QuicMemSliceImpl(*buffer_, slice.len_))); + saved_length += slice.len_; } - // Move each slice into a stand-alone buffer. - // TODO(danzh): investigate the cost of allocating one buffer per slice. - // If it turns out to be expensive, add a new function to free data in the middle in buffer - // interface and re-design QuicMemSliceImpl. - consume(QuicMemSlice(QuicMemSliceImpl(*buffer_, slice.len_))); - saved_length += slice.len_; + } else { + saved_length += mem_slice_->length(); + consume(quic::QuicMemSlice(std::move(*mem_slice_))); } ASSERT(buffer_->length() == 0); return saved_length; diff --git a/source/common/quic/platform/quic_mem_slice_storage_impl.h b/source/common/quic/platform/quic_mem_slice_storage_impl.h index 437e9be46736f..797ade760686e 100644 --- a/source/common/quic/platform/quic_mem_slice_storage_impl.h +++ b/source/common/quic/platform/quic_mem_slice_storage_impl.h @@ -34,9 +34,11 @@ class QuicMemSliceStorageImpl { QuicMemSliceStorageImpl(QuicMemSliceStorageImpl&& other) = default; QuicMemSliceStorageImpl& operator=(QuicMemSliceStorageImpl&& other) = default; + // NOLINTNEXTLINE(readability-identifier-naming) QuicMemSliceSpan ToSpan() { return QuicMemSliceSpan(QuicMemSliceSpanImpl(buffer_)); } - void Append(QuicMemSliceImpl mem_slice) { buffer_.move(mem_slice.single_slice_buffer()); } + // NOLINTNEXTLINE(readability-identifier-naming) + void Append(QuicMemSliceImpl mem_slice) { buffer_.move(mem_slice.getSingleSliceBuffer()); } private: Envoy::Buffer::OwnedImpl buffer_; diff --git a/source/common/quic/platform/quiche_bug_tracker_impl.cc b/source/common/quic/platform/quiche_bug_tracker_impl.cc new file mode 100644 index 0000000000000..170ecfb85e15b --- /dev/null +++ b/source/common/quic/platform/quiche_bug_tracker_impl.cc @@ -0,0 +1,42 @@ +#include "source/common/quic/platform/quiche_bug_tracker_impl.h" + +#include "source/common/common/assert.h" +#include "source/common/quic/platform/quic_logging_impl.h" + +// NOLINT(namespace-envoy) +// +// This file is part of the QUICHE platform implementation, and is not to be +// consumed or referenced directly by other Envoy code. It serves purely as a +// porting layer for QUICHE. + +namespace quic { + +std::atomic g_quiche_bug_exit_disabled; + +ScopedDisableExitOnQuicheBug::ScopedDisableExitOnQuicheBug() + : previous_value_(g_quiche_bug_exit_disabled) { + + g_quiche_bug_exit_disabled.store(true, std::memory_order_relaxed); +} + +ScopedDisableExitOnQuicheBug::~ScopedDisableExitOnQuicheBug() { + g_quiche_bug_exit_disabled.store(previous_value_, std::memory_order_relaxed); +} + +QuicheBugEmitter::~QuicheBugEmitter() { + // Release mode ENVOY_BUG applies rate limit. + if (Envoy::Assert::shouldLogAndInvokeEnvoyBugForEnvoyBugMacroUseOnly(bug_name_)) { + ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::envoy_bug), error, + "QUICHE_BUG failure: {}.{}{}", condition_str_, + stream_.eof() ? "" : " Details: ", stream_.str()); +#if !defined(NDEBUG) && !defined(ENVOY_CONFIG_COVERAGE) + if (!g_quiche_bug_exit_disabled) { + abort(); + } +#else + Envoy::Assert::invokeEnvoyBugFailureRecordActionForEnvoyBugMacroUseOnly(bug_name_.data()); +#endif + } +} + +} // namespace quic diff --git a/source/common/quic/platform/quiche_bug_tracker_impl.h b/source/common/quic/platform/quiche_bug_tracker_impl.h index 0d4f8aa884acb..00155e774c7f3 100644 --- a/source/common/quic/platform/quiche_bug_tracker_impl.h +++ b/source/common/quic/platform/quiche_bug_tracker_impl.h @@ -6,11 +6,47 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include "source/common/quic/platform/quic_logging_impl.h" +#include + +#include "absl/strings/string_view.h" + +namespace quic { + +class QuicheBugEmitter { +public: + explicit QuicheBugEmitter(absl::string_view condition_str, absl::string_view bug_name) + : condition_str_(condition_str), bug_name_(bug_name) {} + + ~QuicheBugEmitter(); + + std::ostringstream& stream() { return stream_; } + +private: + std::ostringstream stream_; + const std::string condition_str_; + const std::string bug_name_; +}; + +// Test and fuzz only, not for production, not thread-safe. +class ScopedDisableExitOnQuicheBug { +public: + ScopedDisableExitOnQuicheBug(); + ~ScopedDisableExitOnQuicheBug(); + +private: + const bool previous_value_; +}; + +} // namespace quic + +#define QUICHE_BUG_IF_IMPL(bug_id, condition) \ + switch (0) \ + default: \ + if (!(condition)) { \ + } else \ + quic::QuicheBugEmitter(#condition, #bug_id).stream() + +#define QUICHE_BUG_IMPL(bug_id) QUICHE_BUG_IF_IMPL(bug_id, true) -// TODO(wub): Implement exponential back off to avoid performance problems due -// to excessive QUIC_BUG. -#define QUICHE_BUG_IMPL(bug_id) QUICHE_LOG_IMPL(DFATAL) -#define QUICHE_BUG_IF_IMPL(bug_id, condition) QUICHE_LOG_IF_IMPL(DFATAL, condition) #define QUICHE_PEER_BUG_IMPL(bug_id) QUICHE_LOG_IMPL(ERROR) #define QUICHE_PEER_BUG_IF_IMPL(bug_id, condition) QUICHE_LOG_IF_IMPL(ERROR, condition) diff --git a/source/common/quic/platform/spdy_containers_impl.h b/source/common/quic/platform/spdy_containers_impl.h deleted file mode 100644 index 676127f066c96..0000000000000 --- a/source/common/quic/platform/spdy_containers_impl.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "absl/container/inlined_vector.h" -#include "absl/hash/hash.h" -#include "quiche/common/quiche_linked_hash_map.h" - -namespace spdy { - -template -using SpdyLinkedHashMapImpl = quiche::QuicheLinkedHashMap; - -template -using SpdySmallMapImpl = absl::flat_hash_map; -} // namespace spdy diff --git a/source/common/quic/platform/spdy_string_utils_impl.h b/source/common/quic/platform/spdy_string_utils_impl.h deleted file mode 100644 index e62fdb3f73aad..0000000000000 --- a/source/common/quic/platform/spdy_string_utils_impl.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) -// -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "source/common/quic/platform/string_utils.h" - -#include "absl/strings/escaping.h" -#include "absl/strings/match.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "fmt/printf.h" - -namespace spdy { - -// NOLINTNEXTLINE(readability-identifier-naming) -inline char SpdyHexDigitToIntImpl(char c) { return quiche::HexDigitToInt(c); } - -// NOLINTNEXTLINE(readability-identifier-naming) -inline std::string SpdyHexDecodeImpl(absl::string_view data) { - return absl::HexStringToBytes(data); -} - -// NOLINTNEXTLINE(readability-identifier-naming) -inline bool SpdyHexDecodeToUInt32Impl(absl::string_view data, uint32_t* out) { - return quiche::HexDecodeToUInt32(data, out); -} - -// NOLINTNEXTLINE(readability-identifier-naming) -inline std::string SpdyHexEncodeImpl(const void* bytes, size_t size) { - return absl::BytesToHexString(absl::string_view(static_cast(bytes), size)); -} - -// NOLINTNEXTLINE(readability-identifier-naming) -inline std::string SpdyHexDumpImpl(absl::string_view data) { return quiche::HexDump(data); } - -} // namespace spdy diff --git a/test/common/quic/active_quic_listener_test.cc b/test/common/quic/active_quic_listener_test.cc index 1dbd90bb6009b..396a75fda6e04 100644 --- a/test/common/quic/active_quic_listener_test.cc +++ b/test/common/quic/active_quic_listener_test.cc @@ -88,7 +88,7 @@ class ActiveQuicListenerTest : public QuicMultiVersionTest { } bool use_http3 = GetParam().second == QuicVersionType::Iquic; SetQuicReloadableFlag(quic_disable_version_draft_29, !use_http3); - SetQuicReloadableFlag(quic_enable_version_rfcv1, use_http3); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !use_http3); return quic::CurrentSupportedVersions(); }()[0]), quic_stat_names_(listener_config_.listenerScope().symbolTable()) {} diff --git a/test/common/quic/envoy_quic_client_session_test.cc b/test/common/quic/envoy_quic_client_session_test.cc index d377abd663a6c..62b9c66516736 100644 --- a/test/common/quic/envoy_quic_client_session_test.cc +++ b/test/common/quic/envoy_quic_client_session_test.cc @@ -64,32 +64,6 @@ class TestEnvoyQuicClientConnection : public EnvoyQuicClientConnection { using EnvoyQuicClientConnection::connectionStats; }; -class TestQuicCryptoClientStream : public quic::QuicCryptoClientStream { -public: - TestQuicCryptoClientStream(const quic::QuicServerId& server_id, quic::QuicSession* session, - std::unique_ptr verify_context, - quic::QuicCryptoClientConfig* crypto_config, - ProofHandler* proof_handler, bool has_application_state) - : quic::QuicCryptoClientStream(server_id, session, std::move(verify_context), crypto_config, - proof_handler, has_application_state) {} - - bool encryption_established() const override { return true; } -}; - -class TestQuicCryptoClientStreamFactory : public EnvoyQuicCryptoClientStreamFactoryInterface { -public: - std::unique_ptr - createEnvoyQuicCryptoClientStream(const quic::QuicServerId& server_id, quic::QuicSession* session, - std::unique_ptr verify_context, - quic::QuicCryptoClientConfig* crypto_config, - quic::QuicCryptoClientStream::ProofHandler* proof_handler, - bool has_application_state) override { - return std::make_unique(server_id, session, - std::move(verify_context), crypto_config, - proof_handler, has_application_state); - } -}; - class EnvoyQuicClientSessionTest : public testing::TestWithParam { public: EnvoyQuicClientSessionTest() @@ -97,7 +71,7 @@ class EnvoyQuicClientSessionTest : public testing::TestWithParam { dispatcher_(api_->allocateDispatcher("test_thread")), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { SetQuicReloadableFlag(quic_disable_version_draft_29, !GetParam()); - SetQuicReloadableFlag(quic_enable_version_rfcv1, GetParam()); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !GetParam()); return quic::ParsedVersionOfIndex(quic::CurrentSupportedVersions(), 0); }()), peer_addr_(Network::Utility::getAddressWithPort(*Network::Utility::getIpv6LoopbackAddress(), diff --git a/test/common/quic/envoy_quic_client_stream_test.cc b/test/common/quic/envoy_quic_client_stream_test.cc index a0e381e8e28a5..5de4695bb4794 100644 --- a/test/common/quic/envoy_quic_client_stream_test.cc +++ b/test/common/quic/envoy_quic_client_stream_test.cc @@ -31,7 +31,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { SetQuicReloadableFlag(quic_disable_version_draft_29, !GetParam()); - SetQuicReloadableFlag(quic_enable_version_rfcv1, GetParam()); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !GetParam()); return quic::CurrentSupportedVersions()[0]; }()), peer_addr_(Network::Utility::getAddressWithPort(*Network::Utility::getIpv6LoopbackAddress(), @@ -42,8 +42,10 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { quic::test::TestConnectionId(), connection_helper_, alarm_factory_, &writer_, /*owns_writer=*/false, {quic_version_}, *dispatcher_, createConnectionSocket(peer_addr_, self_addr_, nullptr))), - quic_session_(quic_config_, {quic_version_}, quic_connection_, *dispatcher_, - quic_config_.GetInitialStreamFlowControlWindowToSend() * 2), + quic_session_(quic_config_, {quic_version_}, + std::unique_ptr(quic_connection_), *dispatcher_, + quic_config_.GetInitialStreamFlowControlWindowToSend() * 2, + crypto_stream_factory_), stream_id_(quic::VersionUsesHttp3(quic_version_.transport_version) ? 4u : 5u), stats_({ALL_HTTP3_CODEC_STATS(POOL_COUNTER_PREFIX(scope_, "http3."), POOL_GAUGE_PREFIX(scope_, "http3."))}), @@ -51,6 +53,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { stats_, http3_options_)), request_headers_{{":authority", host_}, {":method", "POST"}, {":path", "/"}}, request_trailers_{{"trailer-key", "trailer-value"}} { + SetQuicReloadableFlag(quic_single_ack_in_packet2, false); quic_stream_->setResponseDecoder(stream_decoder_); quic_stream_->addCallbacks(stream_callbacks_); quic_session_.ActivateStream(std::unique_ptr(quic_stream_)); @@ -145,6 +148,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { Network::Address::InstanceConstSharedPtr self_addr_; MockDelegate delegate_; EnvoyQuicClientConnection* quic_connection_; + TestQuicCryptoClientStreamFactory crypto_stream_factory_; MockEnvoyQuicClientSession quic_session_; quic::QuicStreamId stream_id_; Stats::IsolatedStoreImpl scope_; diff --git a/test/common/quic/envoy_quic_dispatcher_test.cc b/test/common/quic/envoy_quic_dispatcher_test.cc index f15072bd140f9..8260ef7b6e833 100644 --- a/test/common/quic/envoy_quic_dispatcher_test.cc +++ b/test/common/quic/envoy_quic_dispatcher_test.cc @@ -67,7 +67,7 @@ class EnvoyQuicDispatcherTest : public QuicMultiVersionTest, } bool use_http3 = GetParam().second == QuicVersionType::Iquic; SetQuicReloadableFlag(quic_disable_version_draft_29, !use_http3); - SetQuicReloadableFlag(quic_enable_version_rfcv1, use_http3); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !use_http3); return quic::CurrentSupportedVersions(); }()), quic_version_(version_manager_.GetSupportedVersions()[0]), diff --git a/test/common/quic/envoy_quic_server_session_test.cc b/test/common/quic/envoy_quic_server_session_test.cc index df7bf0c8c7015..193db9aa38a4d 100644 --- a/test/common/quic/envoy_quic_server_session_test.cc +++ b/test/common/quic/envoy_quic_server_session_test.cc @@ -153,7 +153,7 @@ class EnvoyQuicServerSessionTest : public testing::TestWithParam { dispatcher_(api_->allocateDispatcher("test_thread")), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { SetQuicReloadableFlag(quic_disable_version_draft_29, !GetParam()); - SetQuicReloadableFlag(quic_enable_version_rfcv1, GetParam()); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !GetParam()); return quic::ParsedVersionOfIndex(quic::CurrentSupportedVersions(), 0); }()), quic_stat_names_(listener_config_.listenerScope().symbolTable()), diff --git a/test/common/quic/envoy_quic_server_stream_test.cc b/test/common/quic/envoy_quic_server_stream_test.cc index 557975eb41b7b..53ffe144a0e3a 100644 --- a/test/common/quic/envoy_quic_server_stream_test.cc +++ b/test/common/quic/envoy_quic_server_stream_test.cc @@ -46,7 +46,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { SetQuicReloadableFlag(quic_disable_version_draft_29, !GetParam()); - SetQuicReloadableFlag(quic_enable_version_rfcv1, GetParam()); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !GetParam()); return quic::CurrentSupportedVersions()[0]; }()), listener_stats_({ALL_LISTENER_STATS(POOL_COUNTER(listener_config_.listenerScope()), diff --git a/test/common/quic/platform/BUILD b/test/common/quic/platform/BUILD index ad15b0e73441e..c7031156309e9 100644 --- a/test/common/quic/platform/BUILD +++ b/test/common/quic/platform/BUILD @@ -61,18 +61,6 @@ envoy_cc_test( ], ) -envoy_cc_test( - name = "spdy_platform_test", - srcs = ["spdy_platform_test.cc"], - external_deps = ["quiche_spdy_platform"], - deps = [ - "//source/common/quic/platform:quiche_flags_impl_lib", - "//test/test_common:logging_lib", - "//test/test_common:utility_lib", - "@com_googlesource_quiche//:spdy_platform", - ], -) - envoy_cc_test_library( name = "epoll_server_platform_impl_lib", hdrs = [ diff --git a/test/common/quic/platform/http2_platform_test.cc b/test/common/quic/platform/http2_platform_test.cc index c25c0e1c0a845..148ab17b30e5e 100644 --- a/test/common/quic/platform/http2_platform_test.cc +++ b/test/common/quic/platform/http2_platform_test.cc @@ -13,8 +13,6 @@ #include "gtest/gtest.h" #include "quiche/http2/platform/api/http2_bug_tracker.h" -#include "quiche/http2/platform/api/http2_containers.h" -#include "quiche/http2/platform/api/http2_estimate_memory_usage.h" #include "quiche/http2/platform/api/http2_flags.h" #include "quiche/http2/platform/api/http2_logging.h" #include "quiche/http2/platform/api/http2_macros.h" @@ -35,18 +33,6 @@ TEST(Http2PlatformTest, Http2BugTracker) { EXPECT_LOG_NOT_CONTAINS("error", "", HTTP2_BUG_IF(bug_1, false) << "A feature is not a bug."); } -TEST(Http2PlatformTest, Http2Deque) { - http2::Http2Deque deque; - deque.push_back(10); - EXPECT_EQ(10, deque.back()); -} - -TEST(Http2PlatformTest, Http2EstimateMemoryUsage) { - std::string s = "foo"; - // Stubbed out to always return 0. - EXPECT_EQ(0, http2::Http2EstimateMemoryUsage(s)); -} - TEST(Http2PlatformTest, Http2Log) { // HTTP2_LOG macros are defined to QUIC_LOG macros, which is tested in // QuicPlatformTest. Here we just make sure HTTP2_LOG macros compile. diff --git a/test/common/quic/platform/quic_expect_bug_impl.h b/test/common/quic/platform/quic_expect_bug_impl.h index 7ddba5ef37546..fee2dc2b283fa 100644 --- a/test/common/quic/platform/quic_expect_bug_impl.h +++ b/test/common/quic/platform/quic_expect_bug_impl.h @@ -6,11 +6,12 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. +#include "test/test_common/utility.h" + #include "quiche/quic/platform/api/quic_logging.h" #include "quiche/quic/platform/api/quic_mock_log.h" -#define EXPECT_QUIC_BUG_IMPL(statement, regex) \ - EXPECT_QUIC_DFATAL_IMPL(statement, testing::ContainsRegex(regex)) +#define EXPECT_QUIC_BUG_IMPL(statement, regex) EXPECT_ENVOY_BUG(statement, regex) #define EXPECT_QUIC_PEER_BUG_IMPL(statement, regex) \ EXPECT_QUIC_LOG_IMPL(statement, ERROR, testing::ContainsRegex(regex)) diff --git a/test/common/quic/platform/quic_platform_test.cc b/test/common/quic/platform/quic_platform_test.cc index 0d53089815957..73d13b22a733d 100644 --- a/test/common/quic/platform/quic_platform_test.cc +++ b/test/common/quic/platform/quic_platform_test.cc @@ -31,14 +31,11 @@ #include "quiche/quic/platform/api/quic_bug_tracker.h" #include "quiche/quic/platform/api/quic_client_stats.h" #include "quiche/quic/platform/api/quic_containers.h" -#include "quiche/quic/platform/api/quic_estimate_memory_usage.h" #include "quiche/quic/platform/api/quic_expect_bug.h" #include "quiche/quic/platform/api/quic_exported_stats.h" -#include "quiche/quic/platform/api/quic_file_utils.h" #include "quiche/quic/platform/api/quic_flags.h" #include "quiche/quic/platform/api/quic_hostname_utils.h" #include "quiche/quic/platform/api/quic_logging.h" -#include "quiche/quic/platform/api/quic_map_util.h" #include "quiche/quic/platform/api/quic_mem_slice.h" #include "quiche/quic/platform/api/quic_mem_slice_span.h" #include "quiche/quic/platform/api/quic_mem_slice_storage.h" @@ -73,6 +70,7 @@ class QuicPlatformTest : public testing::Test { GetLogger().set_level(spdlog::level::err); } + void SetUp() override { Envoy::Assert::resetEnvoyBugCountersForTest(); } ~QuicPlatformTest() override { setVerbosityLogThreshold(verbosity_log_threshold_); GetLogger().set_level(log_level_); @@ -85,9 +83,17 @@ class QuicPlatformTest : public testing::Test { enum class TestEnum { ZERO = 0, ONE, TWO, COUNT }; TEST_F(QuicPlatformTest, QuicBugTracker) { - EXPECT_DEBUG_DEATH(QUIC_BUG(bug_id) << "Here is a bug,", " bug"); - EXPECT_DEBUG_DEATH(QUIC_BUG_IF(bug_id, true) << "There is a bug,", " bug"); - EXPECT_LOG_NOT_CONTAINS("error", "", QUIC_BUG_IF(bug_id, false) << "A feature is not a bug."); + EXPECT_ENVOY_BUG(QUIC_BUG(bug_id) << "Here is a bug,", " bug"); + EXPECT_ENVOY_BUG(QUIC_BUG_IF(bug_id, 1 == 1) << "There is a bug,", " bug"); + bool evaluated = false; + EXPECT_LOG_NOT_CONTAINS( + "error", "", QUIC_BUG_IF(bug_id_1, false) << "A feature is not a bug." << (evaluated = true)); + EXPECT_FALSE(evaluated); + + { + ScopedDisableExitOnQuicheBug no_crash_quiche_bug; + QUIC_BUG(bug_id_2) << "No crash bug"; + } EXPECT_LOG_CONTAINS("error", " bug", QUIC_PEER_BUG(bug_id) << "Everywhere's a bug,"); EXPECT_LOG_CONTAINS("error", " here", QUIC_PEER_BUG_IF(bug_id, true) << "Including here."); @@ -112,9 +118,14 @@ TEST_F(QuicPlatformTest, QuicExpectBug) { auto bug = [](const char* error_message) { QUIC_BUG(bug_id) << error_message; }; auto peer_bug = [](const char* error_message) { QUIC_PEER_BUG(bug_id) << error_message; }; - EXPECT_QUIC_BUG(bug("bug one is expected"), "bug one"); EXPECT_QUIC_BUG(bug("bug two is expected"), "bug two"); +#ifdef NDEBUG + // The 3rd triggering in release mode should not be logged. + EXPECT_LOG_NOT_CONTAINS("error", "bug three", bug("bug three is expected")); +#else + EXPECT_QUIC_BUG(bug("bug three is expected"), "bug three"); +#endif EXPECT_QUIC_PEER_BUG(peer_bug("peer_bug_1 is expected"), "peer_bug_1"); EXPECT_QUIC_PEER_BUG(peer_bug("peer_bug_2 is expected"), "peer_bug_2"); @@ -139,28 +150,6 @@ TEST_F(QuicPlatformTest, QuicHostnameUtils) { EXPECT_EQ("quicwg.org", QuicHostnameUtils::NormalizeHostname("QUICWG.ORG")); } -TEST_F(QuicPlatformTest, QuicInlinedVector) { - QuicInlinedVector vec; - vec.push_back(3); - EXPECT_EQ(3, vec[0]); -} - -TEST_F(QuicPlatformTest, QuicEstimateMemoryUsage) { - std::string s = "foo"; - // Stubbed out to always return 0. - EXPECT_EQ(0, QuicEstimateMemoryUsage(s)); -} - -TEST_F(QuicPlatformTest, QuicMapUtil) { - std::map stdmap = {{"one", 1}, {"two", 2}, {"three", 3}}; - EXPECT_TRUE(QuicContainsKey(stdmap, "one")); - EXPECT_FALSE(QuicContainsKey(stdmap, "zero")); - - std::vector stdvec = {1, 2, 3}; - EXPECT_TRUE(QuicContainsValue(stdvec, 1)); - EXPECT_FALSE(QuicContainsValue(stdvec, 0)); -} - TEST_F(QuicPlatformTest, QuicMockLog) { ASSERT_EQ(spdlog::level::err, GetLogger().level()); @@ -577,25 +566,6 @@ class FileUtilsTest : public testing::Test { std::stack files_to_remove_; }; -TEST_F(FileUtilsTest, ReadDirContents) { - addSubDirs({"sub_dir1", "sub_dir2", "sub_dir1/sub_dir1_1"}); - addFiles({"file", "sub_dir1/sub_file1", "sub_dir1/sub_dir1_1/sub_file1_1", "sub_dir2/sub_file2"}); - - EXPECT_THAT(ReadFileContents(dir_path_), - testing::UnorderedElementsAre(dir_path_ + "/file", dir_path_ + "/sub_dir1/sub_file1", - dir_path_ + "/sub_dir1/sub_dir1_1/sub_file1_1", - dir_path_ + "/sub_dir2/sub_file2")); -} - -TEST_F(FileUtilsTest, ReadFileContents) { - const std::string data = "test string\ntest"; - const std::string file_path = - Envoy::TestEnvironment::writeStringToFileForTest("test_envoy", data); - std::string output; - ReadFileContents(file_path, &output); - EXPECT_EQ(data, output); -} - TEST_F(QuicPlatformTest, TestEnvoyQuicBufferAllocator) { QuicStreamBufferAllocator allocator; Envoy::Stats::TestUtil::MemoryTest memory_test; @@ -664,6 +634,19 @@ TEST(EnvoyQuicMemSliceTest, ConstructQuicMemSliceSpan) { QuicMemSliceSpan span(&slice); EXPECT_EQ(1024u, span.total_length()); EXPECT_EQ(str, span.GetData(0)); + span.ConsumeAll([](quic::QuicMemSlice&& mem_slice) { mem_slice.Reset(); }); + EXPECT_EQ(0u, span.total_length()); + + QuicMemSlice slice3; + { + quic::QuicMemSlice slice2{quic::QuicMemSliceImpl(std::make_unique(5), 5u)}; + + QuicMemSliceSpan span2(&slice2); + EXPECT_EQ(5u, span2.total_length()); + span2.ConsumeAll([&slice3](quic::QuicMemSlice&& mem_slice) { slice3 = std::move(mem_slice); }); + EXPECT_EQ(0u, span2.total_length()); + } + slice3.Reset(); } TEST(EnvoyQuicMemSliceTest, QuicMemSliceStorage) { diff --git a/test/common/quic/platform/quiche_test_impl.h b/test/common/quic/platform/quiche_test_impl.h index 34e5f3eeefd1e..8362180983c5a 100644 --- a/test/common/quic/platform/quiche_test_impl.h +++ b/test/common/quic/platform/quiche_test_impl.h @@ -6,6 +6,7 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. +#include "absl/strings/str_cat.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -16,5 +17,11 @@ using QuicheTest = ::testing::Test; template using QuicheTestWithParamImpl = ::testing::TestWithParam; +// NOLINTNEXTLINE(readability-identifier-naming) +inline std::string QuicheGetCommonSourcePathImpl() { + std::string test_srcdir(getenv("TEST_SRCDIR")); + return absl::StrCat(test_srcdir, "/external/com_googlesource_quiche/quiche/common"); +} + } // namespace test } // namespace quiche diff --git a/test/common/quic/test_utils.h b/test/common/quic/test_utils.h index ec7249ffd39e0..c5487c81538e0 100644 --- a/test/common/quic/test_utils.h +++ b/test/common/quic/test_utils.h @@ -11,7 +11,6 @@ #endif #include "quiche/quic/core/http/quic_spdy_session.h" -#include "quiche/quic/core/http/quic_spdy_client_session.h" #include "quiche/quic/test_tools/quic_test_utils.h" #include "quiche/quic/test_tools/first_flight.h" #include "quiche/quic/core/quic_utils.h" @@ -25,6 +24,7 @@ #endif #include "source/common/quic/envoy_quic_utils.h" +#include "source/common/quic/envoy_quic_client_session.h" #include "test/test_common/environment.h" namespace Envoy { @@ -66,6 +66,14 @@ class MockEnvoyQuicServerConnection : public EnvoyQuicServerConnection { MOCK_METHOD(void, dumpState, (std::ostream&, int), (const)); }; +class TestQuicCryptoStream : public quic::test::MockQuicCryptoStream { +public: + explicit TestQuicCryptoStream(quic::QuicSession* session) + : quic::test::MockQuicCryptoStream(session) {} + + bool encryption_established() const override { return true; } +}; + class MockEnvoyQuicSession : public quic::QuicSpdySession, public QuicFilterManagerConnectionImpl { public: MockEnvoyQuicSession(const quic::QuicConfig& config, @@ -74,9 +82,8 @@ class MockEnvoyQuicSession : public quic::QuicSpdySession, public QuicFilterMana uint32_t send_buffer_limit) : quic::QuicSpdySession(connection, /*visitor=*/nullptr, config, supported_versions), QuicFilterManagerConnectionImpl(*connection, connection->connection_id(), dispatcher, - send_buffer_limit) { - crypto_stream_ = std::make_unique(this); - } + send_buffer_limit), + crypto_stream_(std::make_unique(this)) {} void Initialize() override { quic::QuicSpdySession::Initialize(); @@ -124,22 +131,47 @@ class MockEnvoyQuicSession : public quic::QuicSpdySession, public QuicFilterMana std::unique_ptr crypto_stream_; }; -class MockEnvoyQuicClientSession : public quic::QuicSpdyClientSession, - public QuicFilterManagerConnectionImpl { +class TestQuicCryptoClientStream : public quic::QuicCryptoClientStream { +public: + TestQuicCryptoClientStream(const quic::QuicServerId& server_id, quic::QuicSession* session, + std::unique_ptr verify_context, + quic::QuicCryptoClientConfig* crypto_config, + ProofHandler* proof_handler, bool has_application_state) + : quic::QuicCryptoClientStream(server_id, session, std::move(verify_context), crypto_config, + proof_handler, has_application_state) {} + + bool encryption_established() const override { return true; } +}; + +class TestQuicCryptoClientStreamFactory : public EnvoyQuicCryptoClientStreamFactoryInterface { +public: + std::unique_ptr + createEnvoyQuicCryptoClientStream(const quic::QuicServerId& server_id, quic::QuicSession* session, + std::unique_ptr verify_context, + quic::QuicCryptoClientConfig* crypto_config, + quic::QuicCryptoClientStream::ProofHandler* proof_handler, + bool has_application_state) override { + return std::make_unique(server_id, session, + std::move(verify_context), crypto_config, + proof_handler, has_application_state); + } +}; + +class MockEnvoyQuicClientSession : public EnvoyQuicClientSession { public: MockEnvoyQuicClientSession(const quic::QuicConfig& config, const quic::ParsedQuicVersionVector& supported_versions, - EnvoyQuicClientConnection* connection, Event::Dispatcher& dispatcher, - uint32_t send_buffer_limit) - : quic::QuicSpdyClientSession(config, supported_versions, connection, - quic::QuicServerId("example.com", 443, false), &crypto_config_, - nullptr), - QuicFilterManagerConnectionImpl(*connection, connection->connection_id(), dispatcher, - send_buffer_limit), - crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting()) {} + std::unique_ptr connection, + Event::Dispatcher& dispatcher, uint32_t send_buffer_limit, + EnvoyQuicCryptoClientStreamFactoryInterface& crypto_stream_factory) + : EnvoyQuicClientSession(config, supported_versions, std::move(connection), + quic::QuicServerId("example.com", 443, false), + std::make_shared( + quic::test::crypto_test_utils::ProofVerifierForTesting()), + nullptr, dispatcher, send_buffer_limit, crypto_stream_factory) {} void Initialize() override { - quic::QuicSpdyClientSession::Initialize(); + EnvoyQuicClientSession::Initialize(); initialized_ = true; } @@ -171,9 +203,6 @@ class MockEnvoyQuicClientSession : public quic::QuicSpdyClientSession, return initialized_ ? connection() : nullptr; } quic::QuicConnection* quicConnection() override { return initialized_ ? connection() : nullptr; } - -private: - quic::QuicCryptoClientConfig crypto_config_; }; Buffer::OwnedImpl @@ -253,11 +282,9 @@ std::string spdyHeaderToHttp3StreamPayload(const spdy::SpdyHeaderBlock& header) } std::string bodyToHttp3StreamPayload(const std::string& body) { - std::unique_ptr data_buffer; - quic::QuicByteCount data_frame_header_length = - quic::HttpEncoder::SerializeDataFrameHeader(body.length(), &data_buffer); - absl::string_view data_frame_header(data_buffer.get(), data_frame_header_length); - return absl::StrCat(data_frame_header, body); + quic::SimpleBufferAllocator allocator; + quic::QuicBuffer header = quic::HttpEncoder::SerializeDataFrameHeader(body.length(), &allocator); + return absl::StrCat(header.AsStringView(), body); } // A test suite with variation of ip version and a knob to turn on/off IETF QUIC implementation. diff --git a/test/integration/quic_http_integration_test.cc b/test/integration/quic_http_integration_test.cc index 9ef03170c68e2..689180997ebd5 100644 --- a/test/integration/quic_http_integration_test.cc +++ b/test/integration/quic_http_integration_test.cc @@ -74,7 +74,7 @@ class QuicHttpIntegrationTest : public HttpIntegrationTest, public QuicMultiVers } bool use_http3 = GetParam().second == QuicVersionType::Iquic; SetQuicReloadableFlag(quic_disable_version_draft_29, !use_http3); - SetQuicReloadableFlag(quic_enable_version_rfcv1, use_http3); + SetQuicReloadableFlag(quic_disable_version_rfcv1, !use_http3); return quic::CurrentSupportedVersions(); }()), conn_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *conn_helper_.GetClock()) {}